Skip to content

Commit 0c23645

Browse files
author
Jaideep Karande
committed
WL#14585: Extend and improve group_replication_set_as_primary behavior
ReviewBoard: 27020
1 parent 85f473f commit 0c23645

File tree

63 files changed

+5279
-64
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+5279
-64
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/* Copyright (c) 2022, Oracle and/or its affiliates.
2+
3+
This program is free software; you can redistribute it and/or modify
4+
it under the terms of the GNU General Public License, version 2.0,
5+
as published by the Free Software Foundation.
6+
7+
This program is also distributed with certain software (including
8+
but not limited to OpenSSL) that is licensed under separate terms,
9+
as designated in a particular file or component or in included license
10+
documentation. The authors of MySQL hereby grant you an additional
11+
permission to link the program and your derivative works with the
12+
separately licensed software that they have included with MySQL.
13+
14+
This program is distributed in the hope that it will be useful,
15+
but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
GNU General Public License, version 2.0, for more details.
18+
19+
You should have received a copy of the GNU General Public License
20+
along with this program; if not, write to the Free Software
21+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22+
23+
#ifndef MYSQL_TRANSACTION_DELEGATE_CONTROL_H
24+
#define MYSQL_TRANSACTION_DELEGATE_CONTROL_H
25+
#include <mysql/components/service.h>
26+
27+
/**
28+
A service to manage transactions execution.
29+
The service will stop new incoming transactions to execute.
30+
31+
@note Some management related queries are allowed.
32+
33+
@sa @ref mysql_new_transaction_control_imp
34+
*/
35+
BEGIN_SERVICE_DEFINITION(mysql_new_transaction_control)
36+
37+
/**
38+
Method to stop new incoming transactions allowing some management queries
39+
to run. New incoming transactions are rolled back.
40+
41+
@sa mysql_new_transaction_control_imp
42+
*/
43+
DECLARE_METHOD(void, stop, ());
44+
45+
/**
46+
Method that allows the transactions which were earlier stopped by
47+
stop method.
48+
49+
@sa mysql_new_transaction_control_imp
50+
*/
51+
DECLARE_METHOD(void, allow, ());
52+
53+
END_SERVICE_DEFINITION(mysql_new_transaction_control)
54+
55+
/**
56+
A service to manage transactions execution.
57+
This service rollbacks the transactions that reach the before_commit state.
58+
This service does not impact transactions that are already in the commit
59+
stage.
60+
61+
@sa @ref mysql_before_commit_transaction_control_imp
62+
*/
63+
BEGIN_SERVICE_DEFINITION(mysql_before_commit_transaction_control)
64+
65+
/**
66+
This method rollback any transaction that reaches the commit stage.
67+
68+
@sa mysql_before_commit_transaction_control_imp
69+
*/
70+
DECLARE_METHOD(void, stop, ());
71+
72+
/**
73+
Method re-allows the commit, earlier stopped in stop function.
74+
75+
@note Flag set in stop function to rollback the transactions in commit is
76+
unset.
77+
78+
@sa mysql_before_commit_transaction_control_imp
79+
*/
80+
DECLARE_METHOD(void, allow, ());
81+
82+
END_SERVICE_DEFINITION(mysql_before_commit_transaction_control)
83+
84+
/**
85+
This service will gracefully close all the client connections which are
86+
running a binloggable transaction that did not reach the commit stage.
87+
The term `bingloggable transactions` is used to identify transactions that
88+
will be written to the binary log once they do commit.
89+
At present when binlog cache is initialized by a transaction, the transaction
90+
is marked as `bingloggable`.
91+
92+
@sa @ref
93+
mysql_close_connection_of_binloggable_transaction_not_reached_commit_imp
94+
*/
95+
BEGIN_SERVICE_DEFINITION(
96+
mysql_close_connection_of_binloggable_transaction_not_reached_commit)
97+
98+
/**
99+
Method that gracefully closes all the client connections which are running a
100+
binloggable transaction that did not reach the commit stage.
101+
102+
@note method sets the killed flag with value THD::KILL_CONNECTION in the THD
103+
to gracefully KILL the transaction and client connection.
104+
105+
@sa mysql_close_connection_of_binloggable_transaction_not_reached_commit_imp
106+
*/
107+
DECLARE_METHOD(void, close, ());
108+
109+
END_SERVICE_DEFINITION(
110+
mysql_close_connection_of_binloggable_transaction_not_reached_commit)
111+
112+
#endif /* MYSQL_TRANSACTION_DELEGATE_CONTROL_H */

