文章目录

  • MySQL45讲
    • 实践篇
      • 20 | 幻读是什么,幻读有什么问题?
        • “幻读”是什么?
        • “幻读”有什么问题?
        • 如何解决幻读?

MySQL45讲

实践篇

20 | 幻读是什么,幻读有什么问题?

示例:

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

“幻读”是什么?

  • Q1 只返回 id=5 这一行;
  • 在 T2 时刻,session B 把 id=0 这一行的 d 值改成了 5,因此 T3 时刻 Q2 查出来的是 id=0 和 id=5 这两行;
  • 在 T4 时刻,session C 又插入一行(1,1,5),因此 T5 时刻 Q3 查出来的是 id=0、id=1 和 id=5 的这三行。

“幻读”指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。(前后数据行数不一致)

“幻读”的说明:

  • 在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。因此,“幻读”在“当前读”下才会出现。
  • 上面 session B 的修改结果,被 session A 之后的 select 语句用“当前读”看到,不能称为幻读。幻读仅专指“新插入的行”。

“幻读”有什么问题?

  • 语义被破坏

    T1 时刻,session A 只是给 id=5 这一行加了行锁, 并没有给 id=0 这行加上锁。因此,session B 在 T2 时刻,可以执行这两条 update 语句。这样,就破坏了 session A 里 Q1 语句要锁住所有 d=5 的行的加锁声明。
  • 数据一致性的问题
    锁的设计是为了保证数据的一致性。而这个一致性,不止是数据库内部数据状态的一致性,还包含了数据和日志在逻辑上的一致性
    session C 也是一样的道理,对 id=1 这一行的修改,也是破坏了 Q1 的加锁声明。

    执行完成后,数据库里的结果:
  • 经过 T1 时刻,id=5 这一行变成 (5,5,100);
  • 经过 T2 时刻,id=0 这一行变成 (0,5,5);
  • 经过 T4 时刻,表里面多了一行 (1,5,5);
  • 其他行跟这个执行序列无关,保持不变。

binlog 里面的内容:

  • T2 时刻,session B 事务提交,写入了两条语句;
  • T4 时刻,session C 事务提交,写入了两条语句;
  • T6 时刻,session A 事务提交,写入了 update t set d=100 where d=5 这条语句。
update t set d=5 where id=0; /*(0,0,5)*/
update t set c=5 where id=0; /*(0,5,5)*/insert into t values(1,1,5); /*(1,1,5)*/
update t set c=5 where id=1; /*(1,5,5)*/update t set d=100 where d=5;/*所有d=5的行,d改成100*/

这个语句序列,不论是拿到备库去执行,还是以后用 binlog 来克隆一个库,这三行的结果,都变成了 (0,5,100)、(1,5,100) 和 (5,5,100)。

显然,id=0 和 id=1 这两行,发生了数据不一致。

如何解决幻读?

InnoDB 引入间隙锁 (Gap Lock),来解决“幻读”问题。

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

因为表 t 里并没有 c=7 这个记录,因此 session A 加的是间隙锁 (5,10)。而 session B 也是在这个间隙加的间隙锁。

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

间隙锁会导致死锁。

  1. session A 执行 select … for update 语句,由于 id=9 这一行并不存在,因此会加上间隙锁 (5,10);
  2. session B 执行 select … for update 语句,同样会加上间隙锁 (5,10),间隙锁之间不会冲突,因此这个语句可以执行成功;
  3. session B 试图插入一行 (9,9,9),被 session A 的间隙锁挡住,只好进入等待;
  4. session A 试图插入一行 (9,9,9),被 session B 的间隙锁挡住。

间隙锁是在可重复读隔离级别下才会生效的。 所以,如果把隔离级别设置为读提交的话,就没有间隙锁了。但同时,要解决可能出现的数据和日志不一致问题,需要把 binlog 格式设置为 row。

