Commit 46386661 authored by Jan Lindström's avatar Jan Lindström

MDEV-20625 : MariaDB asserting when enabling wsrep_on

We need to release global system variables mutex before
doing wsrep_init to avoid race with next show status and
we need to save wsrep_on value as it is changed on wsrep_init.
Added test case.
parent 93278ee8
SET GLOBAL wsrep_on=ON; SET GLOBAL wsrep_on=ON;
SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size'; SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';
Variable_name Value Variable_name Value
wsrep_cluster_size 1 wsrep_cluster_size 0
SET GLOBAL wsrep_on=OFF;
...@@ -7,3 +7,4 @@ ...@@ -7,3 +7,4 @@
SET GLOBAL wsrep_on=ON; SET GLOBAL wsrep_on=ON;
SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size'; SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';
SET GLOBAL wsrep_on=OFF;
...@@ -97,28 +97,29 @@ struct handlerton* innodb_hton_ptr __attribute__((weak)); ...@@ -97,28 +97,29 @@ struct handlerton* innodb_hton_ptr __attribute__((weak));
bool wsrep_on_update (sys_var *self, THD* thd, enum_var_type var_type) bool wsrep_on_update (sys_var *self, THD* thd, enum_var_type var_type)
{ {
if (var_type == OPT_GLOBAL) { if (var_type == OPT_GLOBAL) {
my_bool saved_wsrep_on= global_system_variables.wsrep_on;
thd->variables.wsrep_on= global_system_variables.wsrep_on; thd->variables.wsrep_on= global_system_variables.wsrep_on;
// If wsrep has not been inited we need to do it now // If wsrep has not been inited we need to do it now
if (global_system_variables.wsrep_on && wsrep_provider && !wsrep_inited) if (global_system_variables.wsrep_on && wsrep_provider && !wsrep_inited)
{ {
bool rcode= false;
char* tmp= strdup(wsrep_provider); // wsrep_init() rewrites provider char* tmp= strdup(wsrep_provider); // wsrep_init() rewrites provider
//when fails //when fails
mysql_mutex_unlock(&LOCK_global_system_variables);
if (wsrep_init()) if (wsrep_init())
{ {
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), tmp, my_error, "wsrep_init failed"); my_error(ER_CANT_OPEN_LIBRARY, MYF(0), tmp, my_error, "wsrep_init failed");
rcode= true; //rcode= true;
} }
free(tmp);
// we sure don't want to use old address with new provider free(tmp);
wsrep_cluster_address_init(NULL); mysql_mutex_lock(&LOCK_global_system_variables);
wsrep_provider_options_init(NULL);
if (!rcode)
refresh_provider_options();
} }
thd->variables.wsrep_on= global_system_variables.wsrep_on= saved_wsrep_on;
} }
return false; return false;
...@@ -342,11 +343,11 @@ bool wsrep_provider_update (sys_var *self, THD* thd, enum_var_type type) ...@@ -342,11 +343,11 @@ bool wsrep_provider_update (sys_var *self, THD* thd, enum_var_type type)
WSREP_DEBUG("wsrep_provider_update: %s", wsrep_provider); WSREP_DEBUG("wsrep_provider_update: %s", wsrep_provider);
/* stop replication is heavy operation, and includes closing all client /* stop replication is heavy operation, and includes closing all client
connections. Closing clients may need to get LOCK_global_system_variables connections. Closing clients may need to get LOCK_global_system_variables
at least in MariaDB. at least in MariaDB.
Note: releasing LOCK_global_system_variables may cause race condition, if Note: releasing LOCK_global_system_variables may cause race condition, if
there can be several concurrent clients changing wsrep_provider there can be several concurrent clients changing wsrep_provider
*/ */
mysql_mutex_unlock(&LOCK_global_system_variables); mysql_mutex_unlock(&LOCK_global_system_variables);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment