解决Mysql中的innoDB幻读问题


Posted in MySQL onApril 29, 2022

1.Mysql的事务隔离级别

解决Mysql中的innoDB幻读问题

这四种隔离级别,当存在多个事务并发冲突的时候,可能会出现脏读,不可重复读,幻读的一些问题,而innoDB在可重复读隔离级别模式下解决了幻读的一个问题,

2. 什么是幻读

幻读是指在同一个事务中,前后两次查询相同范围的时候得到的结果不一致

解决Mysql中的innoDB幻读问题

如图,第一个事务里面,我们执行一个范围查询,这个时候满足条件的数据只有一条,而在第二个事务里面,它插入一行数据并且进行了提交,接着第一个事务再去查询的时候,得到的结果比第一次查询的结果多出来一条数据,注意第一个事务的第一次和第二次查询,都在同一个事物里面,所以,幻读会带来数据一致性的问题

3. InnoDB如何解决幻读的问题

InnoDB引入间隙锁next-key lock机制去解决幻读问题

解决Mysql中的innoDB幻读问题

假如现在存在这样一个B+Tree的索引结构,这个结构有4个索引元素,分别是1,4,7,10 当我们通过主键索引查询一条记录,并且对这条记录通过for update加锁的时候

解决Mysql中的innoDB幻读问题

这个时候会产生一个记录锁,也就是行锁,锁定id=1这个索引

解决Mysql中的innoDB幻读问题

被锁定的记录在锁释放之前,其他事务无法对这一条记录做任何操作的,前面我们所过对幻读的定义,幻读是指在同一个事务中,前后两次查询相同范围的时候得到的结果不一致,注意这里敲掉的是范围查询,也就是说要解决幻读的问题,必须保证一个点

解决Mysql中的innoDB幻读问题

就是如果一个事务通过这样一条语句进行锁定的时候,另外一个事务再执行

解决Mysql中的innoDB幻读问题

这样一条insert语句需要被阻塞,直到前面获得所的事务被释放,所以在innonDB设计一种间隙锁,它的主要功能是锁定一定范围内的索引记录

解决Mysql中的innoDB幻读问题

当对查询范围id > 4 and id < 7这个范围加锁的时候,会针对B+数中(4,7)这个开区间的范围加间隙锁,意味着在这种情况下其他事务对这个区间的数据进行插入更新删除都会被锁住,但是还有另外一种情况,比如像这样

解决Mysql中的innoDB幻读问题

这条查询语句针对id > 4这个条件加锁,那么它需要锁定多个索引区间,所以这个情况下InnoDB引入一个叫next-key lock机制,next-key lock相当于间隙锁和记录锁的合集,记录锁锁定存在记录的行,间隙锁锁住的是记录行之间的间隙,而next-key lock锁住的是两者的和

解决Mysql中的innoDB幻读问题

每个数据行非唯一的索引列,都会存在一把next-key lock,当某个事务持有这一行数据的next-key lock的时候,会锁住一段在左开右闭区间的数据,因此当通过id > 4这样一个范围加锁的时候,InnoDB会去加一个next-key lock锁,锁定的区间范围是(4,7 ](7,10 ](10,+♾️ ]。间隙锁next-key lock的区别是在加锁的范围,间隙锁锁定的是两个索引之间的间隙,而next-key lock会锁定多个索引区间,它包含记录锁间隙锁当我们使用范围查询不仅仅命中Record记录,还包含了Gap间隙的时候,在这种情况下使用的就是临键锁,也就是next-key lock它是Mysql里面默认的行锁算法

4. 总结

虽然InnoDB里面通过间隙锁方式解决了幻读的问题但是加锁之后一定会影响到并发性能,因此对与性能较高的一些业务场景,我们可以把隔离级别设置不可重复,那么这个级别不存在间隙锁,也不存在性能的影响。


Tags in this post...

