查当前活跃事务需查询information_schema.innodb_trx表,它仅显示innodb未提交/回滚的事务,字段包括trx_state、trx_started、trx_mysql_thread_id和trx_query,用于定位长时间运行事务及关联会话。

怎么查当前正在跑的事务
直接查 information_schema.innodb_trx 就行,这是 InnoDB 引擎唯一能实时看到活跃事务的系统表。注意:它只显示尚未提交或回滚的事务,已提交的不会出现,MyISAM 表的“事务”也不在这里——因为 MyISAM 根本不支持事务。
最简命令:
SELECT trx_id, trx_state, trx_started, trx_mysql_thread_id, trx_query FROM information_schema.innodb_trx;
常用字段说明:
-
trx_state:关键状态,running表示 SQL 正在执行中,lock wait表示被锁住了,starting或committing是瞬态,但持续时间长就值得盯 -
trx_started:时间戳,如果超过几分钟还没结束,大概率是应用没 commit 或异常挂了 -
trx_mysql_thread_id:对应SHOW PROCESSLIST里的ID,可用来关联查谁连的、在跑什么语句 -
trx_query:当前正在执行的 SQL(可能为 NULL,比如事务里只做了 UPDATE 没新查询)
为什么查不到长时间运行的事务
常见原因不是 SQL 慢,而是事务本身没结束——比如应用代码里开了事务但忘了 COMMIT 或 ROLLBACK,或者连接异常断开但事务没自动清理(取决于 innodb_rollback_on_timeout 和网络超时配置)。
排查步骤:
- 先用
SELECT trx_mysql_thread_id FROM information_schema.innodb_trx WHERE trx_started 找出超 1 分钟的事务 - 再用
SELECT * FROM information_schema.processlist WHERE id = <thread_id>;</thread_id>看该连接的状态和Info字段(可能是空,也可能是 sleep) - 如果
Command是Sleep且Time很大,基本确定是应用端卡在事务里没动
注意:innodb_trx 不会显示只读事务(如纯 SELECT),除非开了 autocommit=0 后手动 BEGIN 了。
trx_query 为空或截断怎么办
trx_query 字段类型是 VARCHAR(1024),超长会被截断;更常见的是值为 NULL——这不代表没语句,而是事务当前没在执行 SQL(比如刚 BEGIN,或 UPDATE 完正在等应用发下一条)。
补救方法:
- 结合
information_schema.processlist的Info字段看最近执行的语句(它也有长度限制,但默认 1MB 可调) - 开启
general_log(仅临时调试)或使用 performance_schema.events_statements_current 表(需提前开启相关 consumers) - 检查应用日志,比数据库侧更容易定位“BEGIN 在哪,为什么没 COMMIT”
别依赖 trx_query 判断业务逻辑,它只是快照,不是执行流。
权限不足查不到 innodb_trx 怎么办
需要 PROCESS 权限(MySQL 5.7+)或 SELECT 权限加 PROCESS(8.0 默认 require 两者)。普通应用账号通常没有。
解决办法:
- DBA 给账号加权限:
GRANT PROCESS ON *.* TO 'user'@'%'; - 用有权限的账号(如 root 或监控专用账号)定期采集,写入自定义表供只读查询
- 避免在生产应用连接里直接查这个表——它本身会加轻量级元数据锁,高并发下可能轻微拖慢
information_schema查询
真正难的不是查到事务,是判断哪个该杀、哪个要等、哪个其实早该超时却还挂着——得结合业务语义,不能光看 trx_started 时间戳。











