尝试获取锁定时,哪个查询导致死锁;尝试重新启动事务

时间:2011-10-16 03:10:48

标签: php mysql deadlock

我无法弄清楚哪个查询导致Deadlock found when trying to get lock; try restarting transaction。 我的mysql包装器有以下几行

if (mysql_errno($this->conn) == 1213) {
  $this->bug_log(0,"Deadlock. SQL:".$this->sql);
}

其中bug_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

我如何追踪它?

2 个答案:

答案 0 :(得分:8)

如果另一个事务等待当前事务完成,则WHERE子句的更新(不是唯一列)将导致死锁。这是一个快速测试:

CREATE TABLE test (pk int PRIMARY KEY, a int);
INSERT INTO test VALUES (0, 0);
INSERT INTO test VALUES (1, 0);

第一节

BEGIN;
SELECT a FROM test WHERE pk=0 FOR UPDATE;

第二节

BEGIN;
SELECT a FROM test WHERE pk=0 FOR UPDATE;

(会议2现已被阻止)

第一节

UPDATE test SET a=1 WHERE a>0;

在第2节中,我们收到错误

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

如果在更新的WHERE子句中我们仅使用pk列,则不会发生错误。

答案 1 :(得分:2)

我发现这种情况发生在以下一种或多种情况中:

  1. 在查询中多次加入同一个表(SELF JOIN)
  2. 使用包含同时以多种方式操作同一个表的查询的事务时
  3. 使用事务并使用相同的表作为SELF JOIN或子查询时
  4. 跟踪可能很困难,但情况基本上是说一个查询阻止另一个查询运行,这反过来又阻止了第一个查询完成......

    http://en.wikipedia.org/wiki/Deadlock