MySQL 8.4 锁等待排查:找出等待事务与阻塞连接
MySQL 8.4 中排查 InnoDB 锁等待,可先查询 sys.innodb_lock_waits,区分等待连接和阻塞连接,再结合事务信息确认业务归属。不要因为某条 SQL 卡住就立即终止连接;先保留现场,确认阻塞链以及事务是否仍未结束。
适用版本与排查前提
本文依据2026年11月5日查阅的 MySQL 8.4 官方手册,面向已启用 Performance Schema、安装 sys schema 的 MySQL 8.4 InnoDB 实例。本文是资料整理,示例未在读者数据库实测,不适用于直接套用到 MySQL 5.7 或 MariaDB。查询前由 DBA 确认账号具备相应视图及底层对象的读取权限;权限错误不能视为没有锁等待。
使用已经授权的管理连接,先核对实例与故障时间,保留应用错误、请求标识和超时时间。下列命令只读取诊断信息,不修改业务数据;繁忙实例也应控制执行频率,不做持续高频轮询。结果中的 SQL 可能含业务数据,共享前应脱敏。
第一步:确认实例并查看等待关系
SELECT VERSION(), @@hostname, @@port, NOW();
SELECT wait_started, wait_age_secs,
locked_table_schema, locked_table_name,
waiting_trx_id, waiting_pid,
blocking_trx_id, blocking_pid,
waiting_query, blocking_query
FROM sys.innodb_lock_waits
ORDER BY wait_age_secs DESC
LIMIT 20;第一条记录服务器版本、主机标识、端口及数据库当前时间;端口与主机名仍需结合管理平台确认,不能单凭它们唯一识别所有容器实例。第二条取等待时间较长的20条关系。waiting_pid 是等待事务的 processlist 连接ID,blocking_pid 是阻塞事务的连接ID;两者都不是操作系统 PID。wait_age_secs 表示锁等待秒数,不能代替事务完整年龄。列定义见官方 innodb_lock_waits 视图说明。
先记录“谁等待谁”及表名,再对照应用负责人确认连接来源。同一个阻塞连接可能影响多个等待者,不能把每行结果当成完全独立的故障。
第二步:区分事务存在与当前 SQL 存在
阻塞会话变为空闲时,blocking_query 可以为 NULL;这不等于它没有未结束事务,官方明确说明了这一情况,见blocking_query 字段解释。可结合下列事务快照继续定位:
SELECT trx_id, trx_state, trx_started,
trx_mysql_thread_id, trx_query,
trx_rows_locked, trx_rows_modified
FROM information_schema.innodb_trx
ORDER BY trx_started
LIMIT 20;按第一步得到的连接ID核对 trx_mysql_thread_id,并看事务开始时间、状态及当前语句。此处按开始时间列出前20条,目标不在结果中时应按已确认的连接ID加 WHERE 条件查询,不能直接断言目标事务不存在。字段含义见INNODB_TRX 官方说明。两次查询之间现场可能变化,记录各自时间,不把它们当成完全一致的历史快照。
第三步:必要时核对底层数据锁依赖
SELECT ENGINE,
REQUESTING_ENGINE_TRANSACTION_ID,
REQUESTING_THREAD_ID,
BLOCKING_ENGINE_TRANSACTION_ID,
BLOCKING_THREAD_ID
FROM performance_schema.data_lock_waits
LIMIT 20;该表描述请求锁与阻塞锁之间的关系,可能是多对多;THREAD_ID 是 Performance Schema 线程ID,不要直接当作前面的 processlist 连接ID。锁细节可按官方表定义再关联 data_locks;见data_lock_waits 文档。本文不提供自动终止 SQL,诊断ID也不应未经复核交给自动清理脚本。
验证方法与处理边界
- 将等待、阻塞连接和业务事务对应起来,检查是否存在事务长时间未提交、应用异常路径漏做回滚,或本次操作范围超出预期。
- 由业务负责人和 DBA 根据事务语义选择处理方式。提交、回滚和终止连接都可能影响业务,不从诊断视图中复制生成的 KILL 字符串直接执行。
- 处理后按合理间隔重复相同诊断,观察原等待关系是否消失,并确认受影响请求恢复、错误率及延迟符合实际业务要求。
- 保留处理前后时间、实例、连接ID、事务ID和应用证据。单次视图为空不等于故障期间从未出现等待,也不代表其他性能问题已消失。
官方提供了结合事务与锁信息排查的示例,参阅InnoDB 事务和锁信息用法。若连诊断连接都无法建立,可先参考本站MySQL Socket 与 TCP 连接排查,避免把连接故障与已建立会话中的锁等待混为一谈。
常见问题
查询为空,为什么 ALTER TABLE 仍然等着?
InnoDB 数据锁等待不是所有等待的总表。元数据锁应另看 performance_schema.metadata_locks,结合锁状态和所属线程确认,并核对相关采集设置。不能把该表中每个已持有锁都判为异常,参阅metadata_locks 官方说明。
超时后等待记录没了,是否还需要排查?
需要结合应用记录判断。当前诊断视图用于观察现场,事后空结果不能恢复已经消失的等待链。保留故障时间及业务错误,在再次出现时由授权人员采样,不通过增加超时掩盖尚未确认的阻塞原因。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