summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Sciascia <daniele.sciascia@galeracluster.com>2022-11-11 13:08:20 +0100
committerJan Lindström <jan.lindstrom@mariadb.com>2022-11-29 13:50:36 +0200
commitf7ee1329f0ac10994c63b37e90d042371cd786c6 (patch)
treea0dec848ee27892977ecf6d365b1c4bc695dcf7f
parent7f03cac98b2c4406e67f4717ab37a92ce90bdfcd (diff)
downloadmariadb-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.result17
-rw-r--r--mysql-test/suite/galera/t/MDEV-25389.test24
-rw-r--r--sql/wsrep_mysqld.cc17
-rw-r--r--sql/wsrep_mysqld.h1
-rw-r--r--sql/wsrep_thd.cc3
-rw-r--r--sql/wsrep_var.cc9
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;
}