1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
source include/not_embedded.inc;
source include/have_innodb.inc;
#
# This test the rpl_semi_sync_master_wait_point functionality
# and illustrates the differences between the two values AFTER_COMMIT and
# AFTER_SYNC
#
--echo #
--echo # Preparation
--echo #
CREATE TABLE t1 (i INT NOT NULL, PRIMARY KEY (i)) ENGINE=InnoDB;
RESET MASTER;
let $save_timeout = `select @@global.rpl_semi_sync_master_timeout`;
let $save_wait_no_slave = `select @@global.rpl_semi_sync_master_wait_no_slave`;
let $save_wait_point = `select @@global.rpl_semi_sync_master_wait_point`;
SET @@global.rpl_semi_sync_master_timeout = 60000;
SET @@global.rpl_semi_sync_master_wait_no_slave = 1;
--echo # It's okay to see "Killed" but we should not see "Timeout" in the log.
call mtr.add_suppression("Killed waiting for reply of binlog");
call mtr.add_suppression("Run function 'after_commit' in plugin 'rpl_semi_sync_master' failed");
call mtr.add_suppression("Run function 'after_sync' in plugin 'rpl_semi_sync_master' failed");
--echo #
--echo # Test wait point = AFTER_COMMIT
--echo #
SET @@global.rpl_semi_sync_master_wait_point = AFTER_COMMIT;
--echo # Make another connection to INSERT from.
connect (other,localhost,root,,);
connection other;
let $other_connection_id = `SELECT CONNECTION_ID()`;
connection default;
--disable_query_log
eval SET @other_connection_id = $other_connection_id;
--enable_query_log
SET GLOBAL rpl_semi_sync_master_enabled = 1;
--echo # Go ahead and send the INSERT; it should block.
connection other;
send INSERT INTO t1 (i) VALUES (1);
connection default;
let $wait_condition =
SELECT COUNT(*) > 0 AS should_be_true
FROM information_schema.processlist
WHERE id = @other_connection_id
AND state = "Waiting for semi-sync ACK from slave";
--source include/wait_condition.inc
--echo # The INSERT thread should now be waiting.
SELECT state AS should_be_waiting
FROM information_schema.processlist WHERE id = @other_connection_id;
--echo # The insert should be visible to other threads
SELECT * FROM t1 ORDER BY 1;
--echo # Kill the waiting thread; it should die immediately.
KILL @other_connection_id;
--echo # Collect the error from the INSERT thread; it should be disconnected.
connection other;
--error 2013,ER_CONNECTION_KILLED
reap;
connection default;
--echo # Wait for INSERT thread to actually disappear (KILL closes connection
--echo # before thread actually finishes its processing).
let $wait_condition =
SELECT COUNT(*) = 0 AS should_be_true
FROM information_schema.processlist
WHERE id = @other_connection_id;
--source include/wait_condition.inc
--echo # The INSERT thread should now be gone.
SELECT state AS should_be_empty_set
FROM information_schema.processlist WHERE id = @other_connection_id;
--echo # The insert is still there
SELECT * FROM t1 ORDER BY 1;
connection default;
disconnect other;
--echo # Make another connection to INSERT from.
connect (other,localhost,root,,);
connection other;
let $other_connection_id = `SELECT CONNECTION_ID()`;
connection default;
--disable_query_log
eval SET @other_connection_id = $other_connection_id;
--enable_query_log
--echo # Go ahead and send the INSERT; it should block.
connection other;
send INSERT INTO t1 (i) VALUES (2);
connection default;
let $wait_condition =
SELECT COUNT(*) > 0 AS should_be_true
FROM information_schema.processlist
WHERE id = @other_connection_id
AND state = "Waiting for semi-sync ACK from slave";
--source include/wait_condition.inc
--echo # The INSERT thread should now be waiting.
SELECT state AS should_be_waiting
FROM information_schema.processlist WHERE id = @other_connection_id;
--echo # The insert should be visible to other threads
SELECT * FROM t1 ORDER BY 1;
--echo # Now restart server
--source include/restart_mysqld.inc
--echo # Done restarting server
--echo # Reset setting that were lost in restart
SET @@global.rpl_semi_sync_master_timeout = 60000;
SET @@global.rpl_semi_sync_master_wait_no_slave = 1;
--echo # Check that row is still there
SELECT * FROM t1 ORDER BY 1;
disconnect other;
--echo #
--echo # Test wait point = AFTER_SYNC
--echo #
SET @@global.rpl_semi_sync_master_wait_point = AFTER_SYNC;
--echo # Make another connection to INSERT from.
connect (other,localhost,root,,);
connection other;
let $other_connection_id = `SELECT CONNECTION_ID()`;
connection default;
--disable_query_log
eval SET @other_connection_id = $other_connection_id;
--enable_query_log
SET GLOBAL rpl_semi_sync_master_enabled = 1;
--echo # Go ahead and send the INSERT; it should block.
connection other;
send INSERT INTO t1 (i) VALUES (3);
connection default;
let $wait_condition =
SELECT COUNT(*) > 0 AS should_be_true
FROM information_schema.processlist
WHERE id = @other_connection_id
AND state = "Waiting for semi-sync ACK from slave";
--source include/wait_condition.inc
--echo # The INSERT thread should now be waiting.
SELECT state AS should_be_waiting
FROM information_schema.processlist WHERE id = @other_connection_id;
--echo # The insert should NOT be visible to other threads
SELECT * FROM t1 ORDER BY 1;
--echo # Kill the waiting thread; it should die immediately.
KILL @other_connection_id;
--echo # Collect the error from the INSERT thread; it should be disconnected.
connection other;
--error 2013,ER_CONNECTION_KILLED
reap;
connection default;
--echo # Wait for INSERT thread to actually disappear (KILL closes connection
--echo # before thread actually finishes its processing).
let $wait_condition =
SELECT COUNT(*) = 0 AS should_be_true
FROM information_schema.processlist
WHERE id = @other_connection_id;
--source include/wait_condition.inc
--echo # The INSERT thread should now be gone.
SELECT state AS should_be_empty_set
FROM information_schema.processlist WHERE id = @other_connection_id;
--echo # The row inserted is there
SELECT * FROM t1 ORDER BY 1;
connection default;
disconnect other;
--echo # Make another connection to INSERT from.
connect (other,localhost,root,,);
connection other;
let $other_connection_id = `SELECT CONNECTION_ID()`;
connection default;
--disable_query_log
eval SET @other_connection_id = $other_connection_id;
--enable_query_log
--echo # Go ahead and send the INSERT; it should block.
connection other;
send INSERT INTO t1 (i) VALUES (4);
connection default;
let $wait_condition =
SELECT COUNT(*) > 0 AS should_be_true
FROM information_schema.processlist
WHERE id = @other_connection_id
AND state = "Waiting for semi-sync ACK from slave";
--source include/wait_condition.inc
--echo # The INSERT thread should now be waiting.
SELECT state AS should_be_waiting
FROM information_schema.processlist WHERE id = @other_connection_id;
--echo # The insert should NOT be visible to other threads
SELECT * FROM t1 ORDER BY 1;
--echo # Now restart server
--source include/restart_mysqld.inc
--echo # Done restarting server
--echo # Reset setting that were lost in restart
SET @@global.rpl_semi_sync_master_timeout = 60000;
SET @@global.rpl_semi_sync_master_wait_no_slave = 1;
--echo # But the row inserted is there
SELECT * FROM t1 ORDER BY 1;
disconnect other;
--echo #
--echo # Cleanup
--echo #
SET GLOBAL rpl_semi_sync_master_enabled = 0;
DROP TABLE t1;
eval SET @@global.rpl_semi_sync_master_timeout = $save_timeout;
eval SET @@global.rpl_semi_sync_master_wait_no_slave = $save_wait_no_slave;
eval SET @@global.rpl_semi_sync_master_wait_point = $save_wait_point;
|