数据库
首页 > 数据库> > mysql-什么时候InnoDB超时而不是报告死锁?

mysql-什么时候InnoDB超时而不是报告死锁?

作者:互联网

我有一个无法复制或诊断的来自MySQL的“超出了锁定等待超时”错误.我确定它是死锁的(相对于事务先抓住一个锁然后摇动它的拇指),因为我的日志显示另一个进程同时开始,也挂起,然后在第一次超时时继续.但是通常,InnoDB可以检测死锁而不会超时.因此,我试图了解为什么未检测到此死锁.

这两个事务都使用隔离级别可序列化. (我对这种隔离级别的InnoDB锁定有相当的了解.)在事务中使用了一个非InnoDB(MyISAM)表,我将其插入并更新了该表.但是,我不了解死锁如何涉及到死锁,因为我相信MyISAM只会在插入和更新期间获取表锁(由于MyISAM不是事务性的,因此会立即释放它),因此在此期间不会再使用其他锁.表锁被保持.

因此,我确信死锁仅涉及InnoDB表,这使我回到了为什么未检测到它的问题. MySQL文档(http://dev.mysql.com/doc/refman/5.1/en/innodb-deadlock-detection.html)暗示死锁检测几乎总是可以正常工作.我在搜索时发现的问题案例涉及显式的“锁定表”,“变更表”和“插入延迟”.我没有做任何这些事情,只是插入,更新和选择(我的一些选择是“用于更新”).

我试图通过创建一个MyISAM表和几个InnoDB表并在MyISAM中进行各种插入和更新序列以及在InnoDB中“选择更新”来重现.但是每次我产生一个死锁时,InnoDB都会立即报告它.我无法重现超时.

还有其他诊断技巧吗?我正在使用mysql 5.1.49.

解决方法:

一个提示是,您可以使用SHOW INNODB STATUS来显示InnoDB引擎的状态.

它返回的信息(大块文本)包括有关当前表锁的信息,以及最后检测到的死锁(在标题为“ LATEST DETECTED DEADLOCK”下),因此,在此事实之后,此技巧并不是很有用,但是可以帮助您跟踪挂起的查询.

mysqladmin debug还可以打印有用的锁调试信息.

第三个技巧是创建一个名为innodb_lock_monitor的魔术表,如表http://dev.mysql.com/doc/refman/5.1/en/innodb-monitors.html所述,该表提供了更详细的锁调试信息.

HTH!

更新:

因为它实际上不是死锁,所以它可能没有检测到死锁,但是更有可能一个进程正在等待另一进程锁定的行上的行锁.从手册中获取innodb_lock_wait_timeout变量:

The timeout in seconds an InnoDB
transaction may wait for a row lock
before giving up. The default value is
50 seconds. A transaction that tries
to access a row that is locked by
another InnoDB transaction will hang
for at most this many seconds before
issuing the following error:

ERROR 1205 (HY000): Lock wait timeout
exceeded; try restarting transaction

When a lock wait timeout occurs, the
current statement is not executed. The
current transaction is not rolled
back. (Until MySQL 5.0.13 InnoDB
rolled back the entire transaction if
a lock wait timeout happened.

例如,当两个进程各自需要锁定由另一个进程锁定的行时,就会发生死锁,并且没有任何等待量可以解决冲突.

标签:deadlock,innodb,mysql
来源: https://codeday.me/bug/20191105/1997704.html