MVCC并发版本控制之重点ReadView
MVCC并发版本控制
本文大部分来自《MySQL是怎样运行的》,这里只是简单总结,用于各位回忆和复习。
版本链
对于使用 InnoDB 存储引擎的表来说,它的聚簇索引记录中都包含两个必要的隐藏列(不知道的快去看《MySQL是怎样运行的》)
trx_id :每次一个事务对某条聚簇索引记录进行改动时,都会把该事务的 事务id 赋值给 trx_id 隐藏列。
roll_pointer :每次对某条聚簇索引记录进行改动时,都会把旧的版本写入到 undo日志中,然后这个隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息。
假设现在有两个事务id 分别为 100 、 200 的事务对这条记录进行 UPDATE 操作,操作流程如下:

每次对记录进行改动,都会记录一条undo日志(不懂的可以理解为一个记录着过去的操作的日志) ,每条 undo日志 也都有一个 roll_pointer 属性( INSERT 操作对应的 undo日志 没有该属性,因为该记录并没有更早的版本),可以将这些 undo日志 都连起来,串成一个链表,所以现在的情况就像下图一样:

对该记录每次更新后,都会将旧值放到一条 undo日志 中,就算是该记录的一个旧版本,随着更新次数的增多, 所有的版本都会被 roll_pointer 属性连接成一个链表,我们把这个链表称之为 版本链 ,版本链的头节点就是当 前记录最新的值。另外,每个版本中还包含生成该版本时对应的 事务id ,这个信息很重要,我们稍后就会用到。
ReadView
我们来引出一下readview是什么东西:
对于使用 READ UNCOMMITTED 隔离级别的事务来说,由于可以读到未提交事务修改过的记录,所以直接读取记录的最新版本就好了
对于使用 SERIALIZABLE 隔离级别的事务来说,则是使用加锁的方式来问记录
但是!!!对于使用 READ COMMITTED 和 REPEATABLE READ 隔离级别的事务来说
都必须保证读到已经提交了的事务修改过的记录,也就是说假如另一个事务已经修改了记录但是尚未提交, 是不能直接读取最新版本的记录的,核心问题就是:需要判断一下版本链中的哪个版本是当前事务可见的。为此,设计 InnoDB 的大叔提出了一个 ReadView 的概念,这个 ReadView 中主要包含4个比较重要的内容:
m_ids :表示在生成 ReadView 时当前系统中活跃的读写事务的事务id 列表。
min_trx_id :表示在生成 ReadView 时当前系统中活跃的读写事务中最小的事务id ,也就是 m_ids 中的最小值。
max_trx_id :表示生成 ReadView 时系统中应该分配给下一个事务的 id 值。
小贴士: 注意max_trx_id并不是m_ids中的最大值,事务id是递增分配的。比方说现在有id为1,2,3这三 个事务,之后id为3的事务提交了。那么一个新的读事务在生成ReadView时,m_ids就包括1和2,mi n_trx_id的值就是1,max_trx_id的值就是4。
creator_trx_id :表示生成该 ReadView 的事务的事务id 。
小贴士: 我们前边说过,只有在对表中的记录做改动时(执行INSERT、DELETE、UPDATE这些语句时)才会 为事务分配事务id,否则在一个只读事务中的事务id值都默认为0。
有了 ReadView ,这样在访问某条记录时,只需要按照下边4个步骤判断记录的某个版本是否可见:注意,与被访问版本对比的东西都是指(当前最新的ReadView)
如果(被访问版本的) trx_id = creator_trx_id ,意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。
如果(被访问版本的) trx_id < min_trx_id ,表明生成该版本的事务在当前事务生成 ReadView 前已经提交,所以该版本可以被当前事务访问。
如果(被访问版本的) trx_id > max_trx_id ,表明生成该版本的事务在当前事务生 成 ReadView 后才开启,所以该版本不可以被当前事务访问。
如果(被访问版本的)min_trx_id < trx_id < max_trx_id ,那就需要判断一下 trx_id 属性值是不是在 m_ids 活跃事务列表中。
如果在,说明创建 ReadView 时生成该版本的事务还是活跃的,还没提交,该版本不可以被访问。
如果不在,说明创建 ReadView 时生成该版本的事务已经被提交,该版本可以被访问。
ReadView生成时机
读已提交 和 可重复读 隔离级别最大的区别就是它们生成ReadView的时机不同:
READ COMMITTED —— 每次读取数据前都生成一个ReadView
每次select操作都生成一个ReadView,所以每一次查询都在用一个最新生成的ReadView进行上述4步走,所以查出来的应该是最新提交的事务中的最后一个操作(因为一个事务可能有多个增改操作)
REPEATABLE READ —— 在第一次读取数据时生成一个ReadView
意味着你在第一次执行select语句之后,不管增删改了多少次,永远拿第一次select生成的ReadView来进行刚刚说的4个步骤判断,所以一直查询的是第一次select语句所查出来的东西。
具体例子这里不过多赘述,还是自行看书。
MVCC并发版本控制之重点ReadView的更多相关文章
- mysql 之mvcc多版本控制
MVCC是multiversion concurrency control的缩写,提供MySQL事物隔离级别下无锁读,例如一个事物在执行update等修改数据的sql,并未提交时其他事物进行数据读取是 ...
- Storm程序的并发机制(重点掌握)
概念 Workers (JVMs): 在一个物理节点上可以运行一个或多个独立的JVM 进程.一个Topology可以包含一个或多个worker(并行的跑在不同的物理机上), 所以worker proc ...
- 《快照读、当前读和MVCC》
1.快照读 快照读是基于 MVCC 和 undo log 来实现的,适用于简单 select 语句,避免了幻读. 读已提交:一个事务内操作一条数据,可以查询到另一个已提交事务操作同一条数据的最新值.( ...
- Spring Framework之事务管理
目录 问题 数据库事务 事务的定义 事务的目的 事务的特性 事务隔离级别 数据并发问题 事务隔离级别对数据并发问题的作用 快照读 Spring事务管理 事务管理接口 TransactionDefini ...
- mysql数据库事务类型
出自:https://blog.csdn.net/u014439239/article/details/78086729 数据库事务有不同的隔离级别,不同的隔离级别对锁的使用是不同的,锁的应用最终导致 ...
- MySQL的事务机制和锁(InnoDB引擎、MVCC多版本并发控制技术)
一.事务(数据库的事务都通用的定义) 1.1 事务定义 事务是由一步或几步数据库操作序列组成逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行.事务通常以 BEGIN TRANSACTION 开始 ...
- [MySQL数据库之事务、读现象、数据库锁机制、多版本控制MVCC、事务隔离机制]
[MySQL数据库之事务.读现象.数据库锁机制.多版本控制MVCC.事务隔离机制] 事务 1.什么是事务: 事务(Transaction),顾名思义就是要做的或所做的事情,数据库事务指的则是作为单个逻 ...
- 看一遍就懂:MVCC原理详解
MVCC实现原理也是一道非常高频的面试题,自己在整理这篇文章的时候,感觉到网上的资料在讲这块知识点上写的五花八门,好像大家的理解并没有一致. 这里将自己所理解的做一个总结,个人会觉得这是一篇含金量挺高 ...
- mysql MVCC原理理解
MVCC多版本控制: 指的是一种提高并发的技术.最早的数据库系统,只有读读之间可以并发,读写,写读,写写都要阻塞.引入多版本之后,只有写写之间相互阻塞,其他三种操作都可以并行,这样大幅度提高了Inno ...
- 从一次“并发修改字段业务”引出多版本并发控制与InnoDB锁
并发字段修改业务 最近在主要在做"工作流引擎"课题的预研工作,在涉及到"会签任务"(工作流业务概念,这与我们今天讨论文问题没有太多关联)的时候,遇到了一个并发修 ...
随机推荐
- ACM-NEFUOJ-P209湖南修路
思路 prim的最小生成树,套上肝就完事了 代码 #include<iostream> #include<cstdio> #include<string.h> #d ...
- Centos7安装配置MySQL 5.6
Centos7安装配置MySql 5.6 首先下载MySql5.6的安装包,具体安装方式分为yum安装与离线安装.在新版本的CentOS7中,默认的数据库已更新为了Mariadb,而非 MySQL. ...
- [Git]解决:error: The following untracked working tree files would be removed by checkout:
1 文由 不小心在本地对master分支做了修改,并commit了,但是没有push成功(因为处于防止代码提交风险,产品部对普通开发者没有项目master的push权限) 后来又经过了一顿骚操作(我已 ...
- golang常用库包:log日志记录-uber的Go日志库zap使用详解
Go 日志记录库:uber-go 的日志操作库 zap 使用 一.简介 zap 是 uber 开源的一个高性能,结构化,分级记录的日志记录包. go1.20.2 zap v1.24.0 zap的特性 ...
- Java:一篇学好设计模式
什么是设计模式 简单理解,设计模式是前人多年写代码踩坑总结出来的优秀代码攻略,目的是减少大量无用代码,让项目更好维护 七大设计原则 接下来要讲的23种设计模式,但遵循下面的七大原则: 单一职责原则 2 ...
- HTML+CSS仿写的登录页面
仿写的登录页面 使用HTML+CSS,感觉很简单,记录下 话不多说,直接上代码 <!DOCTYPE html> <html lang="en"> & ...
- 基于kubeasz部署高可用k8s集群
在部署高可用k8s之前,我们先来说一说单master架构和多master架构,以及多master架构中各组件工作逻辑 k8s单master架构 提示:这种单master节点的架构,通常只用于测试环境, ...
- Prometheus监控之SNMP Exporter介绍和数据展现
由于技术能力有限,文章仅能进行简要分析和说明,如有不对的地方,请指正,谢谢. 1 SNMP协议介绍 SNMP协议全称是:Simple Network Management Protocol,译为简单网 ...
- 2022-12-26:有一个数组包含0、1、2三种值, 有m次修改机会,第一种将所有连通的1变为0,修改次数-1, 第二种将所有连通的2变为1或0,修改次数-2, 返回m次修改机会的情况下,让最大的0
2022-12-26:有一个数组包含0.1.2三种值, 有m次修改机会,第一种将所有连通的1变为0,修改次数-1, 第二种将所有连通的2变为1或0,修改次数-2, 返回m次修改机会的情况下,让最大的0 ...
- 2022-12-14:给定一个正数n, 表示从0位置到n-1位置每个位置放着1件衣服 从0位置到n-1位置不仅有衣服,每个位置还摆着1个机器人 给定两个长度为n的数组,powers和rates pow
2022-12-14:给定一个正数n, 表示从0位置到n-1位置每个位置放着1件衣服 从0位置到n-1位置不仅有衣服,每个位置还摆着1个机器人 给定两个长度为n的数组,powers和rates pow ...