当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL 事务隔离级别下间隙锁影响范围的分析方法

MySQL 事务隔离级别下间隙锁影响范围的分析方法

来源:17golang原创 2026-09-23 13:12:11 0浏览 收藏

MySQL InnoDB 里看到“插入被卡住”,先不要直接判断成表锁。更常见的原因是事务隔离级别、索引条件和扫描范围共同决定了间隙锁覆盖的区间。分析时按“隔离级别 → 实际使用的索引 → 区间前后的索引记录 → 锁等待方”四步还原,通常就能解释阻塞点。

官方参考:https://dev.mysql.com/doc/refman/8.4/en/innodb-locking.html

要点速览
  • InnoDB 默认是 REPEATABLE READ,范围型锁定读会使用间隙锁或临键锁防止范围内插入。
  • 唯一索引的完整等值条件通常只锁命中的索引记录;非唯一条件或范围扫描要看扫描到的索引区间。
  • 排查重点是锁在哪个索引上、阻塞哪个间隙,以及事务何时提交,而不是只看 SQL 表名。

先区分快照读和真正的锁定读

普通 SELECT 默认是非锁定一致性读,不会因为读到了某个范围就自动把插入挡住。SELECT ... FOR UPDATESELECT ... FOR SHARE,以及修改数据的 UPDATEDELETE 才会按照索引扫描获取锁。先在同一个会话查看隔离级别,避免把快照读和锁定读混在一起。

-- 查看当前会话的隔离级别;排查时优先确认会话值
SELECT @@SESSION.transaction_isolation;

-- 只在明确需要锁定范围时使用 FOR UPDATE
START TRANSACTION;
SELECT id, score FROM exam_result
WHERE score BETWEEN 80 AND 90
FOR UPDATE;
-- 业务处理完成后尽快提交,避免锁随事务长时间保留
COMMIT;

默认的 REPEATABLE READ 会在范围型锁定读中使用 next-key locking;切换到 READ COMMITTED 后,普通搜索和索引扫描通常不再使用间隙锁,但外键检查和重复键检查仍可能需要它。

按索引顺序把间隙锁画成区间

帮助读者对照隔离级别、索引条件和插入行为做判断。
图2:隔离级别与索引条件关系说明图,不是运行截图或锁监控结果。

间隙锁锁的不是一行数据,而是索引顺序中两条记录之间“不允许插入”的位置。临键锁则是“索引记录锁 + 该记录之前的间隙锁”。假设索引值为 10、11、13、20,可能观察到的临键区间是 (-∞,10](10,11](11,13](13,20](20,+∞)。最后一个区间对应最大值之后的 supremum 伪记录。

MySQL InnoDB 索引值10 11 13 20与间隙锁和临键锁区间关系说明图
图1:索引区间结构说明图,展示临键锁如何覆盖记录前的间隙。

因此,WHERE score BETWEEN 80 AND 90 FOR UPDATE 是否阻塞新插入,不能只看结果集中返回了几行,还要看优化器沿哪个索引扫描、扫描从哪条记录开始、在哪条记录结束。没有合适索引时,扫描范围和锁持有量都可能扩大。

唯一等值与范围条件要分开判断

完整使用唯一索引做等值查找,例如主键 id = 100,InnoDB 通常只需要锁住命中的索引记录,不必锁住它之前的间隙。若唯一索引只使用了部分列,或者条件落在非唯一索引、范围谓词上,就不能套用这个结论。

条件常见锁范围插入判断
完整唯一索引等值记录锁为主邻近间隙通常可插入
非唯一索引等值扫描到的记录及前方间隙可能阻塞相同范围的新值
范围条件索引扫描区间的间隙/临键锁区间内插入可能等待
READ COMMITTED 普通扫描通常只保留记录锁更容易插入,但要接受幻读边界

这个表只能作为定位起点。真正结论要用 EXPLAIN 确认索引和访问类型,再用锁等待信息确认实际持锁对象。

用两个会话复现“插入等待”

准备一个有索引的表。会话 A 先锁定分数区间但不提交,会话 B 尝试插入区间内的新分数;如果 B 等待,说明它撞上的是 A 扫描范围设置的抑制性间隙锁,而不一定是某一条已存在的行。

-- 会话 A:锁住索引范围,故意保持事务未提交
START TRANSACTION;
SELECT id FROM exam_result
WHERE score BETWEEN 80 AND 90
FOR UPDATE;

-- 会话 B:新值落入同一索引区间时可能等待
START TRANSACTION;
INSERT INTO exam_result(id, score) VALUES (901, 85);
-- 这里的等待对象应结合 data_locks 判断,不要只看客户端卡顿
ROLLBACK;

复现时同时记录 SHOW CREATE TABLEEXPLAIN 和两会话的提交时间。若谓词没有命中预期索引,先解释“实际扫描了什么”,再讨论锁范围;否则很容易把索引设计问题误判为隔离级别问题。

用锁等待信息收敛处理方案

MySQL 8.4 可从 Performance Schema 的 data_locksdata_lock_waits 观察等待关系。重点看阻塞事务、请求事务、表名、索引名和锁类型;事务是否长时间不提交,往往比“是不是间隙锁”更直接地决定事故持续时间。

-- 查看等待边:谁在等、谁在阻塞
SELECT w.REQUESTING_ENGINE_TRANSACTION_ID AS waiting_trx,
       w.BLOCKING_ENGINE_TRANSACTION_ID AS blocking_trx
FROM performance_schema.data_lock_waits AS w;

-- 收敛方案:缩小索引范围、缩短事务、提前提交
-- 只有业务允许出现幻读时,才评估 READ COMMITTED
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

生产环境的判断清单是:索引是否覆盖过滤条件;是否能把锁定读改成唯一等值;事务是否夹带了网络调用;是否必须保持范围内不可插入;切换隔离级别后是否接受幻读和日志格式约束。先缩短持锁时间,再考虑放宽隔离级别。

常见问题

间隙锁会锁住一整张表吗?

它锁的是索引间隙,范围过大或缺少合适索引时效果可能接近“谁都插不进去”,但概念上仍不是表锁。

两个事务能同时持有同一间隙锁吗?

间隙锁是抑制插入的锁,不同事务的间隙锁可以共存;真正插入时才会与该间隙上的抑制关系发生等待。

把隔离级别改成 READ COMMITTED 就一定解决吗?

不一定。它通常减少普通扫描的间隙锁,但外键和重复键检查仍可能加锁,记录锁冲突和长事务也不会自动消失。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
奶油黄纸页手机壁纸用极简纸张纹理承载日期信息奶油黄纸页手机壁纸用极简纸张纹理承载日期信息
上一篇
奶油黄纸页手机壁纸用极简纸张纹理承载日期信息
Go errors.As提取自定义错误类型的分层处理方案
下一篇
Go errors.As提取自定义错误类型的分层处理方案
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    187次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    243次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    201次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    183次使用
  • CMMLU中文大模型评估基准:功能、使用教程与应用场景解析
    CMMLU
    深入了解CMMLU中文评估基准,涵盖67个学科主题,提供数据集下载、Zero-shot/Five-shot评估方法及排行榜,助力优化中文语言模型性能。
    172次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码