IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MVCC如何解决不可重复读和读取未提交 -> 正文阅读

[大数据]MVCC如何解决不可重复读和读取未提交

参考:《MySQL是怎样运行的:从根儿上理解MySQL》

目录

MVCC原理

版本链

ReadView

举例

读取已提交

可重复读

总结


MVCC原理

MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读

那么MVVC是怎么实现的呢,要理解其底层原理,需要知道两个概念,一个是版本链,表示某一个数据被修改的记录,比如某一条数据被事务1、事务2,、事务50依次修改。

一个是readview,表示在执行查询语句时会生成这样一个readview,里面有当前正在执行的事务有哪些,那么这些事务对应版本的数据我就不读取,这样不加锁我也知道哪些数据是还没有被提交的,顺着版本链我就知道哪些数据我可以读取,哪些不能读取。

详解如下

版本链

对于使用 InnoDB 存储引擎的表来说,它的聚簇索引记录中都包含两个必要的隐藏列:

trx_id : 每次一个事务对某条聚簇索引记录进行改动时,都会把该事务的 事务id 赋值给 trx_id
隐藏列。
roll_pointer :每次对某条聚簇索引记录进行改动时,都会把旧的版本写入到 undo日志 中,然后这个隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息
每次对记录进行改动,都会记录一条 undo日志 ,每条 undo日志 也都有一个 roll_pointer 属性 ,可以将这些 undo日志 都连起来,串成一个链表,所以现在的情况就像下图一样:

?这个版本链中 有 80, 100 ,200 这三个事务,当然这三个事务80的可能已经提交结束了,200的和100的可能还没有,那么200和100 就属于活跃事务。

对该记录每次更新后,都会将旧值放到一条 undo日志 中,就算是该记录的一个旧版本,随着更新次数的增多,所有的版本都会被 roll_pointer 属性连接成一个链表,我们把这个链表称之为 版本链 版本链的头节点就是当前记录最新的值 。另外,每个版本中还包含生成该版本时对应的 事务id。

ReadView

ReadView 的概念,这个 ReadView 中主要包含 4 个比较重要的内容: 直接看下面的例子比较好理解
m_ids 表示在生成 ReadView时当前系统中活跃的读写事务的 事务id 列表。
min_trx_id:表示在生成 ReadView 时当前系统中活跃的读写事务中最小的 事务id ,也就是 m_ids 中的最小值。
max_trx_id:表示生成 ReadView 时系统中应该分配给下一个事务的 id 值。
creator_trx_id 表示生成该 ReadView 的事务的 事务id
注意max_trx_id并不是m_ids中的最大值,事务id是递增分配的。比方说现在有id为1,2,3这三
个事务,之后id为3的事务提交了。那么一个新的读事务在生成ReadView时,m_ids就包括1和2,min_trx_id的值就是1,max_trx_id的值就是4。
只有在对表中的记录做改动时(执行INSERT、DELETE、UPDATE这些语句时)才会
为事务分配事务id,否则在一个只读事务中的事务id值都默认为0。

举例

假设一个表中,初始一个事务insert一条记录,名字是张一,事务提交,叫它事务A,事务id是1.

又来了事务2,修改名字为张二,但是还没有提交,属于活跃事务,

又来了事务3,修改名字为张三,也没有提交,属于活跃事务。

读取已提交

这时候又一个事务启动,执行了查询语句,因为只有查询,所以事务id为0,

那么首先会创建一个readview,里面有几项信息,比如当前活跃事务id表 ,这个表里面有2,3,

通过这个就知道2,3还没有提交,那么就不能读取这两个版本对应的名字,说不定后来它们又改成什么样子,而是按照版本链找,知道找到1,因为1不在活跃的事务id表中,所以读取这个版本对应的记录,读到“张一”。

如果之后事务2提交了,那么还是这个事务在读取的时候,就会新创建一个readview,这次里面的活跃id表中就没有事务2了,那么读到的就是“张二”。

可重复读

这时候又一个事务启动,执行了查询语句,因为只有查询,所以事务id为0,

那么首先会创建一个readview,里面有几项信息,比如当前活跃事务id表 ,这个表里面有2,3,

通过这个就知道2,3还没有提交,那么就不能读取这两个版本对应的名字,说不定后来它们又改成什么样子,而是按照版本链找,知道找到1,因为1不在活跃的事务id表中,所以读取这个版本对应的记录,读到“张一”。

如果之后事务2提交了,那么还是这个事务在读取的时候,不会新创建一个readview,这次里面的活跃id表中依旧是事务2,3,那么读到的依然是是“张一”,这样就实现了可重复读。

总结

READ COMMITTD 、REPEATABLE READ 这两个隔离级别的一个很大不同就是:生成ReadView的时机不同,READ COMMITTD在每一次进行普通SELECT操作前都会生成一个ReadView,而REPEATABLE READ只在第一次进行普通SELECT操作前生成一个ReadView,之后的查询操作都重复使用这个ReadView就好了

有了这个 ReadView ,这样在访问某条记录时,只需要按照下边的步骤判断记录的某个版本是否可见:

如果被访问版本的 trx_id 属性值与 ReadView 中的 creator_trx_id 值相同,意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。

如果被访问版本的 trx_id 属性值小于 ReadView 中的 min_trx_id值,表明生成该版本的事务在当前事务生成 ReadView 前已经提交,所以该版本可以被当前事务访问。

如果被访问版本的 trx_id 属性值大于 ReadView 中的 max_trx_id值,表明生成该版本的事务在当前事务生成 ReadView 后才开启,所以该版本不可以被当前事务访问。

如果被访问版本的 trx_id 属性值在 ReadView 的 min_trx_id 和 max_trx_id 之间,那就需要判断一下trx_id 属性值是不是在 m_ids 列表中,如果在,说明创建 ReadView 时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建 ReadView 时生成该版本的事务已经被提交,该版本可以被访问。

如果某个版本的数据对当前事务不可见的话,那就顺着版本链找到下一个版本的数据,继续按照上边的步骤判断可见性,依此类推,直到版本链中的最后一个版本。如果最后一个版本也不可见的话,那么就意味着该条记录对该事务完全不可见,查询结果就不包含该记录。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-04-06 23:15:00  更:2022-04-06 23:17:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:05:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码