Skip to content

Commit 9232fae

Browse files
author
Hemant Dangi
committed
Merge branch 'mysql-5.7' into mysql-trunk
2 parents 3e15934 + a751a0b commit 9232fae

17 files changed

+586
-27
lines changed

include/mysql/plugin_group_replication.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ struct st_mysql_group_replication
9797
/*
9898
This function is used to start the group replication.
9999
*/
100-
int (*start)();
100+
int (*start)(char **error_message);
101101
/*
102102
This function is used to stop the group replication.
103103
*/
104-
int (*stop)();
104+
int (*stop)(char **error_message);
105105
/*
106106
This function is used to get the current group replication running status.
107107
*/

rapid/plugin/group_replication/include/gcs_event_handlers.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ class Plugin_gcs_events_handler: public Gcs_communication_event_listener,
6666
Plugin_gcs_events_handler(Applier_module_interface* applier_module,
6767
Recovery_module* recovery_module,
6868
Plugin_gcs_view_modification_notifier* vc_notifier,
69-
Compatibility_module* compatibility_manager);
69+
Compatibility_module* compatibility_manager,
70+
ulong components_stop_timeout);
7071
virtual ~Plugin_gcs_events_handler();
7172

7273
/*
@@ -79,6 +80,14 @@ class Plugin_gcs_events_handler: public Gcs_communication_event_listener,
7980
void on_suspicions(const std::vector<Gcs_member_identifier>& members,
8081
const std::vector<Gcs_member_identifier>& unreachable) const;
8182

83+
/**
84+
Sets the component stop timeout.
85+
86+
@param[in] timeout the timeout
87+
*/
88+
void set_stop_wait_timeout (ulong timeout){
89+
stop_wait_timeout= timeout;
90+
}
8291

8392
private:
8493
/*
@@ -272,6 +281,9 @@ class Plugin_gcs_events_handler: public Gcs_communication_event_listener,
272281
/**The status of this member when it joins*/
273282
st_compatibility_types* joiner_compatibility_status;
274283

284+
/* Component stop timeout on shutdown */
285+
ulong stop_wait_timeout;
286+
275287
#ifndef DBUG_OFF
276288
bool set_number_of_members_on_view_changed_to_10;
277289
#endif

rapid/plugin/group_replication/include/plugin.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ bool check_async_channel_running_on_secondary();
9898
//Plugin public methods
9999
int plugin_group_replication_init(MYSQL_PLUGIN plugin_info);
100100
int plugin_group_replication_deinit(void *p);
101-
int plugin_group_replication_start();
102-
int plugin_group_replication_stop();
101+
int plugin_group_replication_start(char **error_message= NULL);
102+
int plugin_group_replication_stop(char **error_message= NULL);
103103
bool plugin_is_group_replication_running();
104104
bool plugin_get_connection_status(
105105
const GROUP_REPLICATION_CONNECTION_STATUS_CALLBACKS& callbacks);

rapid/plugin/group_replication/include/plugin_constants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#define GROUP_REPLICATION_COMMUNICATION_LAYER_JOIN_ERROR 5
3434
#define GROUP_REPLICATION_APPLIER_STOP_TIMEOUT 6
3535
#define GROUP_REPLICATION_MAX_GROUP_SIZE 7
36+
#define GROUP_REPLICATION_COMMAND_FAILURE 8
3637

3738
/* View timeout (seconds) */
3839
#define VIEW_MODIFICATION_TIMEOUT 60

rapid/plugin/group_replication/src/applier.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,27 @@ void Applier_module::leave_group_on_failure()
693693
bool set_read_mode= false;
694694
Gcs_operations::enum_leave_state state= gcs_module->leave();
695695

