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上执行。不管为什么会发生这种情况 - 如果两个查询都以相同顺序锁定相同的密钥,为什么会造成死锁?还是我首先误解了僵局?
在另一个查询(在一个或两个线程中)之前运行的另一个查询很可能已锁定某些行。此外,您还会缩短状态报告的时间 - 第二个等待的事务和它持有的锁定是什么? – Vatev
@Vatev我已经将该部分的其余部分添加到输出中。 – Graham
我应该注意到这是第一次...锁在另一张桌子上(images_unread_comments)。是否有与这两个表相关的触发器或外键? – Vatev