INFORMATION_SCHEMA.INNODB_TRX 是唯一开箱即用的活跃事务查询方式,因 INFORMATION_SCHEMA.TRX 不存在且 performance_schema.events_transactions_current 默认关闭;它依赖 PROCESS 权限,反映 InnoDB 事务,关键字段包括 trx_state、trx_started 和 trx_query。

必须用 INFORMATION_SCHEMA.INNODB_TRX 查活跃事务,别试 INFORMATION_SCHEMA.TRX(根本不存在)或默认关闭的 performance_schema.events_transactions_current。
为什么 INFORMATION_SCHEMA.INNODB_TRX 是唯一开箱即用的选择
MySQL 8.0 不再提供 INFORMATION_SCHEMA.TRX 表,执行 SELECT * FROM INFORMATION_SCHEMA.TRX 会直接报错 Unknown table。而 performance_schema.events_transactions_current 默认是关闭的,且只记录显式开启的事务(BEGIN 后的),自动提交模式下的单条语句不会出现——这意味着你查不到大量“执行完 SQL 就挂起”的假空闲事务。
INFORMATION_SCHEMA.INNODB_TRX 不依赖额外配置,只要账号有 PROCESS 权限就能查,且只反映 InnoDB 表的事务(MyISAM 操作不出现,这点要心里有数)。
关键字段说明:
-
trx_state:核心判断依据。RUNNING表示正在执行 SQL;LOCK WAIT表示被锁阻塞;ROLLING BACK/COMMITTING是瞬态,轮询时才可能捕获 -
trx_started:精确到微秒,用NOW() - trx_started可算出持续时间,超过 60 秒建议人工介入 -
trx_query:只显示事务中最后一条执行的 SQL,为空不代表没操作——可能是开了事务但还没发任何语句
如何识别“假空闲”长事务(Sleep 连接 + 长事务)
很多问题不是事务真在跑 SQL,而是应用端开了事务、执行完就睡着了,既不 COMMIT 也不 ROLLBACK。此时 INNODB_TRX 里还能看到记录,但 show processlist 中 State = 'Sleep'、Time 很大——这就是典型的“假空闲”长事务,最容易被忽略。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
单靠 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',基本可断定是应用端忘了提交
用 performance_schema 查更全信息(需手动启用)
如果你需要带用户、主机、当前语句、运行时长等丰富字段的视图,performance_schema 是更好的选择,但它不是默认全开的:
- 先确认消费者已启用:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('events_transactions_current', 'events_statements_current'); - 再执行查询(返回 Top 10 最长事务):
SELECT thr.processlist_id AS mysql_thread_id, CONCAT(PROCESSLIST_USER,'@', PROCESSLIST_HOST) AS `User`, Command, FORMAT_PICO_TIME(trx.timer_wait) AS trx_duration, current_statement AS `latest_statement` FROM performance_schema.events_transactions_current trx INNER JOIN performance_schema.threads thr USING (thread_id) LEFT JOIN sys.processlist p ON p.thd_id = thread_id WHERE thr.processlist_id IS NOT NULL AND PROCESSLIST_USER IS NOT NULL AND trx.state = 'ACTIVE' GROUP BY thread_id, timer_wait ORDER BY TIMER_WAIT DESC LIMIT 10; - 注意:
sys.processlist是视图,依赖performance_schema.threads和events_statements_current,若后者未启用,current_statement会为NULL - 该方式能暴露更多上下文,但无法覆盖自动提交语句产生的“隐形”长事务
真正难排查的,从来不是那个跑了三小时的 UPDATE,而是那个 trx_query 为空、State = 'Sleep'、Time = 17280(5 小时)却没人认领的连接——它不占 CPU,不写慢日志,只悄悄拖住 MDL、撑大 undo、卡死后续所有 DDL。盯住 trx_started 和 PROCESSLIST.time 的差值,比看任何监控曲线都管用。










