查活跃事务必须用 INFORMATION_SCHEMA.INNODB_TRX,它开箱即用且只需 PROCESS 权限;INFORMATION_SCHEMA.TRX 不存在,performance_schema.events_transactions_current 默认关闭且不记录自动提交语句。

查活跃事务必须用 INFORMATION_SCHEMA.INNODB_TRX
MySQL 8.0+ 没有 INFORMATION_SCHEMA.TRX 这张表,别再搜错名字。真正能直接看到未提交事务的,只有 INFORMATION_SCHEMA.INNODB_TRX ——它开箱即用,只要账号有 PROCESS 权限就能查。
常见错误是执行 SELECT * FROM INFORMATION_SCHEMA.TRX 报错“Unknown table”,或误以为 performance_schema.events_transactions_current 是默认可用的替代方案——其实它默认关闭,且只记录显式事务(BEGIN 开启的),自动提交模式下的单条语句不会出现。
-
trx_state是核心判断依据:RUNNING表示正在执行 SQL;LOCK WAIT表示被锁阻塞;ROLLING BACK或COMMITTING是瞬态,轮询时才可能捕获 -
trx_started精确到微秒,用NOW() - trx_started可算出持续时间,超过 60 秒建议人工介入 -
trx_query只显示事务中最后一条执行的 SQL,为空不代表没操作——可能是开了事务但还没发任何语句 - 该表只反映 InnoDB 表的事务,MyISAM 操作完全不出现
识别“假空闲”长事务:光看 INNODB_TRX 不够
有些事务已执行完 SQL,但连接仍保持 open 状态(比如客户端没发 COMMIT 或 ROLLBACK),此时 INNODB_TRX 里还能查到,但 show processlist 中 state 是 Sleep,time 却很大——这就是典型的“假空闲”长事务,最容易被忽略。
单靠 INNODB_TRX 查不到这类事务的上下文(比如是谁连的、从哪来的、当前命令是什么),必须关联 information_schema.PROCESSLIST:
- 用
trx_mysql_thread_id对应PROCESSLIST.id,拿到user、host、db和info(当前执行语句) - 注意
PROCESSLIST.time是线程空闲秒数,不是事务存活时间;要交叉比对trx_started才能确认是否异常 - 如果
PROCESSLIST.command = 'Sleep'且trx_state = 'RUNNING',基本可断定是应用端忘了提交
查锁等待不能依赖 INNODB_LOCK_WAITS
MySQL 8.0+ 的 INFORMATION_SCHEMA.INNODB_LOCK_WAITS 已废弃,查询永远返回空。想定位谁在等、谁在挡,得切到 performance_schema.data_lock_waits,但它默认不采集数据。
启用前先确认权限和开关状态:
- 检查 instruments 是否开启:
SELECT NAME, ENABLED FROM performance_schema.setup_instruments WHERE NAME LIKE 'wait/lock/innoDB%';,确保相关项为YES - 启用消费者:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('global_instrumentation', 'thread_instrumentation'); - 关联查询时注意字段类型:
BLOCKING_ENGINE_TRANSACTION_ID是字符串,需与INNODB_TRX.trx_id类型匹配(有时需 CAST) - 即使启用,也只捕获显式事务的锁等待;自动提交语句的行锁不计入
快速初筛锁等待:用 SHOW STATUS LIKE 'innodb_row_lock_current_waits'
不需要权限、不依赖配置、响应快——这是线上第一时间判断有没有锁争用的最轻量方式。
执行 SHOW STATUS LIKE 'innodb_row_lock_current_waits';,结果大于 0 就说明此刻有事务卡在行锁上。但它只是瞬时快照:
- 归零不代表问题消失,可能刚释放,也可能等待超时(默认
innodb_lock_wait_timeout=50秒) - 搭配看
innodb_row_lock_time_avg:如果平均等待时间突然飙升(比如从 0.2ms 到 40ms+),大概率是慢事务或未提交事务拖累了整体 - 这个值对普通账号开放,适合加到监控脚本里每 5 秒轮询一次
真正难的是把等待链串起来——trx_state = 'LOCK WAIT' 的事务、持有锁的线程、以及它们各自最后执行的 SQL,这三者必须对齐才能准确定位根因。别只盯着一个表查,容易漏掉 sleep 状态下的长事务或锁持有者本身也在等别的资源。


















