Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/246.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 尝试获取锁时发现哪个查询导致死锁;尝试重新启动事务_Php_Mysql_Deadlock - Fatal编程技术网

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”(或者任何只使用唯一列的东西),我不会收到错误。我想这是我第一次真正理解死锁和普通块。