如何配置Performance Schema锁监控事件并开启锁等待追踪

来源:XML-XSL教程作者:沙月恵奈‌头衔:网络博主
导读:本期聚焦于沙月恵奈‌创作的《如何配置Performance Schema锁监控事件并开启锁等待追踪》,敬请观看详情。排查锁等待时,如果只查看 SHOW ENGINE INNODB STATUS,往往只能看到最后一个持锁事务,无法还原完整阻塞链。Performance Schema 提供了一组锁监控事件和等待表,通过 setup_instruments 与 setup_consumers 精确开启后,data_locks、data_lock_waits、metadata_locks 可以记录行锁、意向锁、元数据锁的持有与等待关系。要开启锁等待追踪,重点启用 wait/lock/metadata/sql/mdl 等采集点,并打开 events_waits_current 等消费者。本文会说明这些配置表的关联,给出验证配置是否生效的查询,然后演示如何联合 innodb_trx 与 data_lock_waits 找出等待方和阻塞方。还会介绍在业务高峰期控制采集范围的方法,避免监控本身拖慢数据库。

定位一条 UPDATE 长时间不返回的原因时,光看 InnoDB 状态输出通常会错过元数据锁这一类隐性等待。Performance Schema 里的锁监控事件能够把等待线程、持锁线程、锁类型和涉及的库表都记录下来,但前提是相关 instruments 和 consumers 已经被正确打开。下面直接进入配置和查询链路。

如何配置Performance Schema锁监控事件并开启锁等待追踪

锁监控事件涉及的核心配置表

在 Performance Schema 中,setup_instruments 表控制每个采集点是否启用以及是否计时。锁相关的 instrument 主要有 wait/lock/metadata/sql/mdl,它负责收集元数据锁等待。行级锁和表级锁信息则更多依赖 InnoDB 内部的锁表,但 Performance Schema 本身必须开启,data_locks 和 data_lock_waits 才会有内容。还有一个 wait/lock/table/sql/handler,如果还需要观察 LOCK TABLES 这类表锁行为,可以一并打开。

另一张配置表是 setup_consumers,它决定采集到的事件被写到哪些缓冲表里。对于锁等待追踪,至少要确认 global_instrumentation、thread_instrumentation 以及 events_waits_current 处于启用状态。如果希望保留历史等待记录,可以打开 events_waits_history 和 events_waits_history_long,这样即便等待已经结束,也能从历史表中回查。

需要特别区分的是,data_locks 显示的是当前已经被获取或正在等待的行锁、间隙锁、插入意向锁等,data_lock_waits 则专门表示发生等待的锁关系。metadata_locks 表依赖 wait/lock/metadata/sql/mdl 这个 instrument。如果你没有打开它,表里可能长时间为空,即使当前确实存在元数据锁阻塞。

逐步开启锁等待追踪

第一步先确认 Performance Schema 自身的开关。执行 SHOW VARIABLES LIKE 'performance_schema';,返回值为 ON 表示已启用。如果是 OFF,需要修改 MySQL 配置文件后重启实例。MySQL 8.0 通常默认开启,但某些云数据库或精简部署可能关闭。

第二步打开 MDL 锁采集。可以用下面的 SQL 批量启用所有以 wait/lock/metadata/sql/mdl 开头的 instruments,同时开启计时,方便后面观察等待时长。

-- 启用元数据锁相关采集点
UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES'
WHERE NAME LIKE 'wait/lock/metadata/sql/mdl%';

-- 如果需要观察表锁,也可以打开表锁采集点
UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES'
WHERE NAME LIKE 'wait/lock/table/sql/handler%';

第三步打开等待事件消费者。如果只打开 instrument 而不打开 consumer,事件无法被存储和查询。

-- 确认全局采集开关
UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE NAME = 'global_instrumentation';

-- 打开当前等待、历史等待和长历史等待
UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE NAME LIKE 'events_waits%';

配置完成后,可以查询 setup_instruments 和 setup_consumers 验证是否已经生效。需要注意的是,这些修改在实例重启后不一定保留,如果希望永久生效,需要把同样的配置写入启动初始化 SQL 或由运维平台统一执行。

