MVCC实现原理

news2024/11/14 15:44:32

MVCC实现原理

  • 主要依赖
  • 隐藏字段
  • undo log
    • undolog生成的记录链
  • Read View
    • 可见性规则
      • 三个全局属性
      • 具体的比较规则
  • MVCC的整体处理流程
  • RC、RR级别下的InnoDB快照读有什么不同

主要依赖

mvcc的实现原理主要依赖于记录中的三个隐藏字段(对用户来说是不可见的),undolog(帮助用于事务回滚的,记录数据的历史版本),read view(读视图,用来保证多个并行的事务之间能够读取到彼此之间的数据)来实现。

隐藏字段

每行记录除了我们自定义的字段外,还有数据库隐式定义的DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID等字段。

DB_TRX_ID:6字节,最近修改事务id,记录创建这条记录或者最后一次修改该记录的事务id

DB_ROLL_PTR:7字节,回滚指针,指向这条记录的上一个版本,用于配合undolog,指向上一个旧版本。

DB_ROW_ID:6字节,隐藏的主键,如果数据表没有主键,那么innodb会自动生成一个6字节的row_id。
在这里插入图片描述
在上图中,DB_ROW_ID是数据库默认为该行记录生成的唯一隐式主键,DB_TRX_ID是当前操作该记录的事务,ID,DB_ROLL_PTR是一个回滚指针,用于配合undo日志,指向上一个旧版本。

undo log

undolog被称之为回滚日志,表示在进行insert,delete,update操作的时候产生的方便回滚的日志。

当进行insert操作的时候,产生的undolog只在事务回滚的时候需要,并且在事务提交之后可以被立刻丢弃

当进行update和delete操作的时候,产生的undolog不仅仅在事务回滚的时候需要,在快照读的时候也需要,所以不能随便删除,只有在快照读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除(当数据发生更新和删除操作的时候都只是设置一下老记录的deleted_bit,并不是真正的将过时的记录删除,因为为了节省磁盘空间,innodb有专门的purge线程来清除deleted_bit为true的记录,如果某个记录的deleted_id为true,并且DB_TRX_ID相对于purge线程的read view可见,那么这条记录一定是可以被清除的。

undolog生成的记录链

  1. 假设有一个事务编号为1的事务向表中插入一条记录,那么此时行数据的状态为
    在这里插入图片描述
  2. 假设有第二个事务编号为2对该记录的name做出修改,改为lisi
    1)在事务2修改该行记录数据时,数据库会对该行加排他锁。
    2)然后把该行数据拷贝到undolog中,作为旧记录,即在undolog中有当前行的拷贝副本。
    3)拷贝完毕后,修改该行name为lisi,并且修改隐藏字段的事务id为当前事务2的id,回滚指针指向拷贝到undolog的副本记录中。
    4)事务提交后,释放锁。
    在这里插入图片描述
  3. 假设有第三个事务编号为3对该记录的age做了修改,改为32
    1)在事务3修改该行数据的时,数据库会对该行加排他锁。
    2)然后把该行数据拷贝到undolog中,作为旧记录,发现该行记录已经有了undolog了,那么最新的旧数据作为链表的表头,插在该行记录的unlog最前面。
    3)修改该行age为32岁,并且修改隐藏字段的事务id为当前事务3的id,回滚指针指向刚刚拷贝的undolog的副本记录。
    在这里插入图片描述

从上述的一系列图中,大家可以发现,不同事务或者相同事务的对同一记录的修改,会导致该记录的undolog生成一条记录版本线性表,即链表,undolog的链首就是最新的旧纪录,链尾就是最早的旧纪录。

Read View

Read View是事务进行快照读操作的时候生产的读视图,在该事务执行快照读的那一刻,会生成一个数据系统当前的快照,记录并维护系统当前活跃事务的id,事务的id值是递增的。

