diff options
author | Eugene Kosov <claprix@yandex.ru> | 2018-12-14 01:28:55 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-12-28 17:05:48 +0200 |
commit | c5a5eaa9a996015517c1ebbce19551c6e650cba1 (patch) | |
tree | 8a937d2744264ebf242d5087f49f3ed6e269f82a | |
parent | 9ad1663f785d28a731ab8212ea62b8125282a27f (diff) | |
download | mariadb-git-c5a5eaa9a996015517c1ebbce19551c6e650cba1.tar.gz |
MDEV-17470 Orphan temporary files after interrupted ALTER cause InnoDB: Operating system error number 17 and eventual fatal error 71
Orphan #sql* tables may remain after ALTER TABLE
was interrupted by timeout or KILL or client disconnect.
This is a regression caused by MDEV-16515.
Similar to temporary tables (MDEV-16647), we had better ignore the
KILL when dropping the original table in the final part of ALTER TABLE.
Closes #1020
-rw-r--r-- | mysql-test/suite/innodb/r/innodb-alter-debug.result | 21 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb-alter-debug.test | 28 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 5 | ||||
-rw-r--r-- | storage/xtradb/row/row0mysql.cc | 5 |
4 files changed, 55 insertions, 4 deletions
diff --git a/mysql-test/suite/innodb/r/innodb-alter-debug.result b/mysql-test/suite/innodb/r/innodb-alter-debug.result index d888fb5b034..5ce93b96c77 100644 --- a/mysql-test/suite/innodb/r/innodb-alter-debug.result +++ b/mysql-test/suite/innodb/r/innodb-alter-debug.result @@ -68,3 +68,24 @@ SET DEBUG_SYNC = 'now SIGNAL S2'; ERROR 23000: Duplicate entry '1' for key 'a' SET DEBUG_SYNC='RESET'; DROP TABLE t1; +# +# MDEV-17470 Orphan temporary files after interrupted ALTER +# cause InnoDB: Operating system error number 17 and eventual +# fatal error 71 +# +CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, i INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL,1),(NULL,2),(NULL,3),(NULL,4),(NULL,5),(NULL,6),(NULL,7),(NULL,8); +INSERT INTO t1 SELECT NULL, i FROM t1; +INSERT INTO t1 SELECT NULL, i FROM t1; +INSERT INTO t1 SELECT NULL, i FROM t1; +INSERT INTO t1 SELECT NULL, i FROM t1; +INSERT INTO t1 SELECT NULL, i FROM t1; +LOCK TABLE t1 READ; +SET max_statement_time= 1; +ALTER TABLE t1 FORCE, ALGORITHM=COPY; +ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +SET DEBUG_SYNC = 'now SIGNAL stop_waining'; +SET DEBUG_SYNC = 'now WAIT_FOR stop_waining'; +UNLOCK TABLES; +DROP TABLE t1; +SET DEBUG_SYNC = 'RESET'; diff --git a/mysql-test/suite/innodb/t/innodb-alter-debug.test b/mysql-test/suite/innodb/t/innodb-alter-debug.test index bc4b2ad8e56..d32faf39aad 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-debug.test +++ b/mysql-test/suite/innodb/t/innodb-alter-debug.test @@ -100,3 +100,31 @@ DROP TABLE t1; # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc + +--echo # +--echo # MDEV-17470 Orphan temporary files after interrupted ALTER +--echo # cause InnoDB: Operating system error number 17 and eventual +--echo # fatal error 71 +--echo # +CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, i INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL,1),(NULL,2),(NULL,3),(NULL,4),(NULL,5),(NULL,6),(NULL,7),(NULL,8); +INSERT INTO t1 SELECT NULL, i FROM t1; +INSERT INTO t1 SELECT NULL, i FROM t1; +INSERT INTO t1 SELECT NULL, i FROM t1; +INSERT INTO t1 SELECT NULL, i FROM t1; +INSERT INTO t1 SELECT NULL, i FROM t1; + +LOCK TABLE t1 READ; + +--connect (con1,localhost,root,,test) +SET max_statement_time= 1; +--error ER_STATEMENT_TIMEOUT +ALTER TABLE t1 FORCE, ALGORITHM=COPY; +SET DEBUG_SYNC = 'now SIGNAL stop_waining'; +--disconnect con1 + +--connection default +SET DEBUG_SYNC = 'now WAIT_FOR stop_waining'; +UNLOCK TABLES; +DROP TABLE t1; +SET DEBUG_SYNC = 'RESET'; diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index bb815de3138..6ec45c591eb 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -4224,9 +4224,10 @@ row_drop_table_for_mysql( calling btr_search_drop_page_hash_index() while we hold the InnoDB dictionary lock, we will drop any adaptive hash index entries upfront. */ + const bool is_temp = dict_table_is_temporary(table) + || strstr(tablename_minus_db, tmp_file_prefix); while (buf_LRU_drop_page_hash_for_tablespace(table)) { - if ((!dict_table_is_temporary(table) - && trx_is_interrupted(trx)) + if ((!is_temp && trx_is_interrupted(trx)) || srv_shutdown_state != SRV_SHUTDOWN_NONE) { err = DB_INTERRUPTED; goto funct_exit; diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 88ebe24f3bb..a5381df1995 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -4234,9 +4234,10 @@ row_drop_table_for_mysql( calling btr_search_drop_page_hash_index() while we hold the InnoDB dictionary lock, we will drop any adaptive hash index entries upfront. */ + const bool is_temp = dict_table_is_temporary(table) + || strstr(tablename_minus_db, tmp_file_prefix); while (buf_LRU_drop_page_hash_for_tablespace(table)) { - if ((!dict_table_is_temporary(table) - && trx_is_interrupted(trx)) + if ((!is_temp && trx_is_interrupted(trx)) || srv_shutdown_state != SRV_SHUTDOWN_NONE) { err = DB_INTERRUPTED; goto funct_exit; |