【MYSQL】MYSQL 的学习教程(十三)之 MySQL的加锁规则

在这里插入图片描述

1. MySQL 加锁全局视角

MySQL 分成了 Server 层和存储引擎两部分,每当执行一个查询时,Server 层负责生成执行计划,然后交给存储引擎去执行。其整个过程可以这样描述:

  1. Server 层向 Innodb 获取到扫描区间的第 1 条记录
  2. Innodb 通过 B+ 树定位到扫描区间的第 1 条记录,然后返回给 Server 层
  3. Server 层判断是否符合搜索条件,如果符合则发送给客户端,不符合,则跳过。接着继续向 Innodb 要下一条记录
  4. Innodb 继续根据 B+ 树的双向链表找到下一条记录,会执行具体的 row_search_mvcc 函数做加锁等操作,返回给 Server 层
  5. Server 层继续处理该条记录,并向 Innodb 要下一条记录
  6. 继续不停执行上述过程,直到 Innodb 读到一条不符合边界条件的记录为止

通过上面这个过程,明白两个重要的认识:

  • Innodb 并不是一次性把所有数据找到,然后返回给 Server 层的,而是会循环很多次
  • row_search_mvcc 这个函数是做具体的加锁、加什么锁的重要逻辑,并且由于 Server 层与 Innodb 会循环多次,因此该函数也是会执行多次的

弄懂了上面两个认识,会对后续大家理解有很大帮助。例如:对于 select * from user where id >= 5 进行分析的时候,为什么会出现说第一次加锁是精确查询?它明明是范围查询呀!这是因为第一次是要寻找到 id = 5 的记录,对于 Innodb 来说,它就是精确查找,不是范围查找。随后找到 id = 5 的记录之后,就要找 id > 5 的记录了,此时就变成了范围查找了

2. MySQL 加锁规则

对于 RC 隔离级别,加的排他锁(X锁),是比较好理解的,哪里更新就锁哪里。RR 隔离级别加锁有一定的规则

锁规则一共包括:两个原则、两个优化和一个 bug

  1. 原则 1:加锁的基本单位都是 next-key lock。next-key lock(临键锁)是前开后闭区间
  2. 原则 2:查找过程中访问到的对象才会加锁
  3. 优化 1:索引上的等值查询,给唯一索引加锁的时候,next-key lock 退化为行锁(Record lock)
  4. 优化 2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock 退化为间隙锁(Gap lock)
  5. 一个 bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止

说明:

  • 对于原则 1 说的:加锁的基本单位是 Next-Key 锁,意思是默认都是先加上 Next-Key,之后根据 2 个优化点选择性退化为行锁或间隙锁
  • 对于原则 2 说的:访问到的对象才会加锁,意思是如果直接索引覆盖到了,不需要回表,那么就不会对聚簇索引加锁。这样的话,其他事务就可以对聚簇索引进行操作,而不会阻塞

测试数据:

