幻读就是在同一个事务里面,前后两次查一个区间内的数据,看到了第一次查询看不到的行。

幻读会导致一个是锁语义上的问题,另外一个是数据不一致的问题。

语义上,我们看下面三个session的执行:

在time1时刻,先对d=5的所有行加行锁,然而time2的sessionb 还有time4的sessionC都没有依照sessionA的语义,所以time5的select产生了幻读的现象。

另外一个就是数据一致性的问题。在多个会话的情况下,会导致在binlog下的语句执行序列和预估的不一致,这样复制到备库也会出问题。因为语句只锁住行,所以没办法应对insert新的行进去,导致数据也不一致。

那么怎么解决幻读的问题呢?这里就要引进一个概念,间隙锁,锁住更改的行的间隙,这也是innodb的默认幻读现象解决方案,只在可重复读的事务隔离级别情况下。另外间隙锁之间并不会互斥,他表达的是一种保护作用,保护这个间隙,不被别的数据插入。

间隙锁和行锁合称为next-key lock,这种next-key lock解决了幻读的问题,但是也影响了并发程度,锁的粒度加大了。下面结合一些原则和案例分析一下:

先说下原则:1.加锁的基本单位是next-key lock,他是前开后闭区间

2.在select的时候,只有访问到的数据才会加锁

3.索引上等值查询,唯一索引加锁的时候,next-key 就是行锁。

4.索引上等值查询,向右方向遍历的时候,直到最后一个值不满足等值查询的时候才停下来,体现了间隙锁的特性。

我们先建立一个sql表和插入一些数据:

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);

基于这个表,结合上面的原则,举几个例子:

  1. 案例一 等值查询的间隙锁

    为什么会出现sessionb和c的现象呢?结合上述提到的原则。根据间隙锁的左开右闭原则,sessionA的语句锁的是(5,10],另外这个是一个等职查询,最后一个值不满足不满足查询条件。所以最终锁(5,10),就出现了上叙现象。

  2. 案例二 覆盖索引加锁

    share in mode因为覆盖索引的原因,只锁了c的那条B+树(根据上面的原则,只锁访问到的对象,id=5没有访问到,所有id的主键b+树没有锁,可以正常update)。但是如果是for update就粒度会包括id主键。

    因为是普通索引,根据上面的原则,知道查到一个不满足等值的数才停下来,加间隙锁,锁住了(5,10)。所以sessionC被阻塞了。

  3. 案例三 主键索引的范围锁

    先看下两个语义相同的sql语句

    mysql> select * from t where id=10 for update;

    mysql> select * from t where id>=10 and id<11 for update;

    语义相同,但是锁的逻辑就不相同了,执行效果如图

    按照惯例,依据前面的四大原则分析:id是唯一索引,next-key lock退化为行锁,所以对id=10的这一行加锁。然后范围查询,直到id=15这一行数据,停下来了。所以锁加在[10,15)。

    而如果是非唯一索引,也执行相同的操作,比如:

    那么将会全部被阻塞,因为将锁住(5,10]还有(10,15)因为他并不会退化成行锁,所以有两个间隙区间锁。

  4. limit语句加锁

    下面还是举一个例子,也是语义一致,但是加锁的粒度不同。

    加了limit。虽然c=10的数据也不超过2条,逻辑上加不加没啥区别,但是锁的粒度就不一样了。

    加了limit的语句,在找到第二条数据后就停止了新区间的加锁,但是如果没有limit会到下个数据不满足等值才停止加锁,那么c在(10,15)也是加锁状态,这条insert语句就会不成功,而limit,这条insert语句是成功的。

  5. next key lock死锁

    1.session A 启动事务后执行查询语句加 lock in share mode,在索引 c 上加了 next-key lock(5,10] 和间隙锁 (10,15),这个前面有例子。

    2.session B 的 update 语句也要在索引 c 上加 next-key lock(5,10] ,进入锁等待

    3.所以再insert进去就死锁了。这个时候innodb就会进行事务回滚。

