diff options
Diffstat (limited to 'sql/mysqld.cc')
-rw-r--r-- | sql/mysqld.cc | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 00a7b23b085..9a64fbf2c52 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1559,11 +1559,15 @@ static void kill_thread(THD *thd) /** First shutdown everything but slave threads and binlog dump connections */ -static my_bool kill_thread_phase_1(THD *thd, void *) +static my_bool kill_thread_phase_1(THD *thd, int *n_threads_awaiting_ack) { DBUG_PRINT("quit", ("Informing thread %ld that it's time to die", (ulong) thd->thread_id)); - if (thd->slave_thread || thd->is_binlog_dump_thread()) + + if (thd->slave_thread || thd->is_binlog_dump_thread() || + (shutdown_wait_for_slaves && + repl_semisync_master.is_thd_awaiting_semisync_ack(thd) && + ++(*n_threads_awaiting_ack))) return 0; if (DBUG_IF("only_kill_system_threads") ? !thd->system_thread : 0) @@ -1578,7 +1582,7 @@ static my_bool kill_thread_phase_1(THD *thd, void *) */ static my_bool kill_thread_phase_2(THD *thd, void *) { - if (shutdown_wait_for_slaves) + if (shutdown_wait_for_slaves && thd->is_binlog_dump_thread()) { thd->set_killed(KILL_SERVER); } @@ -1751,7 +1755,29 @@ static void close_connections(void) This will give the threads some time to gracefully abort their statements and inform their clients that the server is about to die. */ - server_threads.iterate(kill_thread_phase_1); + DBUG_EXECUTE_IF("mysqld_delay_kill_threads_phase_1", my_sleep(200000);); + int n_threads_awaiting_ack= 0; + server_threads.iterate(kill_thread_phase_1, &n_threads_awaiting_ack); + + /* + If we are waiting on any ACKs, delay killing the thread until either an ACK + is received or the timeout is hit. + + Allow at max the number of sessions to await a timeout; however, if all + ACKs have been received in less iterations, then quit early + */ + if (shutdown_wait_for_slaves && repl_semisync_master.get_master_enabled()) + { + int waiting_threads= repl_semisync_master.sync_get_master_wait_sessions(); + if (waiting_threads) + sql_print_information("Delaying shutdown to await semi-sync ACK"); + + while (waiting_threads-- > 0) + repl_semisync_master.await_slave_reply(); + } + + DBUG_EXECUTE_IF("delay_shutdown_phase_2_after_semisync_wait", + my_sleep(500000);); Events::deinit(); slave_prepare_for_shutdown(); @@ -1774,7 +1800,8 @@ static void close_connections(void) */ DBUG_PRINT("info", ("THD_count: %u", THD_count::value())); - for (int i= 0; (THD_count::connection_thd_count()) && i < 1000; i++) + for (int i= 0; THD_count::connection_thd_count() - n_threads_awaiting_ack + && i < 1000; i++) my_sleep(20000); if (global_system_variables.log_warnings) @@ -1788,9 +1815,10 @@ static void close_connections(void) wsrep_sst_auth_free(); #endif /* All threads has now been aborted */ - DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)", THD_count::value())); + DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)", + THD_count::connection_thd_count() - n_threads_awaiting_ack)); - while (THD_count::connection_thd_count()) + while (THD_count::connection_thd_count() - n_threads_awaiting_ack) my_sleep(1000); /* Kill phase 2 */ @@ -5353,6 +5381,9 @@ static int init_server_components() if (ha_recover(0)) unireg_abort(1); +#ifndef EMBEDDED_LIBRARY + start_handle_manager(); +#endif if (opt_bin_log) { int error; @@ -5810,8 +5841,6 @@ int mysqld_main(int argc, char **argv) } } - start_handle_manager(); - /* Copy default global rpl_filter to global_rpl_filter */ copy_filter_setting(global_rpl_filter, get_or_create_rpl_filter("", 0)); |