Apply innodb-5.1-ss2146 and innodb-5.1-ss2178 snapshots.

Fixes:

Bug #18942: DROP DATABASE does not drop an orphan FOREIGN KEY constraint
  Fix Bug#18942 by dropping all foreign key constraints at the end of
  DROP DATABASE. Usually, by then, there are no foreign constraints
  left because all of them are dropped when the relevant tables are
  dropped. This code is to ensure that any orphaned FKs are wiped too.

Bug #29157: UPDATE, changed rows incorrect
  Return HA_ERR_RECORD_IS_THE_SAME from ha_innobase::update_row() if no
  columns were updated.

Bug #32440: InnoDB free space info does not appear in SHOW TABLE STATUS or I_S
  Put information about the free space in a tablespace in
  INFORMATION_SCHEMA.TABLES.DATA_FREE. This information was previously
  available in INFORMATION_SCHEMA.TABLES.TABLE_COMMENT, but MySQL has
  removed it from there recently.
  The stored value is in kilobytes.
  This can be considered as a permanent workaround to
  http://bugs.mysql.com/32440. "Workaround" becasue that bug is about the
  data missing from TABLE_COMMENT and this is actually not solved.
parent a0fbcc03
set autocommit=1;
reset master;
create table bug16206 (a int);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
f n Query 1 n use `test`; create table bug16206 (a int)
f n Query 1 n use `test`; insert into bug16206 values(1)
f n Query 1 n use `test`; insert into bug16206 values(2)
drop table bug16206;
reset master;
create table bug16206 (a int) engine= bdb;
insert into bug16206 values(0);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
insert into bug16206 values(3);
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb
f n Query 1 n use `test`; insert into bug16206 values(0)
f n Query 1 n use `test`; insert into bug16206 values(1)
f n Query 1 n use `test`; BEGIN
f n Query 1 n use `test`; insert into bug16206 values(2)
f n Query 1 n use `test`; COMMIT
f n Query 1 n use `test`; insert into bug16206 values(3)
drop table bug16206;
set autocommit=0;
End of 5.0 tests
...@@ -3218,3 +3218,16 @@ a ...@@ -3218,3 +3218,16 @@ a
2 2
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
create table t1 (i int, j int) engine=innodb;
insert into t1 (i, j) values (1, 1), (2, 2);
update t1 set j = 2;
affected rows: 1
info: Rows matched: 2 Changed: 1 Warnings: 0
drop table t1;
create table t1 (id int) comment='this is a comment' engine=innodb;
select table_comment, data_free > 0 as data_free_is_set
from information_schema.tables
where table_schema='test' and table_name = 't1';
table_comment data_free_is_set
this is a comment 1
drop table t1;
...@@ -13,33 +13,33 @@ DROP TABLE t1; ...@@ -13,33 +13,33 @@ DROP TABLE t1;
create table t1 (a int) engine=innodb partition by hash(a) ; create table t1 (a int) engine=innodb partition by hash(a) ;
show table status like 't1'; show table status like 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 2 8192 16384 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned t1 InnoDB 10 Compact 2 8192 16384 0 0 # NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
drop table t1; drop table t1;
create table t1 (a int) create table t1 (a int)
engine = innodb engine = innodb
partition by key (a); partition by key (a);
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 2 8192 16384 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned t1 InnoDB 10 Compact 2 8192 16384 0 0 # NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
insert into t1 values (0), (1), (2), (3); insert into t1 values (0), (1), (2), (3);
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 4 4096 16384 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned t1 InnoDB 10 Compact 4 4096 16384 0 0 # NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
drop table t1; drop table t1;
create table t1 (a int auto_increment primary key) create table t1 (a int auto_increment primary key)
engine = innodb engine = innodb
partition by key (a); partition by key (a);
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 2 8192 16384 0 0 0 1 NULL NULL NULL latin1_swedish_ci NULL partitioned t1 InnoDB 10 Compact 2 8192 16384 0 0 # 1 NULL NULL NULL latin1_swedish_ci NULL partitioned
insert into t1 values (NULL), (NULL), (NULL), (NULL); insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 4 4096 16384 0 0 0 5 NULL NULL NULL latin1_swedish_ci NULL partitioned t1 InnoDB 10 Compact 4 4096 16384 0 0 # 5 NULL NULL NULL latin1_swedish_ci NULL partitioned
insert into t1 values (NULL), (NULL), (NULL), (NULL); insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 8 2048 16384 0 0 0 9 NULL NULL NULL latin1_swedish_ci NULL partitioned t1 InnoDB 10 Compact 8 2048 16384 0 0 # 9 NULL NULL NULL latin1_swedish_ci NULL partitioned
drop table t1; drop table t1;
create table t1 (a int) create table t1 (a int)
partition by key (a) partition by key (a)
......
-- source include/not_embedded.inc
-- source include/have_bdb.inc
#
# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode
#
set autocommit=1;
let $VERSION=`select version()`;
reset master;
create table bug16206 (a int);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
--replace_result $VERSION VERSION
--replace_column 1 f 2 n 5 n
show binlog events;
drop table bug16206;
reset master;
create table bug16206 (a int) engine= bdb;
insert into bug16206 values(0);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
insert into bug16206 values(3);
--replace_result $VERSION VERSION
--replace_column 1 f 2 n 5 n
show binlog events;
drop table bug16206;
set autocommit=0;
--echo End of 5.0 tests
...@@ -2382,6 +2382,27 @@ DROP TABLE t1; ...@@ -2382,6 +2382,27 @@ DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
DISCONNECT c1; DISCONNECT c1;
DISCONNECT c2; DISCONNECT c2;
CONNECTION default;
#
# Bug #29157 UPDATE, changed rows incorrect
#
create table t1 (i int, j int) engine=innodb;
insert into t1 (i, j) values (1, 1), (2, 2);
--enable_info
update t1 set j = 2;
--disable_info
drop table t1;
#
# Bug #32440 InnoDB free space info does not appear in SHOW TABLE STATUS or
# I_S
#
create table t1 (id int) comment='this is a comment' engine=innodb;
select table_comment, data_free > 0 as data_free_is_set
from information_schema.tables
where table_schema='test' and table_name = 't1';
drop table t1;
####################################################################### #######################################################################
# # # #
......
...@@ -20,6 +20,9 @@ DROP TABLE t1; ...@@ -20,6 +20,9 @@ DROP TABLE t1;
# Bug #14673: Wrong InnoDB default row format # Bug #14673: Wrong InnoDB default row format
# #
create table t1 (a int) engine=innodb partition by hash(a) ; create table t1 (a int) engine=innodb partition by hash(a) ;
# Data_free for InnoDB tablespace varies depending on which
# tests have been run before this one
--replace_column 10 #
show table status like 't1'; show table status like 't1';
drop table t1; drop table t1;
...@@ -29,18 +32,33 @@ drop table t1; ...@@ -29,18 +32,33 @@ drop table t1;
create table t1 (a int) create table t1 (a int)
engine = innodb engine = innodb
partition by key (a); partition by key (a);
# Data_free for InnoDB tablespace varies depending on which
# tests have been run before this one
--replace_column 10 #
show table status; show table status;
insert into t1 values (0), (1), (2), (3); insert into t1 values (0), (1), (2), (3);
# Data_free for InnoDB tablespace varies depending on which
# tests have been run before this one
--replace_column 10 #
show table status; show table status;
drop table t1; drop table t1;
create table t1 (a int auto_increment primary key) create table t1 (a int auto_increment primary key)
engine = innodb engine = innodb
partition by key (a); partition by key (a);
# Data_free for InnoDB tablespace varies depending on which
# tests have been run before this one
--replace_column 10 #
show table status; show table status;
insert into t1 values (NULL), (NULL), (NULL), (NULL); insert into t1 values (NULL), (NULL), (NULL), (NULL);
# Data_free for InnoDB tablespace varies depending on which
# tests have been run before this one
--replace_column 10 #
show table status; show table status;
insert into t1 values (NULL), (NULL), (NULL), (NULL); insert into t1 values (NULL), (NULL), (NULL), (NULL);
# Data_free for InnoDB tablespace varies depending on which
# tests have been run before this one
--replace_column 10 #
show table status; show table status;
drop table t1; drop table t1;
......
...@@ -600,7 +600,9 @@ convert_error_code_to_mysql( ...@@ -600,7 +600,9 @@ convert_error_code_to_mysql(
tell it also to MySQL so that MySQL knows to empty the tell it also to MySQL so that MySQL knows to empty the
cached binlog for this transaction */ cached binlog for this transaction */
thd_mark_transaction_to_rollback(thd, TRUE); if (thd) {
thd_mark_transaction_to_rollback(thd, TRUE);
}
return(HA_ERR_LOCK_DEADLOCK); return(HA_ERR_LOCK_DEADLOCK);
} else if (error == (int) DB_LOCK_WAIT_TIMEOUT) { } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
...@@ -609,8 +611,10 @@ convert_error_code_to_mysql( ...@@ -609,8 +611,10 @@ convert_error_code_to_mysql(
latest SQL statement in a lock wait timeout. Previously, we latest SQL statement in a lock wait timeout. Previously, we
rolled back the whole transaction. */ rolled back the whole transaction. */
thd_mark_transaction_to_rollback(thd, if (thd) {
(bool)row_rollback_on_timeout); thd_mark_transaction_to_rollback(
thd, (bool)row_rollback_on_timeout);
}
return(HA_ERR_LOCK_WAIT_TIMEOUT); return(HA_ERR_LOCK_WAIT_TIMEOUT);
...@@ -662,7 +666,9 @@ convert_error_code_to_mysql( ...@@ -662,7 +666,9 @@ convert_error_code_to_mysql(
tell it also to MySQL so that MySQL knows to empty the tell it also to MySQL so that MySQL knows to empty the
cached binlog for this transaction */ cached binlog for this transaction */
thd_mark_transaction_to_rollback(thd, TRUE); if (thd) {
thd_mark_transaction_to_rollback(thd, TRUE);
}
return(HA_ERR_LOCK_TABLE_FULL); return(HA_ERR_LOCK_TABLE_FULL);
} else if (error == DB_TOO_MANY_CONCURRENT_TRXS) { } else if (error == DB_TOO_MANY_CONCURRENT_TRXS) {
...@@ -3769,6 +3775,16 @@ ha_innobase::update_row( ...@@ -3769,6 +3775,16 @@ ha_innobase::update_row(
error = convert_error_code_to_mysql(error, user_thd); error = convert_error_code_to_mysql(error, user_thd);
if (error == 0 /* success */
&& uvect->n_fields == 0 /* no columns were updated */) {
/* This is the same as success, but instructs
MySQL that the row is not really updated and it
should not increase the count of updated rows.
This is fix for http://bugs.mysql.com/29157 */
error = HA_ERR_RECORD_IS_THE_SAME;
}
/* Tell InnoDB server that there might be work for /* Tell InnoDB server that there might be work for
utility threads: */ utility threads: */
...@@ -5720,7 +5736,9 @@ ha_innobase::info( ...@@ -5720,7 +5736,9 @@ ha_innobase::info(
stats.index_file_length = ((ulonglong) stats.index_file_length = ((ulonglong)
ib_table->stat_sum_of_other_index_sizes) ib_table->stat_sum_of_other_index_sizes)
* UNIV_PAGE_SIZE; * UNIV_PAGE_SIZE;
stats.delete_length = 0; stats.delete_length =
fsp_get_available_space_in_free_extents(
ib_table->space);
stats.check_time = 0; stats.check_time = 0;
if (stats.records == 0) { if (stats.records == 0) {
...@@ -7246,6 +7264,7 @@ On return if there is no error then the tables AUTOINC lock is locked.*/ ...@@ -7246,6 +7264,7 @@ On return if there is no error then the tables AUTOINC lock is locked.*/
ulong ulong
ha_innobase::innobase_get_auto_increment( ha_innobase::innobase_get_auto_increment(
/*=====================================*/
ulonglong* value) /* out: autoinc value */ ulonglong* value) /* out: autoinc value */
{ {
ulong error; ulong error;
......
...@@ -3312,6 +3312,66 @@ funct_exit: ...@@ -3312,6 +3312,66 @@ funct_exit:
return((int) err); return((int) err);
} }
/***********************************************************************
Drop all foreign keys in a database, see Bug#18942.
Called at the end of row_drop_database_for_mysql(). */
static
ulint
drop_all_foreign_keys_in_db(
/*========================*/
/* out: error code or DB_SUCCESS */
const char* name, /* in: database name which ends to '/' */
trx_t* trx) /* in: transaction handle */
{
pars_info_t* pinfo;
ulint err;
ut_a(name[strlen(name) - 1] == '/');
pinfo = pars_info_create();
pars_info_add_str_literal(pinfo, "dbname", name);
/* true if for_name is not prefixed with dbname */
#define TABLE_NOT_IN_THIS_DB \
"SUBSTR(for_name, 0, LENGTH(:dbname)) <> :dbname"
err = que_eval_sql(pinfo,
"PROCEDURE DROP_ALL_FOREIGN_KEYS_PROC () IS\n"
"foreign_id CHAR;\n"
"for_name CHAR;\n"
"found INT;\n"
"DECLARE CURSOR cur IS\n"
"SELECT ID, FOR_NAME FROM SYS_FOREIGN\n"
"WHERE FOR_NAME >= :dbname\n"
"LOCK IN SHARE MODE\n"
"ORDER BY FOR_NAME;\n"
"BEGIN\n"
"found := 1;\n"
"OPEN cur;\n"
"WHILE found = 1 LOOP\n"
" FETCH cur INTO foreign_id, for_name;\n"
" IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n"
" ELSIF (" TABLE_NOT_IN_THIS_DB ") THEN\n"
" found := 0;\n"
" ELSIF (1=1) THEN\n"
" DELETE FROM SYS_FOREIGN_COLS\n"
" WHERE ID = foreign_id;\n"
" DELETE FROM SYS_FOREIGN\n"
" WHERE ID = foreign_id;\n"
" END IF;\n"
"END LOOP;\n"
"CLOSE cur;\n"
"COMMIT WORK;\n"
"END;\n",
FALSE, /* do not reserve dict mutex,
we are already holding it */
trx);
return(err);
}
/************************************************************************* /*************************************************************************
Drops a database for MySQL. */ Drops a database for MySQL. */
...@@ -3382,6 +3442,19 @@ loop: ...@@ -3382,6 +3442,19 @@ loop:
} }
} }
if (err == DB_SUCCESS) {
/* after dropping all tables try to drop all leftover
foreign keys in case orphaned ones exist */
err = (int) drop_all_foreign_keys_in_db(name, trx);
if (err != DB_SUCCESS) {
fputs("InnoDB: DROP DATABASE ", stderr);
ut_print_name(stderr, trx, TRUE, name);
fprintf(stderr, " failed with error %d while "
"dropping all foreign keys", err);
}
}
trx_commit_for_mysql(trx); trx_commit_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx); row_mysql_unlock_data_dictionary(trx);
......
...@@ -933,6 +933,7 @@ trx_commit_off_kernel( ...@@ -933,6 +933,7 @@ trx_commit_off_kernel(
trx->rseg = NULL; trx->rseg = NULL;
trx->undo_no = ut_dulint_zero; trx->undo_no = ut_dulint_zero;
trx->last_sql_stat_start.least_undo_no = ut_dulint_zero; trx->last_sql_stat_start.least_undo_no = ut_dulint_zero;
trx->mysql_query_str = NULL;
ut_ad(UT_LIST_GET_LEN(trx->wait_thrs) == 0); ut_ad(UT_LIST_GET_LEN(trx->wait_thrs) == 0);
ut_ad(UT_LIST_GET_LEN(trx->trx_locks) == 0); ut_ad(UT_LIST_GET_LEN(trx->trx_locks) == 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment