这下弄懂什么是快照读和什么是当前读了

2024-01-17 07:50
文章标签 当前 快照 弄懂 这下

本文主要是介绍这下弄懂什么是快照读和什么是当前读了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

锁模块之快照读和当前读

InnoDB可重复读隔离级别下如何避免幻读?

  • 表象:快照读(非阻塞读) --伪MVCC
  • 内在:next-key锁(行锁+gap锁)

回答这个问题前我们先要了解下什么是快照读、什么是当前读。

当前读:select...lock in share mode; select...for update;
当前读:updateinsertdelete
快照读:不加锁的非阻塞读,select

演示一下什么是快照读、什么是当前读

打开两个会话,确保一下两个会话的事务隔离级别都在RR级别下

快照读读到的版本数据取决于快照读先出现的地方的时机,我们来看下开启事务后先不执行快照读直接进行更新操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FKSOFBQO-1594698883837)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200714095058653.png)]

以上演示的是RR级别下的快照读和当前读,快照读的版本取决于快照读发生的时机。而在RC级别下,快照读读取的是当前最新的数据。

RC、RR级别下的InnoDB的非阻塞读如何实现

我们在存储一条数据时,除了我们能看到的字段,其实mysql还给我们添加了许多的隐藏字段,比如与我们题目有关的字段:DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID字段,看他们的名字就能够大致知道是什么意思。

  • DB_TRX_ID:事务ID,每开启一个新事务,当前的事务id就自动加一,事务id越大,表明当前启动事务时间离当前时间越近。
  • DB_ROLL_PTR:回滚指针,比如当前事务去更新一条数据的时候,这条数据的回滚指针会指向undo log里最大的事务id的地址,也就是最新的undo日志
    • undo log是在一个事务中每进行一次增删改操作就形成的一条undo日志,它是用于在事务回滚是回到事务开启之前的版本。它也分为insert undo log和update undo log
  • DB_ROW_ID:行号,新行插入,对应行号,如果一个InnoDB表中的字段没有唯一索引和主键索引,InnoDB会自动生成隐藏自增主键字段,也就是这个字段。

实现快照读除了用到上面的三个隐藏字段和undo日志,还需要一个read view,当我们去执行快照读的时候,针对我们读的数据会创建一个read view来决定我们读到的是哪个版本的数据,有可能是最新版本的数据,也有可能是undo日志里的某个版本的数据。read view遵循一个可见性算法,主要是将要修改的数据的DB_TRX_ID取出来与系统其它活跃事务ID作比较,如果大于等于这些ID,就通过DB_ROLL_PTR指针去取出undolog中的数据直到小于这些活跃事务ID为止,这样就能保证获取到的数据是当前事务可见的最稳定的版本。

在RR级别下,session在开启事务后的第一条快照读会创建一个快照,也就是read view,将当前系统中活跃的其他事务记录起来,此后,再调用这个read view,在RC级别下,在开启事务后每次调用快照读的情况下都会创建一个快照,这就是之前RC级别下快照读每次都能看到其他事务进行的最新的增删改,而在RR级别下如果首次使用快照读是在别的事务进行增删改之前调用的,此后即便别的事务做了增删改还是得不到最新数据的原因。所以在RR级别下,首次进行快照读的时机是很重要的。

为什么是伪MVCC

MVCC就是多版本并发控制,也就是非阻塞读,上面提到的MVCC为什么是伪MVCC呢?因为这里的undo log是串行化的不属于多个版本共存的例子,所以不是MVCC。

这篇关于这下弄懂什么是快照读和什么是当前读了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/615352

相关文章

实例:如何统计当前主机的连接状态和连接数

统计当前主机的连接状态和连接数 在 Linux 中,可使用 ss 命令来查看主机的网络连接状态。以下是统计当前主机连接状态和连接主机数量的具体操作。 1. 统计当前主机的连接状态 使用 ss 命令结合 grep、cut、sort 和 uniq 命令来统计当前主机的 TCP 连接状态。 ss -nta | grep -v '^State' | cut -d " " -f 1 | sort |

批处理以当前时间为文件名创建文件

批处理以当前时间为文件名创建文件 批处理创建空文件 有时候,需要创建以当前时间命名的文件,手动输入当然可以,但是有更省心的方法吗? 假设我是 windows 操作系统,打开命令行。 输入以下命令试试: echo %date:~0,4%_%date:~5,2%_%date:~8,2%_%time:~0,2%_%time:~3,2%_%time:~6,2% 输出类似: 2019_06

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们

Weex入门教程之4,获取当前全局环境变量和配置信息(屏幕高度、宽度等)

$getConfig() 获取当前全局环境变量和配置信息。 Returns: config (object): 配置对象;bundleUrl (string): bundle 的 url;debug (boolean): 是否是调试模式;env (object): 环境对象; weexVersion (string): Weex sdk 版本;appName (string): 应用名字;

Linux 删除 当前下的 mysql-8.0.31 空文件夹

在Linux中,如果你想要删除当前目录下的名为mysql-8.0.31的空文件夹(即该文件夹内没有任何文件或子文件夹),你可以使用rmdir命令。但是,如果mysql-8.0.31文件夹并非完全为空(即它包含文件或子文件夹),rmdir命令会失败。 如果你的目标是删除mysql-8.0.31文件夹及其内部的所有内容(无论是否为空),你应该使用rm命令结合-r(或-R,它们是等价的)选项来递归地删

通用内存快照裁剪压缩库Tailor介绍及源码分析(一)

背景 我们知道内存快照是治理 OOM 问题及其他类型的内存问题的重要数据源,内存快照中保存了进程虚拟机的完整的堆内存数据,很多时候也是调查其他类型异常的重要参考。但是dump出来的堆转储文件.hprof往往很大,以 LargeHeap 应用为例,其 OOM 时的内存快照大小通常在512M左右,要有效的存储和获取都是一个问题。 线下拿到hprof文件相对容易,也可以预防OOM,但覆盖的场景十分有

在项目中,如何根据当前的流水号,生成下一个流水号!

在项目中,如何根据当前的流水号,生成下一个流水号! DataType.java package cn.itcast.crm.util;import org.apache.commons.lang.StringUtils;public class DataType {/*** 利用给定的流水位生成第一个流水号* 流水位3 ----- 001 * 流水位4-----0001*/public

【JavaScript】方法属性的匿名函数是匿名函数么(附:获取当前执行函数名称的方法)

var ninja = {shout: function(){console.log("hello");}}   有些人可能认为,将匿名函数赋值给名为shout的属性也就相当于给它取了名字,其实这是不正确的理解。shout是属性的名称,而不是函数自身的名称。这一点可以通过检查函数的name属性来验证。 下面是一些测试实例,请自行思考(前两个均为匿名函数):

计算当前几点

当前时间的时间戳-今天的时间戳/60/60

el-date-picker年份选择默认值为当前年,并且将获取时间转为年月日格式

<el-date-pickervalue-format="yyyy"v-model="leftQuery.year":disabled="timeArr && timeArr.length != 0 ? true : false"type="year"placeholder="选择年"@change=changeYear:picker-options="pickerOptions"></el-da