mysql 最后行加汇总_[mysql系列]6.幻读和间隙锁相关推荐

  1. 使用mysql命令行的工具_[MySQL]命令行工具和基本操作

    一 MySQL命令行工具  (查看帮助 ---help,或 -?) 1)MySQL MySQL是一个简单的SQL外壳(有GNUreadline功能).它支持交互式和非交互式使用.当交互使用时,查询结果 ...

  2. MySQL读已提交有间隙锁吗_mysql中的幻读与间隙锁

    一.数据库隔离级别 一般来讲,数据库的隔离级别分为读未提交.读已提交(read commit,rc).可重复读(read reapeat,rr).串行化四个级别.在mysql中默认隔离级别是rr.读未 ...

  3. Mysql可重复读隔离级别下如何解决幻读

    Mysql可重复读隔离级别下如何解决幻读 一些概念 具体加锁说明 使用主键索引进行等值查询 使用主键索引进行范围查询 使用二级索引进行等值查询 使用二级索引进行范围查询 一些概念 幻读:在一次事务中, ...

  4. MySQL 关键字和保留字汇总(MySQL 8.0)

    MySQL 关键字和保留字汇总(MySQL 8.0) MySQL 关键字和保留字汇总(MySQL 8.0) MySQL 关键字和保留字汇总(MySQL 8.0) 关键字是在SQL中具有重要意义的单词, ...

  5. MySQL在RR级别下到底有没有修复幻读

    微信搜索"coder-home"或扫一扫下面的二维码,关注公众号,第一时间了解更多干货分享,还有各类视频教程资源.扫描它,带走我 文章目录 背景 疑问点 分析 什么是快照读 开启事 ...

  6. MySQL可重复读隔离级别为何没有解决幻读(MVCC原理简介)

    MySQL可重复读隔离级别为何没有解决幻读(MVCC原理简介) 一.MCVV简介 二.可重复读隔离级别能解决幻读? 三.什么是当前读和快照读? 四.MVCC的实现原理 五.RC,RR级别下的InnoD ...

  7. mysql pt工具 加索引_[转]MySQL中如何为连接添加索引

    SELECT * FROM tblA, tblB, tblC WHERE tblA.col1 = tblB.col1 AND tblA.col2 = tblC.col1; explain的结果如下: ...

  8. mysql 单机双实列_{ mysql } MySQL单机多实例及主从复制

    没有过多的,直接上码 my.cnf [mysql_multi] mysqld = /usr/bin/mysqld_safe mysqladmin = /usr/bin/mysqladmin user ...

  9. mysql 5 7 教程视频_[MySQL] MySQL 5.7从入门到精通视频教程

    资源介绍 目录 ├─MySQL常用命令大全.pdf ├─视频教程 │xa0xa0├─第10讲 存储过程和函数 │xa0xa0│xa0xa0├─10.1xa0xa0创建存储过程和函数.avi │xa0x ...

  10. MySQL学习笔记:等值查询、范围查询、死锁、间隙锁的本质

    环境 MySQL:5.7.26-log 前言 答疑文章(二):用动态的观点看加锁 原则 1:加锁的基本单位是 next-key lock.希望你还记得,next-key lock 是前开后闭区间. 原 ...

最新文章

  1. 链表 + 数组模拟链表
  2. 全国计算机等级二级证书foxbase,2002年4月全国计算机等级考试二级FOXBASE笔试试题...
  3. Andriod --- JetPack (二):LifeCycle 的诞生
  4. 上海库源电气OrCAD视频教程
  5. NSTimer注意内存泄露(真该死)
  6. 【牛客 - 302哈尔滨理工大学软件与微电子学院第八届程序设计竞赛同步赛(低年级)】 小乐乐算数字(水题,快速幂,lowbit)
  7. HandlerAdapter解析参数过程之HandlerMethodArgumentResolver
  8. 阿里云:Table Store(OTS) Writer
  9. Spring Boot使用自定义的properties
  10. python之函数用法__getitem__()
  11. 蓝桥杯1427: -买不到的数目(百钱百鸡问题变体)
  12. 碧桂园博智林机器人总部大楼_博智林机器人谷总部大楼完工
  13. Raki的读paper小记:Bipartite Flat-Graph Network for Nested Named Entity Recognition
  14. Linux服务器建立IP隧道,变更访问出口
  15. Go语言之高级篇beego框架之view
  16. 哈工大计算机网络第一章——计算机网络概述复习
  17. tensorflow机器学习之利用CNN卷积神经网络进行面部表情识别的实例代码
  18. 什么是淘宝店铺SKU
  19. 转载:【SQL练习】经典SQL练习题
  20. DIY时钟类--广州百田笔试之一

热门文章

  1. Atitit postgresql data type 数据类型与mysql对应表 数据库常用数据类型 Postgre Mysql 整数 intgreter Int 小数 numeric FL
  2. Atitit 命令行dsl传递参数的几种模式对比 cli url模式 键值对NameValuePair urlutil String string = -host 101.13
  3. Atitit 文档资料管理同步解决方案
  4. Atitit.在线充值功能的设计
  5. atitit.js 与c# java交互html5化的原理与总结.doc
  6. paip.提升用户体验---c++ QLabel标签以及QLineEdit文本框控件透明 设置
  7. 告诉你一个真实的数字化
  8. 金融用户画像的数据合规法律问题
  9. Rust : 为什么没有lifetime是不行的?
  10. 观点丨企业云管平台(CMP)项目成功的关键因素