当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL performance_schema events_transactions_current 怎样抓住长事务

MySQL performance_schema events_transactions_current 怎样抓住长事务

来源:17golang原创 2026-11-14 03:25:12 0浏览 收藏

线上出现锁等待时,先不要把所有慢 SQL 都当成根因。对“事务还没结束、已经持续很久”的判断,MySQL Performance Schema 已经给了一个直接入口:performance_schema.events_transactions_current。筛选 STATE = 'ACTIVE'、END_EVENT_ID IS NULL,再把 TIMER_WAIT 从皮秒换算成秒,就能先抓住当前仍在运行的长事务。

本文只讨论当前事务、长事务和锁诊断,不把历史事务表当成实时列表,也不把事务持续时间直接等同于锁等待时间。

先确认当前事务事件确实在采集

events_transactions_current 按线程保存最近一个被监控的当前事务事件,每个线程最多对应一行。若事务 instrument 没开,或者 consumer 没开,查询为空并不代表系统没有事务。

-- 先查看事务采集开关,避免把“未采集”误判成“没有长事务”
SELECT NAME, ENABLED, TIMED
FROM performance_schema.setup_instruments
WHERE NAME = 'transaction';

-- current consumer 决定是否维护当前事务表
SELECT NAME, ENABLED
FROM performance_schema.setup_consumers
WHERE NAME = 'events_transactions_current';

-- 仅在确认允许动态调整采集时执行;TIMED=YES 才能获得耗时字段
UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES'
WHERE NAME = 'transaction';

UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE NAME = 'events_transactions_current';
MySQL 事务采集开关、当前事务表和耗时字段的静态关系说明图
图1:结构说明图,展示 transaction instrument、current consumer 与当前事务耗时字段的关系;这是静态说明图,不是运行截图。

生产环境调整前要评估采集开关的影响,并确认账号有访问 Performance Schema 设置表的权限。文章中的 UPDATE 是配置示例,不代表已经在你的实例执行。

用 TIMER_WAIT 抓仍然活跃的长事务

MySQL 8.4 文档说明,当前事件尚未结束时,END_EVENT_ID 为 NULL,TIMER_WAIT 表示从开始到当前时刻经过的时间,单位是皮秒。下面用 300 秒作为排查阈值,你可以按业务事务的正常时长调整。

-- 300 秒 = 300 × 10^12 皮秒;只看仍处于 ACTIVE 的当前事务
SELECT
    THREAD_ID,
    EVENT_ID,
    STATE,
    ROUND(TIMER_WAIT / 1000000000000, 1) AS elapsed_seconds,
    ACCESS_MODE,
    ISOLATION_LEVEL,
    AUTOCOMMIT,
    NESTING_EVENT_ID,
    NESTING_EVENT_TYPE
FROM performance_schema.events_transactions_current
WHERE END_EVENT_ID IS NULL
  AND STATE = 'ACTIVE'
  AND TIMER_WAIT IS NOT NULL
  AND TIMER_WAIT >= 300 * 1000000000000
ORDER BY TIMER_WAIT DESC;

这里的三个条件各有作用:END_EVENT_ID IS NULL 排除已经结束但仍留在当前表的事件;STATE = 'ACTIVE' 把关注点放在尚未提交或回滚的事务;TIMER_WAIT IS NOT NULL 避免未计时的事件进入比较。若结果为空,先回到上一节检查采集开关和查询权限。

别把事务时间和锁等待时间混为一谈

长事务只是“事务保持活动的时间很长”,它可能在等待业务输入、持有锁、执行慢查询,或者只是应用忘记提交。要判断它是否正在阻塞别人,需要把事务线程与 performance_schema.data_lock_waits 关联。

