上周末,我的一个客户从MyISAM切换到了InnoDB,第一天他们在php日志中遇到了死锁错误。这是MySQL的引擎状态:
------------------------
LATEST DETECTED DEADLOCK
------------------------
140616 17:54:23
*** (1) TRANSACTION:
TRANSACTION AA7939, ACTIVE 0 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 6 lock struct(s), heap size 1248, 8 row lock(s), undo log entries 3
MySQL thread id 45955, OS thread handle 0x7f19aea0c700, query id 6087879 {hostname} 10.132.0.18 {dbuser} Updating
Update sid Set SID_Active = 'n' Where SID_Demandeur = '991821' AND SID_Context_Type = 'PORTAL'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3955 page no 80 n bits 168 index `PRIMARY` of table `{db_prod}`.`sid` trx id AA7939 lock_mode X locks rec but not gap waiting
Record lock, heap no 11 PHYSICAL RECORD: n_fields 14; compact format; info bits 0
...
*** (2) TRANSACTION:
TRANSACTION AA5366, ACTIVE 708 sec fetching rows, thread declared inside InnoDB 192
mysql tables in use 2, locked 2
254 lock struct(s), heap size 31160, 18345 row lock(s), undo log entries 18317
MySQL thread id 45393, OS thread handle 0x7f19ae949700, query id 6060259 {hostname} 10.132.0.18 {dbuser} Sending data
Delete From tmp_training_session_dates Where RemoteUserId Not In (Select CONCAT(SID_Demandeur,'_',SID_Sid) From sid Where SID_Active = 'o' And SID_Dern_Maj >='1919-05-24 10:22:35')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 3955 page no 80 n bits 168 index `PRIMARY` of table `{db_prod}`.`sid` trx id AA5366 lock mode S locks rec but not gap
Record lock, heap no 11 PHYSICAL RECORD: n_fields 14; compact format; info bits 0
...
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3955 page no 17 n bits 160 index `PRIMARY` of table `{db_prod}`.`sid` trx id AA5366 lock mode S locks rec but not gap waiting
Record lock, heap no 25 PHYSICAL RECORD: n_fields 14; compact format; info bits 0
帮助我理解这个僵局。在这种情况下SELECT如何保持锁定?
答案 0 :(得分:1)
我认为您正在尝试更新第二个事务应该用来执行删除的记录或索引(第一个事务)。
另见MySQL deadlock documentation:
InnoDB使用自动行级锁定。即使只是插入或删除单行的事务,您也可能会遇到死锁。那是因为这些操作并非真正的“原子”;它们会自动设置对插入或删除的行的(可能是几个)索引记录的锁定。
如果您的软件与MyISAM一起使用,您可以尝试提交每个更新/删除查询,或者更好的是,您可以将sid
表明确定义为MyISAM:
ALTER TABLE sid ENGINE = MyISAM;