diff --git a/mysql-test/suite/rpl/r/rpl_start_slave_deadlock_sys_vars.result b/mysql-test/suite/rpl/r/rpl_start_slave_deadlock_sys_vars.result new file mode 100644 index 0000000..f69a323 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_start_slave_deadlock_sys_vars.result @@ -0,0 +1,31 @@ +include/master-slave.inc +[connection master] +# connection: slave +SET @save_slave_net_timeout = @@GLOBAL.slave_net_timeout; +STOP SLAVE; +include/wait_for_slave_to_stop.inc +# open an extra connection to the slave +# connection: slave2 +# set debug synchronization point +SET DEBUG_SYNC='fix_slave_net_timeout SIGNAL parked WAIT_FOR go'; +# attempt to set slave_net_timeout, will wait on sync point +SET @@GLOBAL.slave_net_timeout = 100; +# connection: slave +SET DEBUG_SYNC='now WAIT_FOR parked'; +# connection: slave1 +# attempt to start the SQL thread +START SLAVE SQL_THREAD; +# connection: slave +# wait until SQL thread has been started +# sleep a bit so that the SQL thread THD handle is initialized +# signal the set slave_net_timeout to continue +SET DEBUG_SYNC='now SIGNAL go'; +# connection: slave2 +# reap result of set slave_net_timeout +# connection: slave1 +# reap result of starting the SQL thread +# disconnect: slave2 +# connection: slave +# cleanup +SET @@GLOBAL.slave_net_timeout = @save_slave_net_timeout; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_start_slave_deadlock_sys_vars.test b/mysql-test/suite/rpl/t/rpl_start_slave_deadlock_sys_vars.test new file mode 100644 index 0000000..dfcec67 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_start_slave_deadlock_sys_vars.test @@ -0,0 +1,57 @@ +source include/master-slave.inc; +source include/have_debug_sync.inc; + +--echo # connection: slave +connection slave; +SET @save_slave_net_timeout = @@GLOBAL.slave_net_timeout; +STOP SLAVE; +source include/wait_for_slave_to_stop.inc; + +--echo # open an extra connection to the slave +connect(slave2,127.0.0.1,root,,test,$SLAVE_MYPORT,); +--echo # connection: slave2 +--echo # set debug synchronization point +SET DEBUG_SYNC='fix_slave_net_timeout SIGNAL parked WAIT_FOR go'; +--echo # attempt to set slave_net_timeout, will wait on sync point +--send SET @@GLOBAL.slave_net_timeout = 100 + +--echo # connection: slave +connection slave; +SET DEBUG_SYNC='now WAIT_FOR parked'; + +--echo # connection: slave1 +connection slave1; +--echo # attempt to start the SQL thread +--send START SLAVE SQL_THREAD + +--echo # connection: slave +connection slave; +--echo # wait until SQL thread has been started +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for slave thread to start" and info = "START SLAVE SQL_THREAD"; +--source include/wait_condition.inc +--echo # sleep a bit so that the SQL thread THD handle is initialized +sleep 2; +--echo # signal the set slave_net_timeout to continue +SET DEBUG_SYNC='now SIGNAL go'; + +--echo # connection: slave2 +connection slave2; +--echo # reap result of set slave_net_timeout +--reap + +--echo # connection: slave1 +connection slave1; +--echo # reap result of starting the SQL thread +--reap + +--echo # disconnect: slave2 +disconnect slave2; + +--echo # connection: slave +connection slave; +--echo # cleanup +SET @@GLOBAL.slave_net_timeout = @save_slave_net_timeout; + +source include/rpl_end.inc; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index f30fafb..4d58589 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -44,6 +44,7 @@ // mysql_user_table_is_in_short_password_format #include "derror.h" // read_texts #include "sql_base.h" // close_cached_tables +#include "debug_sync.h" // DEBUG_SYNC #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE #include "../storage/perfschema/pfs_server.h" @@ -3276,6 +3277,9 @@ static Sys_var_charptr Sys_slave_load_tmpdir( static bool fix_slave_net_timeout(sys_var *self, THD *thd, enum_var_type type) { + DEBUG_SYNC(thd, "fix_slave_net_timeout"); + + mysql_mutex_unlock(&LOCK_global_system_variables); mysql_mutex_lock(&LOCK_active_mi); DBUG_PRINT("info", ("slave_net_timeout=%u mi->heartbeat_period=%.3f", slave_net_timeout, @@ -3285,6 +3289,7 @@ static bool fix_slave_net_timeout(sys_var *self, THD *thd, enum_var_type type) ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX, ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX)); mysql_mutex_unlock(&LOCK_active_mi); + mysql_mutex_lock(&LOCK_global_system_variables); return false; } static Sys_var_uint Sys_slave_net_timeout( @@ -3311,6 +3316,7 @@ static bool check_slave_skip_counter(sys_var *self, THD *thd, set_var *var) } static bool fix_slave_skip_counter(sys_var *self, THD *thd, enum_var_type type) { + mysql_mutex_unlock(&LOCK_global_system_variables); mysql_mutex_lock(&LOCK_active_mi); mysql_mutex_lock(&active_mi->rli.run_lock); /* @@ -3326,6 +3332,7 @@ static bool fix_slave_skip_counter(sys_var *self, THD *thd, enum_var_type type) } mysql_mutex_unlock(&active_mi->rli.run_lock); mysql_mutex_unlock(&LOCK_active_mi); + mysql_mutex_lock(&LOCK_global_system_variables); return 0; } static Sys_var_uint Sys_slave_skip_counter(