Mysql的行级锁到底锁住了哪些行

devtools/2025/3/10 12:14:43/

前置知识

首先明确明确几点:

  • Innodb的行级锁本质上锁的是索引记录!!因为Innodb表中的数据都是按主键索引(即使自己没有明确指定主键行,MySQL会默认选择一个唯一的非空索引作为聚簇索引,如果没有适合的非空唯一索引,则会创建一个隐藏的主键(row id)作为聚簇索引)组织起来的,数据都存储在叶子结点上。二级索引存储主键值,查询时需回表到主键索引获取数据。若通过二级索引更新,先锁二级索引条目,如果命中了索引覆盖这种情况,则不会再锁主键索引条目。若WHERE条件无可用索引,InnoDB会全表扫描(遍历主键索引),导致所有扫描的行(包括不符合条件的行)被加锁。在可重复读隔离级别下,还会添加间隙锁,可能退化为表级锁效果。
  • 只有在RR隔离级别才会有间隙锁。演示证明:

一个course表,cno为主键。预先插入一些数据

开启两个会话,隔离级别都设置为RR

接着会话1用加了写锁的select锁住了>=4002的索引记录

会话2尝试插入4003一行,被阻塞

说明会话1对4003这一间隙也加了锁。

接着将隔离级别都设为RC

会话1锁住>=4002的行记录

会话2插入4003,插入成功

会话2commit后,会话1再查询>=4002的记录

多出来了一行记录,也就是出现了幻读。从这也能看出RR的间隙锁解决了部分场景下的幻读问题。幻读问题可见另一篇博客:

Mysql的Innodb的RR隔离级别到底有没有解决幻读问题?_mysql中的rr隔离级别,到底有没有解决幻读问题-CSDN博客

明确这两点后,那么一条update(不只是update,还有加锁的select、delete都会加行级锁)语句到底锁住了哪些行?

加锁规则

(参考丁奇大佬的《mysql实战45讲》)

因为间隙锁在可重复读隔离级别下才有效,所以本篇文章接下来的描述,若没有特殊说明,默认是可重复读隔离级别。

具体场景的加锁规则

1. 唯一索引的等值查询
  • 记录存在:
SELECT * FROM user WHERE id = 10 FOR UPDATE; -- id 是唯一索引
  • 加锁:仅对 id=10 加 记录锁(X 锁)。
  • 记录不存在:
SELECT * FROM user WHERE id = 7 FOR UPDATE; -- 表中无 id=7 的记录
  • 加锁:锁定 id=7 所在的间隙(如 (5, 10))。
2. 非唯一索引的等值查询
  • 记录存在:
SELECT * FROM user WHERE age = 20 FOR UPDATE; -- age 是非唯一索引
  • 加锁:锁定 age=20 的 Next-Key Lock(如 (15, 20]),继续向右遍历到 age=25 时,退化为间隙锁 (20, 25)
  • 记录不存在:
SELECT * FROM user WHERE age = 22 FOR UPDATE; -- 表中无 age=22 的记录
  • 加锁:锁定 age=22 所在的间隙(如 (20, 25))。
3. 范围查询(唯一索引)
SELECT * FROM user WHERE id >= 10 AND id < 15 FOR UPDATE;
  • 加锁:
  1. 定位到 id=10,加 Next-Key Lock (5, 10],根据优化 1 退化为记录锁(仅锁 id=10)。
  2. 向右扫描到 id=15,加 Next-Key Lock (10, 15]
4. 无索引查询
UPDATE user SET name = 'Bob' WHERE name = 'Alice'; -- name 无索引
  • 加锁:全表扫描主键索引,对所有行加记录锁,并对所有间隙加间隙锁(等效于 表锁)。

其它

在RC级别下还有一个优化,即:语句执行过程中加上的行锁,在语句执行完成后,就要把“不满足条件的行”上的行锁直接释放了,不需要等到事务提交。


http://www.ppmy.cn/devtools/165998.html

相关文章

【架构艺术】变更风险观测的任务调度设计

在先前的文章中&#xff0c;对于变更风险观测的流程逻辑设计&#xff0c;有浅谈一小部分。但从宏观来讲&#xff0c;一个变更观测平台&#xff0c;需要对大量的观测任务做统一调度&#xff0c;这样才能把整个观测平台给支撑起来。因此&#xff0c;本文就简单分享一下&#xff0…

游戏引擎学习第141天

回顾上期内容并介绍今天的议程 我们之前做了一些音频混音的测试&#xff0c;目前的实现方式是每次播放一个新的声音时&#xff0c;都会完整加载整个音频文件。这导致当多个音频同时播放时&#xff0c;可能会出现混乱的声音效果。之前这样做是为了演示是否可以多次播放相同的音…

vue-cli3+vue2+elementUI+avue升级到vite+vue3+elementPlus+avue总结

上一个新公司接手了一个vue-cli3vue2vue-router3.0elementUI2.15avue2.6的后台管理项目&#xff0c;因为vue2在2023年底已经不更新维护了&#xff0c;elementUI也只支持到vue2&#xff0c;然后总结了一下vue3的优势&#xff0c;最后批准升级成为了vitevue3vue-router4.5element…

《OpenCV》—— dlib(换脸操作)

文章目录 dlib换脸介绍仿射变换在 dlib 换脸中的应用 换脸操作 dlib换脸介绍 dlib 换脸是基于 dlib 库实现的一种人脸替换技术&#xff0c;以下是关于它的详细介绍&#xff1a; 原理 人脸检测&#xff1a;dlib 库中包含先进的人脸检测器&#xff0c;如基于 HOG&#xff08;方向…

传输层协议

目录 一、深刻理解read和write &#xff08;1&#xff09;发送/接受缓冲区的存在 &#xff08;2&#xff09;缓冲区是什么样子的 二、UDP协议 &#xff08;1&#xff09;UDP协议报头格式&#xff1a; &#xff08;2&#xff09;UDP的缓冲区 三、TCP协议 &#…

【探商宝】大数据企业销售线索平台:销售型公司的战略转型引擎

一、市场现状与销售型公司的核心痛点 在数字经济高速发展的2025年&#xff0c;全球企业获客成本较五年前增长超过300%&#xff0c;而B2B销售线索的平均转化率仍徘徊在15%-20%之间。这一矛盾背后&#xff0c;折射出传统销售模式的三重困境&#xff1a; ​数据孤岛导致决策滞后…

大模型学习笔记------Llama 3模型架构之RMS Norm与激活函数SwiGLU

大模型学习笔记------Llama 3模型架构之RMS Norm与激活函数SwiGLU 1、归一化模块RMS Norm2、激活函数SwiGLU3、一些思考 上文简单介绍了 Llama 3模型架构。在以后的文章中将逐步学习并记录Llama 3模型中的各个部分。本文将首先介绍归一化模块RMS Norm与激活函数SwiGLU。 1、归…

揭开AI-OPS 的神秘面纱 第三讲(上)数据平台层技术架构与组件选型分析

今天我们延续继续进行第三讲分析 数据平台层技术架构与组件选型分析 (通用性视角) 数据平台层作为 AI-Ops 架构的核心支撑层&#xff0c;负责接收、存储、处理和管理来自数据采集层的海量运维数据。 数据平台层的通用性至关重要&#xff0c;它需要能够高效、可靠地处理 Metr…