CREATE TABLE `t`  (
  `id` int NOT NULL,
  `c` int NULL DEFAULT NULL,
  `d` int NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `c`(`c`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
INSERT INTO `t` VALUES (0, 0, 0);
INSERT INTO `t` VALUES (5, 5, 5);
INSERT INTO `t` VALUES (10, 10, 10);
INSERT INTO `t` VALUES (15, 15, 15);
INSERT INTO `t` VALUES (20, 20, 20);
INSERT INTO `t` VALUES (25, 25, 25);

在这里插入图片描述

3. 七个案例

分7个案例去分析哈:

  1. 等值查询间隙锁
  2. 非唯一索引等值锁
  3. 主键索引范围锁
  4. 非唯一索引范围锁
  5. 唯一索引范围锁 bug
  6. 普通索引上存在"等值"的例子
  7. limit 语句减少加锁范围

3.1 案例一:等值查询间隙锁

我们同时开启 A、B、C三个会话事务,如下:

在这里插入图片描述

发现事务 B 会阻塞等待,而 C 可以执行成功

分析流程:

  1. 在事务 A 中,要查找 id = 7 的记录,其查找过程为:从左到右查找 id 聚簇索引,依次对比 0、5 两个索引,发现不对。接着,对比 10 这个索引,发现 7 <10,于是停止搜索。根据原则 1,默认给其加上一个 Next-Key 锁,即 (5, 10]
  2. 同时根据优化 2,这是一个等值查询 (id=6),而 id=10 不满足查询条件。所以 next-key lock 退化成间隙 Gap 锁,因此最终加锁的范围是 (5,10)

3.2 案例二:非唯一索引等值锁

按顺序执行事务会话A、B、C,如下:

在这里插入图片描述

发现事务B可以执行成功,而 C 阻塞等待

分析流程:

  1. 在事务 A 中,要查找 c=5 的记录,其中 c 是非唯一索引。其查找过程为:从左到右查找 c 索引,找到了 c=5 的索引,根据原则 1,对其加 Next-Key 锁,即 (0,5]
  2. 由于普通索引可能重复,因此其还会继续往后搜索,接着搜索到 10,根据原则 2,访问到的都要加锁,因此再给其加 Next-Key 锁,即 (5,10]
  3. 根据优化2:等值判断,向右遍历,最后一个值 10 不满足 c = 5 这个等值条件,因此退化成间隙锁 (5,10)
  4. 根据原则 2 :只有访问到的对象才会加锁,事务 A 的这个查询使用了覆盖索引,没有回表,并不需要访问主键索引,因此主键索引上没有加任何锁,事务会话 B 是对主键 id 的更新,因此事务会话 B 的 update 语句不会阻塞

3.3 案例三:主键索引范围锁

按顺序执行事务会话A、B、C,如下:

在这里插入图片描述

事务 B:插入 id = 12 时阻塞;插入 id = 6 时顺利执行;
事务 C:阻塞

分析流程:

  1. 事务 A 开始执行的时候,要找到 id 为 10 的记录,于是从左到右找到了 id 为 10 的索引。根据原则 1 会给其加 Next-Key 锁,即 (5,10]
  2. 又因为 id 是主键,也就是唯一值,因此根据优化1:索引上的等值查询,给唯一索引加锁时,next-key lock 退化为行锁(Record lock)。所以只加了 id=10 这个行锁
  3. 接着继续进行范围查找,找到 id=15 这一行,继续加 Next-Key 锁 (10,15]。这时候 id=15 大于 11,因此其不再查找

事务会话 A 执行完后,加的锁是 id=10 这个行锁,以及临键锁 next-key lock(10,15]

3.4 案例四:非唯一索引范围锁

按顺序执行事务会话 A、B、C,如下:

在这里插入图片描述

发现事务会话 B 和事务会话 C 的执行 SQL 都被阻塞了

分析流程:

  1. 事务 A 开始执行的时候,要找到 id 为 10 的记录,根据原则 1 加了 Next-Key 锁,即 (5,10]。 由于索引 C 是非唯一索引,不符合优化1,因此不会退化为行锁
  2. 接着继续进行范围查找,找到 id=15 这一行停下来,因此还需要加 next-key lock (10,15]

3.5 案例五:唯一索引范围锁 bug

按顺序执行事务会话 A、B、C,如下:

在这里插入图片描述

事务 B 阻塞;事务 C 阻塞

分析流程:

  1. 事务 A 开始执行的时候, 0、5、10 都不满足条件,找到 id = 15 的行满足,根据原则1,会加上next-key lock(10,15]
  2. 因为 id 是主键,即唯一的,因此循环判断到 id = 15 这一行就应该停止了
  3. 根据一个 bug:InnoDB 会往前扫描到第一个不满足条件的行为止,直到扫描到 id = 20。而且由于这是个范围扫描,因此索引 id 上的 (15,20] 这个 next-key lock 也会被锁上

3.6 案例六:普通索引上存在"等值"的例子

插入一条数据:

insert into t values(28,10,66);

则 c 索引树如下:

在这里插入图片描述

c 索引值有相等的,但是它们对应的主键是有间隙的。比如(c=10,id=10)和(c=10,id=28)之间

按顺序执行事务会话A、B、C,如下:

在这里插入图片描述

事务 B 阻塞;事务 C 顺利执行

分析流程:

  1. 事务 A 开始执行的时候,要找到 c 为 10 的记录,根据原则 1,加一个(c=5,id=5) 到 (c=10,id=10)的 next-key lock(5, 10]
  2. 由于 c 是非唯一索引,会继续向右进行范围查找,直到碰到 (c=15, id=15) 这一行,循环才结束,会加一个 next-key lock(10, 15]。根据优化 2,这是一个等值查询,向右查找到了不满足条件的行,所以会退化成间隙锁 (10, 15)

在索引 c 上的加锁范围,就是下图灰色阴影部分的:

在这里插入图片描述

3.7 案例七:limit 语句减少加锁范围

事务A、B执行如下:

在这里插入图片描述

事务 B 顺利执行

分析流程:

  1. 事务 A 开始执行的时候,要找到 c 为 10 的记录,根据原则 1,加一个(c=5,id=5) 到 (c=10,id=10)的 next-key lock(5, 10]
  2. 因为明确加了limit 2的限制后,因此在遍历到 (c=10, id=30) 这一行之后,满足条件的语句已经有两条,循环就结束了

如下图所示:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/313944.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SGL-110型定时限过流继电器 额定电流5A 额定电压220V 交直流通用 板前接线

系列型号 LGY-110零序过电压继电器&#xff1b; LGL-110零序过电压继电器&#xff1b; LGL-110/AC零序过电压继电器&#xff1b; LGL-110零序过电流继电器 板前接线 &#xff11; 应用 LGL-110 型零序过电流继电器用作线路和电力设备的零序过电流保护。 LGY-110 型零序过…

WSL2-Ubuntu20.04-配置

WSL2-Ubuntu20.04-配置 安装wsl2安装Ubuntu20.04安装anacondaWSL2可视化&#xff08;VcXsrv&#xff09; 安装wsl2 wsl --install wsl -l -v # 版本查看 默认的都是 wsl2 &#xff08;如果是wsl1 就自行升级 wsl --update&#xff09; 官方教程 安装Ubuntu20.04 安装wsl2之后…

vcruntime140.dll已加载,但找不到入口点的处理方法分享

当遇到错误提示“vcruntime140.dll已加载&#xff0c;但找不到入口点”时&#xff0c;很多人可能会感到困惑&#xff0c;不知道如何去处理这个问题。不过没有必要紧张&#xff0c;在这里我会为大家详细解释 vcruntime140.dll 文件是什么&#xff0c;并指导大家如何高效地解决 v…

kafka除了作为消息队列还能做什么?

Kafka 最初是为大规模处理日志而构建的。它可以保留消息直到过期&#xff0c;并让各个消费者按照自己的节奏提取消息。 与其之前的竞品不同&#xff0c;Kafka 不仅仅是一个消息队列&#xff0c;它还是一个适用于各种情况的开源事件流平台。 让我们回顾一下流行的 Kafka 用例。 …

Win10子系统Ubuntu实战(一)

在 Windows 10 中安装 Ubuntu 子系统&#xff08;Windows Subsystem for Linux&#xff0c;简称 WSL&#xff09;有几个主要的用途和好处&#xff1a;Linux 环境的支持、跨平台开发、命令行工具、测试和验证、教育用途。总体而言&#xff0c;WSL 提供了一种将 Windows 和 Linux…

OpenAI 自带的检索功能好用吗?定量测评带你深度了解!

向量数据库的劲敌来了&#xff1f;又有一批赛道创业公司要倒下&#xff1f; …… 这是 OpenAI 上线 Assistant 检索功能后&#xff0c;技术圈传出的部分声音。原因在于&#xff0c;此功能可以为用户提供基于知识库问答的 RAG&#xff08;检索增强生成&#xff09; 能力。而此前…

Css样式制作图形倒影

该CSS样式是WebKit&#xff08;主要应用于Safari和其他基于WebKit的浏览器&#xff09;的特定前缀属性&#xff0c;用于实现元素内容的反射效果。具体解释如下&#xff1a; -webkit-box-reflect: 定义了一个盒反射效果&#xff0c;仅在支持WebKit的浏览器中生效。 below 15px&a…

springIoc依赖注入循环依赖三级缓存

springIoc的理解&#xff0c;原理和实现 控制反转&#xff1a; 理论思想&#xff0c;原来的对象是由使用者来进行控制&#xff0c;有了spring之后&#xff0c;可以把整个对象交给spring来帮我们进行管理 依赖注入DI&#xff1a; 依赖注入&#xff0c;把对应的属性的值注入到…

矩阵的秩-

一、定义、理解 非零子式的最高阶数。 如何理解&#xff1f;什么叫做非零子式的最高阶数&#xff1f;&#xff1f;&#xff1f; 举个例子&#xff1a;有一个5阶矩阵 首先什么叫子式&#xff1f; 例如2阶子式就是&#xff0c;任取某两行某两列组成的行列式&#xff0c;就叫…

【发票识别】支持pdf、ofd、图片格式的发票

背景 为了能够满足识别各种发票的功能&#xff0c;特地开发了当前发票识别的功能&#xff0c;当前的功能支持pdf、ofd、图片格式的发票识别&#xff0c;使用到的技术包括文本提取匹配、ocr识别和信息提取等相关的技术&#xff0c;用到机器学习和深度学习的相关技术。 体验 体…

论文精读:Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models

Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models Status: Reading Author: Chunrui Han, Haoran Wei, Jianjian Sun, Jinrong Yang, Jinyue Chen, Liang Zhao, Lingyu Kong, Xiangyu Zhang, Zheng Ge Institution: 中国科学院大学, 华中科技大学, 旷…

虚幻UE 材质-材质图层、材质图层混合

学习材质图层和材质图层混合的使用&#xff0c;便于节点扫盲。 文章目录 前言一、材质图层混合二、使用步骤总结 前言 材质混合我们之前用Bridge的插件进行混合过 而此次我们的材质混合使用UE自带的材质图层和材质图层混合来实现 一、材质图层混合 材质图层混合是一种允许将…

Vant4在Vue3.3中如何按需导入组件和样式

前言 最近我在Vue 3.3的项目中对Vant4做按需导入时&#xff0c;尽管按照Vant4的官方指南进行操作&#xff0c;但样式仍然无法正确加载。经过深入研究和多篇文章的比较&#xff0c;我终于找到了在Vue3中如何正确的按需导入Vant 4组件和样式的方法。由于Vue3.3和Vant4相对较新&am…

考古学家 - 华为OD统一考试

OD统一考试 分值: 200分 题解: Java / Python / C++ 题目描述 有一个考古学家发现一个石碑,但是很可惜发现时其已经断成多段。 原地发现N个断口整齐的石碑碎片,为了破解石碑内容,考古学家希望有程序能帮忙计算复原后的石碑文字组合数,你能帮忙吗? 备注: 如果存在石碑…

国产六核CPU商显板,三屏异显,米尔基于全志D9360开发板

芯驰D9-Pro 自主可控、安全可信的高性能商显方案 采用国产CPU&#xff1a;集成了6个ARM Cortex-A551.6GHz 高性能CPU和1个ARM Cortex-R5800MHz&#xff1b; 高性能的高安全HSM安全的处理器&#xff0c;支持TRNG、AES、RSA、SHA、SM2/3/4/9&#xff1b; 它包含100GFLOPS 3D G…

CRLF漏洞靶场记录

搭建 利用 docker 搭建 vulhub 靶场 git clone https://github.com/vulhub/vulhub.git 进入 /vulhub/nginx/insecure-configuration 目录 启动前关闭现有的 8080、8081、8082 端口服务&#xff0c;避免端口占用 docker-compose up -d 进入容器 docker exec -it insecure-…

Spring事务失效场景之类内部方法调用及解决方案

一、背景 在日常开发中&#xff0c;经常有需要使用事务来保证数据一致性的情况。简单点的话直接在方法上面加Transactional注解就可以了。 但这样存在一个问题&#xff0c;在整个业务方法层面加注解会把很多并不需要归入事务的操作也归入到了事务里面&#xff0c;这样会可能会…

uni-app修改头像和个人信息

效果图 代码&#xff08;总&#xff09; <script setup lang"ts"> import { reqMember, reqMemberProfile } from /services/member/member import type { MemberResult, Gender } from /services/member/type import { onLoad } from dcloudio/uni-app impor…

用通俗易懂的方式讲解大模型分布式训练并行技术:序列并行

近年来&#xff0c;随着Transformer、MOE架构的提出&#xff0c;使得深度学习模型轻松突破上万亿规模参数&#xff0c;传统的单机单卡模式已经无法满足超大模型进行训练的要求。因此&#xff0c;我们需要基于单机多卡、甚至是多机多卡进行分布式大模型的训练。 而利用AI集群&a…

杭州中科微 BDS/GNSS 全星座定位导航模块 ATGM332D-5N31使用笔记

一、BDS/GNSS 全星座定位导航模块 ATGM332D-5N31 介绍 ATGM332D-5N 系列模块是 12X16 尺寸的高性能 BDS/GNSS 全星座定位导航模块系列的总称。该系列模块产品都是基于中科微第四代低功耗 GNSS SOC 单芯片—AT6558&#xff0c;支持多种卫星导航系统&#xff0c;包括中国的 BDS&a…
最新文章