diff options
author | Daniele Sciascia <daniele.sciascia@galeracluster.com> | 2022-11-11 13:08:20 +0100 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2022-11-29 13:50:36 +0200 |
commit | f7ee1329f0ac10994c63b37e90d042371cd786c6 (patch) | |
tree | a0dec848ee27892977ecf6d365b1c4bc695dcf7f | |
parent | 7f03cac98b2c4406e67f4717ab37a92ce90bdfcd (diff) | |
download | mariadb-git-bb-10.6-MDEV-29880-galera.tar.gz |
MDEV-29878 Galera test failure on MDEV-26575bb-10.6-MDEV-29880-galera
Test MDEV-26575 fails when it runs after MDEV-25389. This is because
the latter simulates a failure while an applier thread is
created in `start_wsrep_THD()`. The failure was not handled correctly
and would not cleanup the created THD from the global
`server_threads`. A subsequent shutdown would hang and eventually fail
trying to close this THD.
Reviewed-by: Jan Lindström <jan.lindstrom@mariadb.com>
-rw-r--r-- | mysql-test/suite/galera/r/MDEV-25389.result | 17 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/MDEV-25389.test | 24 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 17 | ||||
-rw-r--r-- | sql/wsrep_mysqld.h | 1 | ||||
-rw-r--r-- | sql/wsrep_thd.cc | 3 | ||||
-rw-r--r-- | sql/wsrep_var.cc | 9 |
6 files changed, 66 insertions, 5 deletions
diff --git a/mysql-test/suite/galera/r/MDEV-25389.result b/mysql-test/suite/galera/r/MDEV-25389.result new file mode 100644 index 00000000000..f1da3f055c0 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-25389.result @@ -0,0 +1,17 @@ +connection node_2; +connection node_1; +connection node_1; +connection node_2; +connection node_2; +call mtr.add_suppression("WSREP: Failed to create/initialize system thread"); +SET GLOBAL debug_dbug='+d,simulate_failed_connection_1'; +SET GLOBAL wsrep_slave_threads=2; +ERROR HY000: Incorrect arguments to SET +SELECT @@wsrep_slave_threads; +@@wsrep_slave_threads +1 +SET GLOBAL debug_dbug=''; +SET GLOBAL wsrep_slave_threads=1; +SELECT @@wsrep_slave_threads; +@@wsrep_slave_threads +1 diff --git a/mysql-test/suite/galera/t/MDEV-25389.test b/mysql-test/suite/galera/t/MDEV-25389.test new file mode 100644 index 00000000000..5c78c6d9b56 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-25389.test @@ -0,0 +1,24 @@ +--source include/galera_cluster.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +--let $node_1=node_1 +--let $node_2=node_2 +--source ../galera/include/auto_increment_offset_save.inc + +--connection node_2 +call mtr.add_suppression("WSREP: Failed to create/initialize system thread"); +SET GLOBAL debug_dbug='+d,simulate_failed_connection_1'; +--error ER_WRONG_ARGUMENTS +SET GLOBAL wsrep_slave_threads=2; +SELECT @@wsrep_slave_threads; +SET GLOBAL debug_dbug=''; +SET GLOBAL wsrep_slave_threads=1; +SELECT @@wsrep_slave_threads; + +# MDEV-29878: this test caused a subsequent test to fail +# during shutdown. Do a restart here, to make sure the +# issue is fixed. +--source include/restart_mysqld.inc + +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index f1494773ffc..4e7bc2c612c 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -128,7 +128,7 @@ ulong wsrep_trx_fragment_unit= WSREP_FRAG_BYTES; // unit for fragment size ulong wsrep_SR_store_type= WSREP_SR_STORE_TABLE; uint wsrep_ignore_apply_errors= 0; - +std::atomic <bool> wsrep_thread_create_failed; /* * End configuration options @@ -3480,7 +3480,7 @@ int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len) void* start_wsrep_THD(void *arg) { - THD *thd; + THD *thd= NULL; Wsrep_thd_args* thd_args= (Wsrep_thd_args*) arg; @@ -3511,6 +3511,7 @@ void* start_wsrep_THD(void *arg) mysql_thread_set_psi_id(thd->thread_id); thd->thr_create_utime= microsecond_interval_timer(); + DBUG_EXECUTE_IF("simulate_failed_connection_1", goto error; ); // </5.1.17> /* handle_one_connection() is normally the only way a thread would @@ -3617,6 +3618,18 @@ void* start_wsrep_THD(void *arg) error: WSREP_ERROR("Failed to create/initialize system thread"); + if (thd) + { + close_connection(thd, ER_OUT_OF_RESOURCES); + statistic_increment(aborted_connects, &LOCK_status); + server_threads.erase(thd); + delete thd; + my_thread_end(); + } + delete thd_args; + // This will signal error to wsrep_slave_threads_update + wsrep_thread_create_failed.store(true, std::memory_order_relaxed); + /* Abort if its the first applier/rollbacker thread. */ if (!mysqld_server_initialized) unireg_abort(1); diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index c18746b379a..a63bd5afe02 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -90,6 +90,7 @@ extern bool wsrep_new_cluster; extern bool wsrep_gtid_mode; extern uint32 wsrep_gtid_domain_id; extern ulonglong wsrep_mode; +extern std::atomic <bool > wsrep_thread_create_failed; extern my_bool wsrep_strict_ddl; enum enum_wsrep_reject_types { diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index 770c4657e65..e610d3a6c2b 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -23,8 +23,7 @@ #include "rpl_rli.h" #include "log_event.h" #include "sql_parse.h" -#include "mysqld.h" // start_wsrep_THD(); -#include "wsrep_applier.h" // start_wsrep_THD(); +#include "wsrep_mysqld.h" // start_wsrep_THD(); #include "mysql/service_wsrep.h" #include "debug_sync.h" #include "slave.h" diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index 26853b34dc0..5ec32d63626 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -789,18 +789,25 @@ bool wsrep_slave_threads_update (sys_var *self, THD* thd, enum_var_type type) if (wsrep_slave_count_change > 0) { WSREP_DEBUG("Creating %d applier threads, total %ld", wsrep_slave_count_change, wsrep_slave_threads); + wsrep_thread_create_failed.store(false, std::memory_order_relaxed); res= wsrep_create_appliers(wsrep_slave_count_change, true); mysql_mutex_unlock(&LOCK_global_system_variables); mysql_mutex_unlock(&LOCK_wsrep_slave_threads); // Thread creation and execution is asyncronous, therefore we need // wait them to be started or error produced - while (wsrep_running_applier_threads != (ulong)wsrep_slave_threads) + while (wsrep_running_applier_threads != (ulong)wsrep_slave_threads && + !wsrep_thread_create_failed.load(std::memory_order_relaxed)) { my_sleep(1000); } mysql_mutex_lock(&LOCK_global_system_variables); + if (wsrep_thread_create_failed.load(std::memory_order_relaxed)) { + wsrep_slave_threads= wsrep_running_applier_threads; + return true; + } + WSREP_DEBUG("Running %lu applier threads", wsrep_running_applier_threads); wsrep_slave_count_change = 0; } |