MVCC实现原理以及解决脏读、不可重复读、幻读问题

news2025/1/3 1:55:13

MVCC实现原理以及解决脏读、不可重复读、幻读问题

  • MVCC是什么?有什么作用?
  • MVCC的实现原理
    • 行隐藏的字段
    • undo log日志
    • 版本链
    • Read View
  • MVCC在RC下避免脏读
  • MVCC在RC造成不可重复读、丢失修改
  • MVCC在RR下解决不可重复读问题
  • RR下仍然存在幻读的问题


MVCC是什么?有什么作用?

MVCC即多版本并发控制,每行数据存在多个事务版本,通过对数据多个版本的访问可以使读操作不会阻塞写操作,写操作不会阻塞读操作。我们所使用的mysql,其默认引擎为inndb,就支持MVCC,使用MVCC来提高mysql读写的性能。

MVCC的实现原理

MVCC通过行隐藏的字段、undo log日志以及Read View 来实现。

行隐藏的字段

每一行数据含有三个字段,分别是row_id、trx_id和roll_pointer。
row_id:行ID,当存在主键和非空唯一键时默认为row_id,如果不存在,则每一行数据隐藏了行ID
trx_id:事务id,即数据对应的事务版本号。
roll_pointer:回滚指针,指向undo log日志中的数据

undo log日志

mysql我们直到其存在三大日志,分别时binlog、undo log、redo log。
undo log日志会在事务执行之前记录数据的信息,当事务执行发生错误需要进行回滚时,会通过undo log日志将数据回滚到执行之前的数据。

版本链

当多个事务对数据进行修改时,会通过行隐藏的回滚指针和undo log日志形成一条版本链。版本链从最新数据的回滚指针指向undo log日志中的历史数据版本,然后相连形成一条版本链。
在这里插入图片描述

Read View

我们上面介绍了行隐藏的字段和undo log日志,多个事务可以从版本链中读取想要的数据版本信息,那么每个事务是怎么找到它们想要的版本呢?或者换一种说法它们怎么找到当前事务可见的数据版本呢?
通过Read View实现,当事务执行时进行一次快照读也即普通查询时,会生成一个Read View视图,在版本链中查找数据后,会通过Read View内部的算法来判断是否对当前事务可见,如果不可见,会在版本链中继续遍历。
Read View实现属性:当生成Read View时,会包含以下属性。
m_ids:当前系统活跃(未提交)的事务id集合
min_limit_id:m_ids中最小的事务id,即最小未提交的事务id
max_limit_id:将要生成的事务id,由于事务id递增生成,因此将要生成的事务id对当前事务是不可见的
creator_trx_id:当前事务id
Read View判断可见性算法
对于一个事务trx_id,由Read View内部算法判断是否可见,如下:
1、如果trx_id < min_limit_id,由于事务id是递增的,而事务id小于最小未提交的事务,说明该事务已经提交,对当前事务是可见的。
2、如果trx_id >= max_limit_id,说明该事务版本是在当前事务生成Read View视图之后执行的,对当前事务是不可见的。
3、如果min_limit_id <= trx_id < max_limit_id,进行以下的判断:
@1:如果m_ids中包含trx_id,并且trx_id !=creator_trx_id,说明该事务是当前事务生成Read View视图时未提交的事务,并且不是当前事务,对当前事务是不可见的。
@2:如果m_ids中包含trx_id,并且trx_id ==creator_trx_id,说明该事务是当前事务生成Read View视图时未提交的事务,但是该事务是当前事务,因此是可见的。
@3:如果m_ids中不包含trx_id,说明该事务已经提交,对当前事务是可见的。

MVCC在RC下避免脏读

在这里插入图片描述
当事务101开启后,修改了id=1的数据后会生成一条事务id=101的数据版本
当事务102开始执行时,进行一次快照读,会生成Read View视图,事务101此时还未提交,生成的视图如下:
在这里插入图片描述
此时在版本链中先找到了事务id=101的数据,由于m_ids包含101并且101 != 102,所以事务id为101的数据对当前事务不可见。
再次遍历找到事务id=100的数据,由于100 < 101,所以事务id=100的数据对当前事务是可见的,因此避免了脏读的问题

MVCC在RC造成不可重复读、丢失修改

在这里插入图片描述

对于上图执行的顺序,由于在RC每进行一次快照读都会生成一个Read View。
第一次查询数据时:
生成视图:在这里插入图片描述
由于100 < 101,对当前事务可见,读取了事务id=100的数据。
当进行第二次查询时:
生成视图:
在这里插入图片描述
由于事务102修改数据,生成事务id=102的数据版本。
当遍历事务id=102的数据版本时,由于 101 <= 102 <103并且m_ids中不包含102,因此事务id=102的数据版本对当亲事务可见,读取了事务id=102的数据。
由于事务的多次查询结果不一样,导致了不可重复读的问题。

