上一讲最后抛出了一个问题,Mysql可重复读的“快照”到底是啥?

是对当前数据的全量拷贝吗?每开启一个事务,都要把当前数据库的数据拷贝一份出来?

很明显不是。

一方面,这样做太消耗内存了,另一方面,这样会很慢。

那么Mysql是如何实现“快照”的呢?

我们还是用上一讲的例子:

我们已经知道,Session A在第二次select时,查询到的结果和第一次select时一样,也就是说,Session B的update,对Session A来说,不可见,Mysql是如何做到的呢?

很简单,也很绝妙 —— 数据版本,也就是我们常说的MVCC,多版本并发控制。

下面讲具体实现。

Innodb里面,每行数据,都可以有多个版本,每个版本都有一个字段trx_id,记录生成这个版本的事务的ID。

假设一开始,id=1这行数据,只有一个版本,trx_id是90,意味着生成这个版本的事务ID是90:

这时候Session A开始了,从上一讲,我们已经知道,begin时并不会生成快照,快照在第一次select时才会生成,那么第一次select时,session A都做了什么呢?

session A只需要做一件事:用一个数组,来记录当前活跃的事务ID。

假设session A的事务ID是97,当前还有另外两个事务,事务ID是94、96,所以session A会生成一个[94,96,97]的数组。

这个数组有什么用?后面你就知道了。

接着,session B执行了update语句,来更新id=1这一行数据,给这一行数据生成一个新的版本,假设session B的事务ID是98,因此这行数据就有了两个版本:

这时候,session A又来select了,当前版本是session B生成的,那session A是如何找到之前的版本的呢?

这时候,session A一开始生成的事务数组就派上用场了,session A的事务数组是[94,96,97],最小事务ID是94,最大事务ID是97,所以,当它遇到一行数据时,会先判断这行数据的版本号X:如果X大于97,那么意味着这行数据,是在session A开始之后,才提交的,应该对session A不可见

如果X小于97,那么分两种情况:如果X在数组里面,比如X是96,那么意味着,当session A开始时,生成这个版本的数据的事务,还没提交,因此这行数据对Session A不可见

如果X不在数组里面,比如X是95,那么意味着,当session A开始时,生成这个版本的数据的事务,已经提交,因此这行数据对Session A可见

好,现在session A开始遍历id=1这行数据的所有版本:

当前版本是98,大于97,所以不可见,继续看上一个版本;

再往上,版本是90,小于94,可见,就它了,所以session A select出来的id=1的数据,c的值是1。

当然,这样的人肉判断实在太麻烦了,在《Mysql实战45讲》里,丁奇给出了这样一个“等价判断”可见性的原则:版本未提交,不可见;

版本已提交,但是是在快照创建后提交的,不可见;

版本已提交,而且是在快照创建前提交的,可见。

这其实就是可重复读的想要实现的效果。

最后再给一个复杂点的例子,大家运用上面的原则,来预测sql语句的查询结果:

小结一下:“快照”不是全量拷贝,而是利用了数据多版本的特性,也就是MVCC

MVCC的核心在于每个事务自己维护的一个事务ID数组

可以用“等价原则”来判断数据版本的可见性

问题又来了,这些不同版本的数据,是物理存在于内存或者磁盘中的吗?

参考