mysql-test/suite/group_replication/r/gr_primary_mode_group_operations_03.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Mode switched to single-primary successfully.
3232
# 3. Execute action of set a new primary:
3333
# 3.1. With extra arguments it must fail.
3434
SELECT group_replication_set_as_primary("MEMBER1_UUID", "extra", "arguments");
35-
ERROR HY000: Can't initialize function 'group_replication_set_as_primary'; Wrong arguments: You need to specify a server uuid.
35+
ERROR HY000: Can't initialize function 'group_replication_set_as_primary'; Wrong arguments: UDF accepts maximum of 2 parameters.
3636
# 3.2. With invalid uuid it must fail.
3737
SELECT group_replication_set_as_primary("not an uuid");
3838
ERROR HY000: Can't initialize function 'group_replication_set_as_primary'; Wrong arguments: The server uuid is not valid.

mysql-test/suite/group_replication/r/gr_psi_keys_mysql.result

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ wait/synch/mutex/group_rpl/LOCK_session_thread_method_exec YES YES singleton 0 N
5656
wait/synch/mutex/group_rpl/LOCK_session_thread_run YES YES singleton 0 NULL
5757
wait/synch/mutex/group_rpl/LOCK_stage_monitor_handler YES YES singleton 0 NULL
5858
wait/synch/mutex/group_rpl/LOCK_synchronized_queue YES YES singleton 0 NULL
59+
wait/synch/mutex/group_rpl/LOCK_transaction_monitoring YES YES singleton 0 NULL
5960
wait/synch/mutex/group_rpl/LOCK_transaction_unblocking YES YES singleton 0 NULL
6061
wait/synch/mutex/group_rpl/LOCK_group_member_info_manager_update_lock YES YES singleton 0 NULL
6162
wait/synch/mutex/group_rpl/LOCK_group_member_info_update_lock YES YES singleton 0 NULL
@@ -94,6 +95,7 @@ wait/synch/cond/group_rpl/COND_group_part_handler_run YES YES singleton 0 NULL
9495
wait/synch/cond/group_rpl/COND_group_part_handler_abort YES YES singleton 0 NULL
9596
wait/synch/cond/group_rpl/COND_message_service_run YES YES singleton 0 NULL
9697
wait/synch/cond/group_rpl/COND_multi_primary_action_notification YES YES singleton 0 NULL
98+
wait/synch/cond/group_rpl/COND_transaction_monitoring_wait YES YES singleton 0 NULL
9799
wait/synch/cond/group_rpl/COND_view_modification_wait YES YES singleton 0 NULL
98100
wait/synch/cond/group_rpl/COND_pipeline_continuation YES YES singleton 0 NULL
99101
wait/synch/cond/group_rpl/COND_synchronized_queue YES YES singleton 0 NULL

