Skip to content

锁等待超时 ​

问题现象 ​

出现 Lock wait timeout exceeded,更新卡住数十秒;CPU 不高,但接口线程和连接池逐渐耗尽。

适用环境 ​

MySQL 8 InnoDB;需要 performance_schema 或 sys 视图读取权限。

本文是可复用的排障示例,不代表某次个人生产事故。命令中的名称、账号和数据均为示例,执行前请替换为已确认的目标。

复现或诊断步骤 ​

  1. 在阻塞仍存在时查询 sys.innodb_lock_waits 或 performance_schema.data_lock_waits。
  2. 找到 blocking_pid、被阻塞 SQL、事务开始时间与持锁连接所属应用。
  3. 检查事务是否处于 idle in transaction 类状态:SQL 已结束但未提交;同时核查长批处理。

原因分析 ​

锁被其他未结束事务持有,当前事务只能等待。默认配置下,锁等待超时通常回滚当前语句,不应假定整个事务已经干净结束;具体行为取决于 innodb_rollback_on_timeout。

修复示例 ​

sql
SELECT waiting_pid, blocking_pid, wait_age,
       locked_table, waiting_query, blocking_query
FROM sys.innodb_lock_waits;

SELECT trx_id, trx_started, trx_mysql_thread_id, trx_query
FROM information_schema.innodb_trx
ORDER BY trx_started;

SHOW VARIABLES LIKE 'innodb_rollback_on_timeout';

应用捕获超时后明确回滚事务并返回可重试错误。与连接所属人员确认后优先让持锁事务正常提交或回滚;必须 KILL 时先确认连接身份及回滚影响,终止不是数据恢复手段。批任务分批提交前要评估部分完成的恢复方式。

验证方法 ​

在测试环境持锁并触发超时,检查异常后连接归还、事务回滚与业务状态。解除阻塞后队列应下降;观察长事务是否再次出现。

常见误区 ​

只调整等待时间会拖累连接池。不要把 sleeping 连接一律杀掉,其中可能存在未提交事务;也不要假定 KILL 后回滚立即完成。

官方参考链接 ​

相关分类:数据库与缓存 · 全部笔记