Php 尝试获取锁时发现哪个查询导致死锁;尝试重新启动事务
我无法确定是哪个查询导致了在尝试获取锁时发现的Php 尝试获取锁时发现哪个查询导致死锁;尝试重新启动事务,php,mysql,deadlock,Php,Mysql,Deadlock,我无法确定是哪个查询导致了在尝试获取锁时发现的死锁;尝试重新启动事务。 我的mysql包装器有以下几行 if (mysql_errno($this->conn) == 1213) { $this->bug_log(0,"Deadlock. SQL:".$this->sql); } 其中bug\u log写入文件 错误日志文件没有死锁错误,但/var/log/mysqld.log有多条记录: 111016 3:00:02 [ERROR] /usr/libexec/mysq
死锁;尝试重新启动事务
。
我的mysql包装器有以下几行
if (mysql_errno($this->conn) == 1213) {
$this->bug_log(0,"Deadlock. SQL:".$this->sql);
}
其中bug\u log
写入文件
错误日志文件没有死锁错误,但/var/log/mysqld.log
有多条记录:
111016 3:00:02 [ERROR] /usr/libexec/mysqld: Deadlock found when trying to get lock; try restarting transaction
111016 3:00:02 [ERROR] /usr/libexec/mysqld: Sort aborted
111016 3:00:02 [ERROR] /usr/libexec/mysqld: Deadlock found when trying to get lock; try restarting transaction
111016 3:00:02 [ERROR] /usr/libexec/mysqld: Sort aborted
111016 3:00:02 [ERROR] /usr/libexec/mysqld: Deadlock found when trying to get lock; try restarting transaction
111016 3:00:02 [ERROR] /usr/libexec/mysqld: Sort aborted
如何查找它?我发现在以下一种或多种情况下会发生这种情况:
如果另一个事务等待当前事务完成,则非唯一列的带有WHERE子句的更新将导致死锁。下面是一个快速测试:
CREATE TABLE test (pk int PRIMARY KEY, a int);
INSERT INTO test VALUES (0, 0);
INSERT INTO test VALUES (1, 0);
第1次会议
BEGIN;
SELECT a FROM test WHERE pk=0 FOR UPDATE;
UPDATE test SET a=1 WHERE a>0;
第2次会议
BEGIN;
SELECT a FROM test WHERE pk=0 FOR UPDATE;
(会话2现在被阻止)
第1次会议
BEGIN;
SELECT a FROM test WHERE pk=0 FOR UPDATE;
UPDATE test SET a=1 WHERE a>0;
在会话2中,我们收到一个错误
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
如果在update的WHERE子句中我们只使用pk列,则不会发生错误。我确实有一个嵌套查询,但不是在self上。为什么每次都会导致死锁?您使用的是事务吗?如果两个事务处理同一个表,但关键字不同,也会出现这种情况。像
更新表。。。其中组id=X,用户id=Y
和更新表。。。其中用户id=Y和组id=X
假设这些键不同。您可以看到,如果它们同时运行,它们将锁定另一个索引以供另一个查询返回,从而导致死锁。我会检查你的查询,确保它们在处理任何索引时都是以相同的顺序编写的。可能是,但我如何找到其他查询?目前我跟踪了此死锁查询:updateplayers SET chatban=chatban-1,其中recent=1和chatban>0
这是怎么回事?使用players查找所有其他查询并比较查询。可能您正在选择一个chatban>0且recent=1的,这可能会导致此问题。您所说的“仅使用pk列”是什么意思?这就是您在示例中所做的,不是吗?不是-在更新的WHERE子句中,我有“a>0”。如果我在那里写“pk=0”(或者任何只使用唯一列的东西),我不会收到错误。我想这是我第一次真正理解死锁和普通块。