MySQL核心知识学习之路(7)
作为一个后端工程师,想必没有人没用过数据库,跟我一起复习一下MySQL吧,本文是我学习《MySQL实战45讲》的总结笔记的第七篇,总结了MySQL是如何解决幻读的。
上一篇:MySQL核心知识学习之路(6)
1 关于幻读
我们都知道MySQL的默认隔离级别是可重复读(点此复习MySQL的事务隔离),它仍然存在一个问题:幻读。

啥是幻读?
幻读指在同一个事务中,存在前后两次查询同一个范围的数据,但是第二次查询却看到了第一次查询没看到的行。
啥时候会出现幻读?
事务的隔离级别为可重复读,并且是当前读。
select * from t where id =1; -- 属于快照读。
select * from t where id =1 for update; -- 属于当前读。
一般情况下,幻读仅指新插入的行。
为何会出现幻读?
因为行锁只能锁定存在的行,针对新插入的操作没有限定。
幻读会带来啥问题?
对行锁语义的破坏 和 破坏了数据一致性。
如何解决幻读呢?
最简单的方法就是:升级事务隔离级别到可串行化,但这会让MySQL失去并发处理能力。
加之现有的行锁也解决不了幻读,因为即使锁住所有记录,还是阻止不了插入新数据。
所以,MySQL InnoDB引擎创造了一种新的锁,目的是锁住记录之间的“间隙”,且看下一部分的介绍。
2 间隙锁(gap lock)
啥是间隙锁?
顾名思义,间隙锁,锁的就是两个值之间的空隙。
比如下图所示的某张表t,在该表主键索引(id)上插入了6个记录(0,5,10,15,20,25),因此产生了7个间隙。
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);

图片来源:林晓斌《MySQL实战45讲》
间隙锁是专门用于解决幻读这种问题的锁,它锁了行与行之间的间隙,这样就能够阻塞新插入的操作。
因此,划重点:当MySQL InnoDB引擎在一行行扫描的过程中,不仅会给行加上行锁,还会给行的两边的空隙也加上间隙锁。
补充:间隙锁之间是不冲突的,跟间隙锁存在冲突关系的只是“往这个间隙中插入一个记录”的操作。
注意事项
间隙锁在可重复读级别下才是有效的(换句话说,如果调整隔离级别为读提交就没有间隙锁了)。
间隙锁的引入也带来了一些新的问题,比如:降低并发度,可能导致死锁。
3 next-key lock
由于间隙锁(gap lock)仍在存在一些问题,可能会降低并发度和仍然可能导致死锁。因此,MySQL InnoDB为间隙锁引入了一个补充:next-key lock。
那么,问题来了:啥是next-key lock?
所谓next-key lock,它是间隙锁和行锁的合体,每个next-key lock都是前开后闭区间,如 (0,5]。
间隙锁都是开区间,如 (0,5)。
next-key lock帮助MySQL在默认隔离级别下解决了幻读问题,因此它也是MySQL加锁的基本单位。
MySQL加锁的原则
(1)加锁的基本单位是 next-key lock
(2)查找过程中访问到的对象才会加锁
该原则适用的前提条件为:
MySQL版本:5.x系列<=5.7.24,8.0系列<=8.0.13,且只有在可重复读隔离级别下(切换到读提交的话就只剩下行锁了)。
MySQL加锁的优化
索引上的等值查询,如果是给唯一索引加锁,此时next-key lock 退化为行锁。
索引上的等值查询,如果不是唯一索引,需要向右遍历访问到第一个值不满足等值条件的时候,此时next-key lock 退化为间隙锁。
MySQL加锁的Bug
唯一索引上的范围查询会访问到第一个不满足条件的值为止。
4 小结
本文总结了MySQL的InnoDB引擎是如何解决幻读问题的,即通过 间隙锁 + 行锁组成的next-key lock来实现的。
参考资料
林晓斌(丁奇),《MySQL实战45讲》
扫码订阅《MySQL实战45讲》


