1# ==== Purpose ====
2#
3# Expels a given member from the group by sending a SIGSTOP to it to keep it
4# from sending out his keep-alives.
5#
6# NOTE: you must source linux.inc in order to use this include file, due to the
7# way we expel the member (we send a SIGSTOP/SIGCONT, that doesn't work in
8# Windows).
9#
10# ==== Usage ====
11#
12# --let $member_id = <the ID of the member you want to expel>
13# --source include/gr_expel_member_from_group.inc
14#
15# Parameters:
16#   $member_id
17#     The ID of the member we want to expel from the group
18#
19--let $include_filename = gr_expel_member_from_group.inc
20--source include/begin_include_file.inc
21
22if ($member_id == '')
23{
24  --die ERROR IN TEST: You must set $member_id before sourcing gr_expel_member_from_group.inc
25}
26
27# Save current connection.
28--let $_old_connection= $CURRENT_CONNECTION
29
30#
31# First we find out which connection corresponds to the ID of the member
32# we want to expel.
33#
34--let $itr = $rpl_server_count
35while ($itr > 0)
36{
37  --let $rpl_connection_name=server$itr
38  --source include/rpl_connection.inc
39
40  #
41  # Verify if this is the connection of the member to expel.
42  # If so, we save the connection name.
43  --let $curr_member_id = `SELECT @@GLOBAL.server_uuid`
44  if ($curr_member_id == $member_id)
45  {
46    --let $conn_name = server$itr
47    --let $itr = 1
48  }
49
50  --dec $itr
51}
52
53if ($conn_name == '')
54{
55  --die Could not find a connection with $member_id
56}
57
58#
59# Now we need to obtain the PID of the server to expel, so we can send it the
60# signal we want.
61#
62--let $rpl_connection_name = $conn_name
63--source include/rpl_connection.inc
64SET SESSION sql_log_bin = 0;
65CREATE TABLE pid_table(pid_no INT PRIMARY KEY);
66--let $pid_file=`SELECT @@pid_file`
67--replace_result $pid_file pid_file
68--eval LOAD DATA LOCAL INFILE '$pid_file' INTO TABLE pid_table
69--let $server_pid=`SELECT pid_no FROM pid_table`
70DROP TABLE pid_table;
71SET SESSION sql_log_bin = 1;
72
73#
74# We send a SIGSTOP to the member to expel. This will cause the server process
75# to suspend and thus won't send out his keep-alive packet. The xcom fault
76# detector of some member of the group will think the member is dead and expel
77# it from the group.
78--exec kill -19 $server_pid
79
80#
81# We now go through each member of the group except the one we forced to be
82# expelled, in order to verify that this member has indeed been expelled.
83#
84--let $itr = $rpl_server_count
85--let $new_server_count = $rpl_server_count
86--dec $new_server_count
87while ($itr > 0)
88{
89  # Skip the expelled member
90  --let curr_server = server$itr
91  if ($curr_server != $conn_name)
92  {
93    --let $rpl_connection_name = server$itr
94    --source include/rpl_connection.inc
95    --let $group_replication_number_of_members = $new_server_count
96    --source include/gr_wait_for_number_of_members.inc
97  }
98
99  --dec $itr
100}
101
102#
103# Wake up the suspended member - he should have been expelled.
104#
105--let $rpl_connection_name = $conn_name
106--source include/rpl_connection.inc
107--exec kill -18 $server_pid
108
109# Verify that the member entered an error state
110--let $group_replication_member_state = ERROR
111--let $group_replication_member_id = $member_id
112--source include/gr_wait_for_member_state.inc
113
114# Then verify that it enabled super_read_only
115--let $rpl_connection_name = $conn_name
116--source include/rpl_connection.inc
117--let $assert_text = super_read_only should be enabled
118--let $assert_cond = [SELECT @@GLOBAL.super_read_only] = 1;
119--source include/assert.inc
120
121# Revert old connection.
122--connection $_old_connection
123
124--let $include_filename = gr_expel_member_from_group.inc
125--source include/end_include_file.inc
126