多版本并发控制 MVCC
介绍多版本并发控制
多版本并发控制技术(Multiversion Concurrency Control,MVCC)
技术是为了解决问题而生的,通过 MVCC 我们可以解决以下几个问题:
- 读写之间阻塞的问题:通过 MVCC 可以让读写互相不阻塞,即读不阻塞写,写不阻塞读,这样就可以提升事务并发处理能力。
- 降低了死锁的概率:这是因为 MVCC 没有使用锁,读取数据时并不需要加锁,对于写操作,也只锁定必要的行。
- 解决一致性读的问题:一致性读也被称为快照读,当我们查询数据库在某个时间点的快照时,只能看到这个时间点之前事务提交更新的结果,而不能看到这个时间点之后事务提交更新的结果。
MVCC 的思想
MVCC 是通过数据行的历史版本来实现数据库的并发控制。
简单来说 MVCC 的思想就是保存数据的历史版本。这样一个事务进行查询操作时,就可以通过比较版本号来判断哪个较新的版本对当前事务可见。
InnoDB 对 MVCC 的实现
MVCC 没有正式的标准,所以在不同的 DBMS 中,MVCC 的实现方式可能是不同的。
InnoDB 对 MVCC 的实现主要是通过 版本链 + ReadView 结构完成。
版本链存储记录的多个版本
先介绍聚簇索引记录的隐藏列,再介绍 Undo Log 版本链
对于使用 InnoDB 存储引擎的表来说,它的聚簇索引记录中都包含 3 个隐藏列
- db_row_id:隐藏的行 ID。在没有自定义主键也没有 Unique 键的情况下,会使用该隐藏列作为主键。
- db_trx_id:操作这个数据的事务 ID,也就是最后一个对该数据进行插入或更新的事务 ID。
- db_roll_ptr:回滚指针,也就是指向这个记录的 Undo Log 信息。Undo Log 中存储了回滚需要的数据。
事务ID
事务执行过程中,只有在第一次真正修改记录时(比如进行 insert、delete、update 操作),才会被分配一个唯一的、单调递增的事务 ID,如果没有修改记录操作,按照一定的策略分配一个比较大的事务 ID,减少分配事务 ID 的锁竞争。每当事务向数据库写入新内容时, 所写的数据都会被标记操作所属的事务的事务ID。
在 InnoDB 存储引擎中,版本链由数据行的 Undo Log 组成。
每次对数据行进行修改,都会将旧值记录到 Undo Log,算是该数据行的一个旧版本。
Undo Log 有两个重要的属性:db_roll_ptr、db_trx_id
Undo Log 也有一个 db_roll_ptr 属性(insert 操作对应的 Undo Log 没有 db_roll_ptr 属性,因为 insert 操作对应的数据行没有更早的版本),Undo Log 的 db_roll_ptr 属性指向上一次操作的 Undo Log,所有的版本被 db_roll_ptr 属性连接形成一个链表。该链表即版本链,版本链的头节点就是数据行的最新值。
Undo Log 还包含生成该版本时,对应的事务 ID,用于判断当前版本的数据对事务的可见性。
版本链如下图所示。这样如果我们想要查找历史快照,就可以通过遍历回滚指针的方式进行查找。
ReadView 判断版本链中的哪个较新的版本对当前事务是可见的
ReadView 用来判断版本链中的哪个较新的版本对当前事务是可见的。
ReadView 中主要包含 4 个比较重要的属性:
- m_ids:表示在生成 ReadView 时,当前系统中所有活跃的读写事务的 ID 集合(列表)
- min_transaction_id:表示在生成 ReadView 时,m_ids 中的最小值
- max_transaction_id:表示在生成 ReadView 时,系统应该分配给下一个事务的 ID 值
- creator_transaction_id:表示生成该 ReadView 的事务的 ID
有了这个 ReadView,这样在访问某条记录时,就可以用 ReadView 来判断版本链中的哪个较新的版本对当前事务是可见的。
如果被访问版本的 transaction_id 属性值与 ReadView 中的 creator_trx_id 值相同,表明当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。
如果被访问版本的 transaction_id 属性值 小于 ReadView 中的 min_trx_id 值,表明生成该版本的事务在当前事务生成 ReadView 前已经提交了,所以该版本可以被当前事务访问。
如果被访问版本的 transaction_id 属性值 大于 ReadView 中的 max_trx_id 值,表明生成该版本的事务在当前事务生成 ReadView 后才开启,所以该版本不可以被当前事务访问。
如果被访问版本的 transaction_id 属性值在 ReadView 的 min_trx_id 和 max_trx_id 之间,那就需要判断一下 transaction_id 属性值是不是在 m_ids 列表中:
- 如果在,表明生成 ReadView 时,被访问版本的事务还是活跃的,所以该版本不可以被当前事务访问
- 如果不在,表明生成 ReadView 时,被访问版本的事务已经被提交了,所以该版本可以被当前事务访问
如果某个版本的数据对当前事务不可见的话,那就顺着版本链找到下一个版本的数据,继续按照上边的步骤判断
可见性,依此类推,直到版本链中的最后一个版本。如果最后一个版本也不可见的话,那么就意味着该条记录对当前事务完全不可见,查询结果就不包含该记录。
ReadView 的生成时机
MVCC 可以防止脏读,也可以防止不可重复读。
防止脏读 和 防止不可重复读 实现的不同之处就在:ReadView 的生成时机不同
- 防止脏读:每次读取数据前,都生成一个 ReadView
- 防止不可重复读:在当前事务第一次读取数据时,生成一个 ReadView,之后的查询操作都重复使用这个 ReadView
对于隔离级别为 读未提交 的事务来说,直接读取记录的最新版本即可。
对于隔离级别为 串行化 的事务来说,InnoDB 存储引擎使用加锁的方式来访问记录。
对于隔离级别为 读已提交 和 可重复读 的事务来说,都必须保证只能读到已经提交的事务修改的数据,不能读到未提交的事务修改的数据。
参考资料
MySQL 是怎样运行的:从根儿上理解 MySQL - 小孩子4919 - 掘金课程 (juejin.cn)
多版本并发控制 MVCC的更多相关文章
- 转: 多版本并发控制(MVCC)在分布式系统中的应用 (from coolshell)
from: http://coolshell.cn/articles/6790.html 问题 最近项目中遇到了一个分布式系统的并发控制问题.该问题可以抽象为:某分布式系统由一个数据中心D和若干业务 ...
- 数据库原理-事务隔离与多版本并发控制(MVCC)
刚来美团实习,正好是星期天,不得不说,其内部的资料很丰富,看了部分文档后,对数据库事务这块更理解了.数据库事务的ACID,大家都知道,为了维护这些性质,主要是隔离性和一致性,一般使用加锁这种方式.同时 ...
- MySQL多版本并发控制——MVCC机制分析
MVCC,即多版本并发控制(Multi-Version Concurrency Control)指的是,通过版本链维护一个数据的多个版本,使得读写操作没有冲突,可保证不同事务读写.写读操作并发执行,提 ...
- Mysql InnoDB多版本并发控制MVCC
参考书籍<mysql是怎样运行的> 系列文章目录和关于我 一丶为什么需要事务隔离级别 mysql是一个客户端/服务断软件,对于同一个服务器来说,可以有多个客户端进行连接,每一个客户端进行连 ...
- MySQL多版本并发控制(MVCC)
MVCC是行级锁的一个变种,但是它在很多的情况下避免了加锁操作,因此开销更低.MySQL,包括Oracle.PostgreSQL都实现了MVCC,虽然每个关系数据库实现不一样,但大都是实现了非阻塞的读 ...
- mysql-innoDB-多版本并发控制(MVCC)
InnoDB的MVCC,是通过在每行记录后面保存三个隐藏的列来实现的其中的两个列一个保存了行的创建时间,一个保存行的过期时间(或删除时间).当然存储的并不是实际的时间值,而是系统版本号(system ...
- MySQL MVCC(多版本并发控制)
概述 为了提高并发MySQL加入了多版本并发控制,它把旧版本记录保存在了共享表空间(undolog),当事务提交之后将重做日志写入磁盘(前提innodb_flush_log_at_trx_commit ...
- MVCC PostgreSQL实现事务和多版本并发控制的精华
原创文章,同步发自作者个人博客,http://www.jasongj.com/sql/mvcc/ PostgreSQL针对ACID的实现机制 事务的实现原理可以解读为RDBMS采取何种技术确保事务的A ...
- mysql的mvcc(多版本并发控制)
mysql的mvcc(多版本并发控制) 我们知道,mysql的innodb采用的是行锁,而且采用了多版本并发控制来提高读操作的性能. 什么是多版本并发控制呢 ?其实就是在每一行记录的后面增加两个隐藏列 ...
随机推荐
- ShardingSphere-proxy-5.0.0企业级分库分表、读写分离、负载均衡、雪花算法、取模算法整合(八)
一.简要说明 以下配置实现了: 1.分库分表 2.每一个分库的读写分离 3.读库负载均衡算法 4.雪花算法,生成唯一id 5.字段取模 二.配置项 # # Licensed to the Apache ...
- NC16746 神奇盘子
NC16746 神奇盘子 题目 题目描述 有一个神奇的盘子,形状为圆形.盘子上面爬着一个大象(视作一个点).由于现实的扭曲,当大象在盘子某个直径的一端的时候,可以瞬间传送至直径的另一端.现在大象想去盘 ...
- 【计算机系统基础1】gdb、gcc简易使用指南
目录 1. 基本实验工具的使用 1.1GCC 在IA-32+LINUX平台 基本的GCC 命令 一些其他选项 1.2objdump 1.3gdb 启动gdb 调试工具 设置断点 启动程序运行 查看程序 ...
- VScode中配置Java环境
vscode 中配置Java环境 转载说明:本篇文档原作者[@火星动力猿],文档出处来自哔哩哔哩-[教程]VScode中配置Java运行环境 转载请在开头或显眼位置标注转载信息. 1.下载VScode ...
- Linux系列之文本操作命令
前言 Linux 有八个常用的文本操作命令:cat.head.tail.nl.grep.sed.more.less.本文介绍它们的区别和简单用法. cat命令 显示文本的最基本命令. cat file ...
- Linux关闭avahi-daemon服务
avahi-daemon是一种Linux操作系统上运行在客户机上实施查找基于网络的Zeroconf service的服务守护进程. 该服务可以为Zeroconf网络实现DNS服务发现及DNS组播规范. ...
- 利用MATLAB仿真节点个数和节点通信半径与网络连通率的关系
一.目的 ①在不同节点个数的情况下,用Matlab拟合出连通率与通信半径的关系曲线. ②在不同节点通信半径的情况下,用Matlab拟合出连通率与节点个数的关系曲线. 二.方法描述 在1x1的单位矩形中 ...
- 使用ventoy制作启动盘
先去应用商店下载,非Deepin用户去官网下载Download.Ventoy. 先确认一下自己的系统镜像是否在清单内.(其实不在也没事) 按照使用说明操作Get start.Ventoy,建议配置为G ...
- 5-5 SpringGateway 网关
SpringGateway 网关 奈非框架简介 早期(2020年前)奈非提供的微服务组件和框架受到了很多开发者的欢迎 这些框架和Spring Cloud Alibaba的对应关系我们要知道 Nacos ...
- firewall 命令简单操作
Firewalld 是维护防火墙策略的守护程序的名称.使用 firewall-cmd 命令与防火墙配置进行交互, 使用区域概念对与系统交互的流量进行分段.网络接口分配给一个或多个区域,每个区域都包含允 ...