summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Kosov <claprix@yandex.ru>2018-12-14 01:28:55 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-12-28 17:05:48 +0200
commitc5a5eaa9a996015517c1ebbce19551c6e650cba1 (patch)
tree8a937d2744264ebf242d5087f49f3ed6e269f82a
parent9ad1663f785d28a731ab8212ea62b8125282a27f (diff)
downloadmariadb-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.result21
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter-debug.test28
-rw-r--r--storage/innobase/row/row0mysql.cc5
-rw-r--r--storage/xtradb/row/row0mysql.cc5
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;