其实Read View的最大作用是用来做可见性判断的,也就是说当某个事务在执行快照读的时候,对该记录创建一个Read View的视图,把它当作条件去判断当前事务能够看到那个版本的数据,有可能读取到的是最新的数据,也有可能读取的是当前行记录的undolog中某个版本的数据。

Read Viewi遵循的可见性算法主要是将要被修改的数据的最新记录中的DB_TRX_ID(当前事务id)取出来,与系统当前其他活跃事务的id去对l比,如果DB_TRX_ID跟Read View的属性做了比较,不符合可见性,那么就通过DB_ROLL_PTR回滚指针去取出undolog中的DB_TRX_ID做比较,即遍历链表中的DB_TRX_ID,直到找到满足条件的DB_TRX_ID,这个DB_TRX_ID所在的旧记录就是当前事务能看到的最新老版本数据。

可见性规则

Read View的可见性规则如下所示

三个全局属性

首先要知道Read View中的三个全局属性
trx_list:一个数值列表,用来维护Read View生成时刻系统正活跃的事务ID
up_limit_id:记录trx_list列表中事务ID最小的ID
low_limit_id:Read View生成时刻系统尚未分配的下一个事务ID

具体的比较规则

1、首先比较DB_TRX_ID(最后修改的)<up_limit_id,如果小于,则当前事务能看到DB_TRX_ID所在的记录,如果大于等于进入下一个判断。
2、接下来判断DB_TRX_ID>=Iow_limit_id,如果大于等于则代表DB_TRX_ID所在的记录在Read View生成后才出现的,那么对于当前事务肯定不可见,如果小于,则进入下一步判断。
3、判断DB_TRX_ID是否在活跃事务中,如果在,则代表在Read Views生成时刻,这个事务还是活跃状态,还没有commit,修改的数据,当前事务也是看不到,如果不在,则说明这个事务在Read Views生成之前就已经开始commit,那么修改的结果是能够看见的。

MVCC的整体处理流程

假设有四个事务同时在执行,如下图所示:
在这里插入图片描述
从上述表格中,我们可以看到,当事务2对某行数据执行了快照读,数据库为该行数据生成一个Read View视图,可以看到事务1和事务3还在活跃状态,事务4在事务2快照读的前一刻提交了更新,所以,在Read View中记录了系统当前活跃事务1,3,维护在一个列表中。同时可以看到up_limit_id的值为1,而low_limit_id为5,如下图所示:
在这里插入图片描述
在上述的例子中,只有事务4修改过该行记录,并在事务2进行快照读前,就提交了事务,所以该行当前数据的undolog如下所示:
在这里插入图片描述

RC、RR级别下的InnoDB快照读有什么不同

RC级别:已提交读 (READ COMMITED)简称(RC) 。(允许存在不可重复读和幻读的)
RR级别:可重复读(REPEATABLE READ)简称(RR )。(不允许存在幻读)

因为Read View生成时机的不同,从而造成RC、RR级别下快照读的结果的不同:
1、在RR级别下的某个事务的对某条记录的第一次快照读会创建一个快照即Reād View,将当前系统活跃的其他事务记录起来,此后在调用快照读的时候,还是使用的是同一个Read View,所以只要当前事务在其他事务提交更新之前使用过快照读,那么之后的快照读使用的都是同一个Read View, 所以对之后的修改不可见
2、在RR级别下,快照读生成Read View时,Read View会记录此时所有其他活动和事务的快照,这些事务的修改对于当前事务都是不可见的,而早于Read View创建的事务所做的修改均是可见。
3、在RC级别下,事务中,每次快照读都会新生成一个快照和Read View,这就是我们在RC级别下的事务中可以看到别的事务提交的更新的原因。

总结:在RC隔离级别下,是每个快照读都会生成并获取新的Read View,而在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View,之后的快照读获取的都是同一个Read View。

参考资料:中高级面试常问的:MVCC实现原理是什么? 被大佬讲明白了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/456713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring Cloud Alibaba】8.路由网关(Gateway)

