Mysql幻读

幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。


幻读仅专指“新插入的行”


在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。因此,幻读在“当前读”下才会出现。


当前读的规则,就是要能读到所有已经提交的记录的最新值

  • 产生幻读的原因

行锁只能锁住行,但是新插入记录这个动作,要更新的是记录之间的“间隙”,新插入记录行还不存在,不存在也就加不上行锁。

  • 间隙锁 (Gap Lock)

行锁,分成读锁和写锁。写锁与写锁、写锁与读锁都是冲突的,也就是说,跟行锁有冲突关系的是“另外一个行锁”


跟间隙锁存在冲突关系的,是“往这个间隙中插入一个记录”这个操作


  • next-key lock

间隙锁和行锁合称 next-key lock,每个 next-key lock 是前开后闭区间。

CREATE TABLE `t` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `c` (`c`)
) ENGINE=InnoDB;

insert into t values(0,0,0),(5,5,5),
(10,10,10),(15,15,15),(20,20,20),(25,25,25);

如果用 select * from t for update 要把整个表所有记录锁起来,就形成了 7 个 next-key lock,分别是 (-∞,0]、(0,5]、(5,10]、(10,15]、(15,20]、(20, 25]、(25, +supremum]。


因为 +∞是开区间,InnoDB 给每个索引加了一个不存在的最大值 supremum

等值查询的间隙锁
加锁单位是 next-key lock,session A 加锁范围就是 (5,10];
等值查询 (id=7),而 id=10 不满足查询条件,next-key lock 退化成间隙锁,因此最终加锁的范围是 (5,10)。
session B 要往这个间隙里面插入 id=8 的记录会被锁住,但是 session C 修改 id=10 这行是可以的

只加在非唯一索引上的锁
session A 要给索引 c 上 c=5 的这一行加上读锁
加锁单位是 next-key lock,因此会给 (0,5] 加上 next-key lock。
c 是普通索引,因此仅访问 c=5 这一条记录是不能马上停下来的,需要向右遍历,查到 c=10 才放弃。访问到的都要加锁,因此要给 (5,10] 加 next-key lock。
等值判断,向右遍历,最后一个值不满足 c=5 这个等值条件,因此退化成间隙锁 (5,10)。
只有访问到的对象才会加锁,这个查询使用覆盖索引,并不需要访问主键索引,所以主键索引上没有加任何锁, session B 的 update 语句可以执行完成。但 session C 要插入一个 (7,7,7) 的记录,就会被 session A 的间隙锁 (5,10) 锁住。


lock in share mode 只锁覆盖索引,但是如果是 for update 就不一样了。 执行 for update 时,系统会认为你接下来要更新数据,因此会顺便给主键索引上满足条件的行加上行锁。

主键索引上范围查询的锁
找到第一个 id=10 的行,因此本该是 next-key lock(5,10],主键 id 上的等值条件,退化成行锁,只加了 id=10 这一行的行锁。
范围查找就往后继续找,找到 id=15 这一行停下来,因此需要加 next-key lock(10,15]。

非唯一索引范围锁
c=10 定位记录的时候,索引 c 上加了 (5,10] 这个 next-key lock 后,由于索引 c 是非唯一索引,不会蜕变为行锁,因此最终 sesion A 加的锁是,索引 c 上的 (5,10] 和 (10,15] 这两个 next-key lock。
for update 锁,c=10,c=15 对应主键 10,15 加行锁

唯一索引范围锁的bug
索引 id 上加 (10,15] 这个 next-key lock,id 有小于这个范围,会往前扫描到第一个不满足条件的行为止,也就是 id=20。因此索引 id 上的 (15,20] 这个 next-key lock 也会被锁上。

insert into t values(30,10,30);

非唯一索引等值
非唯一索引等值
session A 在遍历的时候,先访问第一个 c=10 的记录。这里加的是 (c=5,id=5) 到 (c=10,id=10) 这个 next-key lock。
session A 向右查找,直到碰到 (c=15,id=15) 这一行,循环才结束。等值查询,向右查找到了不满足条件的行,所以会退化成 (c=10,id=10) 到 (c=15,id=15) 的间隙锁。
c 上加锁范围 (5,10]、(10,10]、(10,15)—> (5,15)

