Skip to content

Commit 8ff1096

Browse files
committed
MDEV-29081 trx_t::lock.was_chosen_as_deadlock_victim race in lock_wait_end()
The issue is that trx_t::lock.was_chosen_as_deadlock_victim can be reset before the transaction check it and set trx_t::error_state. The fix is to reset trx_t::lock.was_chosen_as_deadlock_victim only in trx_t::commit_in_memory(), which is invoked on full rollback. There is also no need to have separate bit in trx_t::lock.was_chosen_as_deadlock_victim to flag transaction it was chosen as a victim of Galera conflict resolution, the same variable can be used for both cases except debug build. For debug build we need to distinguish deadlock and Galera's abort victims for debug checks. Also there is no need to check for deadlock in lock_table_enqueue_waiting() for Galera as the coresponding check presents in lock_wait(). Local variable "error_state" in lock_wait() was replaced with trx->error_state, because before the replace lock_sys_t::cancel<false>(trx, lock) and lock_sys.deadlock_check() could change trx->error_state, which then could be overwritten with the local "error_state" variable value. The lock_wait_suspend_thread_enter DEBUG_SYNC point name is misleading, because lock_wait_suspend_thread was eliminated in e71e613. It was renamed to lock_wait_start. Reviewed by: Marko Mäkelä, Jan Lindström.
1 parent 5b4c832 commit 8ff1096

13 files changed

+271
-96
lines changed

mysql-test/suite/galera/r/galera_FK_duplicate_client_insert.result

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ connection node_1_u;
1414
begin;
1515
update user set j = j + 1 WHERE id > 0;
1616
connection node_1_i;
17-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
17+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
1818
insert into user_session(id,fk1,fk2) values (2, 2, 2);
1919
connection node_1;
2020
set debug_sync='now WAIT_FOR ins_waiting';
@@ -32,7 +32,7 @@ connection node_1_u;
3232
begin;
3333
update user set j = j + 1 WHERE id > 0;
3434
connection node_1_i;
35-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
35+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
3636
insert into user_session(id,fk1,fk2) values (2, 2, 2);
3737
connection node_1;
3838
set debug_sync='now WAIT_FOR ins_waiting';
@@ -50,7 +50,7 @@ connection node_1_u;
5050
begin;
5151
update user set j = j + 1 WHERE id > 0;
5252
connection node_1_i;
53-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
53+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
5454
insert into user_session(id,fk1,fk2) values (2, 2, 2);
5555
connection node_1;
5656
set debug_sync='now WAIT_FOR ins_waiting';
@@ -68,7 +68,7 @@ connection node_1_u;
6868
begin;
6969
update user set j = j + 1 WHERE id > 0;
7070
connection node_1_i;
71-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
71+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
7272
insert into user_session(id,fk1,fk2) values (2, 2, 2);
7373
connection node_1;
7474
set debug_sync='now WAIT_FOR ins_waiting';
@@ -86,7 +86,7 @@ connection node_1_u;
8686
begin;
8787
update user set j = j + 1 WHERE id > 0;
8888
connection node_1_i;
89-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
89+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
9090
insert into user_session(id,fk1,fk2) values (2, 2, 2);
9191
connection node_1;
9292
set debug_sync='now WAIT_FOR ins_waiting';
@@ -104,7 +104,7 @@ connection node_1_u;
104104
begin;
105105
update user set j = j + 1 WHERE id > 0;
106106
connection node_1_i;
107-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
107+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
108108
insert into user_session(id,fk1,fk2) values (2, 2, 2);
109109
connection node_1;
110110
set debug_sync='now WAIT_FOR ins_waiting';
@@ -122,7 +122,7 @@ connection node_1_u;
122122
begin;
123123
update user set j = j + 1 WHERE id > 0;
124124
connection node_1_i;
125-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
125+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
126126
insert into user_session(id,fk1,fk2) values (2, 2, 2);
127127
connection node_1;
128128
set debug_sync='now WAIT_FOR ins_waiting';
@@ -140,7 +140,7 @@ connection node_1_u;
140140
begin;
141141
update user set j = j + 1 WHERE id > 0;
142142
connection node_1_i;
143-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
143+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
144144
insert into user_session(id,fk1,fk2) values (2, 2, 2);
145145
connection node_1;
146146
set debug_sync='now WAIT_FOR ins_waiting';
@@ -158,7 +158,7 @@ connection node_1_u;
158158
begin;
159159
update user set j = j + 1 WHERE id > 0;
160160
connection node_1_i;
161-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
161+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
162162
insert into user_session(id,fk1,fk2) values (2, 2, 2);
163163
connection node_1;
164164
set debug_sync='now WAIT_FOR ins_waiting';
@@ -176,7 +176,7 @@ connection node_1_u;
176176
begin;
177177
update user set j = j + 1 WHERE id > 0;
178178
connection node_1_i;
179-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
179+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
180180
insert into user_session(id,fk1,fk2) values (2, 2, 2);
181181
connection node_1;
182182
set debug_sync='now WAIT_FOR ins_waiting';
@@ -202,7 +202,7 @@ connection node_1_u;
202202
begin;
203203
execute upd;
204204
connection node_1_i;
205-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
205+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
206206
execute ins1;
207207
connection node_1;
208208
set debug_sync='now WAIT_FOR ins_waiting';
@@ -220,7 +220,7 @@ connection node_1_u;
220220
begin;
221221
execute upd;
222222
connection node_1_i;
223-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
223+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
224224
execute ins1;
225225
connection node_1;
226226
set debug_sync='now WAIT_FOR ins_waiting';
@@ -238,7 +238,7 @@ connection node_1_u;
238238
begin;
239239
execute upd;
240240
connection node_1_i;
241-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
241+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
242242
execute ins1;
243243
connection node_1;
244244
set debug_sync='now WAIT_FOR ins_waiting';
@@ -256,7 +256,7 @@ connection node_1_u;
256256
begin;
257257
execute upd;
258258
connection node_1_i;
259-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
259+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
260260
execute ins1;
261261
connection node_1;
262262
set debug_sync='now WAIT_FOR ins_waiting';
@@ -274,7 +274,7 @@ connection node_1_u;
274274
begin;
275275
execute upd;
276276
connection node_1_i;
277-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
277+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
278278
execute ins1;
279279
connection node_1;
280280
set debug_sync='now WAIT_FOR ins_waiting';
@@ -292,7 +292,7 @@ connection node_1_u;
292292
begin;
293293
execute upd;
294294
connection node_1_i;
295-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
295+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
296296
execute ins1;
297297
connection node_1;
298298
set debug_sync='now WAIT_FOR ins_waiting';
@@ -310,7 +310,7 @@ connection node_1_u;
310310
begin;
311311
execute upd;
312312
connection node_1_i;
313-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
313+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
314314
execute ins1;
315315
connection node_1;
316316
set debug_sync='now WAIT_FOR ins_waiting';
@@ -328,7 +328,7 @@ connection node_1_u;
328328
begin;
329329
execute upd;
330330
connection node_1_i;
331-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
331+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
332332
execute ins1;
333333
connection node_1;
334334
set debug_sync='now WAIT_FOR ins_waiting';
@@ -346,7 +346,7 @@ connection node_1_u;
346346
begin;
347347
execute upd;
348348
connection node_1_i;
349-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
349+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
350350
execute ins1;
351351
connection node_1;
352352
set debug_sync='now WAIT_FOR ins_waiting';
@@ -364,7 +364,7 @@ connection node_1_u;
364364
begin;
365365
execute upd;
366366
connection node_1_i;
367-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
367+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
368368
execute ins1;
369369
connection node_1;
370370
set debug_sync='now WAIT_FOR ins_waiting';

