diff --git a/mysql-test/suite/innodb/r/rename_table_debug.result b/mysql-test/suite/innodb/r/rename_table_debug.result index 912ed9de48b..7c9b961dee5 100644 --- a/mysql-test/suite/innodb/r/rename_table_debug.result +++ b/mysql-test/suite/innodb/r/rename_table_debug.result @@ -1,5 +1,5 @@ -CREATE TABLE t1 (a INT UNSIGNED PRIMARY KEY) ENGINE=InnoDB; -INSERT INTO t1 VALUES(42); +CREATE TABLE t1 (a SERIAL, b INT, c INT, d INT) ENGINE=InnoDB; +INSERT INTO t1 () VALUES (); connect con1,localhost,root,,test; SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever'; RENAME TABLE t1 TO t2; @@ -7,6 +7,29 @@ connection default; SET DEBUG_SYNC='now WAIT_FOR renamed'; disconnect con1; SELECT * FROM t1; -a -42 +a b c d +1 NULL NULL NULL +BEGIN; +COMMIT; +UPDATE t1 SET b=a%7, c=a%11, d=a%13; +SET DEBUG_DBUG='+d,crash_commit_before'; +ALTER TABLE t1 +ADD INDEX(b,c,d,a),ADD INDEX(b,c,a,d),ADD INDEX(b,a,c,d),ADD INDEX(b,a,d,c), +ADD INDEX(b,d,a,c),ADD INDEX(b,d,c,a),ADD INDEX(a,b,c,d),ADD INDEX(a,b,d,c), +ADD INDEX(a,c,b,d),ADD INDEX(a,c,d,b),ADD INDEX(a,d,b,c),ADD INDEX(a,d,c,b), +ADD INDEX(c,a,b,d),ADD INDEX(c,a,d,b),ADD INDEX(c,b,a,d),ADD INDEX(c,b,d,a), +ADD INDEX(c,d,a,b),ADD INDEX(c,d,b,a),ADD INDEX(d,a,b,c),ADD INDEX(d,a,c,b), +ADD INDEX(d,b,a,c),ADD INDEX(d,b,c,a),ADD INDEX(d,c,a,b),ADD INDEX(d,c,b,a), +ADD INDEX(a,b,c), ADD INDEX(a,c,b), ADD INDEX(a,c,d), ADD INDEX(a,d,c), +ADD INDEX(a,b,d), ADD INDEX(a,d,b), ADD INDEX(b,c,d), ADD INDEX(b,d,c), +ALGORITHM=COPY; +ERROR HY000: Lost connection to MySQL server during query +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +1000 DROP TABLE t1; +SET GLOBAL innodb_background_drop_list_empty= +@@GLOBAL.innodb_background_drop_list_empty; diff --git a/mysql-test/suite/innodb/t/rename_table_debug.test b/mysql-test/suite/innodb/t/rename_table_debug.test index 4620f7bef22..20af12dc15c 100644 --- a/mysql-test/suite/innodb/t/rename_table_debug.test +++ b/mysql-test/suite/innodb/t/rename_table_debug.test @@ -3,8 +3,10 @@ --source include/have_debug_sync.inc --source include/not_embedded.inc -CREATE TABLE t1 (a INT UNSIGNED PRIMARY KEY) ENGINE=InnoDB; -INSERT INTO t1 VALUES(42); +LET $datadir= `SELECT @@datadir`; + +CREATE TABLE t1 (a SERIAL, b INT, c INT, d INT) ENGINE=InnoDB; +INSERT INTO t1 () VALUES (); --connect (con1,localhost,root,,test) SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever'; @@ -16,4 +18,37 @@ SET DEBUG_SYNC='now WAIT_FOR renamed'; --source include/restart_mysqld.inc --disconnect con1 SELECT * FROM t1; + +let $c = 999; +BEGIN; +--disable_query_log +while ($c) { +INSERT INTO t1() VALUES(); +dec $c; +} +--enable_query_log +COMMIT; +UPDATE t1 SET b=a%7, c=a%11, d=a%13; + +--source include/expect_crash.inc +SET DEBUG_DBUG='+d,crash_commit_before'; +--error 2013 +ALTER TABLE t1 +ADD INDEX(b,c,d,a),ADD INDEX(b,c,a,d),ADD INDEX(b,a,c,d),ADD INDEX(b,a,d,c), +ADD INDEX(b,d,a,c),ADD INDEX(b,d,c,a),ADD INDEX(a,b,c,d),ADD INDEX(a,b,d,c), +ADD INDEX(a,c,b,d),ADD INDEX(a,c,d,b),ADD INDEX(a,d,b,c),ADD INDEX(a,d,c,b), +ADD INDEX(c,a,b,d),ADD INDEX(c,a,d,b),ADD INDEX(c,b,a,d),ADD INDEX(c,b,d,a), +ADD INDEX(c,d,a,b),ADD INDEX(c,d,b,a),ADD INDEX(d,a,b,c),ADD INDEX(d,a,c,b), +ADD INDEX(d,b,a,c),ADD INDEX(d,b,c,a),ADD INDEX(d,c,a,b),ADD INDEX(d,c,b,a), +ADD INDEX(a,b,c), ADD INDEX(a,c,b), ADD INDEX(a,c,d), ADD INDEX(a,d,c), +ADD INDEX(a,b,d), ADD INDEX(a,d,b), ADD INDEX(b,c,d), ADD INDEX(b,d,c), +ALGORITHM=COPY; +--source include/start_mysqld.inc +CHECK TABLE t1; +SELECT COUNT(*) FROM t1; DROP TABLE t1; +# MDEV-11415 TODO: remove the following +SET GLOBAL innodb_background_drop_list_empty= +@@GLOBAL.innodb_background_drop_list_empty; +# Work around missing crash recovery at the SQL layer. +--remove_files_wildcard $datadir/test #sql-*.frm diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 8f9b5296015..c3c6e66b3e4 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -3712,7 +3712,7 @@ row_drop_table_for_mysql( if (table->n_foreign_key_checks_running > 0) { defer: - if (!strstr(table->name.m_name, "/" TEMP_FILE_PREFIX_INNODB)) { + if (!strstr(table->name.m_name, "/" TEMP_FILE_PREFIX)) { heap = mem_heap_create(FN_REFLEN); const char* tmp_name = dict_mem_create_temporary_tablename( @@ -4477,7 +4477,7 @@ row_rename_table_for_mysql( goto funct_exit; - } else if (new_is_tmp) { + } else if (!old_is_tmp && new_is_tmp) { /* MySQL is doing an ALTER TABLE command and it renames the original table to a temporary table name. We want to preserve the original foreign key constraint definitions despite the