最准、最轻量的活跃事务查询入口是INFORMATION_SCHEMA.INNODB_TRX表,它直接暴露所有未提交的InnoDB事务,TRX_STATE字段明确标识状态,TRX_STARTED可识别异常长事务;需结合INNODB_LOCK_WAITS定位阻塞链,而INNODB_LOCKS在5.7.15+已废弃,应改用performance_schema.data_locks;SHOW ENGINE INNODB STATUS不适用于自动化检测,因其输出非结构化且有截断风险。

查 INFORMATION_SCHEMA.INNODB_TRX 看活跃事务
MySQL 5.6+ 的 INFORMATION_SCHEMA.INNODB_TRX 表直接暴露当前所有未提交的 InnoDB 事务,这是最准、最轻量的入口。它不依赖锁等待关系,只要事务 STARTED 且没 COMMIT/ROLLBACK,就一定在里头。
常见错误是只查 PROCESSLIST,但那个只显示连接和语句,根本看不出事务是否已 BEGIN 或卡在中间;而 INNODB_TRX 的 TRX_STATE 字段明确标出 RUNNING、LOCK WAIT、ACTIVE 等状态,TRX_STARTED 还能帮你揪出“挂了两小时没提交”的脏事务。
-
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX WHERE TRX_STATE = 'ACTIVE';—— 查所有真正活跃(含已 BEGIN 未 COMMIT)的事务 - 重点关注
TRX_MYSQL_THREAD_ID(可关联PROCESSLIST.ID)、TRX_QUERY(当前执行语句)、TRX_STARTED(时间戳,判断是否异常长) - 注意:MyISAM 表事务不在此列,它压根不支持事务;只有显式开启的 InnoDB 事务才被记录
连带查 INFORMATION_SCHEMA.INNODB_LOCK_WAITS 判断阻塞链
单看 INNODB_TRX 只知道“有事务”,但不知道谁在等谁。一旦出现慢查询或应用超时,大概率是锁等待导致的连锁阻塞,这时必须结合 INNODB_LOCK_WAITS 定位源头。
这个表每行代表一个等待关系:WAITING_TRX_ID 在等 BLOCKING_TRX_ID 释放锁。它本身不存事务详情,必须 JOIN INNODB_TRX 才能拿到线程 ID 和 SQL。
SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, r.trx_query waiting_query, b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread, b.trx_query blocking_query FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS w INNER JOIN INFORMATION_SCHEMA.INNODB_TRX b ON b.trx_id = w.BLOCKING_TRX_ID INNER JOIN INFORMATION_SCHEMA.INNODB_TRX r ON r.trx_id = w.WAITING_TRX_ID;- 如果查不到结果,不代表没锁争用——可能只是没形成“等待”,比如两个事务同时更新同一行,其中一个会立刻报死锁并回滚,不会进
LOCK_WAITS -
INNODB_LOCK_WAITS是实时快照,不是历史日志;事务一结束,对应行就消失
别漏掉 INFORMATION_SCHEMA.INNODB_LOCKS(MySQL 5.7+ 已废弃)
MySQL 5.7.15 起,INNODB_LOCKS 表被移除,官方改推 performance_schema.data_locks。如果你用的是 5.7.15+ 或 8.0,默认查 INNODB_LOCKS 会返回空或报错,但很多老脚本还硬编码着它,容易误判“没锁”。
新路径下,performance_schema.data_locks 提供更细粒度的锁信息(包括记录锁、间隙锁、临键锁),但需要先确保 performance_schema 开启且相关消费者已启用:
- 检查:
SELECT * FROM performance_schema.setup_consumers WHERE NAME = 'events_statements_current';,确认ENABLED = 'YES' - 查锁:
SELECT ENGINE_TRANSACTION_ID, INDEX_NAME, LOCK_TYPE, LOCK_MODE, LOCK_DATA FROM performance_schema.data_locks; - 注意:8.0 默认关闭部分 consumers,光开
performance_schema不够,得手动开data_locks相关项,否则查出来永远是空
为什么 SHOW ENGINE INNODB STATUS 不适合自动化检测
这个命令输出人眼友好,但结构松散、无固定字段分隔,解析极其脆弱。比如 “TRANSACTIONS” 小节里事务列表用空行分隔,但某条 SQL 里恰好有换行,整个解析就错位;再比如锁信息混在大段文本里,正则一写错就漏掉关键事务。
它适合人工临时诊断,但写成监控脚本或告警逻辑时,稳定性远不如 INFORMATION_SCHEMA 系列表——后者是标准 SQL 查询,字段稳定、类型明确、权限可控。
- 运维脚本、Zabbix 告警、Prometheus exporter 都应优先走
INNODB_TRX+INNODB_LOCK_WAITS -
SHOW ENGINE INNODB STATUS的输出长度上限是 1MB,超长事务会被截断,而INNODB_TRX.TRX_QUERY默认只存前 1024 字符,但至少字段可预期 - 权限上,查
INFORMATION_SCHEMA只需普通 SELECT 权限;而SHOW ENGINE需要PROCESS权限,安全策略收紧时容易失败
真正难的不是查到事务,而是区分“合理长事务”和“意外卡住”。比如一个报表导出事务持续 15 分钟可能是正常的,但同个事务在凌晨三点还在跑 UPDATE 就得干预。时间阈值、业务上下文、线程来源(应用名、IP)这些信息得自己补全,INFORMATION_SCHEMA 只给骨架,血肉得靠你填。


