MySQL 相关文章推荐
mysql部分操作
Apr 05 MySQL
MySQL 数据丢失排查案例
May 08 MySQL
MySQL的Query Cache图文详解
Jul 01 MySQL
SQL之各种join小结详细讲解
Aug 04 MySQL
Mysql数据库中datetime、bigint、timestamp来表示时间选择,谁来存储时间效率最高
Aug 23 MySQL
MySQL 数据类型详情
Nov 11 MySQL
MySQL中IO问题的深入分析与优化
Apr 02 MySQL
数据分析数据库ClickHouse在大数据领域应用实践
Apr 03 MySQL
Windows下载并安装MySQL8.0.x 版本的完整教程
Apr 10 MySQL
mysql使用FIND_IN_SET和group_concat两个方法查询上下级机构
Apr 20 MySQL
MYSQL如何查看操作日志详解
May 30 MySQL
一文解答什么是MySQL的回表
Aug 05 MySQL
详解Mysq MVCC多版本的并发控制
详解Mysql事务并发(脏读、不可重复读、幻读)
MySQL 条件查询的常用操作
Apr 28 #MySQL
mysql 子查询的使用
Apr 28 #MySQL
Mysql 数据库中的 redo log 和 binlog 写入策略
Apr 26 #MySQL
优化Mysql查询的示例
Apr 26 #MySQL
MySQL的存储过程和相关函数
Apr 26 #MySQL
You might like
Windows 下的 PHP-PEAR 安装方法
2010/11/20 PHP
ThinkPHP中的系统常量和预定义常量集合
2014/07/01 PHP
php计算两个文件相对路径的方法
2015/03/14 PHP
golang与PHP输出excel示例
2016/07/22 PHP
Centos 6.5系统下编译安装PHP 7.0.13的方法
2016/12/19 PHP
关于IE、Firefox、Opera页面呈现异同 写脚本很痛苦
2009/08/28 Javascript
javascript操作ul中li的方法
2015/05/14 Javascript
详解Node.js模块间共享数据库连接的方法
2016/05/24 Javascript
移动端 一个简单易懂的弹出框
2016/07/06 Javascript
vue调用高德地图实例代码
2017/04/28 Javascript
vue修改vue项目运行端口号的方法
2017/08/04 Javascript
JS获取指定月份的天数两种实现方法
2018/06/22 Javascript
使用JS判断移动端手机横竖屏状态
2018/07/30 Javascript
node中IO以及定时器优先级详解
2019/05/10 Javascript
Vue 中使用lodash对事件进行防抖和节流操作
2020/07/26 Javascript
Vue+Element自定义纵向表格表头教程
2020/10/26 Javascript
原生js实现下拉框选择组件
2021/01/20 Javascript
python实现简易数码时钟
2021/02/19 Python
Python常用的json标准库
2019/02/19 Python
python selenium firefox使用详解
2019/02/26 Python
python绘图pyecharts+pandas的使用详解
2020/12/13 Python
详解如何在css中引入自定义字体(font-face)
2018/05/17 HTML / CSS
HTML5仿手机微信聊天界面
2016/03/18 HTML / CSS
十佳大学生村官事迹
2014/01/09 职场文书
幼儿园秋游活动方案
2014/01/21 职场文书
优秀中学生事迹材料
2014/01/31 职场文书
物理专业大学生职业生涯规划书
2014/02/07 职场文书
2014学习全国两会精神心得体会2000字
2014/03/11 职场文书
城管综合整治方案
2014/05/01 职场文书
城市轨道交通工程职业生涯规划书范文
2014/09/16 职场文书
先进个人推荐材料
2014/12/29 职场文书
逃课检讨书怎么写
2015/01/01 职场文书
致我们终将逝去的青春观后感
2015/06/10 职场文书
Nginx location 和 proxy_pass路径配置问题小结
2021/09/04 Servers
Spring Data JPA框架自定义Repository接口
2022/04/28 Java/Android
xhunter1.sys可以删除嘛? win11提示xhunter1.sys驱动不兼容解决办法
2022/09/23 数码科技