讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在MySQL8.0中查看具体的事务锁等待图

小瑶小哥_4357

小瑶小哥_4357

发布时间:2026-11-06 09:11:38

|

729人浏览过

|

来源于php中文网

原创

performance_schema.data_lock_waits 是 MySQL 8.0+ 唯一能直接映射“等待者→持有者”关系的视图,需先启用 %wait/lock% instrumentation 并确认 consumers 开启,再关联 data_locks 和 INNODB_TRX 才能闭环定位阻塞源头。

如何在mysql8.0中查看具体的事务锁等待图

怎么用 performance_schema.data_lock_waits 直接看到“谁在等谁”

MySQL 8.0 中唯一能直接输出锁等待关系图(即有向边:A → B 表示 A 等待 B 持有的锁)的表就是 performance_schema.data_lock_waits。它不依赖事务是否活跃,只要等待存在就能捕获,比旧版 INNODB_LOCK_WAITS 更稳定、字段更语义化。

但必须先确认 instrumentation 已启用:

  • UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE '%wait/lock%';
  • 检查 consumers 是否开启:SELECT * FROM performance_schema.setup_consumers WHERE NAME LIKE '%lock%';,确保 events_statements_current 和 data_locks 对应行是 ENABLED = 'YES'
  • 如果查 data_lock_waits 返回空,八成是 instrument 没开,不是没锁

启用后执行:

SELECT 
  r.OBJECT_SCHEMA, r.OBJECT_NAME,
  r.LOCK_MODE AS requested_mode,
  b.LOCK_MODE AS blocking_mode,
  r.OWNER_THREAD_ID AS waiting_thread,
  b.OWNER_THREAD_ID AS blocking_thread
FROM performance_schema.data_lock_waits w
JOIN performance_schema.data_locks r ON w.REQUESTING_ENGINE_LOCK_ID = r.ENGINE_LOCK_ID
JOIN performance_schema.data_locks b ON w.BLOCKING_ENGINE_LOCK_ID = b.ENGINE_LOCK_ID
WHERE r.OBJECT_SCHEMA = 'your_db';

结果里每行就是一个等待边:waiting_thread 正卡在 blocking_thread 持有的锁上,配合 OBJECT_NAME 能立刻定位到具体表和锁粒度。

为什么只查 data_lock_waits 不够?必须连查 INNODB_TRX 和 data_locks

单独看 data_lock_waits 只知道“谁等谁”,但不知道“等什么 SQL”“持有什么锁”“锁在哪几行”。闭环定位必须三表联动:

MySQL8 CRM Schema Design Expert
MySQL8 CRM Schema Design Expert

面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。

下载
  • 用 waiting_thread 和 blocking_thread 去查 performance_schema.threads,拿到 PROCESSLIST_INFO(即实际执行的 SQL)和连接来源(避免误杀监控探针)
  • 用 blocking_trx_id 查 information_schema.INNODB_TRX,重点看 trx_state = 'RUNNING' 且 trx_query IS NULL 的长事务——这类“睡着了却没提交”的事务才是真凶
  • 用 blocking_engine_lock_id 关联 data_locks,看 LOCK_DATA 字段:如果是 123 就是精确行锁;如果是 min_value 或跨度极大(如 1, 5000),大概率是间隙锁失控或索引失效导致锁扩大

漏掉任意一环,就只能看到图的骨架,看不到血肉——比如你发现 thread 1001 在等 thread 1002,但不知道 thread 1002 其实 15 分钟前就执行完 SELECT ... FOR UPDATE 后挂起了,也没法判断它锁的是 1 行还是 2000 行。

怎么把锁等待链转成可读的调用图(例如 A → B → C)

真实生产中常出现多层嵌套等待(A 等 B,B 等 C,C 等 D),data_lock_waits 默认只存直接等待对,需要用 CTE 递归展开:

WITH RECURSIVE wait_chain AS (
  SELECT 
    blocking_trx_id, 
    requesting_trx_id, 
    1 AS level,
    CAST(requesting_trx_id AS CHAR(64)) AS path
  FROM performance_schema.data_lock_waits
  WHERE blocking_trx_id IN (
    SELECT requesting_trx_id FROM performance_schema.data_lock_waits
  )
  UNION ALL
  SELECT 
    w.blocking_trx_id,
    w.requesting_trx_id,
    wc.level + 1,
    CONCAT(wc.path, ' → ', w.requesting_trx_id)
  FROM performance_schema.data_lock_waits w
  INNER JOIN wait_chain wc ON w.blocking_trx_id = wc.requesting_trx_id
)
SELECT * FROM wait_chain ORDER BY level;

这个查询会把链式阻塞拉成扁平路径,比如 trx_300 → trx_200 → trx_100,一眼看出最上游是谁。但注意:MySQL 8.0 的 CTE 递归深度默认是 1000,超深链需调大 cte_max_recursion_depth;另外,该查询只适用于当前快照,锁释放后链就断了——所以得在卡顿发生时立刻跑。

容易被忽略的关键细节:锁等待图不是实时刷新的

data_lock_waits 是瞬时快照,不是流式监控。它只记录“此刻正在发生的等待”,一旦任一环节释放锁(哪怕只释放 1ms),整条链就从视图中消失。这意味着:

  • 不能靠定时轮询来抓问题——等你查的时候可能已经空了
  • 日志里没有对应记录,除非你同时开了 innodb_print_all_deadlocks = ON 并盯住 error log
  • 如果 SHOW ENGINE INNODB STATUS\G 里 LATEST DETECTED DEADLOCK 区块反复出现,说明应用逻辑里存在稳定的加锁顺序冲突,此时锁等待图只是表象,根因在代码里两个事务对同一组行用了不同顺序的 UPDATE

真正要盯住的,不是图本身,而是图里反复出现的那几个 OBJECT_NAME 和 LOCK_MODE 组合——它们指向的是缺失的索引、错用的 WHERE 条件,或者没加 FOR UPDATE 却又想更新的业务逻辑。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2493

2023.06.20

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

1499

2023.06.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

895

2023.07.18

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

3552

2023.07.19

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

6128

2023.07.25

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

1299

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6391

2023.08.11

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

5502

2023.08.14

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

20

2026.11.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 194人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn