Skip to content

Commit 92bf147

Browse files
author
Jaideep Karande
committed
Bug #25423650: QUICK UNINSTALL PLUGIN WHILE START GR CAN RESULT INTO DEADLOCK
Problem: GR Uninstall & GR Start lock each other Description: Try executing UNINSTALL PLUGIN command while START G.R. is in progress. 1. Start command takes LOCK_group_replication_handler 2. Uninstall starts and locks SQL Queries - function "open_ltable()" 3. Uninstall waits for LOCK_group_replication_handler 4. Start command tries to set the server read only mode that waits on 2) Resolution: Group_replication_handler class has been removed along with lock LOCK_group_replication_handler. With use of my_plugin_lock_by_name, server will have better visibility over GR operations and take decisions accordingly.
1 parent b368e36 commit 92bf147

11 files changed

+277
-265
lines changed

include/mysql/group_replication_priv.h

+2-5
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,9 @@
3131

3232

3333
/**
34-
Server side initializations and cleanup.
34+
Server side initializations.
3535
*/
36-
int group_replication_init(const char* plugin_name);
37-
int group_replication_cleanup();
38-
int group_replication_start();
39-
int group_replication_stop();
36+
int group_replication_init();
4037

4138

4239
/**

rapid/plugin/group_replication/src/observer_server_state.cc

+1-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ int group_replication_before_server_shutdown(Server_state_param*)
5858
int group_replication_after_server_shutdown(Server_state_param*)
5959
{
6060
server_shutdown_status= true;
61-
if (plugin_is_group_replication_running())
62-
group_replication_stop();
61+
plugin_group_replication_stop();
6362

6463
return 0;
6564
}

rapid/plugin/group_replication/src/plugin.cc

+11-6
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,12 @@ int plugin_group_replication_start()
349349

350350
Mutex_autolock auto_lock_mutex(&plugin_running_mutex);
351351

352+
DBUG_EXECUTE_IF("group_replication_wait_on_start",
353+
{
354+
const char act[]= "now signal signal.start_waiting wait_for signal.start_continue";
355+
DBUG_ASSERT(!debug_sync_set_action(current_thd, STRING_WITH_LEN(act)));
356+
});
357+
352358
int error= 0;
353359
bool enabled_super_read_only= false;
354360
bool read_only_mode= false, super_read_only_mode=false;
@@ -909,7 +915,7 @@ int plugin_group_replication_init(MYSQL_PLUGIN plugin_info)
909915

910916
plugin_info_ptr= plugin_info;
911917

912-
if (group_replication_init(group_replication_plugin_name))
918+
if (group_replication_init())
913919
{
914920
/* purecov: begin inspected */
915921
log_message(MY_ERROR_LEVEL,
@@ -976,7 +982,7 @@ int plugin_group_replication_init(MYSQL_PLUGIN plugin_info)
976982
}
977983

978984
plugin_is_auto_starting= start_group_replication_at_boot_var;
979-
if (start_group_replication_at_boot_var && group_replication_start())
985+
if (start_group_replication_at_boot_var && plugin_group_replication_start())
980986
{
981987
log_message(MY_ERROR_LEVEL,
982988
"Unable to start Group Replication on boot");
@@ -994,10 +1000,9 @@ int plugin_group_replication_deinit(void *p)
9941000
plugin_is_being_uninstalled= true;
9951001
int observer_unregister_error= 0;
9961002

997-
//plugin_group_replication_stop will be called from this method stack
998-
if (group_replication_cleanup())
1003+
if (plugin_group_replication_stop())
9991004
log_message(MY_ERROR_LEVEL,
1000-
"Failure when cleaning Group Replication server state");
1005+
"Failure when stopping Group Replication on plugin uninstall");
10011006