mysql-test/suite/galera/t/galera_FK_duplicate_client_insert.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ while($counter > 0)
7272
update user set j = j + 1 WHERE id > 0;
7373

7474
--connection node_1_i
75-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
75+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
7676
send insert into user_session(id,fk1,fk2) values (2, 2, 2);
7777

7878
--connection node_1
@@ -126,7 +126,7 @@ while($counter > 0)
126126
#update user set j = j + 1 WHERE id > 0;
127127

128128
--connection node_1_i
129-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL ins_waiting WAIT_FOR cont_ins';
129+
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
130130
send execute ins1;
131131

132132
--connection node_1

mysql-test/suite/innodb/r/cursor-restore-locking.result

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ SET DEBUG_SYNC = 'innodb_row_search_for_mysql_exit SIGNAL first_del_row_search_m
77
DELETE FROM t WHERE b = 20;
88
connect con_ins_1,localhost,root,,;
99
SET DEBUG_SYNC = 'now WAIT_FOR first_del_row_search_mvcc_finished';
10-
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL first_ins_locked';
10+
SET DEBUG_SYNC = 'lock_wait_start SIGNAL first_ins_locked';
1111
SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL first_ins_row_inserted WAIT_FOR first_ins_cont';
1212
INSERT INTO t VALUES(10, 20);
1313
connect con_del_2,localhost,root,,;
1414
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_locked';
15-
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL second_del_locked';
15+
SET DEBUG_SYNC = 'lock_wait_start SIGNAL second_del_locked';
1616
DELETE FROM t WHERE b = 20;
1717
connection default;
1818
SET DEBUG_SYNC = 'now WAIT_FOR second_del_locked';
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
CREATE TABLE t (a int PRIMARY KEY, b int) engine = InnoDB;
2+
CREATE TABLE t2 (a int PRIMARY KEY) engine = InnoDB;
3+
INSERT INTO t VALUES (10, 10), (20, 20), (30, 30);
4+
INSERT INTO t2 VALUES (10), (20), (30);
5+
BEGIN;
6+
SELECT * FROM t WHERE a = 20 FOR UPDATE;
7+
a b
8+
20 20
9+
connect con_2,localhost,root,,;
10+
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
11+
BEGIN;
12+
SET DEBUG_SYNC = 'lock_trx_handle_wait_enter SIGNAL upd_locked WAIT_FOR upd_cont EXECUTE 2';
13+
UPDATE t SET b = 100;
14+
connect con_3,localhost,root,,;
15+
BEGIN;
16+
UPDATE t2 SET a = a + 100;
17+
SELECT * FROM t WHERE a = 30 FOR UPDATE;
18+
a b
19+
30 30
20+
SET DEBUG_SYNC='now WAIT_FOR upd_locked';
21+
SET DEBUG_SYNC = 'lock_wait_start SIGNAL sel_locked';
22+
SELECT * FROM t WHERE a = 20 FOR UPDATE;
23+
connection default;
24+
SET DEBUG_SYNC='now WAIT_FOR sel_locked';
25+
ROLLBACK;
26+
SET DEBUG_SYNC='now SIGNAL upd_cont';
27+
SET innodb_lock_wait_timeout=1;
28+
SET DEBUG_SYNC="now WAIT_FOR upd_locked";
29+
SET DEBUG_SYNC="lock_wait_end SIGNAL upd_cont";
30+
SELECT * FROM t WHERE a = 10 FOR UPDATE;
31+
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
32+
connection con_3;
33+
a b
34+
20 20
35+
connection con_2;
36+
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
37+
disconnect con_3;
38+
disconnect con_2;
39+
connection default;
40+
SET DEBUG_SYNC = 'RESET';
41+
DROP TABLE t;
42+
DROP TABLE t2;

