700*_*are 8 mysql innodb deadlock
我正在解决 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
您问了变体问题:“SELECT 是否可能会抛出 InnoDB 死锁异常” 在特定条件下,答案可以是 Yes。那条件是什么?如果由于错误而仅回滚单个 SQL 语句,则可能会保留该语句设置的某些锁。发生这种情况是因为 InnoDB 以一种格式存储行锁,以至于它之后无法知道哪个语句设置了哪个锁。
根据该陈述,导致这种情况的事件序列理论上可能如下:
就个人而言,最后一句话让我感到害怕。如果 MySQL 能够将这个怪癖告知每个人,那就太好了。然而,该声明来自 MySQL 文档。(哦,是的,Oracle 拥有 InnoDB)
今年早些时候,我了解到Percona 有一个很酷的 Nagios 检查,可以找到这些隐藏在睡眠连接后面的讨厌的锁。您现在要做的就是从该链接运行代码:
SELECT COALESCE(MAX(IF(p.command = 'Sleep', p.time, 0)), 0) AS idle_in_trx
FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS AS w
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS b ON b.trx_id = w.blocking_trx_id
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS r ON r.trx_id = w.requesting_trx_id
LEFT JOIN INFORMATION_SCHEMA.PROCESSLIST AS p ON p.id = b.trx_mysql_thread_id;
Run Code Online (Sandbox Code Playgroud)
这仅适用于 MySQL 5.5+。如果您有 MySQL 5.1 或更低版本,则必须终止所有休眠连接以释放锁。
归档时间: |
|
查看次数: |
7343 次 |
最近记录: |