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多版本控制

MVCC MySQL官方文档

简介

MVCC 版本控制是一种MySQL实现隔离级别的机制,利用版本链、undo日志、readView 可以解决脏读、不可重复读问题,MySQL默认的隔离级别是可重复读(REPEARABLE READ),解决了脏读不可重读问题,幻读则需要间隙锁+行锁的解决方案,此文不做讨论。

MySQL 隔离级别

MySQL默认的隔离级别为可重复读(Repeatable Read)
在这里插入图片描述

MVCC

undo Log

undo log 官方文档
undo log 是一种用于撤销回退的日志,在事务没提交之前,MySQL会有限记录更新前的数据到 undo log日志文件当中,当事务回滚的时候可以用undo log进行回退。如下图的右侧就是一个undo log 版本链,具体解释我们等下再讲。
图 1-1

解释一下其中的roll_ptr 和 trx_id,先来看一下官方解释:

在这里插入图片描述
即:

trx_id : 事务字段,当一个事务去操作某个行的数据时,会将自己的事务Id赋值给trx_id字段
roll_ptr : 回滚指针,当一个事务更新了一个字段的时候,并不会直接删除掉之前的字段,而是将该指针指向之前的字段存储到undo blog

ReadView

MVCC当中,版本号比较是通过比较事务id,通过ReadView这样的数据结构,数据结构如下

m_ids:当前活跃事务ID列表,所有事务链表中事务的id集合
min_trx_id:最先开始的事务,该SQL启动时,当前事务链表中最小的事务id编号,也就是当前系统中创建最早但还未提交的事务
max_trx_id:最后开始的事务,该SQL启动时,当前事务链表中最大的事务id编号,也就是最近创建的除自身以外最大事务编号
creator_trx_id:表示生成该ReadView的事务的事务id。

1.如果被访问版本的trx_id属性值与ReadView中的creator_trx_id值相同,意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。
2.如果被访问版本的trx_id属性值小于ReadView中的min_trx_id值,表明生成该版本的事务在当前事务生成ReadView前已经提交,所以该版本可以被当前事务访问。
3.如果被访问版本的trx_id属性值大于或等于ReadView中的max_trx_id值,表明生成该版本的事务在当前事务生成ReadView后才开启,所以该版本不可以被当前事务访问。
4.如果被访问版本的trx_id属性值在ReadView的min_trx_id和max_trx_id之间,那就需要判断一下trx_id属性值是不是在m_ids列表中,如果在,说明创建ReadView时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版本可以被访问。

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

举个例子:
在这里插入图片描述
有一条select语句,它之前的操作咱们暂且不提,假设它的trx_id为110,select时生成ReadView,此时m_ids当中有100和120,min_trx_id 为100,max_trx_id为120,min<110<max,所以符合第四条规则,trx_id 100和trx_id 120都对其不可见,则只能顺着版本链往前找,最后找到之前的trx_id 不在活跃id(m_ids)当中的“初始”的数据。

在MySQL中,READ COMMITTED和REPEATABLE READ隔离级别的的一个非常大的区别就是它们生成ReadView的时机不同。

READ COMMITTED —— 每次读取数据前都生成一个ReadView

因为每次都生成一个readview,所以可能导致第一次select m_ids等数据和之后的不一样,解决不了可重复读的问题。

REPEATABLE READ —— 在第一次读取数据时生成一个ReadView

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:18:23  更:2022-06-01 15:18:34 
 
开发: 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/23 20:04:54-

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