找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

892

积分

0

好友

118

主题
发表于 17 小时前 | 查看: 2| 回复: 0

在MySQL 5.7及8.0版本之后,官方已明确不推荐仅依赖information_schema来排查锁问题,其重心已转向 performance_schema (P_S)

相比于记录静态元数据的information_schema,performance_schema的优势在于记录“正在发生什么”,是线上实时诊断与排障的利器。然而,其表结构众多、字段含义抽象,常令使用者无从下手。本文将通过一条完整的排查链路,帮助你真正掌握其用法。

为何转向performance_schema?

简单总结如下:

工具 核心场景
SHOW ENGINE INNODB STATUS 查看最近一次死锁详情
information_schema 查看静态锁信息(传统方式)
performance_schema 实时监控锁等待、追踪“谁在等谁”、分析等待时长

当你遇到以下场景时,performance_schema是你的最佳选择:

  • 线上请求无故卡顿
  • SQL执行极慢但未报错
  • 锁等待现象频发

👉 此时,performance_schema是最强大的实时诊断工具,它逐步替代了旧有的排查方式,成为现代数据库与中间件运维的核心技能。

第一步:确认performance_schema已启用

执行以下命令进行验证:

SHOW VARIABLES LIKE 'performance_schema';

预期结果为:

performance_schema = ON

若状态为OFF(常见于一些旧环境),需在MySQL配置文件my.cnf[mysqld]部分添加:

performance_schema=ON

修改后需重启MySQL服务生效。

第二步:掌握锁等待排查的核心四表

无需记忆所有表,聚焦以下四个核心视图即可。

1. data_locks:查看当前持有的锁

SELECT * FROM performance_schema.data_locks;

此表展示了:

  • 锁类型:行锁或表锁
  • 锁模式:共享锁(S)、排他锁(X)、间隙锁(GAP)、临键锁(NEXT-KEY)
  • 锁对象:所在的表、索引
  • 持有者:是哪个事务持有的锁

2. data_lock_waits:揭示锁等待关系(⭐最关键)

SELECT * FROM performance_schema.data_lock_waits;

这是锁等待关系的核心映射表,关键字段如下:

字段 含义
requesting_engine_lock_id 正在等待的锁ID
blocking_engine_lock_id 造成阻塞的锁ID
requesting_thread_id 等待锁的线程ID
blocking_thread_id 持有锁的阻塞线程ID

👉 只要存在锁等待,就一定能在此表中找到记录。

3. threads:关联线程与连接

SELECT * FROM performance_schema.threads;

通过此表,可将thread_id映射到具体的MySQL连接、用户及其当前状态。

4. events_statements_current:定位正在执行的SQL

SELECT * FROM performance_schema.events_statements_current;

此表用于定位“哪条SQL在等待锁”或“哪条SQL持锁不放”,是关联问题SQL的关键。

实战演练:如何逐步排查一条卡住的SQL?

问题场景

业务反馈:一条UPDATE语句长时间执行无返回,不报错也不结束。

✅ 排查第一步:确认存在锁等待

SELECT * FROM performance_schema.data_lock_waits;

若有记录返回,则证实存在锁等待。

✅ 排查第二步:锁定“谁等谁”的核心关系

SELECT
  r.trx_id AS waiting_trx,
  r.trx_mysql_thread_id AS waiting_thread,
  b.trx_id AS blocking_trx,
  b.trx_mysql_thread_id AS blocking_thread
FROM performance_schema.data_lock_waits w
JOIN information_schema.innodb_trx r ON w.requesting_engine_transaction_id = r.trx_id
JOIN information_schema.innodb_trx b ON w.blocking_engine_transaction_id = b.trx_id;

此查询结果将清晰显示:哪个事务(waiting_trx)在等待,哪个事务(blocking_trx)在阻塞它

✅ 排查第三步:查看当事双方执行的SQL

SELECT
  t.THREAD_ID,
  es.SQL_TEXT
