Взаимные блокировки в MYSQL: как узнать, почему блокировка не может быть получена?

0

Мы имеем следующую ситуацию, которая приводит к тупиковой ситуации, как показано результатом SHOW INNODB STATUS:

  • Transaction1 пытается обновить mytable, где id = 5, и ожидает запись блокировки строки типа X
  • Transaction2 пытается обновить mytable, где id = 5 содержит запись блокировки строки типа S и ожидает запись блокировки строки типа X

Ни одна из двух транзакций фактически не содержит правильную запись, поэтому мы не можем понять, почему это приведет к тупиковой ситуации, если нет третьей транзакции, которая владеет этой блокировкой и тоже зашла в тупик. Как этот вопрос может быть дополнительно исследован и может быть каким-то образом связан с триггерами?

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)
Теги:
deadlock

1 ответ

0

Вторая транзакция сохраняет общую (S) блокировку, которая препятствует первой транзакции получить исключительную (X) блокировку.

Но mysql зарегистрировал, что первая транзакция хочет иметь эксклюзивную блокировку, которая входит в очередь.

Затем вторая транзакция хочет перевести блокировку в эксклюзивную, чего она не может сделать, поскольку первая транзакция уже зарегистрировала свое намерение для эксклюзивной блокировки.

Это случай учебника для тупика в mysql, см. Раздел 14.5.5.1. Пример тупика InnoDB в руководстве mysql

  • 0
    Спасибо, но что останавливает 2-ю транзакцию, чтобы получить X-блокировку, продолжить и завершить себя?
  • 0
    Дизайн MySQL. Выше приведено документированное поведение mysql.
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню