登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  数据库 >  MySQL

MySQL INFORMATION_SCHEMA.INNODB_TRX 怎样查看未提交事务

来源:17golang原创

时间:2026-11-02 04:40:02 189浏览 收藏

排查 MySQL 中“事务一直没有提交”时,可以先查询 INFORMATION_SCHEMA.INNODB_TRX。它展示当前仍在 InnoDB 内执行的事务,包括事务状态、开始时间、当前语句,以及事务大致锁住和修改的行数。

需要先划清一个边界:INNODB_TRX 不是提交历史表,也不会为每一种只读查询永久保留记录。它更像一个快速变化的观察窗口,适合回答“现在有哪些 InnoDB 事务还活着”,不适合单独证明完整的锁等待链。

结论:先用 TRX_STATE、TRX_STARTED 和 TRX_QUERY 找到可疑事务,再用 TRX_MYSQL_THREAD_ID 映射会话;如果要确认谁持有什么锁、谁在等待谁,还要结合 Performance Schema 的 data_locks 和 data_lock_waits。
INNODB_TRX 事务字段与状态、当前语句、连接会话关系的静态说明图
图1:INNODB_TRX 事务概况字段与连接映射的静态结构说明图,不是数据库截图或运行结果。

先用 INNODB_TRX 列出当前事务

最小查询不必一开始就关联很多系统表。先把事务身份、状态、时间和当前语句列出来,通常就能判断是否存在长期未提交的写事务:

SELECT
    trx_id,
    trx_state,
    trx_started,
    trx_mysql_thread_id,
    trx_rows_locked,
    trx_rows_modified,
    trx_query
FROM information_schema.innodb_trx
ORDER BY trx_started;
-- 先按开始时间查看仍在 InnoDB 中的事务,便于发现持续时间较长的记录。

TRX_ID 是 InnoDB 的内部事务标识;TRX_STATE 常用来区分 RUNNING 和 LOCK WAIT;TRX_STARTED 给出事务开始时间;TRX_QUERY 可能包含该事务当前正在执行的语句。TRX_ROWS_LOCKED 是近似的锁定行数,TRX_ROWS_MODIFIED 则反映该事务修改和插入的行数,不能把它们当成精确的业务计数。

按持续时间和修改痕迹筛选可疑事务

如果记录很多,可以把“已经持续较久”和“有写入痕迹”作为第一轮筛选条件。时间阈值应该结合业务请求时长决定,下面只演示查询结构,不代表所有系统都应使用同一个秒数:

SELECT
    trx_id,
    trx_state,
    trx_started,
    TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS age_seconds,
    trx_mysql_thread_id,
    trx_rows_locked,
    trx_rows_modified,
    trx_query
FROM information_schema.innodb_trx
WHERE trx_started IS NOT NULL
  AND TIMESTAMPDIFF(SECOND, trx_started, NOW()) >= 60
  AND (trx_is_read_only = 0 OR trx_rows_modified > 0)
ORDER BY trx_started;
-- 60 秒只是示例阈值;生产环境应按接口或批处理的正常时长调整。
-- 只把非只读或有修改痕迹的事务放进第一轮排查结果。

看到一条持续时间很长的 RUNNING 记录,不等于可以立即终止连接:它可能正在执行合法批处理,也可能只是应用忘记了 COMMIT。先看 TRX_QUERY、开始时间和修改规模,再回到应用日志确认请求归属。

用 TRX_MYSQL_THREAD_ID 找回连接上下文

TRX_MYSQL_THREAD_ID 是把事务观察结果映射回 MySQL 会话的重要线索。它可以帮助你把内部事务记录与进程列表中的连接 ID 对照起来,但对照过程也受权限和数据刷新时机影响,不能把两个系统表的内容当成同一时刻的强一致快照。

SELECT
    trx_mysql_thread_id,
    trx_state,
    trx_started,
    trx_query
FROM information_schema.innodb_trx
WHERE trx_mysql_thread_id IS NOT NULL
ORDER BY trx_started;
-- 先取出连接线索,再到会话信息中查看用户、主机和连接状态。
-- 不要只凭 trx_id 猜测应用连接,trx_mysql_thread_id 才是会话映射字段。

如果你还需要查看连接用户、来源主机或当前会话的更多字段,可以再按这个 ID 查询会话信息。查询结果为空时,要考虑事务刚好结束、会话信息已刷新,或者当前账号没有读取相应系统信息的权限。

事务概况和锁关系排查不是一回事

INNODB_TRX 与 data_locks、data_lock_waits、PROCESSLIST 的职责边界说明图
图2:事务概况、锁关系与会话权限的职责边界说明图,不是线上监控截图。

INNODB_TRX 适合回答“事务是谁、何时开始、当前处于什么状态、正在做什么”。当问题变成“哪个事务持有了具体锁”“哪个请求在等待”“等待关系是否已经变化”,应该继续查看 Performance Schema 的 data_locks 和 data_lock_waits。

这几个观察表的数据本身变化很快。事务可能在你执行第一条查询后立即提交,锁等待也可能在第二条查询前消失。因此,把它们当成定位线索而不是审计日志;需要留证时,应在应用日志、慢查询日志或专门的监控采集链路中保存上下文。

权限、只读事务和快照边界

查询 INNODB_TRX 通常需要 PROCESS 权限。没有权限时,不要通过改写查询去猜测缺失数据,应让管理员按最小权限原则授予观察权限,并确认生产环境的权限审计要求。

还要注意两个容易误判的情况:

  • 只读且不加锁的事务可能不会创建 InnoDB 事务 ID,因此不能用“没有 TRX_ID”推断业务没有执行查询。
  • TRX_ROWS_LOCKED 是近似值,且系统表反映的是读取瞬间的内部状态;不要把一次结果直接当成完整的锁定行清单。
SELECT
    trx_id,
    trx_state,
    trx_is_read_only,
    trx_autocommit_non_locking,
    trx_started,
    trx_query
FROM information_schema.innodb_trx
ORDER BY trx_started;
-- 通过只读和 autocommit 标记区分“观察到的事务”与普通写事务。
-- 这些标记用于解释结果,不应单独作为终止事务的依据。

常见问题

INNODB_TRX 为空,是否代表没有未提交事务?

不能直接这样下结论。它只表示当前查询窗口没有返回正在 InnoDB 中执行的事务记录,还要排除事务刚结束、事务属于非 InnoDB 表、只读非锁定查询没有生成对应事务 ID,以及权限不足等情况。

TRX_STATE 是 LOCK WAIT 就一定存在严重阻塞吗?

它说明事务正在等待锁,但严重程度仍取决于等待时间、业务超时和阻塞关系。要找具体锁和等待双方,应继续查看 data_locks 与 data_lock_waits,不要只凭状态值终止连接。

为什么 TRX_QUERY 为空?

事务可能暂时没有正在执行的语句,或者语句已经结束但事务仍未提交。此时结合 TRX_STARTED、TRX_MYSQL_THREAD_ID 和应用侧请求日志判断,比把空值当成异常更可靠。

把 INNODB_TRX 当作“当前事务概况表”,先定位身份、状态和时间,再按需扩展到锁关系和会话上下文,排查未提交事务会更稳妥。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>