直接查sys.innodb_lock_waits的wait_age_secs字段可直观获知锁等待秒数,>30秒属异常;需实时查询,结果为空不等于无等待;配合sys.innodb_trx和sys.schema_table_lock_waits定位行锁与MDL锁问题,并确认performance_schema及相关采集器已启用。

直接查 sys.innodb_lock_waits 看等待时长
这个视图里 wait_age_secs 字段就是锁等待已持续的秒数,它比 wait_started 更直观——不用自己算时间差。执行 SELECT * FROM sys.innodb_lock_waits ORDER BY wait_age_secs DESC LIMIT 5; 就能立刻拿到当前最久的 5 个等待项。
注意:wait_age_secs 是采样时刻的瞬时值,不是累计历史最大值;如果锁刚释放,这条记录就没了,所以得在卡顿发生时实时查。
-
wait_age_secs> 30 秒基本可判定为异常,需优先介入 - 若结果为空,不代表没锁等待——可能是锁已释放、或持锁事务还没被 performance_schema 捕获(毫秒级延迟)
- 字段
waiting_query可能为NULL(比如事务只BEGIN未执行语句),这时得结合waiting_pid去SHOW PROCESSLIST查Info列
结合 sys.innodb_trx 找出“赖着不走”的长事务
锁等待根源八成是某个事务迟迟不提交。sys.innodb_trx 提供了 trx_started 和运行时长计算,比原生 INFORMATION_SCHEMA.INNODB_TRX 更友好。
执行:SELECT trx_id, trx_mysql_thread_id, trx_state, trx_started, TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) AS duration_sec, trx_query FROM sys.innodb_trx WHERE trx_state = 'LOCK WAIT' OR TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 60 ORDER BY duration_sec DESC;
-
trx_state = 'LOCK WAIT':正在等锁,优先处理 -
duration_sec > 60:运行超 1 分钟的活跃事务,大概率是应用层卡住或忘了COMMIT -
trx_query为空?别跳过——用trx_mysql_thread_id去SHOW PROCESSLIST查Info,那里可能有最后执行的语句
为什么 sys.schema_table_lock_waits 有时更关键
当看到大量线程状态是 Waiting for table metadata lock,说明不是行锁问题,而是 DDL(如 ALTER TABLE)被 SELECT 或其他长事务阻塞了 MDL 锁。这时候 sys.innodb_lock_waits 会完全沉默——它只管 InnoDB 行级锁。
查它:SELECT blocking_pid, waiting_pid, blocking_query, waiting_query, sql_kill_blocking_query FROM sys.schema_table_lock_waits\G;
-
blocking_lock_type是SHARED_READ?那大概率是个没提交的普通查询在 hold 表级读锁 -
sql_kill_blocking_query给出的是KILL QUERY命令,但注意:它只中断语句,不结束事务;若事务未提交,MDL 锁仍在,得用KILL <code>blocking_pid彻底干掉连接 - 这个视图不依赖
INNODB_TRX,所以即使行锁视图查不到东西,只要 DDL 卡住,它就能报出来
权限和基础配置必须先确认
sys 库不是“装上 MySQL 就自动可用”,它依赖 performance_schema 且需要显式启用相关采集器。很多线上环境返回空结果,其实只是配置没开。
- 先确认
sys存在:SHOW SCHEMAS LIKE 'sys';,若无则需运行 MySQL 自带脚本重建(路径常见于/usr/share/mysql/) - 检查
performance_schema是否开启:SELECT @@performance_schema;必须返回ON - 确保锁相关 consumer 已启用:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'events%lock%'; - 用户至少要有
SELECT权限在sys和performance_schema库,否则视图返回空或报错
真实锁等待链路往往跨多个环节:一个 WAITING_TRX_ID 对应的事务可能早已消失,而持锁者可能只执行了一条简单 SELECT ... FOR UPDATE 就睡着了。别只盯着 SQL 内容,重点看 trx_started 时间戳和 wait_age_secs 的落差——差得越远,越说明应用层逻辑有缺陷。


















