From f618bda5d3184bc01fe599ef739746a620fe9c62 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 13 May 2026 14:27:25 +1000 Subject: [PATCH 1/3] MDEV-39585 mariadb bootstrap fails to perform plugin deinitalization mariadbd under --bootstrap failed to preform plugin deinitialization. The sleep(2);exit is removed and replaced to a goto termination label to perform the same shutdown procedure of the server after all the connection closing. To prevent a compile error about char *user being uninitialized this sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN)) is moved to its own block. The memory free did need to occur in the bootstrap mode too to avoid memory leak errors. wait_for_signal_thread_to_end(), was previously in close_connections() however its required too for --bootstrap. --- sql/mysqld.cc | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3b49c53c52b26..a0de762f0dd4e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1842,12 +1842,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 +2073,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 +6034,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 +6109,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 +6122,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"); From 6eaae247086bbefc80bb91df434699d4901aad1a Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 15 May 2026 19:28:20 +1000 Subject: [PATCH 2/3] MDEV-39585: mariadb bootstrap fails for perform plugin deinitialization (Windows) Don't perform mysqld_win_initiate_shutdown under --bootstrap when triggered by SHUTDOWN. With this we don't perform any service interactions. Then the shutdown can proceeded without then hard process termination in mysqld_win_initiate_shutdown. THis previously occured because the handle_connections_win() was never called in --bootstrap and therefore startup_complete() was false. Thanks Vladislav Vaintroub for investigation and providing implementation guidance. --- sql/mysqld.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a0de762f0dd4e..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) From 9e731da72b221bf978f3d6b4aa04ea872ddfabe4 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 12 May 2026 15:17:05 +1000 Subject: [PATCH 3/3] MDEV-39541 mem_pressure::~mem_pressure() causes a crash on bootstrap Fill in the anomaly shutdown paths of InnoDB to include call to buf_mem_pressure_shutdown now that MDEV-39585 provides some proper calls shutdown InnoDB and other plugins during the shutdown under --bootstrap. Alternate: destructor attribute on buf_mem_pressure_shutdown would acheive the same thing and given Linux compilers are capabile of this. This is possible as mem_pressure is currently implemented in Linux onny. --- mysql-test/main/bootstrap_innodb.result | 4 ++++ mysql-test/main/bootstrap_innodb.test | 12 ++++++++++++ storage/innobase/handler/ha_innodb.cc | 2 ++ storage/innobase/include/srv0start.h | 6 ++++++ storage/innobase/log/log0log.cc | 6 ------ 5 files changed, 24 insertions(+), 6 deletions(-) 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/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