MySQL记录锁与间隙锁的区别及应用场景
记录锁只会锁住已经存在的索引记录,间隙锁则用于锁定两个索引值之间的空白区间以阻止新数据插入;当使用非唯一索引进行等值查询时,二者通常会组合成临键锁。要准确判断 MySQL InnoDB 当前使用的是哪种锁,需要通过SHOW ENGINE INNODB STATUS确认,而且具体加锁方式还会受到事务隔
记录锁只会锁住已经存在的索引记录,间隙锁则用于锁定两个索引值之间的空白区间以阻止新数据插入;当使用非唯一索引进行等值查询时,二者通常会组合成临键锁。要准确判断 MySQL InnoDB 当前使用的是哪种锁,需要通过SHOW ENGINE INNODB STATUS确认,而且具体加锁方式还会受到事务隔离级别与索引类型的共同影响。

记录锁只锁已存在的索引行,不会锁定索引间隙
记录锁(Record Lock)是 InnoDB 中真正意义上“锁某一行”的最小粒度锁,但它锁住的并不是物理数据行本身,而是该行在**聚簇索引或二级索引中的对应索引记录**。只要 SQL 条件能够命中索引,尤其是主键索引或唯一索引,并且精确匹配到某条已存在的数据,InnoDB 通常只会加记录锁。
常见触发场景:
SELECT * FROM users WHERE id = 10 FOR UPDATE;——id是主键,命中后只锁该条索引记录UPDATE orders SET status = 'paid' WHERE order_no = 'ORD-2026-001';——order_no是唯一索引,也只会锁对应记录
关键点:如果没有走索引,MySQL InnoDB 的加锁范围可能显著扩大;如果查询没有找到目标记录,也不会产生记录锁——此时更有可能出现的是间隙锁。
间隙锁只锁“空白区间”,核心作用是防止插入新数据
间隙锁(Gap Lock)不会锁住任何真实存在的数据行,它锁定的是**两个索引值之间的空隙范围**,通常可以表示为左开右开的区间,例如 (10, 20)。它的主要目的只有一个:阻止其他事务在这个索引区间内执行 INSERT,从而避免幻读问题。
典型触发条件:
- 事务隔离级别通常需要是
REPEATABLE READ(在READ COMMITTED下默认不会启用大多数间隙锁) - 查询使用了**非唯一索引**或**范围查询条件**,并且扫描范围覆盖到了索引间隙
- 例如:
SELECT * FROM users WHERE age BETWEEN 25 AND 35 FOR UPDATE;—— 即使表里不存在age=28的记录,也可能锁住(25, 35)这段间隙
需要注意的是:SELECT ... FOR UPDATE、UPDATE、DELETE 都可能触发间隙锁,而普通的 SELECT(一致性非锁定读)通常不会加这种锁。
等值查询非唯一索引时,记录锁和间隙锁往往会同时出现
这是 MySQL 锁机制实战中最容易让人困惑的地方之一。只要查询条件基于非唯一索引进行等值匹配(例如 WHERE status = 'pending'),InnoDB 加的通常就不只是单纯的记录锁:它会先对每个命中的索引记录加锁,再把这些记录前后的索引间隙一并锁住,最终形成的就是临键锁(Next-Key Lock)。
举例说明:
- 表
orders上有非唯一索引idx_status(status),当前存在status='pending'的记录,对应索引值分别为:20、25、30 - 执行
SELECT * FROM orders WHERE status = 'pending' FOR UPDATE; - 实际加锁范围可能包括:
(15,20]、(20,25]、(25,30]、(30,35](假设相邻索引值为 15 和 35)
也就是说,看起来你只是锁住了三条 pending 记录,实际上连这些记录之间的空隙,以及前后相邻索引值之间的区域也一起被锁住了。这也是为什么 MySQL 中看似简单的等值查询,在高并发场景下反而容易造成插入阻塞。
判断当前到底加了哪种锁,要看 SHOW ENGINE INNODB STATUS 输出
执行完相关加锁 SQL 后,可以在另一个会话中运行 SHOW ENGINE INNODB STATUSG,重点查看 TRANSACTIONS 段中的 RECORD LOCKS 相关内容:
- 包含
locks rec but not gap→ 表示纯记录锁 - 包含
locks gap before rec→ 表示间隙锁(或临键锁中的间隙部分) - 同时出现
locks rec but not gap和locks gap before rec→ 通常说明表现为临键锁
不要只依赖 explain 或执行计划去推测锁类型——真正可靠的判断依据,是 INNODB STATUS 中展示的锁结构信息,这才是 MySQL 实际加锁行为的直接证据。
最容易被忽略的一点是:间隙锁是否会出现,根本上取决于事务隔离级别和索引类型,而不只是 SQL 写法本身。比如同样一句 WHERE age = 25,在 READ COMMITTED 下,可能根本不会触发间隙锁;但如果切换到 REPEATABLE READ,就有可能把整段空白索引区间一起锁住。因此在系统上线前,一定要在目标数据库隔离级别下实际验证锁行为,这一步非常关键,不能省略。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
Redis是什么:核心特性、架构与应用场景解析
Redis是一款基于内存的键值型NoSQL数据库,以超高读写速度和丰富的数据结构著称。本文系统梳理Redis的核心特性、架构组成、性能优势及典型应用场景,并通过与Memcached、MySQL、MongoDB的对比,帮助开发者快速判断Redis是否适合当前业务需求。
Windows 安装 MongoDB 完整图文教程
本文详细介绍在 Windows 系统上安装 MongoDB 的完整流程。从官网下载 MSI 安装包开始,逐步演示自定义安装路径、配置 Windows 服务、跳过 MongoDB Compass 等关键选项,并提供通过系统服务列表验证安装是否成功的方法,帮助开发者快速搭建本地 MongoDB 环境。
Linux 安装 MongoDB 完整指南:依赖配置、环境变量与服务启动
本文详解在 Linux 系统下安装 MongoDB 的完整流程,涵盖依赖包安装、二进制包下载解压、环境变量配置、数据与日志目录创建及服务启动验证。通过标准化命令与路径说明,帮助开发者快速完成部署并确认服务状态。
MacOS安装MongoDB完整教程
本文介绍在MacOS系统下安装MongoDB的完整流程,涵盖下载、解压、目录配置、环境变量设置及服务启动。通过明确的命令与参数说明,帮助开发者快速完成环境搭建并验证安装结果。
Ubuntu系统安装与配置Redis完整指南
本文详解在Ubuntu系统中安装Redis的两种主流方式:apt在线安装与源码编译安装。涵盖版本选择逻辑、服务启停与状态检查、连接验证方法,以及在线练习工具与桌面GUI客户端的对比与使用建议,帮助开发者快速搭建并验证Redis运行环境。
- 热门数据榜
1
2
3
4
5
6
7
8
9
10
相关攻略
2026-09-01 06:20
2026-09-01 06:20
2026-09-01 06:20
2026-09-01 06:19
2026-09-01 06:19
2026-09-01 06:19
2026-09-01 06:18
2026-09-01 06:18
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