696+
char **error_message= NULL;
697+
int error= channel_stop_all(CHANNEL_APPLIER_THREAD|CHANNEL_RECEIVER_THREAD,
698+
stop_wait_timeout, error_message);
699+
if (error)
700+
{
701+
if (error_message != NULL && *error_message != NULL)
702+
{
703+
log_message(MY_ERROR_LEVEL,
704+
"Error stopping all replication channels while server was"
705+
" leaving the group. %s", *error_message);
706+
my_free(error_message);
707+
}
708+
else
709+
{
710+
log_message(MY_ERROR_LEVEL,
711+
"Error stopping all replication channels while server was"
712+
" leaving the group. Got error: %d. Please check the error"
713+
" log for more details.", error);
714+
}
715+
}
716+
696717
std::stringstream ss;
697718
plugin_log_level log_severity= MY_WARNING_LEVEL;
698719
switch (state)

rapid/plugin/group_replication/src/gcs_event_handlers.cc

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ Plugin_gcs_events_handler::
3030
Plugin_gcs_events_handler(Applier_module_interface* applier_module,
3131
Recovery_module* recovery_module,
3232
Plugin_gcs_view_modification_notifier* vc_notifier,
33-
Compatibility_module* compatibility_module)
33+
Compatibility_module* compatibility_module,
34+
ulong components_stop_timeout)
3435
: applier_module(applier_module), recovery_module(recovery_module),
3536
view_change_notifier(vc_notifier),
36-
compatibility_manager(compatibility_module)
37+
compatibility_manager(compatibility_module),
38+
stop_wait_timeout(components_stop_timeout)
3739
{
3840
this->temporary_states= new std::set<Group_member_info*,
3941
Group_member_info_pointer_comparator>();
@@ -1628,6 +1630,28 @@ void
16281630
Plugin_gcs_events_handler::leave_group_on_error() const
16291631
{
16301632
Gcs_operations::enum_leave_state state= gcs_module->leave();
1633+
char **error_message= NULL;
1634+
1635+
int error= channel_stop_all(CHANNEL_APPLIER_THREAD|CHANNEL_RECEIVER_THREAD,
1636+
stop_wait_timeout, error_message);
1637+
if (error)
1638+
{
1639+
if (error_message != NULL && *error_message != NULL)
1640+
{
1641+
log_message(MY_ERROR_LEVEL,
1642+
"Error stopping all replication channels while server was"
1643+
" leaving the group. %s", *error_message);
1644+
my_free(error_message);
1645+
}
1646+
else
1647+
{
1648+
log_message(MY_ERROR_LEVEL,
1649+
"Error stopping all replication channels while server was"
1650+
" leaving the group. Got error: %d. Please check the error"
1651+
" log for more details.", error);
1652+
}
1653+
}
1654+
16311655
std::stringstream ss;
16321656
plugin_log_level log_severity= MY_WARNING_LEVEL;
16331657
switch (state)

rapid/plugin/group_replication/src/plugin.cc

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ void initialize_group_partition_handler();
266266
int start_group_communication();
267267
void declare_plugin_running();
268268
int leave_group();
269-
int terminate_plugin_modules();
269+
int terminate_plugin_modules(bool flag_stop_async_channel= false,
270+
char **error_message= NULL);
270271
int terminate_applier_module();
271272
int terminate_recovery_module();
272273
void terminate_asynchronous_channels_observer();
@@ -378,7 +379,7 @@ plugin_get_group_member_stats(
378379
gcs_module, channel_name);
379380
}
380381

381-
int plugin_group_replication_start()
382+
int plugin_group_replication_start(char **)
382383
{
383384
DBUG_ENTER("plugin_group_replication_start");
384385

@@ -846,7 +847,7 @@ int leave_group()
846847
return 0;
847848
}
848849

849-
int plugin_group_replication_stop()
850+
int plugin_group_replication_stop(char **error_message)
850851
{
851852
DBUG_ENTER("plugin_group_replication_stop");
852853

@@ -893,7 +894,7 @@ int plugin_group_replication_stop()
893894
/* first leave all joined groups (currently one) */
894895
leave_group();
895896

896-
int error= terminate_plugin_modules();
897+
int error= terminate_plugin_modules(true, error_message);
897898

898899
group_replication_running= false;
899900

@@ -922,7 +923,7 @@ int plugin_group_replication_stop()
922923
DBUG_RETURN(error);
923924
}
924925

925-
int terminate_plugin_modules()
926+
int terminate_plugin_modules(bool flag_stop_async_channel, char **error_message)
926927
{
927928

928929
if(terminate_recovery_module())
@@ -953,6 +954,58 @@ int terminate_plugin_modules()
953954

954955
terminate_asynchronous_channels_observer();
955956

957+
if (flag_stop_async_channel)
958+
{
959+
int channel_err= channel_stop_all(CHANNEL_APPLIER_THREAD|CHANNEL_RECEIVER_THREAD,
960+
components_stop_timeout_var, error_message);
961+
if (channel_err)
962+
{
963+
if (error_message != NULL)
964+
{
965+
if (*error_message == NULL)
966+
{
967+
char err_tmp_arr[MYSQL_ERRMSG_SIZE];
968+
size_t err_len= my_snprintf(err_tmp_arr, sizeof(err_tmp_arr),
969+
"Error stopping all replication channels while"
970+
" server was leaving the group. Got error: %d."
971+
" Please check the error log for more details.",
972+
channel_err);
973+
974+
*error_message= (char *)my_malloc(PSI_NOT_INSTRUMENTED,
975+
err_len + 1, MYF(0));
976+
strncpy(*error_message, err_tmp_arr, err_len);
977+
}
978+
else
979+
{
980+
char err_tmp_arr[]= "Error stopping all replication channels while"
981+
" server was leaving the group. ";
982+
size_t total_length= strlen(*error_message) + strlen(err_tmp_arr);
983+
size_t error_length= strlen(*error_message);
984+
985+
if (total_length < MYSQL_ERRMSG_SIZE)
986+
{
987+
log_message(MY_INFORMATION_LEVEL, "error_message: %s", *error_message);
988+
989+
char *ptr= (char *)my_realloc(PSI_NOT_INSTRUMENTED,
990+
*error_message,
991+
total_length + 1, MYF(0));
992+
993+
memmove(ptr + strlen(err_tmp_arr), ptr, error_length);
994+
memcpy(ptr, err_tmp_arr, strlen(err_tmp_arr));
995+
ptr[total_length]= '\0';
996+
*error_message= ptr;
997+
}
998+
}
999+
}
1000+
1001+
1002+
if (!error)
1003+
{
1004+
error= GROUP_REPLICATION_COMMAND_FAILURE;
1005+
}
1006+
}
1007+
}
1008+
9561009
delete group_partition_handler;
9571010
group_partition_handler= NULL;
9581011

@@ -1490,7 +1543,8 @@ int start_group_communication()
14901543
events_handler= new Plugin_gcs_events_handler(applier_module,
14911544
recovery_module,
14921545
view_change_notifier,
1493-
compatibility_mgr);
1546+
compatibility_mgr,
1547+
components_stop_timeout_var);
14941548

14951549
view_change_notifier->start_view_modification();
14961550

@@ -2127,6 +2181,10 @@ static void update_component_timeout(MYSQL_THD, SYS_VAR*,
21272181
{
21282182
recovery_module->set_stop_wait_timeout(in_val);
21292183
}
2184+
if (events_handler != NULL)
2185+
{
2186+
events_handler->set_stop_wait_timeout(in_val);
2187+
}
21302188

21312189
DBUG_VOID_RETURN;
21322190
}

rapid/plugin/group_replication/src/recovery.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,27 @@ void Recovery_module::leave_group_on_recovery_failure()
199199

200200
Gcs_operations::enum_leave_state state= gcs_module->leave();
201201

202+
char **error_message= NULL;
203+
int error= channel_stop_all(CHANNEL_APPLIER_THREAD|CHANNEL_RECEIVER_THREAD,
204+
stop_wait_timeout, error_message);
205+
if (error)
206+
{
207+
if (error_message != NULL && *error_message != NULL)
208+
{
209+
log_message(MY_ERROR_LEVEL,
210+
"Error stopping all replication channels while server was"
211+
" leaving the group. %s", *error_message);
212+
my_free(error_message);
213+
}
214+
else
215+
{
216+
log_message(MY_ERROR_LEVEL,
217+
"Error stopping all replication channels while server was"
218+
" leaving the group. Got error: %d. Please check the error"
219+
" log for more details.", error);
220+
}
221+
}
222+
202223
std::stringstream ss;
203224
plugin_log_level log_severity= MY_WARNING_LEVEL;
204225
switch (state)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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+
############################################################
8+
# 1. Setup Group Replication on server 1.
9+
[connection server1]
10+
include/start_and_bootstrap_group_replication.inc
11+
12+
############################################################
13+
# 2. Setup a asynchronous replication connection from server 2
14+
# into group (server 1)
15+
[connection server1]
16+
CHANGE MASTER TO MASTER_HOST='localhost', MASTER_USER='root', MASTER_PORT=SERVER_2_PORT, MASTER_AUTO_POSITION=1 for channel 'ch2_1';
17+
Warnings:
18+
Note 1759 Sending passwords in plain text without SSL/TLS is extremely insecure.
19+
Note 1760 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.
20+
include/start_slave.inc
21+
22+
############################################################
23+
# 3. Execute some transactions on server 2.
24+
[connection server2]
25+
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
26+
INSERT INTO t1 VALUES (0);
27+
28+
############################################################
29+
# 4. Wait until transactions executed on server 2 are applied
30+
# on group.
31+
include/sync_slave_sql_with_master.inc [FOR CHANNEL ch2_1]
32+
33+
############################################################
34+
# 5. Activate group_replication_stop_all_channels_failure
35+
# debug sync point, which will return
36+
# ER_GROUP_REPLICATION_COMMAND_FAILURE error, when stop
37+
# group replication calls to stop all replication channels.
38+
[connection server1]
39+
# 5.1. Stop Group Replication
40+
SET @debug_save= @@GLOBAL.DEBUG;
41+
SET @@GLOBAL.DEBUG='d,group_replication_stop_all_channels_failure';
42+
STOP GROUP_REPLICATION;
43+
ERROR HY000: The STOP GROUP_REPLICATION command encountered a failure. Error stopping all replication channels while server was leaving the group. Error stopping channel(s): '' [error number: 1], 'ch2_1' [error number: 1]. Please check the error log for additional details.
44+
SET @@GLOBAL.DEBUG= @debug_save;
45+
# 5.2. Verify member is OFFLINE
46+
include/gr_wait_for_member_state.inc
47+
# 5.3. Verify occurrence of error message
48+
Occurrences of 'Error stopping channel: ch2_1. Got error: 1, Error_code: 1' in the input file: 1
49+
Occurrences of 'Error stopping channel: . Got error: 1, Error_code: 1' in the input file: 1
50+
51+
############################################################
52+
# 6. Execute data on server 2 and ensure it is not accepted on server 1.
53+
[connection server2]
54+
INSERT INTO t1 VALUES (1);
55+
56+
############################################################
57+
# 7. Verify channel ch2_1 IO and SQL THREADS are OFF
58+
[connection server1]
59+
include/wait_for_slave_to_stop.inc [FOR CHANNEL 'ch2_1']
60+
include/assert.inc [Verify channel ch2_1 IO_THREAD is OFF]
61+
include/assert.inc [Verify channel ch2_1 SQL_THREAD is OFF]
62+
63+
############################################################
64+
# 8. Verify data isn't replicated to group i.e. server1
65+
include/assert.inc ['There is no value 1 in table t1']
66+
67+
############################################################
68+
# 9. Clean Up
69+
[connection server1]
70+
SET GLOBAL read_only= 0;
71+
RESET SLAVE ALL FOR CHANNEL 'ch2_1';
72+
DROP TABLE test.t1;
73+
[connection server2]
74+
DROP TABLE test.t1;
75+
include/group_replication_end.inc
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--no-console --log_error=$MYSQLTEST_VARDIR/tmp/gr_stop_async_on_stop_gr.err

0 commit comments

Comments
 (0)