查询锁等待链路的实用SQL

对于 InnoDB 行锁等待,最直接的定位方式是联合 performance_schema.data_lock_waits 和 information_schema.innodb_trx。前者记录等待方和阻塞方的事务 ID,后者提供事务对应的线程 ID、SQL 文本和状态。下面这条 SQL 可以找出谁在等谁,以及双方正在执行什么语句。

SELECT
  r.trx_id                    AS waiting_trx_id,
  r.trx_mysql_thread_id       AS waiting_thread,
  r.trx_query                 AS waiting_query,
  b.trx_id                    AS blocking_trx_id,
  b.trx_mysql_thread_id       AS blocking_thread,
  b.trx_query                 AS blocking_query,
  w.blocking_lock_id          AS lock_id
FROM performance_schema.data_lock_waits w
JOIN information_schema.innodb_trx b
  ON b.trx_id = w.blocking_trx_id
JOIN information_schema.innodb_trx r
  ON r.trx_id = w.requesting_trx_id;

如果想进一步确认锁的模式和锁定对象,可以把 data_locks 表关联进来。重点看 lock_type、lock_mode 和 lock_status,例如 RECORD 行锁、X 排他锁、WAITING 等待状态。这样就能知道等待发生在一个主键记录、二级索引上,还是间隙锁上。

SELECT
  l.engine_lock_id,
  l.engine_transaction_id,
  l.object_name,
  l.index_name,
  l.lock_type,
  l.lock_mode,
  l.lock_status,
  l.lock_data
FROM performance_schema.data_locks l
JOIN performance_schema.data_lock_waits w
  ON l.engine_lock_id = w.blocking_lock_id;

对于元数据锁等待,直接查询 performance_schema.metadata_locks 往往更有效。它能显示 SHARED_READ、EXCLUSIVE 等 MDL 类型,以及锁对象所在库表。把 metadata_locks 和 performance_schema.threads 关联后,可以拿到对应的连接 ID 和 SQL 信息。下面这条 SQL 适合用来排查 DDL 或 DML 被 MDL 阻塞的场景。

SELECT
  m.object_schema,
  m.object_name,
  m.lock_type,
  m.lock_status,
  m.owner_thread_id,
  t.processlist_id,
  t.processlist_command,
  t.processlist_state,
  t.processlist_info
FROM performance_schema.metadata_locks m
LEFT JOIN performance_schema.threads t
  ON m.owner_thread_id = t.thread_id
WHERE m.object_schema IS NOT NULL
ORDER BY m.object_schema, m.object_name;

如果不熟悉底层表结构,也可以使用 sys.schema_table_lock_waits 视图,它内部整合了元数据锁信息,输出更加直观。但视图依赖底层 instruments 已开启,否则查询结果可能不完整。

生产环境开启监控的注意事项

锁监控虽然能帮助定位阻塞,但每个 MDL 获取和释放都会经过探针,开启后可能对高并发短查询带来可感知的 CPU 开销。建议不要在业务高峰期全量打开所有锁相关 instruments,可以先用一个窗口期采集,复现问题后立即关闭。常见的折中方法是只开启 wait/lock/metadata/sql/mdl,而不打开表锁或者更细粒度的同步对象监控。

消费者表也有内存上限,events_waits_history_long 默认保存 10000 行,超出后会覆盖旧数据。如果锁等待发生得很快,历史表可能已经失去现场,因此最好结合 data_lock_waits 和 data_locks 这类实时表进行观察。对于已经消失的等待,仍可以通过 events_waits_history 按线程回查,但需要知道线程 ID 才能缩小范围。

最后还需要区分信息粒度。Performance Schema 给出的锁等待链路偏向事务和线程级别,而 SHOW ENGINE INNODB STATUS 的 LATEST DETECTED DEADLOCK 段落更适合查看已经发生的死锁。两者配合使用,再结合 information_schema.innodb_trx 中的 trx_started 时间,可以快速判断哪个事务长时间未提交,从而决定是否终止阻塞源。

Performance Schema锁等待追踪MySQL锁监控修改时间:2026-09-27 14:22:01

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0927/62589.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。