summaryrefslogtreecommitdiffstats
path: root/mysql-test/suite/galera/t/MDEV-20616.test
blob: 1cbc4aadbddb8ff2214c1ffc19a7a9386f215932 (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
#
# Test different deadlock scenarios in innodb and make sure that
# wsrep patch does not handle them as BF aborts.
#

--source include/galera_cluster.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc

##############################################################################
# test case to verify that natural deadlock of trigger SP execution is
# handled correctly
##############################################################################

--echo
--echo Test phase 1 to make sure that natral deadlock in trigger SP execution is
--echo handled correctly
--echo
--let $aborts_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`

CREATE TABLE t1(a INT);
CREATE TABLE t2(f1 INT, f2 INT, f3 INT);
--disable_query_log
let $run=1000;
while($run)
{
  INSERT INTO t2 VALUES (1, 2, 3);
  dec $run;
}
--enable_query_log

DELIMITER |;
CREATE PROCEDURE proc()
BEGIN
    INSERT INTO t2 VALUES(100, 200, 300);
    UPDATE t2 SET f3 = f3 + 100;
END|
DELIMITER ;|

CREATE TRIGGER t1 BEFORE INSERT ON t1 FOR EACH ROW CALL proc();

--send INSERT INTO t1 VALUES(2);

--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
--send INSERT INTO t1 VALUES(1);

--connection node_1
--error 0,ER_LOCK_DEADLOCK
--reap

--connection node_1a
--error 0,ER_LOCK_DEADLOCK
--reap

--connection node_1
--let $aborts_new = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`
--disable_query_log
--eval SELECT $aborts_new - $aborts_old AS wsrep__bf_aborts;
--enable_query_log
DROP TABLE t1;
DROP TABLE t2;
DROP PROCEDURE proc;

##############################################################################
#
# test case to verify that BF abort for SP execution is handled correctly
#
##############################################################################

--echo
--echo Test phase 2 to make sure that BF abort for SP execution is
--echo handled correctly
--echo
--connection node_1
SET SESSION wsrep_retry_autocommit = 0;
SET SESSION wsrep_sync_wait = 0;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1));

# Control connection for Galera sync point management
--connection node_1a

SET SESSION wsrep_retry_autocommit = 0;
SET SESSION wsrep_sync_wait = 0;
--let $aborts_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`

DELIMITER |;
CREATE PROCEDURE proc_update()
BEGIN
  UPDATE t1 SET f2 = 'b';
END|
DELIMITER ;|

INSERT INTO t1 VALUES(1, 'a');

--connection node_1
SET debug_sync='wsrep_before_certification SIGNAL ready WAIT_FOR cont';
--send CALL proc_update

--connection node_1a
SET debug_sync='now WAIT_FOR ready';

--connection node_2
UPDATE t1 SET f2='c';

--connection node_1a
# wait for BF to happen
--let $wait_condition = SELECT VARIABLE_VALUE = $aborts_old + 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'
--source include/wait_condition.inc

SET debug_sync='now SIGNAL cont';

--connection node_1
--error ER_LOCK_DEADLOCK
--reap

--connection node_1a
SET debug_sync='RESET';

DROP PROCEDURE proc_update;


##############################################################################
#
# test case to verify that natural deadlock  does not cause BF abort
#
##############################################################################

--connection node_1
--echo
--echo Test phase 3 to make sure natural deadlock is not treated as BF abort
--echo
TRUNCATE t1;
INSERT INTO t1 VALUES (1, 'a'), (2, 'a');

--connection node_1a
--let $aborts_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`

START TRANSACTION;
UPDATE t1 SET f2 = 'b' WHERE f1 = 1;

--connection node_1
START TRANSACTION;
UPDATE t1 SET f2 = 'c' WHERE f1 = 2;

--connection node_1a
# this hangs for lock wait
--send UPDATE t1 SET f2 = 'b' WHERE f1 = 2

#
# classic deadlock happens here
#
--connection node_1
--error 0, ER_LOCK_DEADLOCK
UPDATE t1 SET f2 = 'c' WHERE f1 = 1;

--connection node_1a
--error 0, ER_LOCK_DEADLOCK
--reap
COMMIT;

#
# either one of SP executions was aborted because of natural deadlock, or in worst case
# they were ordered seqeuntailly, and both succeeded.
# anyways, we just check here that no BF aborts happened
#
--let $aborts_new = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`
--disable_query_log
--eval SELECT $aborts_new - $aborts_old AS wsrep__bf_aborts;
--enable_query_log

--connection node_1
ROLLBACK;

##############################################################################
#
# test case to verify that natural deadlock within SP exceution
# does not cause BF abort
#
##############################################################################

--echo
--echo Test phase 4 to make sure natural deadlock inside SP execution
--echo is not treated as BF abort
--echo

--connection node_1a
TRUNCATE t1;
INSERT INTO t1 VALUES (1, 'a'), (2, 'a');

--let $aborts_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`

DELIMITER |;
CREATE PROCEDURE proc_update_1()
BEGIN
  START TRANSACTION;
  UPDATE t1 SET f2 = 'b' WHERE f1 = 1;
  SELECT SLEEP(5);
  UPDATE t1 SET f2 = 'b' WHERE f1 = 2;
  COMMIT;
END|
DELIMITER ;|

DELIMITER |;
CREATE PROCEDURE proc_update_2()
BEGIN
  START TRANSACTION;
  UPDATE t1 SET f2 = 'c' WHERE f1 = 2;
  SELECT SLEEP(5);
  UPDATE t1 SET f2 = 'c' WHERE f1 = 1;
  COMMIT;
END|
DELIMITER ;|

--connection node_1
--send CALL proc_update_1

--connection node_1a
#
# calling proc_update_2 should cause a natural deadlock
# however, this test is not deterministic, and depends on the sleep() to
# cause expected ordering for update statement execution within SPs
# We therefore, allow both success and deadlock error for the result
#
--error 0, ER_LOCK_DEADLOCK
CALL proc_update_2;

#
# either one of SP executions was aborted because of natural deadlock, or in worst case
# they were ordered seqeuntailly, and both succeeded.
# anyways, we just check here that no BF aborts happened
#
--let $aborts_new = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`
--disable_query_log
--eval SELECT $aborts_new - $aborts_old AS wsrep__bf_aborts;
--enable_query_log


--connection node_1
--error 0, ER_LOCK_DEADLOCK
--reap

DROP PROCEDURE proc_update_1;
DROP PROCEDURE proc_update_2;
DROP TABLE t1;