10021007
if (group_member_mgr != NULL)
10031008
{
@@ -1513,7 +1518,7 @@ static int check_if_server_properly_configured()
15131518
//Struct that holds startup and runtime requirements
15141519
Trans_context_info startup_pre_reqs;
15151520

1516-
get_server_startup_prerequirements(startup_pre_reqs, true);
1521+
get_server_startup_prerequirements(startup_pre_reqs, !plugin_is_auto_starting);
15171522

15181523
if(!startup_pre_reqs.binlog_enabled)
15191524
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
include/group_replication.inc
2+
Warnings:
3+
Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
4+
Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
5+
[connection server1]
6+
7+
# 1. Setup GR environment and execute START GR.
8+
9+
[connection server1]
10+
SET GLOBAL group_replication_bootstrap_group=ON;
11+
SET GLOBAL group_replication_group_name = '8a94f357-bbbb-22aa-33bb-cccaaa420000';
12+
13+
# 2. Block start, so we can execute UNINSTALL.
14+
15+
SET @debug_save= @@GLOBAL.DEBUG;
16+
SET @@GLOBAL.DEBUG= 'd,group_replication_wait_on_start';
17+
START GROUP_REPLICATION;
18+
19+
# 3. Execute UNINSTALL PLUGIN GR from second connection.
20+
21+
[connection server_1]
22+
SET DEBUG_SYNC= "now WAIT_FOR signal.start_waiting";
23+
UNINSTALL PLUGIN group_replication;
24+
Warnings:
25+
Warning 1620 Plugin is busy and will be uninstalled on shutdown
26+
Wait for group replication plugin to be deleted.
27+
28+
# 4. SIGNAL START GR to resume processing.
29+
30+
SET DEBUG_SYNC= 'now SIGNAL signal.start_continue';
31+
[connection server1]
32+
33+
# 5. Confirm plugin is UNINSTALLED.
34+
35+
Wait for group replication plugin to be removed.
36+
37+
# 6. Cleanup
38+
39+
INSTALL PLUGIN group_replication SONAME 'GROUP_REPLICATION';
40+
SET @@GLOBAL.DEBUG= @debug_save;
41+
include/group_replication_end.inc

rapid/plugin/group_replication/tests/mtr/r/gr_concurrent_uninstall_stop.result

-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,5 @@ UNINSTALL PLUGIN group_replication;
1616
STOP GROUP_REPLICATION;
1717
[connection server1]
1818
SET @@GLOBAL.read_only= 0;
19-
UNINSTALL PLUGIN group_replication;
2019
INSTALL PLUGIN group_replication SONAME 'GROUP_REPLICATION';
2120
include/group_replication_end.inc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
################################################################################
2+
# This test resolves Deadlock. GR deadlocks when START GR and
3+
# UNINSTALL happens at same time.
4+
#
5+
# Test:
6+
# 0. The test requires one server.
7+
# 1. Setup GR environment and execute START GR.
8+
# 2. Block start, so we can execute UNINSTALL.
9+
# 3. Execute UNINSTALL PLUGIN GR.
10+
# 4. SIGNAL START GR to resume processing.
11+
# 5. Confirm plugin is UNINSTALLED
12+
# 6. Cleanup
13+
#
14+
################################################################################
15+
--source ../inc/have_group_replication_plugin.inc
16+
--let $rpl_skip_group_replication_start= 1
17+
--source ../inc/group_replication.inc
18+
19+
--echo
20+
--echo # 1. Setup GR environment and execute START GR.
21+
--echo
22+
23+
--let $rpl_connection_name= server1
24+
--source include/rpl_connection.inc
25+
26+
SET GLOBAL group_replication_bootstrap_group=ON;
27+
SET GLOBAL group_replication_group_name = '8a94f357-bbbb-22aa-33bb-cccaaa420000';
28+
29+
--echo
30+
--echo # 2. Block start, so we can execute UNINSTALL.
31+
--echo
32+
33+
## If START GR gets lock and UNINSTALL blocks SQL Query execution,
34+
## GR used to deadlock.
35+
36+
SET @debug_save= @@GLOBAL.DEBUG;
37+
SET @@GLOBAL.DEBUG= 'd,group_replication_wait_on_start';
38+
39+
--send START GROUP_REPLICATION
40+
41+
--echo
42+
--echo # 3. Execute UNINSTALL PLUGIN GR from second connection.
43+
--echo
44+
--let $rpl_connection_name= server_1
45+
--source include/rpl_connection.inc
46+
# Wait for the debug sync to be reached.
47+
SET DEBUG_SYNC= "now WAIT_FOR signal.start_waiting";
48+
49+
UNINSTALL PLUGIN group_replication;
50+
51+
--echo Wait for group replication plugin to be deleted.
52+
--let $wait_condition= SELECT COUNT(*)=1 from information_schema.plugins where PLUGIN_NAME like 'group_replication' and PLUGIN_STATUS like 'DELETED';
53+
--source include/wait_condition.inc
54+
55+
--echo
56+
--echo # 4. SIGNAL START GR to resume processing.
57+
--echo
58+
SET DEBUG_SYNC= 'now SIGNAL signal.start_continue';
59+
60+
--let $rpl_connection_name= server1
61+
--source include/rpl_connection.inc
62+
--reap
63+
64+
--echo
65+
--echo # 5. Confirm plugin is UNINSTALLED.
66+
--echo
67+
68+
--echo Wait for group replication plugin to be removed.
69+
--let $wait_condition= SELECT COUNT(*)=0 from information_schema.plugins where PLUGIN_NAME like 'group_replication';
70+
--source include/wait_condition.inc
71+
72+
--echo
73+
--echo # 6. Cleanup
74+
--echo
75+
--replace_result $GROUP_REPLICATION GROUP_REPLICATION
76+
--eval INSTALL PLUGIN group_replication SONAME '$GROUP_REPLICATION'
77+
--enable_warnings
78+
79+
SET @@GLOBAL.DEBUG= @debug_save;
80+
--source ../inc/group_replication_end.inc

rapid/plugin/group_replication/tests/mtr/t/gr_concurrent_uninstall_stop.test

+8-5
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,29 @@ SET SESSION sql_log_bin= 1;
3030

3131
--source ../inc/start_and_bootstrap_group_replication.inc
3232

33+
## Warnings depends upon sequence of execution of
34+
## query "STOP GROUP_REPLICATION" and "UNINSTALL PLUGIN group_replication"
35+
--disable_warnings
36+
3337
--send UNINSTALL PLUGIN group_replication
3438

3539
--let $rpl_connection_name= server_1
3640
--source include/rpl_connection.inc
3741
--echo #
3842
--echo # STOP GROUP_REPLICATION in parallel.
3943
--echo #
44+
## Uninstall will not fail.
45+
## However, STOP GR may fail if UNINSTALL is executed first.
4046
--error 0, ER_GROUP_REPLICATION_CONFIGURATION
4147
STOP GROUP_REPLICATION;
4248

4349
--let $rpl_connection_name= server1
4450
--source include/rpl_connection.inc
45-
--error 0, ER_OPTION_PREVENTS_STATEMENT
4651
--reap
4752

53+
--enable_warnings
54+
4855
SET @@GLOBAL.read_only= 0;
49-
# The previous UNINSTALL attempt may have failed due to SUPER_READ_ONLY=1, as
50-
# such we uninstall the plugin again.
51-
--error 0, ER_SP_DOES_NOT_EXIST
52-
UNINSTALL PLUGIN group_replication;
5356

5457
--replace_result $GROUP_REPLICATION GROUP_REPLICATION
5558
--eval INSTALL PLUGIN group_replication SONAME '$GROUP_REPLICATION'

sql/mysqld.cc

-5
Original file line numberDiff line numberDiff line change
@@ -1136,7 +1136,6 @@ mysql_cond_t COND_server_started;
11361136
mysql_mutex_t LOCK_reset_gtid_table;
11371137
mysql_mutex_t LOCK_compress_gtid_table;
11381138
mysql_cond_t COND_compress_gtid_table;
1139-
mysql_mutex_t LOCK_group_replication_handler;
11401139
#if !defined(_WIN32)
11411140
mysql_mutex_t LOCK_socket_listener_active;
11421141
mysql_cond_t COND_socket_listener_active;
@@ -3807,8 +3806,6 @@ static int init_thread_environment()
38073806
&LOCK_compress_gtid_table, MY_MUTEX_INIT_FAST);
38083807
mysql_cond_init(key_COND_compress_gtid_table,
38093808
&COND_compress_gtid_table);
3810-
mysql_mutex_init(key_LOCK_group_replication_handler,
3811-
&LOCK_group_replication_handler, MY_MUTEX_INIT_FAST);
38123809
Events::init_mutexes();
38133810
#if defined(_WIN32)
38143811
mysql_mutex_init(key_LOCK_handler_count,
@@ -9472,7 +9469,6 @@ PSI_cond_key key_object_loading_cond; // TODO need to initialize
94729469
PSI_mutex_key key_mts_temp_table_LOCK;
94739470
PSI_mutex_key key_mts_gaq_LOCK;
94749471
PSI_mutex_key key_thd_timer_mutex;
9475-
PSI_mutex_key key_LOCK_group_replication_handler;
94769472
PSI_mutex_key key_commit_order_manager_mutex;
94779473
PSI_mutex_key key_mutex_slave_worker_hash;
94789474
PSI_mutex_key
@@ -9561,7 +9557,6 @@ static PSI_mutex_info all_server_mutexes[]=
95619557
{ &key_mutex_slave_worker_hash, "Relay_log_info::slave_worker_hash_lock", 0, 0},
95629558
{ &key_LOCK_offline_mode, "LOCK_offline_mode", PSI_FLAG_GLOBAL, 0},
95639559
{ &key_LOCK_default_password_lifetime, "LOCK_default_password_lifetime", PSI_FLAG_GLOBAL, 0},
9564-
{ &key_LOCK_group_replication_handler, "LOCK_group_replication_handler", PSI_FLAG_GLOBAL, 0},
95659560
{ &key_LOCK_mandatory_roles, "LOCK_mandatory_roles", PSI_FLAG_GLOBAL, 0}
95669561
};
95679562

sql/mysqld.h

-2
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,6 @@ extern PSI_mutex_key key_gtid_ensure_index_mutex;
375375
extern PSI_mutex_key key_mts_temp_table_LOCK;
376376
extern PSI_mutex_key key_mts_gaq_LOCK;
377377
extern PSI_mutex_key key_thd_timer_mutex;
378-
extern PSI_mutex_key key_LOCK_group_replication_handler;
379378

380379
extern PSI_mutex_key key_commit_order_manager_mutex;
381380
extern PSI_mutex_key key_mutex_slave_worker_hash;
@@ -641,7 +640,6 @@ extern mysql_cond_t COND_manager;
641640
extern mysql_rwlock_t LOCK_sys_init_connect;
642641
extern mysql_rwlock_t LOCK_sys_init_slave;
643642
extern mysql_rwlock_t LOCK_system_variables_hash;
644-
extern mysql_mutex_t LOCK_group_replication_handler;
645643

646644
extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
647645
*opt_ssl_key, *opt_ssl_crl, *opt_ssl_crlpath, *opt_tls_version;

0 commit comments

Comments
 (0)