间隙锁排查实战:一条SQL揪出阻塞元凶

本文涉及的产品
RDS AI 助手,专业版
PolarDB Agent Express,2核4GB
PolarDB Agent Flow,2核4GB
简介: 数据库小学妹带你实战排查间隙锁!用`SHOW ENGINE INNODB STATUS`快速定位`LOCK WAIT`与`gap before rec`,结合`performance_schema.data_lock_waits`精准识别阻塞源,厘清锁等待、死锁根因,避开RC无隙锁、无索引变表锁等常见误区。

📌 关键词:间隙锁、锁等待、performance_schema、SHOW ENGINE INNODB STATUS、死锁

大家好呀!我是数据库小学妹👋

上一篇我们搞懂了MVCC和锁联手如何解决幻读,知道了Next-Key Lock(行锁+间隙锁)是RR隔离级别下的“幻读克星”。

但理论懂了,实战中遇到问题时,怎么快速定位?比如,事务突然卡住、插入被阻塞——这背后很可能藏着一个间隙锁幽灵在作祟!

今天我们就用MySQL自带的监控工具,手把手揪出间隙锁,让问题无所遁形!


一、场景模拟:间隙锁引发的“插入阻塞”

假设订单表 orders 有索引字段 order_date。事务A执行了范围锁定:

--- 事务A
BEGIN;
SELECT * FROM orders 
WHERE order_date BETWEEN '2026-05-01' AND '2026-05-10' 
FOR UPDATE;
-- 事务A 未提交

此时,事务B试图插入一条新订单:

-- 事务B(另一个会话)
INSERT INTO orders (order_id, order_date) VALUES (1005, '2026-05-05');

​🌈结果:​事务B被​卡住不动​。
​🚩原因:​事务A的间隙锁锁住了 order_date[2026-05-01, 2026-05-10] 范围内的“间隙”,导致新插入被阻塞。


二、排查利器1:SHOW ENGINE INNODB STATUS——快速定位锁等待

当系统出现卡顿时,第一步:登录MySQL,执行:

SHOW ENGINE INNODB STATUS\G

在输出中搜索 TRANSACTIONS 段落,找到处于 LOCK WAIT 的事务。关键信息:

  • WAITING FOR THIS LOCK TO BE GRANTED:显示正在等待的锁类型(如 lock_mode X locks gap before rec
  • 锁的范围​:例如 RECORD LOCKS ... index order_date ... lock_mode X locks gap before rec
  • 阻塞事务ID​:找到持有锁的事务(事务A)

💡 如果看到 LATEST DETECTED DEADLOCK,说明发生了死锁(InnoDB已自动回滚一个事务),需进一步分析。


三、排查利器2:performance_schema——深入锁细节

MySQL 5.7+版本提供了更强大的性能监控工具performance_schema

执行以下查询,直接获取锁等待关系:

SELECT 
    OBJECT_SCHEMA, OBJECT_NAME,
    INDEX_NAME,
    LOCK_TYPE, LOCK_MODE,
    LOCK_STATUS,
    BLOCKING_ENGINE_TRANSACTION_ID,
    REQUESTING_ENGINE_TRANSACTION_ID
FROM performance_schema.data_lock_waits
JOIN performance_schema.data_locks 
  ON data_lock_waits.REQUESTING_ENGINE_LOCK_ID = data_locks.ENGINE_LOCK_ID;

🔖重点关注字段:

  • LOCK_MODE = 'X,GAP' → 排他间隙锁
  • LOCK_STATUS = 'WAITING' → 谁在等
  • BLOCKING_ENGINE_TRANSACTION_ID → 谁在阻塞

拿到阻塞事务ID后,到 INNODB_TRX 表查具体SQL:

SELECT trx_id, trx_state, trx_started, trx_query 
FROM information_schema.INNODB_TRX 
WHERE trx_id = 阻塞事务ID;

四、实战解读:一个典型的间隙锁日志

执行 SHOW ENGINE INNODB STATUS 后,你会看到类似这样的片段:

---TRANSACTION 31045, ACTIVE 10 sec
2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 8, query id 123 localhost root
SELECT * FROM orders WHERE status = 'pending' FOR UPDATE
---TRANSACTION 31046, ACTIVE 5 sec
1 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 9, query id 124 localhost root
INSERT INTO orders (id, status, amount) VALUES (7, 'pending', 150)
------- TRX HAS BEEN WAITING 5 sec FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28 page no 4 n bits 72 index idx_status of table `test`.`orders` trx id 31046 lock_mode X locks gap before rec

​🌈结论:​事务31046(INSERT)在等待一个 lock_mode X locks gap before rec(间隙锁),持有者是事务31045(FOR UPDATE查询)。


五、避坑指南:间隙锁排查的3个易错点

易错点 正确理解
间隙锁 ≠ 死锁 间隙锁导致锁等待(需手动处理);死锁自动回滚,日志会记录
RC级别无间隙锁 读已提交(RC)下不会产生间隙锁。若performance_schema仍显示gap,可能是视图残留,以实际隔离级别为准
无索引 = 表锁陷阱 WHERE条件无索引时,间隙锁会升级为全表锁,性能暴跌!务必先用EXPLAIN检查

👋 我是数据库小学妹一个用设计师思维学数据库的转行人。我们一起把复杂的技术变得简单有趣!💕

本文示例基于 ​MySQL​ 8.0。不同版本锁表名有差异(5.7用INNODB_LOCKS等),请自行适配。

相关文章
|
2月前
|
SQL 关系型数据库 MySQL
数据量大查询慢?索引让你的SQL秒级响应!|转行学DB第9天
用生活化比喻(如字典目录)详解索引原理:它通过B+树结构加速查询,避免全表扫描;涵盖创建、查看、删除索引方法,联合索引的最左前缀原则,以及读写平衡等实战要点——让查询从“等几秒”变“秒出”!
数据量大查询慢?索引让你的SQL秒级响应!|转行学DB第9天
|
1月前
|
SQL 缓存 数据库
你还在用LIMIT 1000000,10?献上分页查询优化技巧
本文详解“深分页”陷阱:`LIMIT 1000000,10`为何慢?3种优化方案(游标法、子查询定位、延迟关联)实测提速数十倍,助你零成本提升SQL性能!
|
1月前
|
SQL 关系型数据库 MySQL
MySQL慢查询诊断实战:从10秒到0.1秒,我的5步排障法
数据库小学妹分享慢查询优化实战:从10秒降至0.08秒!详解「发现→收集→分析→优化→验证」5步排障法,覆盖慢日志配置、EXPLAIN进阶、索引失效场景、JOIN与分页优化等核心技巧,附真实案例与速查表。
|
11天前
|
Prometheus 监控 Cloud Native
MySQL 性能监控实战:从零搭建 Prometheus + Grafana 监控告警体系(附排查 SOP)
数据库小学妹带你从零学监控!本文详解MySQL五大核心指标维度(资源、连接、查询、InnoDB、主从),手把手配置PMM/Prometheus+Grafana监控栈,设置关键告警规则,并提供SQL快照脚本与三步排障SOP。新手友好,即装即用,让性能问题无所遁形!
|
11天前
|
SQL 监控 关系型数据库
数据库三大日志深度解析:Redo Log、Binlog、Undo Log 如何守护你的数据
本文由“数据库小学妹”带你厘清MySQL三大核心日志:Redo Log(引擎层物理日志,保障crash-safe)、Undo Log(支撑回滚与MVCC)和Binlog(Server层逻辑日志,用于复制与恢复),详解WAL机制与两阶段提交原理,助你真正理解事务安全底层逻辑。
|
1月前
|
运维 容灾 关系型数据库
数据库容灾配置全攻略:同城容灾vs两地三中心,RPO、RTO一篇讲透
数据库小学妹带你轻松搞懂容灾核心概念!本文用通俗语言解析同城容灾、两地三中心、高可用集群,厘清RPO(数据丢失容忍)与RTO(恢复时效)关键指标,对比方案选型要点,并揭秘同步/异步复制、自动切换、读写分离等实战技术,附避坑指南与演练建议。
|
1月前
|
关系型数据库 MySQL 测试技术
JOIN、IN、EXISTS谁最快?实测三种写法性能差异与执行计划深度剖析
本文用MySQL 8.0实测拆解`IN`/`EXISTS`/`JOIN`子查询性能:从执行计划、半连接优化、临时表开销等底层原理出发,结合10万+100万数据实测(`EXISTS`最快95ms),给出三条选型铁律——告别盲从“最佳实践”,只选最适配业务与数据的写法!
|
1月前
|
数据采集 人工智能 安全
阿里巴巴 & 蚂蚁共建 LoongSuite GenAI 可观测语义规范:从统一数据语言到规模化落地
阿里巴巴与蚂蚁集团联合推出 LoongSuite GenAI 可观测语义规范,在 OpenTelemetry 标准之上,为 AI Agent、Skill、Token 级推理等场景建立统一数据语言。从链路追踪到引擎“显微镜”,本文揭秘如何让 GenAI 应用真正可看见、可分析、可治理。
279 17
|
1月前
|
弹性计算 人工智能 测试技术
2026年阿里云便宜云服务器推荐与选购指南
2026年阿里云推出史上最强优惠:打破新老用户壁垒,实现“新老同价、续费同价”。99元/年e实例、199元/年u1实例长期稳定;新用户可抢38元/年轻量服务器;企业享百万迁云补贴与GPU 4折。省钱避坑指南,助你轻松上云!
452 4
|
1月前
|
人工智能 监控 测试技术
AI智能体的开发流程
AI智能体开发需结构化推进:明确定义目标与角色,设计含规划、记忆、工具、模型的四大核心架构;借助LangChain/CrewAI等框架实现;通过基准测试与人工审核保障可靠性;最终部署并持续监控优化。初学者可从Coze等低代码平台入门。(239字)