我在修改MySQL数据库中的同一个表的2个进程中遇到了一些问题。偶尔它会导致死锁,并且其中一个或另一个进程得到一个'尝试锁定时发现的死锁;尝试重新启动事务'错误。MySQL事务发生死锁,但SHOW ENGINE INNODB STATUS不显示真正的死锁
我发现了几个答案,为什么这发生在stackoverflow上,这让我有一些解决问题的方法。 (只需重试交易)。我希望有一个比这更好的解决方案,因此开始使用SHOW ENGINE INNODB STATUS进行调查。
我一直困惑的STATUS命令的输出。从我所看到的情况来看,它并没有表现出真正的僵局。第一笔交易等待一行锁定购买第二笔交易,第一笔交易不持有其他锁定。第二个事务持有4个锁,其中一个是第一个事务所需的锁,并且正在等待第5个锁。没有提到任何其他交易持有的第五把锁。
有关僵局的输出是:
------------------------
LATEST DETECTED DEADLOCK
------------------------
130514 8:54:12
*** (1) TRANSACTION:
TRANSACTION 0 487333931, ACTIVE 0 sec, process no 1007, OS thread id 2990889792 fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 320, 24 row lock(s), undo log entries 3
MySQL thread id 774102, query id 166772615 localhost 127.0.0.1 nesie updating
DELETE FROM DeviceStatus WHERE serialNo=1234567 AND subDevice=1 AND (parameter='band' OR parameter='arfcn' OR parameter='txPower' OR parameter='lac' OR parameter='cellId' OR parameter='channel' OR parameter='rxReversePower' OR parameter='reverseSnr' OR parameter='reverseGmp' OR parameter='reverseBepm' OR parameter='mobileHeldOn' OR parameter='mobileHeldBand' OR parameter='mobileTxPower' OR parameter='mobileCommandedPower' OR parameter='rxPathLoss' OR parameter='holdState' OR parameter='band' OR parameter='channel' OR parameter='arfcn' OR parameter='rxForwardPower' OR parameter='forwardSnr' OR parameter='forwardGmp' OR parameter='forwardBepm' OR parameter='lac' OR parameter='cellId')
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1267 page no 3 n bits 96 index `PRIMARY` of table `nesie`.`DeviceStatus` trx id 0 487333931 lock_mode X waiting
Record lock, heap no 20 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80151487; asc ;; 1: len 4; hex 80000001; asc ;; 2: len 10; hex 6d6f6e69746f72696e67; asc monitoring;; 3: len 6; hex 00001d0c202a; asc *;; 4: len 7; hex 00000000342dbd; asc 4- ;; 5: len 4; hex 80000000; asc ;;
*** (2) TRANSACTION:
TRANSACTION 0 487333930, ACTIVE 0 sec, process no 1007, OS thread id 3063302976 inserting, thread declared inside InnoDB 488
mysql tables in use 1, locked 1
5 lock struct(s), heap size 320, 6 row lock(s), undo log entries 4
MySQL thread id 774099, query id 166772616 localhost nesie update
REPLACE INTO DeviceStatus VALUES (1381511,1,'scanning',1),(1381511,1,'monitoring',0),(1381511,1,'transmitting',0),(1381511,1,'power',-84),(1381511,1,'band',1),(1381511,1,'uarfcn',10661),(1381511,1,'scramblingCode',377)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 1267 page no 3 n bits 96 index `PRIMARY` of table `nesie`.`DeviceStatus` trx id 0 487333930 lock_mode X locks rec but not gap
Record lock, heap no 20 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80151487; asc ;; 1: len 4; hex 80000001; asc ;; 2: len 10; hex 6d6f6e69746f72696e67; asc monitoring;; 3: len 6; hex 00001d0c202a; asc *;; 4: len 7; hex 00000000342dbd; asc 4- ;; 5: len 4; hex 80000000; asc ;;
Record lock, heap no 21 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80151487; asc ;; 1: len 4; hex 80000001; asc ;; 2: len 5; hex 706f776572; asc power;; 3: len 6; hex 00001d0c202a; asc *;; 4: len 7; hex 00000000342e11; asc 4. ;; 5: len 4; hex 7fffffac; asc ;;
Record lock, heap no 22 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80151487; asc ;; 1: len 4; hex 80000001; asc ;; 2: len 8; hex 7363616e6e696e67; asc scanning;; 3: len 6; hex 00001d0c202a; asc *;; 4: len 7; hex 00000000342d96; asc 4- ;; 5: len 4; hex 80000001; asc ;;
Record lock, heap no 24 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80151487; asc ;; 1: len 4; hex 80000001; asc ;; 2: len 12; hex 7472616e736d697474696e67; asc transmitting;; 3: len 6; hex 00001d0c202a; asc *;; 4: len 7; hex 00000000342de6; asc 4- ;; 5: len 4; hex 80000000; asc ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1267 page no 3 n bits 96 index `PRIMARY` of table `nesie`.`DeviceStatus` trx id 0 487333930 lock_mode X locks rec but not gap waiting
Record lock, heap no 17 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80151487; asc ;; 1: len 4; hex 80000001; asc ;; 2: len 4; hex 62616e64; asc band;; 3: len 6; hex 00001d0c19ff; asc ;; 4: len 7; hex 000000003428a7; asc 4(;; 5: len 4; hex 80000001; asc ;;
*** WE ROLL BACK TRANSACTION (1)
我的问题是:
为什么这个标记为死锁,事务1可以排队,直到交易2次完成,因为它没有保持所需的锁通过交易2?
有没有人知道这是MySQL的正常行为还是它可能是一个错误?
谢谢,
西蒙。
“*是否有任何人知道如果MySQL或该正常行为可能是一个错误*?” - 两者并不相互排斥的(错误*是* MySQL的正常行为)。 :) – eggyal
@eggyal我想对于很多软件和API也是如此。微软发布这么多新API的原因是因为修复旧API会破坏所有依赖于它们中的错误的代码! – SimonAlfie
的确如此。关于你的情况,Peter Zaitsev的文章[SHOW INNODB STATUS walk through](http://www.mysqlperformanceblog.com/2006/07/17/show-innodb-status-walk-through/)(链接自MySQL手册)状态“*注 - Innodb只打印关于事务持有的少量锁的信息,并且只显示每个事务的最后一条语句,而锁的行可以被以前的语句之一锁住对于复杂的死锁调查,您可能需要查看在日志文件中找到真正相互冲突的语句。*“ – eggyal