20 | 幻读是什么,幻读有什么问题?相关推荐

  1. mysql 幻读理解_Mysql 幻读 的一些个人理解

    背景 由于最近在准备换工作,所以开始补充一些基础知识,以前准备的时候总是去硬背一些知识点,这次花了不少时间去问了问为什么,年前对于幻读的内容有了点心得,为了不遗忘,也是为了只有能讲出来才算是真的理解了 ...

  2. 数据库基础知识ACID,隔离级别RC,RR,RU,SERIALIZABLE,Phantom Rows幻读,解决幻读,脏读dirty read

    ACID A atomicity, C consistency,I isolation, and D durability的缩写,这些特性和事务是紧密联系的,InnoDB事务的特点和ACID原则紧密联 ...

  3. mysql 什么是幻读_何为幻读?MySQL又是如何解决幻读的?

    一.什么是幻读 在一次事务里面,多次查询之后,查询的结果集的个数不一致的情况叫做幻读.而多出来或者少的哪一行被叫做 幻行 二.为什么要解决幻读 在高并发数据库系统中,需要保证事务与事务之间的隔离性,还 ...

  4. mysql 面试知识点笔记(七)RR如何避免幻读及非阻塞读、范式

    2019独角兽企业重金招聘Python工程师标准>>> 表象:快照读(非阻塞读)--伪MVCC (Multi-Version Concurrent Controll多版本并发控制) ...

  5. 某手机在-20度环境下,只能读到电池温度为-18℃

    某手机在-20度环境下,只能读到电池温度为-18℃ 作者:AirCity 2020.3.1 Aircity007@sina.com 本文所有权归作者Aircity所有 问题回顾 MSM8953平台手机 ...

  6. 事务隔离级别——未提交读、已提交读、可重复读、串行

    事务隔离级别--未提交读.已提交读.可重复读.串行 事务隔离级别是指多个事务之间,不同事务中涉及的读写操作互相影响的隔离.其中多个事务中同时对同一条数据或者表进行写操作(insert.update.d ...

  7. MySQL怎么运行的系列(十一)快照读、锁定读、半一致性读 和 加锁语句分析

    本系列文章目录 展开/收起 MySQL怎么运行的系列(一)mysql体系结构和存储引擎 MySQL怎么运行的系列(二)Innodb缓冲池 buffer pool 和 改良版LRU算法 Mysql怎么运 ...

  8. CoLoRMap: Correcting Long Reads by Mapping short reads CoLoRMap:通过映射短读来纠正长读

    CoLoRMap: Correcting Long Reads by Mapping short reads CoLoRMap:通过映射短读来纠正长读 Motivation: 第二代测序技术为测序基因 ...

  9. java imap 标记已读,JavaMail通过IMAP和POP3接收未读以及设置已读邮件

    JavaMail通过IMAP和POP3接收未读以及设置已读邮件 博客分类: javamail javamailpop3imap 使用javaMail收邮件主要有两种协议,一种是pop3,一种是imap ...

  10. 需要天天读月月读年年读的书

    1,数学基础 2,计算理论导引 3,Random Graphs 4,模式分类 5,计算机图形学的算法基础 6,计算几何--C语言描述 7,编译原理 8,应用随机过程 9,计算机系统 10,Comput ...

最新文章

  1. BZOJ-1192-[HNOI2006]鬼谷子的钱袋
  2. 零基础自学python教程-零基础学Python不迷茫——基本学习路线及教程
  3. MongoDB 数组类型查询 —— $elemMatch 操作符
  4. vue 圆形 水波_vue项目百度地图+echarts的涟漪水波效果
  5. 单层神经网络线性回归_单层神经网络| 使用Python的线性代数
  6. Python很简单,你一定能学会【加油!】
  7. idea 删除 output directory文件_郑州Java培训新手必知的IDEA高频快捷键
  8. 劝你们,千千千万不要当一个程序员!!!!!!
  9. linux破解卡到抓包,请大家帮帮忙,真的是不会了,本来想做个抓包工具的,结果卡这了...
  10. bzoj 2946: [Poi2000]公共串 后缀自动机
  11. 怎么用计算机做求余,怎样用计算器求余数
  12. word一键生成ppt 分页_WORD自动生成PPT
  13. 无损音乐ape格式怎么转为ogg格式
  14. Evil Corp 团伙开始使用 LockBit Ransomware 逃避制裁
  15. Android让屏幕保持常亮,不熄屏的三种方法
  16. ubuntu搜狗输入法中文无法切换英文
  17. 移远BC35-G配置网络连接阿里云MQTT发送数据
  18. Office办公 如何设置WPS的默认背景大小
  19. C++_DOS命令下_猫狗大战小游戏(初识QT小练习)
  20. 福禄克FLUKE 435-2与438-2三相电能质量分析仪特性

热门文章

  1. html实现鼠标悬停效果实现
  2. 流程审批: 有个人不走申请人直属领导审批,审批流程设定(设定条件,矩阵相关)
  3. 2020.04.10 【ABAP随笔】- ABAP面试分享
  4. 任建新照常去办公室领取工资
  5. TC358860XBG EDP/DP TO DAUL MIPI DSI
  6. 你敢信?码农靠倒卖烂水果,融资上亿
  7. java hbase连接kerberos的几个常见错误
  8. VS2015编译时“ The POSIX name for this item is deprecated.”的分析
  9. 华为电脑怎么不上鸿蒙,我找不到不喜欢华为鸿蒙操作系统的理由
  10. 图片太大怎么压缩变小,如何压缩图片?