-- requesting 是等待锁的一方,blocking 是持有阻塞锁的一方
SELECT
    w.REQUESTING_THREAD_ID,
    w.BLOCKING_THREAD_ID,
    ROUND(r.TIMER_WAIT / 1000000000000, 1) AS requesting_seconds,
    ROUND(b.TIMER_WAIT / 1000000000000, 1) AS blocking_seconds,
    r.STATE AS requesting_state,
    b.STATE AS blocking_state,
    r.ACCESS_MODE AS requesting_mode,
    b.ACCESS_MODE AS blocking_mode
FROM performance_schema.data_lock_waits AS w
LEFT JOIN performance_schema.events_transactions_current AS r
  ON r.THREAD_ID = w.REQUESTING_THREAD_ID
LEFT JOIN performance_schema.events_transactions_current AS b
  ON b.THREAD_ID = w.BLOCKING_THREAD_ID
WHERE r.END_EVENT_ID IS NULL
   OR b.END_EVENT_ID IS NULL;
MySQL data_lock_waits 连接 requesting 事务与 blocking 事务的静态关系说明图
图2:关系说明图,展示 data_lock_waits 如何连接等待线程与阻塞线程,并回到各自的当前事务属性;这是静态说明图,不是运行截图。

如果 BLOCKING_THREAD_ID 对应的事务持续时间很长,同时又出现在多个等待关系中,它更值得优先处理。但不要仅凭这张表直接终止会话:先结合业务确认是否处在必须原子完成的流程,再决定提交、回滚或让应用修复事务边界。

需要更具体的引擎信息时再看 InnoDB 状态

events_transactions_current 适合回答“哪个线程有一笔仍活跃的事务、已经持续多久、事务属性是什么”。当问题进一步变成“具体锁住了哪个索引记录、出现了什么 InnoDB 锁描述”,可以补充:

-- 该命令需要 PROCESS 权限;它提供 InnoDB Monitor 的引擎侧状态
SHOW ENGINE INNODB STATUS;

它们的分工可以这样记:当前事务表负责按线程和耗时排序,data_lock_waits 负责看等待与阻塞关系,InnoDB 状态负责补充引擎侧细节。三者不是同一份数据,也不能互相替代。

常见误区与速查结论

  • 查询 events_transactions_history 只能看到已经结束的近期事务,不能代替 current 表抓实时长事务。
  • TIMER_WAIT 是皮秒,不是秒;换算时使用 1000000000000,不要直接和 300 比较。
  • 事务很长不必然代表它正在阻塞别人;是否阻塞要看 data_lock_waits 的 blocking 关系。
  • 事务事件边界和服务器事务状态基本一致,但只访问非事务表的语句不会让 Performance Schema 事务事件进入同一事务边界。

排查顺序可以压缩成一句话:先确认采集,再用 END_EVENT_ID、STATE 和 TIMER_WAIT 找出活动长事务,随后用线程 ID 关联锁等待,最后用 InnoDB 状态补足记录级信息。

相关问题

为什么 TIMER_WAIT 是 NULL?

通常是对应 instrument 没有开启计时,即 TIMED 不是 YES。先查看 setup_instruments,不要把 NULL 当成零秒。

events_transactions_current 为什么看不到我刚执行的事务?

检查 Performance Schema 是否启用、transaction instrument 和 current consumer 是否开启,并确认事务确实访问了事务性存储引擎。自动提交模式下,每条使用事务性引擎的语句也可能形成很短的隐式事务。

长事务应该立刻 KILL 吗?

不建议只按时长自动处理。先确认它是否是阻塞链中的 blocking 方、是否处在可安全回滚的业务阶段,再由业务负责人决定提交、回滚、终止会话或修复连接池的事务边界。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
MySQL 在线 DDL 怎样判断操作是否会阻塞写入MySQL 在线 DDL 怎样判断操作是否会阻塞写入
上一篇
MySQL 在线 DDL 怎样判断操作是否会阻塞写入
MySQL 连接池空闲断开后应用为什么出现坏连接
下一篇
MySQL 连接池空闲断开后应用为什么出现坏连接
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    1018次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    1020次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1155次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1121次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    962次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码