当前位置:首页 > 技术 > 正文内容

MySQL 间隙锁详解与实战分析

访客 技术 2026年6月4日 1

间隙锁(Gap Lock)是 InnoDB 存储引擎中用于解决并发事务中幻读问题的一种重要机制。它作用于索引记录之间的"间隙",也可作用于第一条记录之前或最后一条记录之后的空间。

间隙锁的核心特性

间隙锁并不锁定具体的某条记录,而是锁定记录之间的空间或者边界区域,从而防止其他事务在此区间内插入新数据,进而避免幻读的发生。

间隙锁的应用场景

考虑如下 SQL:

SELECT c1 FROM t WHERE c1 BETWEEN 10 AND 20 FOR UPDATE;

这条语句不仅会对已有数据加锁,还会对 10 到 20 之间的间隙加锁,即使这些值并不存在于表中。这意味着任何试图插入值为 15 的操作都会被阻塞。

间隙锁的作用范围

  • 记录间间隙:两个相邻索引记录之间的空间。
  • 起始前间隙:第一条记录之前的无限空间。
  • 结尾后间隙:最后一条记录之后的无限空间。

间隙锁与索引类型的关系

当使用唯一索引进行精确查找时,InnoDB 只会加记录锁(Record Lock),不会触发间隙锁。例如:

SELECT * FROM child WHERE id = 100;

但如果该字段不是唯一索引,则仍会施加间隙锁。

不同隔离级别下的处理方式

隔离级别 是否启用间隙锁 说明
READ UNCOMMITTED 允许脏读,无需间隙锁支持。
READ COMMITTED 仅锁定实际访问的数据行。
REPEATABLE READ 默认使用间隙锁来防止幻读。
SERIALIZABLE 间接实现 通过表级锁替代间隙锁,完全串行化执行。

为什么需要间隙锁?

为了保证在可重复读隔离级别下,同一事务多次读取相同范围的结果保持一致,避免出现新增数据导致的"幽灵"现象。例如:

SELECT * FROM employees WHERE age > 30 FOR UPDATE;

此语句将锁定所有 age 大于 30 的记录及它们之间的间隙,防止其他事务插入满足条件的新纪录。

间隙锁的影响

  • 性能影响:增加系统开销,特别是在频繁插入数据的环境中。
  • 并发性下降:部分写入操作会被挂起等待锁释放。

实验验证:间隙锁的行为

以下是一组测试用例,演示间隙锁的具体行为:

环境准备

-- 表结构示例
CREATE TABLE orders (
  id INT PRIMARY KEY,
  order_amount DECIMAL(10,2),
  create_date DATETIME
);

案例一:基础范围查询

BEGIN;
SELECT * FROM orders WHERE id BETWEEN 3 AND 7 FOR SHARE;

此时会锁定 id 为 3 和 7 之间的间隙,同时也会锁定 id=7 后的所有空间(若它是最大值)。尝试插入 id=4 或 id=8 将被阻塞。

案例二:小于某个值的查询

BEGIN;
SELECT * FROM orders WHERE id < 3 FOR SHARE;

这次会锁定从负无穷到 id=3 的整个区间,包括前面的所有间隙。插入 id=-5 会被拒绝。

案例三:非边界情况

BEGIN;
SELECT * FROM orders WHERE id BETWEEN 3 AND 7 FOR SHARE;

如果表中还存在更大的 id 值(如 10),则 id=7 之后的间隙不会被锁定。

结论

间隙锁主要用于防止并发插入带来的幻读问题,在 REPEATABLE READ 隔离级别中尤为重要。但其副作用是可能降低系统的并发能力,因此在设计数据库应用时需权衡利弊。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。