2013-07-04 4 views
1

Я пытаюсь разрешить ошибку с взаимоблокировками в одной из наших занятых таблиц. Я прочитал this SO question о взаимоблокировках, и хотя это имеет смысл, порядок запросов, по-видимому, не является причиной в моем случае.Тупик с идентичными запросами

Вот сокращенный вывод SHOW ENGINE INNODB STATUS;:

*** (1) TRANSACTION: 
TRANSACTION 1 2611184895, ACTIVE 0 sec, process no 17501, OS thread id 140516779579136 starting index read 
mysql tables in use 1, locked 1 
LOCK WAIT 2 lock struct(s), heap size 368, 1 row lock(s) 
MySQL thread id 211935717, query id 3146186174 [SERVER A] Searching rows for update 

UPDATE images_unread_comments 
    SET unread = 0 
    WHERE user_id = 1 AND comment_id IN(1,2,3) AND unread = 1 

*** (1) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 0 page no 404976 n bits 632 index `users_unread_comments` of table images_unread_comments trx id 1 2611184895 lock_mode X waiting 
Record lock, heap no 558 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67d888; asc g ;; 

*** (2) TRANSACTION: 
TRANSACTION 1 2611184892, ACTIVE 0 sec, process no 17501, OS thread id 140516774520576 updating or deleting, thread declared inside InnoDB 494 
mysql tables in use 1, locked 1 
6 lock struct(s), heap size 1216, 11 row lock(s), undo log entries 1 
MySQL thread id 211935715, query id 3146186169 [SERVER B] Updating 

UPDATE images_unread_comments 
    SET unread = 0 
    WHERE user_id = 1 AND comment_id IN(1,2,3) AND unread = 1 
    *** (2) HOLDS THE LOCK(S): 
RECORD LOCKS space id 0 page no 404976 n bits 632 index users_unread_comments of table images_unread_comments trx id 1 2611184892 lock_mode X 
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 
0: len 8; hex 73757072656d756d; asc supremum;; 

Record lock, heap no 555 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67daf0; asc g ;; 

Record lock, heap no 556 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67dadb; asc g ;; 

Record lock, heap no 557 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67d940; asc g @;; 

Record lock, heap no 558 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67d888; asc g ;; 

*** (2) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 0 page no 404976 n bits 632 index users_unread_comments of table images_unread_comments trx id 1 2611184892 lock_mode X locks gap before rec insert intention waiting 
Record lock, heap no 558 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67d888; asc g ;; 

*** WE ROLL BACK TRANSACTION (1) 

То, что я заметил, что два SQL заявления являются идентичными; однако один выполняется на сервере A, а другой - на сервере B. Независимо от того, почему это происходит - почему это создает тупик, если оба запроса блокируют одни и те же ключи в одном порядке? Или я неправильно понимаю ситуацию с тупиками?

+0

Вероятно, что другой запрос, который выполняется до этого (в одном или обоих потоках), заблокировал некоторые строк. Также вы немного сократили отчет о состоянии - какова вторая ожидающая транзакция и какая блокировка удерживается? – Vatev

+0

@Vatev Я добавил остальную часть этого раздела к выходу. – Graham

+0

Я должен был заметить это 1-е время ... Замки находятся на другом столе (images_unread_comments). Существуют ли триггеры или внешние ключи, относящиеся к двум таблицам? – Vatev

ответ

0

Похоже, что транзакция 1 выполнила другую операцию (вставить?), В которой она заблокировала пробел в индексе. Он не ожидает выполнения транзакции 2 для обновления, поскольку 2 заблокировал запись с идентификатором 1. Транзакция 2, однако, не может продолжаться, поскольку транзакция 1 содержит блокировку индекса. Если вы можете изолировать все операторы SQL, которые используются в транзакции этой операцией, мы можем видеть точную причину взаимоблокировки

Смежные вопросы