首页 > 解决方案 > MySQL锁等待超时错误,但仅在表的某些部分?

问题描述

我们有一个在 AWS RDS 上运行的 MySQL 数据库,其中包含一个非常大的事件表,大约有 7000 万行(表 A)。我们正在尝试创建一个聚合表(表 B),将表 A 到每日级别的事件分组,以便更轻松地处理数据。我使用的查询如下:

INSERT INTO Aggregate_table_B 
SELECT
        A.username AS username,
        LEFT(A.event_cts, 10) AS eventtime,
        SUM(A.total_event_value) AS total_daily_event_value
    FROM
        Table_A as A
    WHERE
        A.id >= x
        AND A.id < y

    GROUP BY
        username,
        eventtime;

id列是事件表 A 中的事件索引。现在如果该值与表 Ay非常接近max(id),则查询将失败并出现锁定等待超时错误。但如果该值y足够小于max(id),则查询将成功运行。因此,如果我连续两次运行相同的查询,但一次id在“好”范围内,另一次id在“坏”范围内,那么坏范围内的查询将得到锁定等待超时错误和查询良好的范围将运行良好。

错误信息如下:

错误代码:1205。超过锁定等待超时;尝试重启事务

我已经确定了y查询停止工作的值的限制,并检查了具有该id值的行,这似乎完全正常。

另外,我尝试运行此查询:

show open tables where In_use > 0

当第一个查询以太大的y值运行时(这将触发错误)并且结果显示每个表上只有一个锁,而不是多个锁。

我也试着跑

Show PROCESSLIST

查看是否存在导致锁定的睡眠连接,但查询失败和查询成功时的结果相同,但id范围不同

另一件事是,如果我尝试运行第一个查询的类似版本:

INSERT INTO Aggregate_table_B 
SELECT
        A.username AS username,
        LEFT(A.event_cts, 10) AS eventtime,
        SUM(A.total_event_value) AS total_daily_event_value
    FROM
        Table_A as A
    WHERE
        A.id = z

    GROUP BY
        username,
        eventtime;

但是我在条件中只指定了一个事件行,那么即使z超过了破坏第一个查询的限制,查询也可以正常运行。z只有当我指定的值大于时,错误才会再次出现max(id)

最后一点是这个数据库每天都会被销毁,并创建一个新版本,其中包含前一天和之前所有日子的更新数据。而且这个错误只发生在某些日子。这意味着曾经属于查询失败的先前数据库状态的数据仍然存在于后续数据库状态中,但查询在较新的数据库状态下运行良好。

我很欣赏有关如何深入了解实际错误原因的任何见解。

标签: mysqlsqlamazon-web-servicesdatabase-deadlocks

解决方案


推荐阅读