文章目录 简介什么是 Spring Cloud Gateway功能介绍工作流程 开始搭建创建项目修改POM文件添加启动类添加配置文件启动项目测试 网关全局过滤创建全局过滤器测试 结尾 简介 接下来对服务消费者添加路由网关来实现统一访问接口&#xff0c;本操作先要完成之前的步骤&#xff0c…

API 自动化测试难点总结与分享

笔者是 API 管理工具的项目参与者之一&#xff0c;在日常工作中会经常遇到 API 自动化测试难点&#xff0c;我决定总结分享给大家&#xff1a; API 自动化测试的难点包括&#xff1a; 接口的参数组合较多&#xff0c;需要覆盖各种可能的情况。 接口的状态和数据关联较多&#…

DJ4-1 存储器的层次结构

目录 4.1.1 存储器的层次结构 1. 主存储器&#xff08;内存&#xff0c;主存&#xff0c;可执行存储器&#xff09; 2. 寄存器 3. 高速缓存 4. 磁盘缓存 存储器层次结构的特点 4.1.2 存储器管理的目的和功能 1. 主存储器的分配和管理 2. 提高主存储器的利用率 3. 扩…

基于ArcGIS Pro、Python、USLE、INVEST模型等多技术融合的生态系统服务构建生态安全格局

近年来&#xff0c;由于社会经济的快速发展和人口增长&#xff0c;社会活动对环境的压力不断增大&#xff0c;人地矛盾加剧。虽然全球各国在生态环境的建设和保护上已取得不少成果&#xff0c;但还是未从根本上转变生态环境的恶化趋势&#xff1b;生态破坏、环境退化、生物多样…

OceanMind海睿思入选“2023爱分析·智能制造最佳实践案例”

近日&#xff0c;中国领先的产业数字化研究与咨询机构 爱分析 发布了《2023爱分析智能制造最佳实践案例》&#xff0c;该奖项旨在肯定智能制造领域领先企业的数字化创新应用和最佳实践。 中新赛克海睿思凭借为星宇股份构建的“星宇车灯数据智能解决方案”入选智能制造最佳实践…

AWR1642毫米波雷达实测行人、自行车和汽车等目标

本文编辑 | 调皮哥的小助理 AWR1642因为最大中频带宽 固定只有5MHz&#xff0c;最大中频带宽是发射信号与回波信号混频之后得到的最大中频频率&#xff0c;即代表着最大的回波延迟时间。 因此根据雷达方程和目标最大探测距离公式&#xff0c;如下所示&#xff1a; 复采样&…

一文谈谈文心一言对比ChatGPT4.0的差距

对于想体验文心一言的朋友&#xff0c;可以进行申请尝试&#xff0c;快速入口 如果想体验ChatGPT的朋友&#xff0c;可以自行fq注册&#xff1b;但是由于现在限制注册并且不稳定&#xff0c;对于不会用梯子不想注册的朋友可以使用这个进行访问&#xff0c;快速入口 关于ChatG…

CTF之SSRF常见绕过

1.绕过localhost和127.0.0.1 当程序中限制了我们使用localhost和127.0.0.1时&#xff0c;便可以利用进制转换来绕过 http://0x7F.0.0.1 //16进制 http://0177.0.0.1 //8进制 http://2130706433 //10进制整数格式 http://0x7F000001 16进制整数格式 http://127.1 //省略模式 h…

【算法】C程序的运行速度测试

C语言程序的运行速度测试 代码随想录上提到了一点&#xff0c;即我们应该学会估计一个时间复杂度较高的算法&#xff0c;在机器上的运行速度。 如果题目给出的数据量级在高复杂度的算法中会超时&#xff0c;那就应该放弃使用这个代码&#xff0c;而想其他时间复杂度更优的解法…

QMS-云质说质量 - 9 我和我的客户投诉(1) - 逢年过节要祈祷

云质QMS原创 转载请注明来源 作者&#xff1a;王洪石 逢年过节都要祈祷 在某外资汽车零部件企业工作的那些年&#xff0c;无论在质量部还是项目部&#xff0c;都是成天和客户打交道&#xff0c;也经常面对各种各样的客户投诉。 尤其是当质量经理的那些年&#xff0c;每年都要被…

