应先执行SHOW STATUS LIKE 'innodb_row_lock_current_waits'初筛,返回值>0表示此刻有行锁等待;再通过performance_schema.data_lock_waits关联INNODB_TRX定位阻塞链,并用NOW()-trx_wait_started计算秒级等待时长用于告警。

查 innodb_row_lock_current_waits 判断是否真有锁等待
别一上来就跑复杂 JOIN,先用低开销命令确认有没有真实等待:执行 SHOW STATUS LIKE 'innodb_row_lock_current_waits'。返回值 > 0 就说明此刻有事务卡在行锁上——这是最轻量、权限要求最低的初筛方式,普通账号也能高频轮询。
搭配看 innodb_row_lock_time_avg:如果该值突然从毫秒级跳到几十毫秒以上,说明等待已成规模,不是偶发抖动。注意它归零不代表问题消失,可能只是锁刚释放,或等待刚好超时(默认 innodb_lock_wait_timeout=50 秒)。
用 performance_schema.data_lock_waits 定位阻塞链
MySQL 8.0+ 中 INNODB_LOCK_WAITS 表已废弃且为空,必须用 performance_schema.data_lock_waits 关联 INNODB_TRX 才能拿到有效阻塞关系。
操作前确保开关已开:
-
SELECT NAME, ENABLED FROM performance_schema.setup_instruments WHERE NAME LIKE 'wait/lock/%'→ 确保wait/lock/innoDB/lock等项为YES UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('global_instrumentation', 'thread_instrumentation')
关键查询要严格匹配字段类型:BLOCKING_ENGINE_TRANSACTION_ID 必须连 INNODB_TRX.trx_id,不能误连 trx_mysql_thread_id(后者是线程 ID,类型不一致,查不到结果)。
算当前等待时长用于告警,别只看“谁在等”
仅知道谁被谁堵住不够,得量化影响。核心是计算“已等多久”:
MySQL 数据库管理技能,能够通过自然语言查询和管理数据库,支持 SELECT/INSERT/UPDATE/DELETE、表管理、备份恢复等操作。当用户提及 MySQL、数据库查询、建表或数据备份时使用此技能。
- 从
INNODB_TRX表取trx_wait_started字段(MySQL 5.7+ 支持) - 用
NOW() - trx_wait_started得到秒级等待时长 - 告警阈值建议设为 10–30 秒(远低于默认 50 秒),早于超时发生就触发
避免用 PROCESSLIST.TIME,它反映的是线程空闲时间,不是锁等待真实耗时。
监控脚本里必须过滤掉隐式事务干扰
很多报错看似无事务,实则是单条 UPDATE 或 DELETE 触发了隐式事务。这类事务在 INNODB_TRX 中仍会显示 TRX_STATE = 'LOCK WAIT',但 TRX_STARTED 和 TRX_WAIT_STARTED 时间接近,且 TRX_ISOLATION_LEVEL 常为 REPEATABLE READ。
真正需要预警的是那些 TRX_WAIT_STARTED 比 TRX_STARTED 晚得多、且持续增长的事务——它们大概率卡在业务逻辑或慢查询上,不是简单 DML。
复杂点在于:同一个阻塞源头可能引发多个等待事务,脚本需按 blocking_trx_id 聚合统计,否则告警会刷屏;另外 data_lock_waits 是瞬时快照,必须配合轮询频率(建议 5–10 秒)才能捕捉短时锁争抢。