mysql-test/suite/group_replication/r/gr_psi_keys_xcom.result

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ wait/synch/mutex/group_rpl/LOCK_session_thread_method_exec YES YES singleton 0 N
5656
wait/synch/mutex/group_rpl/LOCK_session_thread_run YES YES singleton 0 NULL
5757
wait/synch/mutex/group_rpl/LOCK_stage_monitor_handler YES YES singleton 0 NULL
5858
wait/synch/mutex/group_rpl/LOCK_synchronized_queue YES YES singleton 0 NULL
59+
wait/synch/mutex/group_rpl/LOCK_transaction_monitoring YES YES singleton 0 NULL
5960
wait/synch/mutex/group_rpl/LOCK_transaction_unblocking YES YES singleton 0 NULL
6061
wait/synch/mutex/group_rpl/LOCK_group_member_info_manager_update_lock YES YES singleton 0 NULL
6162
wait/synch/mutex/group_rpl/LOCK_group_member_info_update_lock YES YES singleton 0 NULL
@@ -94,6 +95,7 @@ wait/synch/cond/group_rpl/COND_group_part_handler_run YES YES singleton 0 NULL
9495
wait/synch/cond/group_rpl/COND_group_part_handler_abort YES YES singleton 0 NULL
9596
wait/synch/cond/group_rpl/COND_message_service_run YES YES singleton 0 NULL
9697
wait/synch/cond/group_rpl/COND_multi_primary_action_notification YES YES singleton 0 NULL
98+
wait/synch/cond/group_rpl/COND_transaction_monitoring_wait YES YES singleton 0 NULL
9799
wait/synch/cond/group_rpl/COND_view_modification_wait YES YES singleton 0 NULL
98100
wait/synch/cond/group_rpl/COND_pipeline_continuation YES YES singleton 0 NULL
99101
wait/synch/cond/group_rpl/COND_synchronized_queue YES YES singleton 0 NULL
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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. Start group in single primary mode.
8+
# Server1 will be primary and server 2 secondary.
9+
include/start_and_bootstrap_group_replication.inc
10+
[connection server2]
11+
include/start_group_replication.inc
12+
13+
# 2. Run UDF group_replication_set_as_primary from server2.
14+
# 2.A. Promote server2 as a new primary.
15+
SELECT group_replication_set_as_primary("SERVER2_UUID", 600);
16+
group_replication_set_as_primary("SERVER2_UUID", 600)
17+
Primary server switched to: SERVER2_UUID
18+
include/assert.inc [Time elapsed must be less than the timeout]
19+
include/gr_assert_primary_member.inc
20+
[connection server1]
21+
include/gr_assert_secondary_member.inc
22+
23+
# 2.B. Promote server1 as a new primary.
24+
[connection server2]
25+
SELECT group_replication_set_as_primary("SERVER1_UUID", 600);
26+
group_replication_set_as_primary("SERVER1_UUID", 600)
27+
Primary server switched to: SERVER1_UUID
28+
include/assert.inc [Time elapsed must be less than the timeout]
29+
include/gr_assert_secondary_member.inc
30+
[connection server1]
31+
include/gr_assert_primary_member.inc
32+
33+
# 3. Run UDF group_replication_set_as_primary from server1.
34+
# 3.A. Make server2 primary from server1(present primary).
35+
[connection server1]
36+
SELECT group_replication_set_as_primary("SERVER2_UUID", 600);
37+
group_replication_set_as_primary("SERVER2_UUID", 600)
38+
Primary server switched to: SERVER2_UUID
39+
include/assert.inc [Time elapsed must be less than the timeout]
40+
include/gr_assert_secondary_member.inc
41+
[connection server2]
42+
include/gr_assert_primary_member.inc
43+
44+
# 3.B. Make server1 primary from server1(present secondary).
45+
[connection server1]
46+
SELECT group_replication_set_as_primary("SERVER1_UUID", 600);
47+
group_replication_set_as_primary("SERVER1_UUID", 600)
48+
Primary server switched to: SERVER1_UUID
49+
include/assert.inc [Time elapsed must be less than the timeout]
50+
include/gr_assert_primary_member.inc
51+
[connection server2]
52+
include/gr_assert_secondary_member.inc
53+
54+
# 4. Cleanup.
55+
include/group_replication_end.inc
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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 group of 2 servers, M1(primary) and M2(secondary).
8+
CREATE TABLE t1(c1 int primary key);
9+
include/start_and_bootstrap_group_replication.inc
10+
[connection server2]
11+
include/start_group_replication.inc
12+
13+
# 2. Execute change primary from server2(secondary) and block the operation.
14+
[connection server2]
15+
SET @@GLOBAL.DEBUG= '+d,group_replication_block_primary_action_validation';
16+
SELECT group_replication_set_as_primary("SERVER2_UUID", 1);;
17+
[connection server1]
18+
19+
# 3. Execute transaction on server1(primary), transactions should fail.
20+
[connection server1]
21+
INSERT INTO t1 values(1);
22+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
23+
CREATE TABLE t2(c1 int primary key);
24+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
25+
CREATE TABLE t1(c1 int primary key);
26+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
27+
SELECT c1 FROM t1;
28+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
29+
DO group_replication_enable_member_action("mysql_disable_super_read_only_if_primary", "AFTER_PRIMARY_ELECTION");
30+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
31+
SELECT group_replication_enable_member_action("mysql_disable_super_read_only_if_primary", "AFTER_PRIMARY_ELECTION");
32+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
33+
34+
# 4. Execute commands which are unaffected with
35+
# group_replication_set_as_primary() in execution.
36+
DO SLEEP(1);
37+
SELECT SLEEP(1);
38+
SLEEP(1)
39+
0
40+
SELECT COUNT(*) from performance_schema.replication_group_members;
41+
COUNT(*)
42+
2
43+
SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE='debug sync point: now';
44+
COUNT(*)=0
45+
1
46+
SELECT COUNT(*)=1 FROM sys.version;
47+
COUNT(*)=1
48+
1
49+
50+
# 5. Unblock change primary from server2 and reap the operation.
51+
[connection server_2]
52+
SET DEBUG_SYNC= "now SIGNAL signal.primary_action_continue";
53+
[connection server2]
54+
group_replication_set_as_primary("SERVER2_UUID", 1)
55+
Primary server switched to: SERVER2_UUID
56+
57+
# 6. Assert primary changed.
58+
# Assert data is not present on M1 and M2.
59+
[connection server2]
60+
include/gr_assert_primary_member.inc
61+
[connection server1]
62+
include/gr_assert_secondary_member.inc
63+
include/assert.inc ['There is no value 1 in table t1']
64+
include/assert.inc ['Check table t2 does not exist.']
65+
include/diff_tables.inc [server1:test.t1, server2:test.t1]
66+
67+
# 7. Execute change primary from server2(primary) and block the operation.
68+
[connection server2]
69+
SELECT group_replication_set_as_primary("SERVER1_UUID", 1);;
70+
[connection server_2]
71+
72+
# 8. Execute transaction on server2(primary), transactions should fail.
73+
[connection server_2]
74+
INSERT INTO t1 values(1);
75+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
76+
CREATE TABLE t2(c1 int primary key);
77+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
78+
CREATE TABLE t1(c1 int primary key);
79+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
80+
SELECT c1 FROM t1;
81+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
82+
DO group_replication_enable_member_action("mysql_disable_super_read_only_if_primary", "AFTER_PRIMARY_ELECTION");
83+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
84+
SELECT group_replication_enable_member_action("mysql_disable_super_read_only_if_primary", "AFTER_PRIMARY_ELECTION");
85+
ERROR HY000: All queries have been blocked while function 'group_replication_set_as_primary()' is executing. Please refer timeout parameter of function 'group_replication_set_as_primary()'.
86+
87+
# 9. Execute commands which are not stopped.
88+
DO SLEEP(1);
89+
SELECT SLEEP(1);
90+
SLEEP(1)
91+
0
92+
SELECT COUNT(*) from performance_schema.replication_group_members;
93+
COUNT(*)
94+
2
95+
SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE='debug sync point: now';
96+
COUNT(*)=0
97+
1
98+
SELECT COUNT(*)=1 FROM sys.version;
99+
COUNT(*)=1
100+
1
101+
102+
# 10. Unblock change primary from server2 and reap the operation.
103+
SET DEBUG_SYNC= "now SIGNAL signal.primary_action_continue";
104+
[connection server2]
105+
group_replication_set_as_primary("SERVER1_UUID", 1)
106+
Primary server switched to: SERVER1_UUID
107+
108+
# 11. Assert primary changed.
109+
# Assert data is not present on M1 and M2.
110+
[connection server1]
111+
include/gr_assert_primary_member.inc
112+
[connection server2]
113+
include/gr_assert_secondary_member.inc
114+
include/assert.inc ['There is no value 1 in table t1']
115+
include/assert.inc ['Check table t2 does not exist.']
116+
include/diff_tables.inc [server1:test.t1, server2:test.t1]
117+
118+
# 12. Cleanup.
119+
[connection server1]
120+
DROP TABLE t1;
121+
[connection server2]
122+
SET DEBUG_SYNC= 'RESET';
123+
SET @@GLOBAL.DEBUG= '-d,group_replication_block_primary_action_validation';
124+
include/group_replication_end.inc

0 commit comments

Comments
 (0)