MVCC在RR下解决不可重复读问题

在RR隔离级别下,每个事务只能生成一个Read View,就可以保证一个事务中进行多次查询时使用的是同一个视图,就保证了查询的数据相同,解决了不可重复读的问题,
同MVCC解决不可重复读问题一样,MVCC解决了幻读的问题,但是并没有完全解决,还存在一些问题。

RR下仍然存在幻读的问题

在这里插入图片描述
如上图,事务102插入了id=10的数据,由于Read View事务101本来是对事务102插入的数据是不可见的,但是由于事务101对插入的数据进行了修改,而当前修改的数据对当前事务是可见的,就导致了事务101读取了新插入的数据,造成了脏读的问题,但是在业务中发生这种情况的概率相当低

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

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

相关文章

自学记录鸿蒙API 13:实现人脸比对Core Vision Face Comparator

完成了文本识别和人脸检测的项目后&#xff0c;我发现人脸比对是一个更有趣的一个小技术玩意儿。我决定整一整&#xff0c;也就是对HarmonyOS Next最新版本API 13中的Core Vision Face Comparator API的学习&#xff0c;这项技术能够对人脸进行高精度比对&#xff0c;并给出相似…

代码解析:安卓VHAL的AIDL参考实现

以下内容基于安卓14的VHAL代码。 总体架构 参考实现采用双层架构。上层是 DefaultVehicleHal&#xff0c;实现了 VHAL AIDL 接口&#xff0c;并提供适用于所有硬件设备的通用 VHAL 逻辑。下层是 FakeVehicleHardware&#xff0c;实现了 IVehicleHardware 接口。此类可模拟与实…

通过 Ansys Electronics Desktop 中的高级仿真优化 IC 设计

半导体行业继续通过日益复杂的集成电路 (IC) 设计突破技术界限。随着工艺节点缩小和电路密度达到前所未有的水平&#xff0c;电磁效应对设备性能和可靠性变得越来越重要。现代 IC 设计面临着来自复杂的布局相关耦合机制、信号完整性问题和功率分布问题的挑战&#xff0c;这些问…

Kafka数据迁移全解析:同集群和跨集群

文章目录 一、同集群迁移二、跨集群迁移 Kafka两种迁移场景&#xff0c;分别是同集群数据迁移、跨集群数据迁移。 一、同集群迁移 应用场景&#xff1a; broker 迁移 主要使用的场景是broker 上线,下线,或者扩容等.基于同一套zookeeper的操作。 实践&#xff1a; 将需要新添加…

【OpenGL ES】GLSL基础语法

1 前言 本文将介绍 GLSL 中数据类型、数组、结构体、宏、运算符、向量运算、矩阵运算、函数、流程控制、精度限定符、变量限定符&#xff08;in、out、inout&#xff09;、函数参数限定符等内容&#xff0c;另外提供了一个 include 工具&#xff0c;方便多文件管理 glsl 代码&a…

ffmpeg之播放一个yuv视频

播放YUV视频的步骤 初始化SDL库&#xff1a; 目的&#xff1a;确保SDL库正确初始化&#xff0c;以便可以使用其窗口、渲染和事件处理功能。操作&#xff1a;调用 SDL_Init(SDL_INIT_VIDEO) 来初始化SDL的视频子系统。 创建窗口用于显示YUV视频&#xff1a; 目的&#xff1a;…

复习打卡大数据篇——Hadoop MapReduce

目录 1. MapReduce基本介绍 2. MapReduce原理 1. MapReduce基本介绍 什么是MapReduce MapReduce是一个分布式运算程序的编程框架&#xff0c;核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff0c;并发运行在Hadoop集群上。 MapRed…

小程序配置文件 —— 13 全局配置 - window配置

全局配置 - window配置 这里讲解根目录 app.json 中的 window 字段&#xff0c;window 字段用于设置小程序的状态栏、导航条、标题、窗口背景色&#xff1b; 状态栏&#xff1a;顶部位置&#xff0c;有网络信号、时间信息、电池信息等&#xff1b;导航条&#xff1a;有一个当…

el-pagination 为什么只能展示 10 条数据(element-ui@2.15.13)

