summaryrefslogtreecommitdiff
path: root/mysql-test/suite/galera/t/galera_bf_kill_debug.test
blob: f83d4a28ce9cd93a1bfd69183914da31fbd27349 (plain)
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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
--source include/galera_cluster.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc

--echo #
--echo # Case 1: We execute bf kill to wsrep_innobase_kill_one_trx
--echo # function just before wsrep_thd_LOCK(thd) call. Then we
--echo # try to kill victim transaction by KILL QUERY
--echo #

CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);

#
# This will be victim transaction for both bf kill and
# user KILL
#
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
begin;
update t1 set b = b * 10 where id between 2 and 4;

#
# Take thread id for above query
#
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
--let $k_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'root' AND COMMAND = 'Sleep' LIMIT 1`

#
# Set DEBUG_SYNC and send conflicting DDL that will be TOI (bf) and
# cause bf_kill
#
--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1
SET DEBUG_SYNC='wsrep_before_BF_victim_lock SIGNAL bf_kill WAIT_FOR bf_continue';
--send ALTER TABLE t1 ADD UNIQUE KEY b1(b);

#
# Wait until we have reached the sync point
#
--connection node_1
SET DEBUG_SYNC='now WAIT_FOR bf_kill';

#
# Try to kill update query
#
--connection node_1b
--disable_query_log
--send_eval KILL QUERY $k_thread;


#
# Let bf_kill continue
#
--connection node_1
SET DEBUG_SYNC='now SIGNAL bf_continue';
--connection node_1c
--reap
SHOW CREATE TABLE t1;
SELECT * FROM t1;

--connection node_1b
--reap
--enable_query_log

--connection node_1
SET DEBUG_SYNC= 'RESET';
DROP TABLE t1;

--disconnect node_1a
--disconnect node_1b
--disconnect node_1c

--echo #
--echo # Case 2: We execute bf kill to wsrep_innobase_kill_one_trx
--echo # function just after wsrep_thd_LOCK(thd) call. Then we
--echo # try to kill victim transaction by KILL QUERY
--echo #

CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);

#
# This will be victim transaction for both bf kill and
# user KILL
#
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
begin;
update t1 set b = b * 10 where id between 2 and 4;

#
# Take thread id for above query
#
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
--let $k_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'root' AND COMMAND = 'Sleep' LIMIT 1`

#
# Set DEBUG_SYNC and send conflicting DDL that will be TOI (bf) and
# cause bf_kill
#
--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1
SET DEBUG_SYNC='wsrep_after_BF_victim_lock SIGNAL bf_kill WAIT_FOR bf_continue';
--send ALTER TABLE t1 ADD UNIQUE KEY b1(b);

#
# Wait until we have reached the sync point
#
--connection node_1
SET DEBUG_SYNC='now WAIT_FOR bf_kill';

#
# Try to kill update query
#
--connection node_1b
--disable_query_log
--send_eval KILL QUERY $k_thread;

#
# Let bf_kill continue
#
--connection node_1
SET DEBUG_SYNC='now SIGNAL bf_continue';
--connection node_1c
--reap
SHOW CREATE TABLE t1;
SELECT * FROM t1;

--connection node_1b
--reap
--enable_query_log

--connection node_1
SET DEBUG_SYNC= 'RESET';
DROP TABLE t1;

--disconnect node_1a
--disconnect node_1b
--disconnect node_1c

--echo #
--echo # Case 3: Create victim transaction and try to send user KILL
--echo # from several threads
--echo #

CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);

#
# This will be victim transaction for user KILL
#
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
begin;
update t1 set b = b * 10 where id between 2 and 4;

#
# Take thread id for above query
#
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1
--connect node_1d, 127.0.0.1, root, , test, $NODE_MYPORT_1

--connection node_1b
--let $k_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'root' AND COMMAND = 'Sleep' LIMIT 1`

#
# Try to kill update query from several connections concurrently
#
--disable_query_log
--send_eval KILL QUERY $k_thread;

--connection node_1c
--disable_query_log
--send_eval KILL QUERY $k_thread;

--connection node_1d
--disable_query_log
--send_eval KILL QUERY $k_thread;

#
# We do not know execution order so any of these could fail as KILL
# has been already done
#
--connection node_1b
--enable_query_log
--error 0,ER_KILL_DENIED_ERROR
--reap
--connection node_1c
--enable_query_log
--error 0,ER_KILL_DENIED_ERROR
--reap
--connection node_1d
--enable_query_log
--error 0,ER_KILL_DENIED_ERROR
--reap

--connection node_1
--disconnect node_1a
--disconnect node_1b
--disconnect node_1c
--disconnect node_1d
DROP TABLE t1;

--echo #
--echo # Case 4: MDL-conflict, we execute ALTER until we hit gap in
--echo # wsrep_abort_transaction, while we are there we try to
--echo # manually KILL conflicting transaction (UPDATE) and
--echo # send conflicting transaction from other node to be executed
--echo # in this node by applier. As ALTER and KILL are TOI they
--echo # are not executed concurrently. Similarly UPDATE from other
--echo # node will wait for certification.
--echo #

CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);

#
# This will be victim transaction for both bf kill and
# user KILL, and should not have any effect on result
#
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
begin;
update t1 set b = b * 10 where id between 2 and 4;

#
# Take thread id for above query
#
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
--let $k_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'root' AND COMMAND = 'Sleep' LIMIT 1`

#
# Set DEBUG_SYNC and send conflicting DDL that will be TOI (bf) and
# cause bf_kill but let's execute it only to gap in wsrep_abort_transaction
#
--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1
SET DEBUG_SYNC='wsrep_abort_victim_unlocked SIGNAL bf_kill_unlocked WAIT_FOR bf_continue';
--send ALTER TABLE t1 ADD UNIQUE KEY b1(b);

#
# Wait until we have reached the sync point
#
--connection node_1
SET DEBUG_SYNC='now WAIT_FOR bf_kill_unlocked';

#
# Try to kill update query
#
--connection node_1b
--disable_query_log
--send_eval KILL QUERY $k_thread;

#
# Send conflicting update from other node, this should be applied on both nodes
# but should not kill ALTER
#
--enable_query_log
--connection node_2
--send update t1 set b = b + 1000 where id between 2 and 4;

#
# Let bf_kill continue
#
--connection node_1
SET DEBUG_SYNC='now SIGNAL bf_continue';
--connection node_1c
--reap
SHOW CREATE TABLE t1;
SELECT * FROM t1;

--connection node_1b
--reap
--enable_query_log

--connection node_1
SET DEBUG_SYNC= 'RESET';
SELECT * FROM t1;

--connection node_2
--reap
SHOW CREATE TABLE t1;
SELECT * FROM t1;
DROP TABLE t1;

--disconnect node_1a
--disconnect node_1c