mysql-test/suite/innodb/r/update-cascade.result

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ select f1, f2 from t2 for update;
3838
f1 f2
3939
1 2
4040
connection default;
41-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
41+
set debug_sync='lock_wait_start SIGNAL upd_waiting WAIT_FOR go_upd';
4242
update t1 set f1 = 10 where f1 = 2;
4343
connection con1;
4444
set debug_sync='now WAIT_FOR upd_waiting';
@@ -97,7 +97,7 @@ select f1, f2 from t2 for update;
9797
f1 f2
9898
1 91
9999
connection default;
100-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
100+
set debug_sync='lock_wait_start SIGNAL upd_waiting WAIT_FOR go_upd';
101101
update t1 set f2 = 28 where f2 = 91;
102102
connection con1;
103103
set debug_sync='now WAIT_FOR upd_waiting';
@@ -164,7 +164,7 @@ select f1 from t3 for update;
164164
f1
165165
2
166166
connection default;
167-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
167+
set debug_sync='lock_wait_start SIGNAL upd_waiting WAIT_FOR go_upd';
168168
update t1 set f1 = 10 where f1 = 2;
169169
connection con1;
170170
set debug_sync='now WAIT_FOR upd_waiting';
@@ -253,7 +253,7 @@ select f1 from t3 for update;
253253
f1
254254
2
255255
connection default;
256-
set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
256+
set debug_sync='lock_wait_start SIGNAL upd_waiting WAIT_FOR go_upd';
257257
update t1 set f2 = 28 where f2 = 91;
258258
connection con1;
259259
set debug_sync='now WAIT_FOR upd_waiting';

mysql-test/suite/innodb/t/cursor-restore-locking.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@ SET DEBUG_SYNC = 'innodb_row_search_for_mysql_exit SIGNAL first_del_row_search_m
1616
--connect(con_ins_1,localhost,root,,)
1717
SET DEBUG_SYNC = 'now WAIT_FOR first_del_row_search_mvcc_finished';
1818
# It's supposed the following INSERT will be suspended just after
19-
# lock_wait_suspend_thread_enter syncpoint, and will be awaken
19+
# lock_wait_start syncpoint, and will be awaken
2020
# after the previous DELETE commits. ib_after_row_insert will be executed
2121
# after the INSERT is woken up. The previous DELETE will wait for
2222
# first_del_cont signal before commit, and this signal will be sent later.
2323
# So it's safe to use two signals in a row here, it's guaranted the first
2424
# signal will be received before the second signal is sent.
25-
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL first_ins_locked';
25+
SET DEBUG_SYNC = 'lock_wait_start SIGNAL first_ins_locked';
2626
SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL first_ins_row_inserted WAIT_FOR first_ins_cont';
2727
--send INSERT INTO t VALUES(10, 20)
2828

2929
--connect(con_del_2,localhost,root,,)
3030
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_locked';
31-
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL second_del_locked';
31+
SET DEBUG_SYNC = 'lock_wait_start SIGNAL second_del_locked';
3232
###############################################################################
3333
# This DELETE is locked by the previous DELETE, after that DELETE is
3434
# committed, it will still be locked by the next INSERT on delete-marked

0 commit comments

Comments
 (0)