limit语句加锁
session A 的 delete 语句加了 limit 2,因此在遍历到 (c=10, id=30) 这一行之后,满足条件的语句已经有两条,循环就结束了。
索引 c 上的加锁范围就变成了从(c=5,id=5) 到(c=10,id=30) 这个前开后闭区间
带limit2的加锁效果

next-key
session A 启动事务后执行查询语句加 lock in share mode,在索引 c 上加了 next-key lock(5,10] 和间隙锁 (10,15);
session B 的 update 语句也要在索引 c 上加 next-key lock(5,10] ,进入锁等待
然后 session A 要再插入 (8,8,8) 这一行,被 session B 的间隙锁锁住。由于出现了死锁,InnoDB 让 session B 回滚。

session B 的“加 next-key lock(5,10] ”操作,实际上分成了两步,先是加 (5,10) 的间隙锁,加锁成功;然后加 c=10 的行锁,这时候才被锁住的。


间隙锁是在可重复读隔离级别下才会生效的
间隙锁和 next-key lock 的引入,解决了幻读的问题,但间隙锁的引入,可能会导致同样的语句锁住更大的范围,影响了并发度的。

加锁规则

next-key lock ,具体执行的时候,是要分成间隙锁和行锁两段来执行的。

  • 可重复读隔离级别 (repeatable-read)

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

  • 读提交隔离级别
    值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock 退化为间隙锁。**

5、范围查询会访问到不满足条件的第一个值为止(唯一索引也一样)。

  • 读提交隔离级别

语句执行过程中加上的行锁,在语句执行完成后,就要把“不满足条件的行”上的行锁直接释放了,不需要等到事务提交。

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

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

相关文章

【JavaEE网络】HTTP/HTTPS协议的工作原理与格式详解

目录 HTTP/HTTPSHTTP是什么理解“应用层协议”理解HTTP协议的工作过程HTTP协议格式 HTTP/HTTPS HTTP是什么 应用层,一方面是需要自定义协议,一方面也会用到一些现成的协议 HTTP及HTTPS是应用层重点协议 使用浏览器,打开网站,这…

自动化运维工具——Ansible

一、Ansible的概念: 1.Ansible的介绍: Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以…

OpenHarmony 实战开发(南向)-Docker编译环境搭建

Docker环境介绍 OpenHarmony为开发者提供了两种Docker环境,以帮助开发者快速完成复杂的开发环境准备工作。两种Docker环境及适用场景如下: 独立Docker环境:适用于直接基于Ubuntu、Windows操作系统平台进行版本编译的场景。 基于HPM的Docker…

2024车载测试还有发展吗?

2024年已过接近1/4了,你是不是还在围观车载测试行业的发展? 现在入车载测试还来得及吗? 如何高效学习车载测试呢? 首先我们看一下车载测试行情发展,通过某大平台,我们后去数据如下: 这样的数据可以预估一下未来车载测试还是会持续发展. 随着科技的发展和汽车行业的不断创新,…

第08章 IP分类编址和无分类编址

8.1 本章目标 了解IP地址的用途和种类了解分类编址和无分类编址区别掌握IP地址、子网掩码、网关概念及使用掌握子网划分及超网划分方法掌握无分类编址的改变和使用 8.2 IP地址的用途和种类 分类编址:造成地址的浪费,以及地址不够用;无分类编…

labview技术交流-字符串数组连接成字符串

应用场景 我们可能需要将一维的字符串数组转换成一整条字符串,然后方便记录在数据库或表格中的一个单元格中。 代码展示 方案一 我们使用for循环完成这样的功能需求,见下图: 这种方案可能相对基础和普通,但是它更方便和易于扩展…

在Flask中使用Celery完成异步和定时任务(Flask、Celery、Redis)

编程目标 通过使用Flask和Celery,实现一个简单的Web应用程序,能够接收HTTP POST请求,并异步发送电子邮件。 说明 使用Flask创建一个简单的Web应用程序,包含一个HTTP POST路由,用于接收发送电子邮件的请求。使用Cele…

【Java SE】对象的比较

🥰🥰🥰来都来了,不妨点个关注叭! 👉博客主页:欢迎各位大佬!👈 本期内容满满干货,将会深入介绍对象与对象之间是如何进行比较的,我们知道基本数据类型是可以直…

使用 docker-compose 搭建个人博客 Halo

