调用某些查询时,MySQL“超过锁定等待超时”

Posted

技术标签:

【中文标题】调用某些查询时,MySQL“超过锁定等待超时”【英文标题】:MySQL "Lock wait timeout exceeded" when calling certain query 【发布时间】:2021-10-15 16:45:26 【问题描述】:

我有一个包含一组表的 mysql 5.7,我使用以下查询。


    SET innodb_lock_wait_timeout = 900;
    DROP TABLE IF EXISTS aggregated_table;

    CREATE TABLE aggregated_table AS
    SELECT
        itbl.u AS u,
        LEFT(itbl.e, 10) AS e,
        itbl.b AS b,
        itbl.c AS c,
        itbl.d AS d,
        itbl.ee AS ee,
        h,
        p,
        s,
        SUM(time_column) AS total_time
    FROM
        input_table AS itbl
    WHERE
        s = 1
        AND b = 0
    GROUP BY
        u,
        e,
        b,
        c,
        d,
        ee,
        h,
        p,
        s;

80% 的查询执行正常,但有时CREATE 会失败并显示 ERROR __main__: (1205, 'Lock wait timeout exceeded; try restarting transaction'),这可能取决于在特定时刻在数据库中找到的特定数据。在相同的数据库状态下,总是会重现错误。

我想了解为什么它可能会失败以及如何保护查询免受无限锁定。

更新:EXPLAIN SELECT... 提供答案(由我的数据库客户端格式化为 JSON):

[
  
    "id": 1,
    "select_type": "SIMPLE",
    "table": "itbl",
    "partitions": null,
    "type": "ALL",
    "possible_keys": null,
    "key": null,
    "key_len": null,
    "ref": null,
    "rows": 56035815,
    "filtered": 1,
    "Extra": "Using where; Using temporary; Using filesort"
  
]

SHOW ENGINE INNODB STATUS 输出:https://pastebin.com/ZNeRi6AY

【问题讨论】:

哪个查询失败 - DROP 或 CREATE? 当然是创建。 你能发布EXPLAIN SELECT...的输出吗? 您是说 EXPLAIN SELECT 还是 EXPLAIN CREATE SELECT? @PeterKoltai EXPLAIN SELECT 【参考方案1】:

这个综合索引可能会有所帮助:

INDEX(s, b)   -- (in either order)

问题似乎在于读取大约 56M 行需要花费 900 多秒。

这是一个相当可怕的GROUP BY,它是否有意义,还是ONLY_FULL_GROUP_BY 的解决方法?

你有多少内存?桌子有多大?

如果这个“聚合”(“汇总”)表可以增量构建(如每​​天晚上用当天的数据更新),则可以非常有效地避免超时。 http://mysql.rjweb.org/doc.php/summarytables 如果你可以这样做,我会使用我建议的索引,而是使用 id 或日期来控制每晚读取哪些行,而不用担心过滤 @987654325 @ 和b

【讨论】:

尝试创建索引,同时增加了 innodb_lock_wait_timeout。原来ALTER TABLE input_table ADD INDEX (s,b); 会导致相同的“锁定超时”错误。你能建议如何解决这个问题吗? @AskarIbragimov - 显着增加超时。 ADD INDEX 是一次性任务。 1 天 = 86400 秒;如果超时,那么我错过了一些重要的东西。

以上是关于调用某些查询时,MySQL“超过锁定等待超时”的主要内容,如果未能解决你的问题,请参考以下文章

超过锁定等待超时;尝试重新启动事务 MYSQL Python

为啥在尝试更新 MySQL 条目时出现“超过锁定等待超时”错误?

Laravel - DatabaseTransactions - 超过锁定等待超时

使用 C# 在 Mysql 上死锁 - “超过锁定等待超时;尝试重新启动事务”

保存/更新模型时,Django“超过锁定等待超时;尝试重新启动事务”

mysql_query("START TRANSACTION")- 超过锁定等待超时;尝试在 Codeigniter Mysql 中重新启动事务