MySQL核心知识学习之路(7)的更多相关文章
- 零基础的学习者应该怎么开始学习呢?Python核心知识学习思维分享
近几年,Python一路高歌猛进,成为最受欢迎的编程语言之一,受到无数编程工作者的青睐. 据悉,Python已经入驻部分小学生教材,可以预见学习Python将成为一项提高自身职业竞争力的必修课.那么零 ...
- MySQL索引知识学习笔记
目录 一.索引的概念 二.索引分类 三.索引用法 四 .索引架构简介 五.索引适用的情况 六.索引不适用的情况 继我的上篇博客:Oracle索引知识学习笔记,再记录一篇MySQL的索引知识学习笔记,本 ...
- MYSQL+PHP的学习之路
MYSQL+PHP 先从MYSQL开始吧 第一步:SQL语句基础 1.书籍 2.网站: 这个网站在线测试和考试http://sqlzoo.net/wiki/SELECT_basics/zh 3.学习过 ...
- mysql 核心知识要点
整体知识介绍:mysql基本操作和使用,mysql优化(索引,分表等),mysql部署(读写分离,负载均衡等) 数据库基本介绍:数据库概念,常用数据库,web应用三大软件分工,PHP动态语言特点(处理 ...
- MySQL核心知识
MySQL常用的命令 启动:net start mySql; 进入:mysql -u root -p/mysql -h localhost -u root -p databaseName; 列出数据库 ...
- Webwork 学习之路【03】核心类 ServletDispatcher 的初始化
1. Webwork 与 Xwork 搭建环境需要的的jar 为:webwork-core-1.0.jar,xwork-1.0.jar,搭建webwork 需要xwork 的jar呢?原因是这样的,W ...
- MySQL学习之路(一)——初涉MySQL。
MySQL学习之路(一) 1.1MySQL的概述 MySQL由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一个开源的关系型数据库管理系统. MySQL分为社区版和企业版. 1 ...
- Docker 与 K8S学习笔记(二)—— 容器核心知识梳理
本篇主要对容器相关核心知识进行梳理,通过本篇的学习,我们可以对容器相关的概念有一个全面的了解,这样有利于后面的学习. 一.什么是容器? 容器是一种轻量级.可移植.自包含的软件打包技术,使应用程序可以在 ...
- 阿里封神谈hadoop学习之路
阿里封神谈hadoop学习之路 封神 2016-04-14 16:03:51 浏览3283 评论3 发表于: 阿里云E-MapReduce >> 开源大数据周刊 hadoop 学生 s ...
- 13本热门书籍免费送!(Python、SpingBoot、Entity Framework、Ionic、MySQL、深度学习、小程序开发等)
七月第一周,网易云社区联合清华大学出版社为大家送出13本数据分析以及移动开发的书籍(Python.SpingBoot.Entity Framework.Ionic.MySQL.深度学习.小程序开发等) ...
随机推荐
- Visual Studio 2017 导出 ASP.NET Core 项目模版项目文件为空
问题重现 VS 2017 针对 ASP.NET Core 导出模版功能有问题 解决办法 visual-studio-2017-templates-and-the-missing-content 目前官 ...
- Koin 依赖注入: 在 Android 模块化项目中定义 Room 数据库的最佳实践
前置 本文发布于个人小站:https://wavky.top/db-in-multi-modules/ 欢迎移步至小站,关注更多技术分享,获得更佳阅读体验 (不保证所有技术文章都会同步发表到博客园) ...
- thinkphp 3.2的一些笔记
1.基础操作"::"语法.A()方法 2.php与js混写实现ajax无刷新执行控制器的方法 3.session的使用,通过session验证用户登录状态 4.使用UTFWry.d ...
- 反悔贪心&局部调整法学习笔记
一.什么是反悔贪心 反悔贪心就是在普通贪心的过程中"反悔",从而使得一些看似不太好贪心的题变成贪心可做题. 二.反悔贪心普遍流程 就是先使用一个好想的贪心策略,使用优先队列进行维护 ...
- 【SQL 周周练】爬取短视频发现数据缺失,如何用 SQL 填充
大家好,我是"蒋点数分",多年以来一直从事数据分析工作.从今天开始,与大家持续分享关于数据分析的学习内容. 本文是第 5 篇,也是[SQL 周周练]系列的第 4 篇.该系列是挑选或 ...
- AD 侦查-LLMNR 毒化
本文通过 Google 翻译 AD Recon – LLMNR Poisoning with Responder 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充. 导航 ...
- pyqt点击右上角关闭界面但子线程仍在运行
现象: 通过右上角的叉关闭图形界面后,程序运行的子线程却不会被自动关闭,依然留存在系统中 原因: 子线程没有正确关闭 解决方法: 1.将子线程设置成守护线程 self.your_thread = th ...
- C#网络编程(六)----Socket编程模型
简介 Socket(套接字)是计算机网络中的一套编程接口,是网络编程的核心,它将复杂的网络协议封装为简单的API,是应用层(HTTP)与传输层(TCP)之间的桥梁. 应用程序通过调用Socket AP ...
- 题解:P4586 [FJOI2015] 最小覆盖双圆问题
写了这么久终于过了,发篇题解记录一下. 第一次写黑题题解,写的不好请见谅. 目录 本题思路 三点定圆 最小圆覆盖 关于最小圆覆盖时间复杂度 回到本题 二分法划分点集 总时间复杂度 最小覆盖双圆问题代码 ...
- Gitee、Github上star星星数获取到一个图片里,用于MD文档
记录一下 Gitee 用这个链接当图片地址即可 https://gitee.com/用户名/仓库名/badge/star.svg?theme=white https://gitee.com/用户名/仓 ...