好的&#xff0c;我来帮你分析前端为什么只能展示 10 条数据&#xff0c;以及如何解决这个问题。 问题分析&#xff1a; pageSize 的值&#xff1a; 你的 el-pagination 组件中&#xff0c;pageSize 的值被设置为 10&#xff1a;<el-pagination:current-page"current…

单片机与MQTT协议

MQTT 协议简述 MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输协议&#xff09;&#xff0c;是一种基于发布 / 订阅&#xff08;publish/subscribe&#xff09;模式的 “轻量级” 通讯协议&#xff0c;该协议构建于 TCP/IP 协议上&#xf…

Debian-linux运维-docker安装和配置

腾讯云搭建docker官方文档&#xff1a;https://cloud.tencent.com/document/product/213/46000 阿里云安装Docker官方文档&#xff1a;https://help.aliyun.com/zh/ecs/use-cases/install-and-use-docker-on-a-linux-ecs-instance 天翼云常见docker源配置指导&#xff1a;htt…

使用Docker-compose部署SpringCloud项目

docker编写dockfile遇到的问题&#xff1a; 需要在docker-compose.yml文件下执行命令 docker-compose.yml文件格式的问题 1和2处空2格&#xff0c;3处空1格&#xff0c;4为本地配置文件目录&#xff0c;5为docker容器的目录&#xff0c;version为自己安装的docker-compose版本 …

KG4Diagnosis 分层多代理的医疗诊断框架,结合大模型与知识图谱构建,覆盖362种常见疾病

KG4Diagnosis 分层多代理的医疗诊断框架&#xff0c;结合大模型与知识图谱构建&#xff0c;覆盖362种常见疾病 论文大纲理解1. 提出背景是什么&#xff1f;2. 概念的性质是什么&#xff1f;是什么导致这个性质&#xff1f;3. 请举一个正例、一个反例&#xff0c;对比4. 请使用类…

【LLM综述】29种大模型Prompt Engineering技术

note 从零样本&#xff08;Zero-shot&#xff09;提示到最新进展的各种提示技术&#xff0c;包括推理和逻辑链&#xff08;Chain-of-Thought, CoT&#xff09;提示、自动链式思考&#xff08;Auto-CoT&#xff09;提示、自我一致性&#xff08;Self-Consistency&#xff09;提…

【黑马头条训练营】day02-黑马头条-App端文章展示

目录 描述app端首页从请求到数据显示的全部流程 描述文章微服务的组成及首页展示业务与实现 自己编写文章微服务关键逻辑 描述app端首页从请求到数据显示的全部流程 浏览器请求我们的app端 会通过nginx请求到我们app前端 app端输入手机号和密码 点击登录 请求 会到我们的…

DBeaver 咋手动配置sqlite 驱动

目录 1 问题2 下载 1 问题 离线安装了DBeaver 数据库软件&#xff0c;现在需要使用这个数据库打开sqlite 数据库&#xff0c;但是提示没有 驱动&#xff0c;那么我们就需要手动下载驱动&#xff0c;在这个软件里面导入 2 下载 https://repo1.maven.org/maven2/org/xerial/sql…

Linux 的历史与发展:从诞生到未来

Linux 的历史与发展&#xff1a;从诞生到未来 1. 起源之前&#xff1a;操作系统的历史背景 在 Linux 问世之前&#xff0c;操作系统的发展经历了多个重要阶段&#xff0c;这些阶段为 Linux 的诞生奠定了基础&#xff1a; 1940-1950 年代&#xff1a;计算机初期 早期计算机如 [[…

八爪鱼easyspider:

参考我的上一篇博客&#xff1a; scraper插件与软件&#xff0c; 主八爪鱼&#xff0c;easyspider 1&#xff0c;八爪鱼&#xff1a; 同时注意数据横向还是纵向&#xff0c;但是不好操作 二&#xff0c;easyspider&#xff1a; 其中1/2是不需要用户登入的&#xff0c;第3个…

算法基础一:冒泡排序

一、冒泡排序 1、定义 冒泡排序&#xff08;英语&#xff1a;Bubble Sort&#xff09;是一种简单的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序&#xff08;如从大到小、首字母从A到Z&#xff09;错误就把他们交换过来。 …

llamafactory报错:双卡4090GPU,训练qwen2.5:7B、14B时报错GPU显存不足(out of memory),轻松搞定~~~

实际问题场景&#xff1a; 使用llamafactory进行微调qwen2.5 7B和14B的大模型时&#xff0c;会出现out of memory的报错。尝试使用降低batch_size&#xff08;原本是2&#xff0c;现在降到1&#xff09;的方式&#xff0c;可以让qwen2.5:7B跑起来&#xff0c;但时不时会不稳定…