From e417af2cb8ee615ba3b0a3f557797271e7bf7c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 5 Jul 2017 12:45:15 +0300 Subject: [PATCH] MDEV-13143 Server crashes in srv_init_abort_low() when started with inaccessible tmpdir This is a regression caused by commit bb60a832ede139d24a2470a1b1217d30799d726e srv_shutdown_all_bg_threads(): If os_thread_count indicates that no threads are running, do not bother checking thread status. This avoids a crash when InnoDB startup is aborted before os_aio_init() has been invoked. (os_aio_all_slots_free() would dereference AIO::s_reads even though it is NULL.) --- .../suite/innodb/r/temporary_table.result | 2 ++ .../suite/innodb/t/temporary_table.test | 31 +++++++++++++++++++ storage/innobase/srv/srv0start.cc | 8 ++--- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/innodb/r/temporary_table.result b/mysql-test/suite/innodb/r/temporary_table.result index 074dd413947..689d5a530d2 100644 --- a/mysql-test/suite/innodb/r/temporary_table.result +++ b/mysql-test/suite/innodb/r/temporary_table.result @@ -137,6 +137,8 @@ Tables_in_test create temporary table t1 (keyc int, c1 char(100), c2 char(100)) engine = innodb; ERROR HY000: Can't create table `test`.`t1` (errno: 165 "Table is read only") # test various bad start-up parameters +FOUND 3 /Can't create/write to file '.dev.null.nonexistent.ib/ in mysqld.1.err +FOUND 3 /InnoDB: Unable to create temporary file/ in mysqld.1.err FOUND 1 /innodb_temporary and innodb_system file names seem to be the same/ in mysqld.1.err SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); diff --git a/mysql-test/suite/innodb/t/temporary_table.test b/mysql-test/suite/innodb/t/temporary_table.test index 1148f2ee1a0..45f84834edb 100644 --- a/mysql-test/suite/innodb/t/temporary_table.test +++ b/mysql-test/suite/innodb/t/temporary_table.test @@ -10,6 +10,8 @@ --source include/no_valgrind_without_big.inc --disable_query_log +call mtr.add_suppression("Can't create/write to file '.dev.null.nonexistent.ib"); +call mtr.add_suppression("InnoDB: Unable to create temporary file"); call mtr.add_suppression("last file in setting innodb_temp_data_file_path"); call mtr.add_suppression("The table 't1' is full"); call mtr.add_suppression("Plugin 'InnoDB' init function returned error"); @@ -125,6 +127,35 @@ let SEARCH_ABORT = NOT FOUND; let $check_no_innodb=SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); +# We cannot use include/restart_mysqld.inc in this particular test, +# because SHOW STATUS would fail due to unwritable (nonexistent) tmpdir. +--source include/shutdown_mysqld.inc +--exec echo "restart: --tmpdir=/dev/null/nonexistent" > $_expect_file_name +--enable_reconnect +--disable_result_log +--disable_query_log +let $counter= 5000; +let $mysql_errno= 9999; +while ($mysql_errno) +{ + --error 0,ER_SERVER_SHUTDOWN,ER_CONNECTION_KILLED,2002,2006,2013 + select 1; + + dec $counter; + if (!$counter) + { + --die Server failed to restart + } + --sleep 0.1 +} +--enable_query_log +--enable_result_log +--disable_reconnect +--let SEARCH_PATTERN= Can't create/write to file '.dev.null.nonexistent.ib +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN= InnoDB: Unable to create temporary file +--source include/search_pattern_in_file.inc + --let $restart_parameters= --innodb_data_file_path=ibdata1:12M:autoextend --innodb_temp_data_file_path=ibdata1:12M:autoextend --source include/restart_mysqld.inc --let SEARCH_PATTERN = innodb_temporary and innodb_system file names seem to be the same diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 6068b48e0cb..64ddb5a7ec5 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1302,6 +1302,10 @@ srv_shutdown_all_bg_threads() } } + if (!os_thread_count) { + return; + } + switch (srv_operation) { case SRV_OPERATION_BACKUP: break; @@ -1313,10 +1317,6 @@ srv_shutdown_all_bg_threads() } } - if (!os_thread_count) { - return; - } - os_thread_sleep(100000); }