我正在解决 MySQL 错误“尝试获取锁定时发现死锁;尝试重新启动事务”。
我将不得不更新一个程序以允许死锁。该SELECT
语句是否可能会产生死锁错误?我知道它只是一个读锁,所以多选不会有问题,但是如果有一个INSERT
, UPDATE
orDELETE
语句(可能有连接的子查询)和一个SELECT
语句(可能有连接或子查询)怎么办?
是否有可能在 ,SELECT
而不是INSERT
,UPDATE
或DELETE
.
我正在解决 MySQL 错误“尝试获取锁定时发现死锁;尝试重新启动事务”。
我将不得不更新一个程序以允许死锁。该SELECT
语句是否可能会产生死锁错误?我知道它只是一个读锁,所以多选不会有问题,但是如果有一个INSERT
, UPDATE
orDELETE
语句(可能有连接的子查询)和一个SELECT
语句(可能有连接或子查询)怎么办?
是否有可能在 ,SELECT
而不是INSERT
,UPDATE
或DELETE
.
您问题标题的直接答案是“否”。
SELECT 查询可以对gen_clust_index执行锁定,也就是聚集索引。
以下是我与提出这些问题的人@RedBlueThing一起积极研究的三个 DBA Stack Exchanges问题。@RedBlueThing 为他的问题找到了解决方法。
只是为了让您的问题保持正确,当您查看这些答案时(不要看得太深,即使我看到自己复杂的答案也会头晕目眩)应该很快就会发现 SELECT 查询可以锁定数据。
您也有特殊的 SELECT 案例,您可以根据需要锁定特定的行。
更新 2011-08-08 16:49 EDT
您问了变体问题:“InnoDB 死锁异常是否可能会被 SELECT 抛出” 在特定条件下,答案可能是“是”。那是什么条件?如果由于错误而仅回滚一条 SQL 语句,则该语句设置的某些锁可能会被保留。发生这种情况是因为 InnoDB 以一种格式存储行锁,这样它就无法知道哪个锁是由哪个语句设置的。
基于该陈述,导致这种情况的事件序列理论上可能如下:
就个人而言,最后一句话让我害怕。如果 MySQL 能告知大家这个怪癖,那就太好了。然而,该声明来自 MySQL 文档。(哦,是的,Oracle 拥有 InnoDB)
更新 2015-09-22 18:40 EST
今年早些时候,我了解到Percona 有一个很酷的 Nagios 检查,可以找到隐藏在睡眠连接后面的这些讨厌的锁。您现在所要做的就是从该链接运行代码:
这仅适用于 MySQL 5.5+。如果您有 MySQL 5.1 或更早版本,则必须终止所有休眠连接以释放锁。