diff options
author | Daniele Sciascia <daniele.sciascia@galeracluster.com> | 2017-02-08 23:36:34 +0100 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2017-08-11 12:31:26 +0300 |
commit | 364b15c090e7337eb752eec4bea239052f73b2ed (patch) | |
tree | 2d886478eaa0a9ef662d3298b839da71131a8127 /sql/wsrep_var.cc | |
parent | 7af44d7aa07e1678bb48d4f4b9ce2c809b611079 (diff) | |
download | mariadb-git-364b15c090e7337eb752eec4bea239052f73b2ed.tar.gz |
MW-336 Avoid slave threads leaking
This patch fixes two problems that may arise when changing the
value of wsrep_slave_threads:
1) Threads may be leaked if wsrep_slave_threads is changed
repeatedly. Specifically, when changing the number of slave
threads, we keep track of wsrep_slave_count_change, the
number of slaves to start / stop. The problem arises when
wsrep_slave_count_change is updated before slaves had a
chance to exit (threads may take some time to exit, as they
exit only after commiting one more replication event).
The fix is to update wsrep_slave_count_change such that it
reflects the number of threads that already exited or are
scheduled to exit.
2) Attempting to set out of range value for wsrep_slave_threads
(below 1 / above 512) results in wsrep_slave_count_change to
be computed based on the out of range value, even though a
warning is generated and wsrep_slave_threads is set to a
truncated value. wsrep_slave_count_change is computed in
wsrep_slave_threads_check(), which is called before mysql
checks for valid range. Fix is to update wsrep_count_change
whenever wsrep_slave_threads is updated with a valid value.
Diffstat (limited to 'sql/wsrep_var.cc')
-rw-r--r-- | sql/wsrep_var.cc | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index 8a507711daf..9a5c7b86068 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -36,6 +36,8 @@ const char* wsrep_node_address = 0; const char* wsrep_node_incoming_address = 0; const char* wsrep_start_position = 0; +static long wsrep_prev_slave_threads = wsrep_slave_threads; + int wsrep_init_vars() { wsrep_provider = my_strdup(WSREP_NONE, MYF(MY_WME)); @@ -497,18 +499,15 @@ void wsrep_node_address_init (const char* value) wsrep_node_address = (value) ? my_strdup(value, MYF(0)) : NULL; } -bool wsrep_slave_threads_check (sys_var *self, THD* thd, set_var* var) +static void wsrep_slave_count_change_update () { - mysql_mutex_lock(&LOCK_wsrep_slave_threads); - wsrep_slave_count_change += (var->save_result.ulonglong_value - - wsrep_slave_threads); - mysql_mutex_unlock(&LOCK_wsrep_slave_threads); - - return 0; + wsrep_slave_count_change += (wsrep_slave_threads - wsrep_prev_slave_threads); + wsrep_prev_slave_threads = wsrep_slave_threads; } bool wsrep_slave_threads_update (sys_var *self, THD* thd, enum_var_type type) { + wsrep_slave_count_change_update(); if (wsrep_slave_count_change > 0) { wsrep_create_appliers(wsrep_slave_count_change); |