mysql 快照_Mysql可重复读(2) —— 快照真的就是快照吗相关推荐

  1. mysql 可重复读 快照_MYSQL可重复读及原理、快照读和当前读

    什么是可重复读 可重复读的实现 Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录(读已经提交的,其实是读早于本事务开始且已经提交的),但是不能看到 ...

  2. mysql读提交和重复读区别_读已提交和可重复读的区别 命令行测试

    可重复读:两个事务进行数据操作他们是互不干扰的 ,事务先A进行数据查询,事务B进行一次事务修改并进行数据提交,事务A再进行一次查询,数据是不改变的. 读已提交:两个事务进行数据操作,事务先A进行数据查 ...

  3. mysql可重复读概念_Mysql可重复读原理

    概念 可重复读的实现 Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录(读已经提交的,其实是读早于本事务开始且已经提交的),但是不能看到其他事务对 ...

  4. mysql可重复读有什么好处_mysql可重复读现象及原理分析

    mysql可重复读现象及原理分析 一.可重复读 我们先看看现象,再分析原理.我的mysql版本是5.5. 下面是一张表,只有一条数据,并且我开启了事物 此时,另一个事物将record加1,因此我在开启 ...

  5. mysql 可重复读_mysql 可重复读

    概念 Repeatable Read(可重复读):即:事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,读到的还是原来的内容. 实现原理(MVCC [ 多版本并发控制 ...

  6. mysql可重复读 加锁_mysql可重复读隔离级别加锁分析

    问题 myql可重复读隔离级别下可能会导致插入阻塞,问题复现如下 表中有3列都是int类型 其索引情况如下: id为主索引,c,d为普通索引 现在开始制作问题: 在这里我分别开启两个事务:第一个事务中 ...

  7. MySQL事务的四种隔离级别,mysql中的不可重复读和幻读的区别,Repeatable read可重复读隔离级别下怎么不存在幻读问题?

    1. 事务的隔离级别 1.1 read uncommited:读未提交.一个事务读到了另一个事务未提交的脏数据,称之为脏读. 1.2 read commited:读已提交.解决了脏读问题,但当前事务两 ...

  8. 正确理解MYSQL事务的可重复读RR隔离级别与锁

    1,mysql默认的事务隔离级别是可重复度. 可重复度就是在一个事务中对相同数据的多次查询将返回相同结果. 比如 事务1: BEGIN; SELECT age from student where i ...

  9. Mysql如何实现可重复读

    首先对于mysql来说相信也并不陌生,mysql默认的事务的隔离级别是3,即可以实现可重复读,那mysql又是怎样实现可重复读的呢? 下边进行简单的介绍 这里就要提到了mvcc,即多版本并发控制 首先 ...

最新文章

  1. webView加载不出网页的一种可能情况
  2. 关于无人驾驶商业化现状的一个小研究
  3. Struts2动态方法调用
  4. vmware 8 精简 安装版_被困免安装版下载
  5. ccs安装多版本编译器离线_windows 安装mysql多版本 主从复制
  6. (下)python3 selenium3 从框架实现代码学习selenium让你事半功倍
  7. 二次优化大招(由泰勒公式推出最值条件)
  8. HTML前端开发之路——Transition
  9. Electron使用时拦截HTTP请求的解决方案
  10. 2017 Multi-University Training Contest - Team 7:1005. Euler theorem(答案是(n+3)/2)
  11. houghlinesp找到多条直线_拿什么拯救焦虑的你,一个有勇气的人终将找到他的路...
  12. 04. Make sure that objects are initialized before they're used
  13. failed to execute ‘dot‘, make sure the Graphviz executables are on your systems‘ PATH
  14. 智汇华云 | 集群自动化部署服务流程之自动化集群配置(下)
  15. 使用云打码识别验证码
  16. ASCALL码表对照表 最全、最成体系表格 与对比
  17. 【机器学习】左逆、右逆、伪逆和广义逆的概念理解
  18. python下载需要花钱吗,python下载要钱多少钱
  19. 人工智能TensorFlow进行车辆检测车辆识别
  20. 关于Window10系统无法打开Microsoft Store(应用商店)解决方案

热门文章

  1. 【社区周会】2021-05-11 内容概要
  2. 解决 Idea 下 Tomcat 乱码(淇℃伅璀﹀憡)问题
  3. 74LS160(两个)驱动数码管显示两位十进制数
  4. ECCV 2022|文本图像分析领域再起波澜,波士顿大学联合MIT和谷歌提出全新多模态新闻数据集NewsStories
  5. SAS小白入门第二节:SAS数据类型和格式化(输入和输出)
  6. 神威OpenFOAM——最流行的开源CFD软件与神威·太湖之光的珠联璧合
  7. PW2312A输入55V,输出0.6A降压IC
  8. jQuery - 获取兄弟元素
  9. 计算机科学与技术专业学建模嘛,工学学科(基本专业四):计算机科学与技术专业介绍...
  10. 选修课《创新创业执行力》第一次课有感