docker搭建简单elk日志系统5(logstash管道配置文件logstash.conf)

1.查看logstash管道配置文件logstash.conf cd ~/elk/logstash/pipeline/ cat logstash.conf默认的配置文件输入是beat&#xff1b; beat表示ELK Stack中的核心组件Beats; Beats指轻量型数据采集器&#xff0c;是一些列beat的合称&#xff1b;目前官网上的beat有&#xff1a; …

sql注入 Quine注入解析

前言 quine注入,即查询的结果是查询的语句 首先看看如下sql语句会返回什么 select replace(".",char(46),".");返回了一个点 匹配字符串".“中ascii码为46的字符并替换为”.“,也就是将”.“转换为”."并返回 继续看下面这个sql语句 selec…

状态机编程

//定义的枚举 typedef enum { KEY_UP 1, //按键按下 Edge_Lead2, //前沿抖动 KEY_DOWN 3, //按键松开 Edge_Back4, //后沿抖动 } KEY_Status; 主函数&#xff1a; #include "stm32f4xx.h" #include "led.h" #include "delay.h" #include "…

QMS-云质说质量 - 8 颠覆你的认知,中小型企业数字化转型更容易成功

数字化转型&#xff0c;不但不遥远&#xff0c;而且似乎离我们每个人的生活还非常近。尤其是近几年&#xff0c;出于政府号召与扶持&#xff0c;市场竞争以及企业自身发展需要等各方面原因&#xff0c;越来越多的企业已经开始或者正在准备进行数字化转型。即使是规模一两百人的…

MATLAB如何自定义颜色图(colormap)

MATLAB有一套自己的颜色库&#xff0c;常用的都有&#xff0c;但是数量不算太多。我们有时候需要用到一些MATLAB没有的colormap&#xff0c;比如Python的Matplotlib就有很多的colormap&#xff0c;我们也有可能需要自己来定义一些渐变的颜色。本片笔记主要是介绍colormap如何自…

在vite中使用mockjs, vite中使用vite-plugin-mock

相信前端同学都会碰见类似的问题&#xff0c;就是页面可能很快写完了&#xff0c;但是接口同学还在缓慢设计表中&#xff01; 这个时候咳咳&#xff0c;你就可以去摸鱼了或者看小说了 但实际上可不能这样哦&#xff0c;要老老实实做个打工人 步入正题了 在vite中有个mock的插…

SpringCloud学习6(Spring Cloud Alibaba)断路器Sentinel熔断降级

文章目录 服务熔断降级Sentinel高并发请求模拟&#xff08;这里我们使用contiperf来进行测试&#xff09;修改tomcat配置最大线程数引入测试依赖编写测试代码 服务雪崩服务雪崩的容错方案&#xff08;隔离、超时、限流、熔断、降级&#xff09;隔离机制&#xff1a;超时机制&am…

混淆电路(GC)

基本概念 在混淆电路框架下&#xff0c;任意功能函数可被表示为一个与门和异或门组成的布尔电路&#xff0c;协议的参与方由生成方&#xff08;Garbler&#xff09;和计算方&#xff08;Evaluator&#xff09;组成。 **大致的流程&#xff1a;**生成方生成密钥并加密查找表&am…

淘宝天猫数据查询(天猫智能手环数据分析)

近几年&#xff0c;中国智能可穿戴设备市场规模不断增长&#xff0c;也取得了傲人的成绩。从可穿戴设备市场整体发展来看&#xff0c;智能手环是一大主角。智能手环市场接受度和认可度的逐渐提升&#xff0c;为各类厂商提供了更多机会&#xff0c;同时这也蕴含了更多市场增量空…

分享两个有意思的登录界面

1.带有浮动占位符和灯光按钮的登录界面 先上效果: 代码如下: <!DOCTYPE html> <html lang="en"> <head>