说明 我这里使用的是 Halo 作为博客的工具,毕竟是开源了,也是使用 Java 写的嘛,另外一点就是使用 docker 来安装(自动挡,不用自己考虑太多的环境因素),这样子搭建起来更快一点,我们…

【STM32 |新建一个工程】基于标准库(库函数)新建工程

目录 STM32开发方式 库函数文件夹 建工程步骤 库函数工程建立 建立工程总结 STM32开发方式 目前stm32的开发方式主要有基于寄存器的方式、基于标准库的方式(库函数的方式)、基于HAL库的方式基于库函数的方式是使用ST官方提供的封装好的函数&…

17、线上系统中垃圾回收参数的精准调校指南

17.1、前文回顾 在上一篇文章中,我们已经通过逐步的图解方式,详细解释了CMS垃圾回收的运行机制。简单来说,CMS垃圾回收器采用了四个阶段来进行垃圾回收,以尽量避免长时间的“Stop the World”现象。这四个阶段分别是:初始标记、并发标记、重新标记和并发清理。 在初始标…

AlphaFold 3 可以预测所有生命分子的结构和相互作用

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

《二十二》Qt 音频编程实战---做一个音频播放器

1.UI界面制作 作为一个音乐播放器,最基础的肯定就是播放、暂停、上一首以及下一首,为了使这个界面好看一点,还加入了音量控制、进度条、歌曲列表等内容,至于这种配色和效果好不好看,我也不知道,个人审美一如…

【Java基础】数学相关的方法

基本方法 Return TypeFunctionDescriptionstatic doublerandom()返回值为 double&#xff0c;值为正号&#xff0c; ≥0.0 <1.0static 数值类型abs(数值类型 a)返回值为a的绝对值static doublepow(double a, double b)将第一个参数的值返回到第二个参数的幂static doublesq…

Taro 快速开始

大家好我是苏麟 , 今天聊聊Trao. 官网 : Taro 介绍 | Taro 文档 (jd.com) 点击快速开始 全局安装 CLI 初始化一个项目 选择配置 : 根据自己需求选择 安装失败先不用管 , 用前端工具打开项目 npm install 安装 , 显示安装失败 怎么解决 ? : 查看报错信息 百度 , 问 AI 工具 运…

第十讲:指针(2)

第十讲&#xff1a;指针&#xff08;2&#xff09; 1.对于数组名的理解1.1验证数组名就是数组首元素的地址1.2sizeof数组名和&数组名1.2.1sizeof数组名1.2.2&数组名 2.使用指针访问数组3.数组传参的本质4.冒泡排序5.二级指针6.指针数组7.指针数组模拟二维数组 这一讲讲…

TODESK怎么查看有人在远程访问

odesk怎么查看有人在远程访问 Todesk作为一款远程桌面控制软件&#xff0c;为用户提供了便捷的远程访问与控制功能。但在享受这种便利的同时&#xff0c;许多用户也关心如何确保自己设备的安全&#xff0c;特别是如何知道是否有人在未经授权的情况下远程访问自己的电脑。本文将…

TODESK远程开机的原理

在现代计算机技术飞速发展的背景下&#xff0c;远程控制软件成为我们日常工作中不可或缺的工具。其中&#xff0c;ToDesk作为一款高效且易用的远程控制软件&#xff0c;备受用户青睐。那么&#xff0c;ToDesk远程开机的原理是什么呢&#xff1f;本文将为你揭晓这个秘密。 KKVie…

《TAM》论文笔记(上)

原文链接 [2005.06803] TAM: Temporal Adaptive Module for Video Recognition (arxiv.org) 原文代码 GitHub - liu-zhy/temporal-adaptive-module: TAM: Temporal Adaptive Module for Video Recognition 原文笔记 What&#xff1a; TAM: Temporal Adaptive Module for …

Disk Doctor for Mac 免激活版:数据安全守卫者

数据丢失是每个人都可能遇到的问题&#xff0c;但Disk Doctor for Mac能让这个问题迎刃而解。这款强大的数据恢复软件&#xff0c;能迅速找回因各种原因丢失的数据。 Disk Doctor采用先进的扫描技术&#xff0c;能深入剖析磁盘&#xff0c;找到并恢复被删除或损坏的文件。同时&…
最新文章