FROM performance_schema.events_statements_current es
JOIN performance_schema.threads t ON es.THREAD_ID = t.THREAD_ID;

通过此步骤可直接定位:

  • 正在等待锁的SQL(受害者)
  • 持有锁不释放的SQL(通常是未提交的长事务)

✅ 排查第四步:分析锁定的对象与范围

SELECT
  OBJECT_SCHEMA,
  OBJECT_NAME,
  INDEX_NAME,
  LOCK_TYPE,
  LOCK_MODE
FROM performance_schema.data_locks;

需要重点关注:

  • INDEX_NAME是否为NULLNULL通常意味着表锁)
  • LOCK_MODE是否为X(排他锁)、X,GAP(排他间隙锁)、X,NEXT-KEY(排他临键锁)

此步是判断锁范围是否过大、是否因索引缺失引起全表扫描的关键。

完整案例:一个真实的锁等待分析

  1. data_lock_waits发现:事务T1正在等待事务T2释放锁。
  2. data_locks查看到锁详情
    • TABLE: orders
    • INDEX: idx_user_id
    • LOCK_MODE: X,NEXT-KEY
  3. 关联的SQL语句
    • T1(等待方):UPDATE orders SET status=1 WHERE user_id=100;
    • T2(持有方):SELECT * FROM orders WHERE user_id=100 FOR UPDATE;
  4. 结论分析
    • 锁定发生在二级索引idx_user_id上。
    • 锁模式为NEXT-KEY LOCK
    • 在RR(可重复读)隔离级别下,对同一索引区间进行并发更新/加锁。
    • 👉 这是一个典型的由范围锁(Next-Key Lock)引发的并发竞争问题。

生产环境紧急“止血”与优化建议

1. 立即终止阻塞源(最快)

KILL <blocking_thread_id>;

通常优先KILL掉持有锁时间最长的事务以快速恢复业务。

2. 优化事务设计(治本)

  • 避免在事务中进行远程RPC调用。
  • 事务内切勿使用SLEEP()或进行耗时操作。
  • 遵循“短事务”原则,操作完成后尽快提交。

3. 检查并优化索引(解决90%的锁问题)

无合适索引是导致锁范围过大(如锁全表、大范围Next-Key Lock)的根因。务必为WHERE条件和UPDATE语句的过滤条件添加高效索引。

4. 利用MySQL 8.0新特性

对于任务队列、抢单等高并发场景,可使用:

SELECT ... FOR UPDATE NOWAIT; -- 若无法立即获锁则立即报错
SELECT ... FOR UPDATE SKIP LOCKED; -- 跳过已被锁定的行

这些特性可以有效减少锁等待,是运维与DevOps工作中提升系统并发能力的重要手段。

performance_schema 与 SHOW ENGINE INNODB STATUS 对比

一句话总结:
SHOW ENGINE INNODB STATUS 像查看“尸检报告”,而 performance_schema 则用于监控“正在抢救的现场”。

对比项 performance_schema INNODB STATUS
实时性 ⭐⭐⭐⭐⭐ ⭐⭐
能否关联具体SQL
展示锁等待链
死锁信息复现 一般 ⭐⭐⭐⭐⭐

👉 结论:对于线上实时锁问题排查,应优先使用performance_schema。

总结

使用performance_schema排查MySQL锁等待,核心路径是:通过data_lock_waits表定位锁等待关系,利用data_locks表分析锁的类型与作用范围,再结合events_statements_currentthreads表追溯至具体的SQL语句和连接。它能够实时、精准地反映“谁被谁阻塞”以及“锁住了什么”,是定位和解决线上数据库锁性能问题最有效的工具集。




上一篇:嵌入式软件开发实战:基于STM32的定时器注册机制设计与解耦
下一篇:TEN VAD轻量级语音活动检测器:306KB超低延迟,优化实时语音交互
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-17 17:29 , Processed in 0.120459 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表