diff --git a/mysql-test/main/bootstrap_innodb.result b/mysql-test/main/bootstrap_innodb.result index 2807a9776a55f..7a4d88d1a920e 100644 --- a/mysql-test/main/bootstrap_innodb.result +++ b/mysql-test/main/bootstrap_innodb.result @@ -1,4 +1,7 @@ create table t1(a int) engine=innodb; +# +# MDEV-39541 mem_pressure::~mem_pressure() causes a crash on bootstrap +# # restart select * from t1; a @@ -6,3 +9,4 @@ a 2 5 drop table t1; +# End of 10.11 tests diff --git a/mysql-test/main/bootstrap_innodb.test b/mysql-test/main/bootstrap_innodb.test index eb3d09c0e74ed..6606c5ecba287 100644 --- a/mysql-test/main/bootstrap_innodb.test +++ b/mysql-test/main/bootstrap_innodb.test @@ -22,6 +22,18 @@ EOF exec $MYSQLD_BOOTSTRAP_CMD --datadir=$datadir --tmpdir=$MYSQL_TMP_DIR --innodb < $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1; remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql; +--echo # +--echo # MDEV-39541 mem_pressure::~mem_pressure() causes a crash on bootstrap +--echo # + +write_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql; +SHUTDOWN; +EOF +exec $MYSQLD_BOOTSTRAP_CMD --datadir=$datadir --tmpdir=$MYSQL_TMP_DIR --innodb < $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1; +remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql; + source include/start_mysqld.inc; select * from t1; drop table t1; + +--echo # End of 10.11 tests diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3b49c53c52b26..71b826927d1c3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1667,7 +1667,8 @@ static void break_connect_loop() abort_loop= 1; #if defined(_WIN32) - mysqld_win_initiate_shutdown(); + if (!opt_bootstrap) + mysqld_win_initiate_shutdown(); #else mysql_mutex_lock(&LOCK_start_thread); if (termination_event_fd >= 0) @@ -1842,12 +1843,6 @@ static void close_connections(void) } /* End of kill phase 2 */ - /* - The signal thread can use server resources, e.g. when processing SIGHUP, - and it must end gracefully before clean_up() - */ - wait_for_signal_thread_to_end(); - DBUG_PRINT("quit",("close_connections thread")); DBUG_VOID_RETURN; } @@ -2079,7 +2074,6 @@ static void clean_up(bool print_message) #ifndef EMBEDDED_LIBRARY - /** This is mainly needed when running with purify, but it's still nice to know that all child threads have died when mysqld exits. @@ -6041,10 +6035,7 @@ int mysqld_main(int argc, char **argv) if (!abort_loop) unireg_abort(bootstrap_error); else - { - sleep(2); // Wait for kill - exit(0); - } + goto termination; } /* Copy default global rpl_filter to global_rpl_filter */ @@ -6119,11 +6110,11 @@ int mysqld_main(int argc, char **argv) run_main_loop(); /* Shutdown requested */ - char *user= shutdown_user.load(std::memory_order_relaxed); - sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN), my_progname, + { + char *user= shutdown_user.load(std::memory_order_relaxed); + sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN), my_progname, user ? user : "unknown"); - if (user) - my_free(user); + } #ifdef WITH_WSREP wsrep_shutdown(); @@ -6132,6 +6123,19 @@ int mysqld_main(int argc, char **argv) #endif close_connections(); + +termination: + { + char *user= shutdown_user.load(std::memory_order_relaxed); + if (user) + my_free(user); + } + /* + The signal thread can use server resources, e.g. when processing SIGHUP, + and it must end gracefully before clean_up() + */ + wait_for_signal_thread_to_end(); + ha_pre_shutdown(); clean_up(1); sd_notify(0, "STATUS=MariaDB server is down"); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2665fa0012f35..37c1bcefde468 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4273,6 +4273,8 @@ innobase_end(handlerton*, ha_panic_function) innodb_shutdown(); mysql_mutex_destroy(&log_requests.mutex); } + else + buf_mem_pressure_shutdown(); DBUG_RETURN(0); } diff --git a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h index e562458722c75..27d953311d911 100644 --- a/storage/innobase/include/srv0start.h +++ b/storage/innobase/include/srv0start.h @@ -52,6 +52,12 @@ void innodb_preshutdown(); /** Shut down InnoDB. */ void innodb_shutdown(); +/** Stop mem presure thread and free file descriptors */ +#ifdef __linux__ +void buf_mem_pressure_shutdown() noexcept; +#else +inline void buf_mem_pressure_shutdown() noexcept {} +#endif /*************************************************************//** Copy the file path component of the physical file to parameter. It will copy up to and including the terminating path separator. diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index fe951c49406f3..763f95295583f 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -1351,12 +1351,6 @@ void log_free_check() noexcept } } -#ifdef __linux__ -extern void buf_mem_pressure_shutdown() noexcept; -#else -inline void buf_mem_pressure_shutdown() noexcept {} -#endif - /** Make a checkpoint at the latest lsn on shutdown. @return the shutdown LSN */ ATTRIBUTE_COLD lsn_t logs_empty_and_mark_files_at_shutdown() noexcept