Мы имеем следующую ситуацию, которая приводит к тупиковой ситуации, как показано результатом SHOW INNODB STATUS:
Ни одна из двух транзакций фактически не содержит правильную запись, поэтому мы не можем понять, почему это приведет к тупиковой ситуации, если нет третьей транзакции, которая владеет этой блокировкой и тоже зашла в тупик. Как этот вопрос может быть дополнительно исследован и может быть каким-то образом связан с триггерами?
LATEST DETECTED DEADLOCK
------------------------
2018-07-28 08:27:08 0x7f1a08537700
*** (1) TRANSACTION:
TRANSACTION 2183, ACTIVE 0 sec starting index read
mysql tables in use 5, locked 5
LOCK WAIT 7 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 47, OS thread handle 139750051079936, query id 1481 172.24.0.1 myuser updating
update 'mytable' set 'status' = 'OK' where 'mytable'.'id' = 5
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 37 page no 3 n bits 72 index PRIMARY of table 'mydb'.'mytable' trx id 2183 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 18; compact format; info bits 0
0: len 4; hex 80000005; asc ;;
1: len 6; hex 000000000885; asc ;;
2: len 7; hex 2c0000018b0110; asc , ;;
3: len 30; hex 66643164396162382d663462642d343237652d626461362d316430626634; asc fd1d9ab8-f4bd-427e-bda6-1d0bf4; (total 36 bytes);
4: len 4; hex 5b5c28d7; asc [\( ;;
5: len 4; hex 5b5c28dc; asc [\( ;;
6: len 6; hex 80000186a000; asc ;;
7: len 4; hex 80000005; asc ;;
8: len 3; hex 455552; asc EUR;;
9: len 4; hex 80000001; asc ;;
10: len 17; hex 52454144595f464f525f414456414e4345; asc OK;;
11: SQL NULL;
12: len 3; hex 8fc55a; asc Z;;
13: len 3; hex 8fc55a; asc Z;;
14: SQL NULL;
15: len 15; hex 30303141307965644562686c466966; asc 001A0yedEbhlFif;;
16: SQL NULL;
17: len 1; hex 80; asc ;;
*** (2) TRANSACTION:
TRANSACTION 2187, ACTIVE 0 sec starting index read
mysql tables in use 5, locked 5
7 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 50, OS thread handle OK, query id 1482 172.24.0.1 myuser updating
update 'mytable' set 'status' = 'OK' where 'mytable'.'id' = 5
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 37 page no 3 n bits 72 index PRIMARY of table 'mydb'.'mytable' trx id 2187 lock mode S locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 18; compact format; info bits 0
0: len 4; hex 80000005; asc ;;
1: len 6; hex 000000000885; asc ;;
2: len 7; hex 2c0000018b0110; asc , ;;
3: len 30; hex 66643164396162382d663462642d343237652d626461362d316430626634; asc fd1d9ab8-f4bd-427e-bda6-1d0bf4; (total 36 bytes);
4: len 4; hex 5b5c28d7; asc [\( ;;
5: len 4; hex 5b5c28dc; asc [\( ;;
6: len 6; hex 80000186a000; asc ;;
7: len 4; hex 80000005; asc ;;
8: len 3; hex 455552; asc EUR;;
9: len 4; hex 80000001; asc ;;
10: len 17; hex 52454144595f464f525f414456414e4345; asc OK;;
11: SQL NULL;
12: len 3; hex 8fc55a; asc Z;;
13: len 3; hex 8fc55a; asc Z;;
14: SQL NULL;
15: len 15; hex 30303141307965644562686c466966; asc 001A0yedEbhlFif;;
16: SQL NULL;
17: len 1; hex 80; asc ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 37 page no 3 n bits 72 index PRIMARY of table 'mydb'.'mytable' trx id 2187 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 18; compact format; info bits 0
0: len 4; hex 80000005; asc ;;
1: len 6; hex 000000000885; asc ;;
2: len 7; hex 2c0000018b0110; asc , ;;
3: len 30; hex 66643164396162382d663462642d343237652d626461362d316430626634; asc fd1d9ab8-f4bd-427e-bda6-1d0bf4; (total 36 bytes);
4: len 4; hex 5b5c28d7; asc [\( ;;
5: len 4; hex 5b5c28dc; asc [\( ;;
6: len 6; hex 80000186a000; asc ;;
7: len 4; hex 80000005; asc ;;
8: len 3; hex 455552; asc EUR;;
9: len 4; hex 80000001; asc ;;
10: len 17; hex 52454144595f464f525f414456414e4345; asc OK;;
11: SQL NULL;
12: len 3; hex 8fc55a; asc Z;;
13: len 3; hex 8fc55a; asc Z;;
14: SQL NULL;
15: len 15; hex 30303141307965644562686c466966; asc 001A0yedEbhlFif;;
16: SQL NULL;
17: len 1; hex 80; asc ;;
*** WE ROLL BACK TRANSACTION (2)
Вторая транзакция сохраняет общую (S
) блокировку, которая препятствует первой транзакции получить исключительную (X
) блокировку.
Но mysql зарегистрировал, что первая транзакция хочет иметь эксклюзивную блокировку, которая входит в очередь.
Затем вторая транзакция хочет перевести блокировку в эксклюзивную, чего она не может сделать, поскольку первая транзакция уже зарегистрировала свое намерение для эксклюзивной блокировки.
Это случай учебника для тупика в mysql, см. Раздел 14.5.5.1. Пример тупика InnoDB в руководстве mysql