当前位置: 首页 > news >正文

MySQL MVCC原理

        全称Multi-Version Concurrency Control,即多版本并发控制,主要是为了提高数据库的并发性能。

1、版本链

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

1、trx_id:每次一个事务对某条聚簇索引记录进行改动时,都会把该事务的事务id赋值给trx_id隐藏列。
2、roll_pointer:每次对某条聚簇索引记录进行改动时,都会把旧的版本写入到undo日志中,然后这个隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息。

        为了实现事务的原子性,InnoDB存储引擎在实际进行增、删、改一条记录时,都需要先把对应的undo日志记下来。

事务id为10的事务,插入一条数据

事务30和事务50分别对这条数据进行修改操作

         每次对记录进行改动,都会记录一条undo日志,每条undo日志也都有一个roll_pointer属性(INSERT操作对应的undo日志没有该属性,因为该记录并没有更早的版本),可以将这些undo日志都连起来,串成一个链表:

        对该记录每次更新后,都会将旧值放到一条undo日志中,就算是该记录的一个旧版本,随着更新次数的增多,所有的版本都会被roll_pointer属性连接成一个链表,我们把这个链表称之为版本链,版本链的头节点就是当前记录最新的值。另外,每个版本中还包含生成该版本时对应的事务id。于是可以利用这个记录的版本链来控制并发事务访问相同记录的行为,那么这种机制就被称之为多版本并发控制(Mulit-Version Concurrency Control MVCC)。 

2、ReadView

ReadView中主要包含4个比较重要的内容:
m_ids:表示在生成ReadView时当前系统中活跃的读写事务的事务id列表。
min_trx_id:表示在生成ReadView时当前系统中活跃的读写事务中最小的事务id,也就是m_ids中的最小值。
max_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。
creator_trx_id:表示生成该ReadView的事务的事务id。

2.1、使用读已提交解决脏读

        此隔离级别的事务在每次查询开始时都会生成一个独立的ReadView。在MuSQL中读已提交和可重复的很大一个区别就是ReadView的生成时机不同。

        假设现在表 table 中只有一条由事务id为10的事务插入的一条记录。
读已提交 —— 每次读取数据前都生成一个ReadView:
        现在系统里有两个事务id分别为80、120的事务在执行。

第1次select的时间点

执行过程 

        在执行SELECT语句时会先生成一个ReadView:

        ReadView的m_ids列表的内容就是[80, 120],min_trx_id为80,max_trx_id为121。

        然后从版本链中挑选可见的记录,从图中可以看出,最新版本的列data的内容是 '222',该版本的trx_id值为80,在m_ids列表内,所以不符合可见性要求(trx_id属性值在ReadView的min_trx_id和max_trx_id之间说明创建ReadView时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版本可以被访问),根据roll_pointer跳到下一个版本。

        下一个版本的列data的内容是'111',该版本的trx_id值也为80,也在m_ids列表内,所以也不符合要求,继续跳到下一个版本。下一个版本的列data的内容是'xx',该版本的trx_id值为10,小于ReadView中的min_trx_id值,所以这个版本是符合要求的,最后返回给用户的版本就是这条列data为'xx'的记录。

        所以有了这种机制,就不会发生脏读问题!因为会去判断活跃版本,必须是不在活跃版本的才能用,不可能读到没有commit的记录。

 不可重复读问题

        然后,我们把事务id为80的事务提交一下,然后再到事务id为120的事务中更新一下表table中data的记录。

最后版本链

 第二次select

        执行过程:

        在执行SELECT语句时会又会单独生成一个ReadView,该ReadView信息如下:

        m_ids列表的内容就是[120](事务id为80的那个事务已经提交了,所以再次生成快照时就没有它了),min_trx_id为120,max_trx_id为121。

        然后从版本链中挑选可见的记录,从图中可以看出,最新版本的列data的内容是'bbb',该版本的trx_id值为120,在m_ids列表内,所以不符合可见性要求,根据roll_pointer跳到下一个版本。
下一个版本的列data的内容是'aaa',该版本的trx_id值为120,也在m_ids列表内,所以也不符合要求,继续跳到下一个版本。
        下一个版本的列name的内容是'222',该版本的trx_id值为80,小于ReadView中的min_trx_id值120,所以这个版本是符合要求的,最后返回给用户的版本就是这条列name为'222'的记录。

 2.2、使用可重复读级别解决不可重复读问题

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

        对于使用REPEATABLE READ隔离级别的事务来说,只会在第一次执行查询语句时生成一个ReadView,之后的查询就不会重复生成了。

        在上面的例子中:

        这个SELECE1的执行过程如下:
        在执行SELECT语句时会先生成一个ReadView:

        ReadView的m_ids列表的内容就是[80, 120],min_trx_id为80,max_trx_id为121。

        然后从版本链中挑选可见的记录,从图中可以看出,最新版本的列data的内容是'222',该版本的trx_id值为80,在m_ids列表内,所以不符合可见性要求(trx_id属性值在ReadView的min_trx_id和max_trx_id之间说明创建ReadView时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版本可以被访问),根据roll_pointer跳到下一个版本。
        下一个版本的列data的内容是'111',该版本的trx_id值也为80,也在m_ids列表内,所以也不符合要求,继续跳到下一个版本。
        下一个版本的列data的内容是'xx',该版本的trx_id值为60,小于ReadView中的min_trx_id值,所以这个版本是符合要求的,最后返回给用户的版本就是这条列data为'xx'的记录。

        之后,我们把事务id为80的事务提交一下,然后再到事务id为120的事务中更新一下表table中data的记录。

        这个SELECE2的执行过程如下:

        因为当前事务的隔离级别为可重复读,而之前在执行SELECE1时已经生成过ReadView了,所以此时直接复用之前的ReadView,之前的ReadView的m_ids列表的内容就是[80, 120],min_trx_id为80,max_trx_id为121。

        根据前面的分析,返回的值还是'xx'。

        也就是说两次SELECT查询得到的结果是重复的,记录的列data值都是'xx',这就是可重复读的含义。

2.3、MVCC下的幻读现象和解决

表中只有一条事务10插入的数据

 第一次select

        在执行SELECT语句时会先生成一个ReadView:

        m_ids列表的内容就是[80],min_trx_id为80,max_trx_id为81。

        然后从版本链中挑选可见的记录,从图中可以看出,最新版本的列data的内容是'xx',版本的trx_id值为10,可以被当前事务访问,最后返回给用户的版本就是这条列data为'xx'的记录。

第二次select

        因为当前事务的隔离级别为可重复读,而之前在执行SELECE1时已经生成过ReadView了,所以此时直接复用之前的ReadView, m_ids列表的内容就是[80],min_trx_id为80,max_trx_id为81。

        然后从版本链中挑选可见的记录,从图中可以看出,最新版本的列data的内容是'222',版本的trx_id值为120,如果被访问版本的trx_id属性值大于或等于ReadView中的max_trx_id值,表明生成该版本的事务在当前事务生成ReadView后才开启,所以该版本不可以被当前事务访问。

        最终,最后返回给用户的版本还是这条列data为'xx'的记录。这是这种情况下,不会出现幻读现象。

特殊幻读现象:

 此时第一次读是 没有数据,第二次 出现一条数据

 就是第一次读如果是空的情况,且在自己事务中进行了该条数据的修改。

2.4、ReadView中的比较规则

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

2.5、总结

        MVCC(Multi-Version Concurrency Control ,多版本并发控制)进行普通的SEELCT查询时才生效。

        它指的就是在使用读已提交、可重复读这两种隔离级别的事务在执行普通的SELECT操作时访问记录的版本链的过程,这样子可以使不同事务的读-写、写-读操作并发执行,从而提升系统性能。

        读已提交、可重复读这两个隔离级别的一个很大不同就是:生成ReadView的时机不同,读已提交在每一次进行普通SELECT操作前都会生成一个ReadView,而可重复读只在第一次进行普通SELECT操作前生成一个ReadView,之后的查询操作都重复使用这个ReadView就好了,从而基本上可以避免幻读现象(就是第一次读如果ReadView是空的情况中的某些情况则避免不了)。

相关文章:

MySQL MVCC原理

全称Multi-Version Concurrency Control&#xff0c;即多版本并发控制&#xff0c;主要是为了提高数据库的并发性能。 1、版本链 对于使用InnoDB存储引擎的表来说&#xff0c;它的聚簇索引记录中都包含两个必要的隐藏列&#xff1a; 1、trx_id&#xff1a;每次一个事务对某条…...

编织文字的魔法:探索WebKit的CSS文本效果

编织文字的魔法&#xff1a;探索WebKit的CSS文本效果 在现代网页设计中&#xff0c;文本不仅仅是信息的载体&#xff0c;更是视觉表现的重要元素。WebKit&#xff0c;作为众多浏览器的核心引擎&#xff0c;支持一系列CSS文本效果&#xff0c;使开发者能够创造出引人注目的文本…...

如何在Linux上部署Ruby on Rails应用程序

在Linux上部署Ruby on Rails应用程序是一个相对复杂的过程&#xff0c;需要按照一系列步骤进行。下面是一个基本的部署过程&#xff0c;涵盖了从安装所需软件到部署应用程序的所有步骤。 安装必要的软件 在部署Ruby on Rails应用程序之前&#xff0c;需要确保Linux系统上安装了…...

极狐GitLab 如何管理 PostgreSQL 扩展?

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署…...

SpringBoot如何使用Kafka来优化接口请求的并发

在Spring Boot中使用 Kafka 来优化接口请求的并发&#xff0c;主要是通过将耗时的任务异步化到Kafka消息队列中来实现。这样&#xff0c;接口可以立即响应客户端&#xff0c;而不需要等待耗时任务完成。 在Spring Boot应用程序中调用Kafka通常涉及使用Spring Kafka库&#xff…...

全面了解不同GPU算力型号的价格!

这两年人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;、深度学习和高性能计算&#xff08;HPC&#xff09;领域的快速发展&#xff0c;GPU算力已成为不可或缺的资源。企业、研究机构乃至个人开发者越来越依赖于GPU加速计算来处理大规模数据集和复杂模…...

Linux网络编程之UDP

文章目录 Linux网络编程之UDP1、端口号2、端口号和进程ID的区别3、重新认识网络通讯过程4、UDP协议的简单认识5、网络字节序6、socket编程接口6.1、socket常见接口6.2、sockaddr通用地址结构 7、简单的UDP网络程序7.1、服务器响应程序7.2、服务器执行命令行7.3、服务器英语单词…...

graham 算法计算平面投影点集的凸包

文章目录 向量的内积&#xff08;点乘&#xff09;、外积&#xff08;叉乘&#xff09;确定旋转方向numpy 的 cross 和 outernp.inner 向量与矩阵计算示例np.outer 向量与矩阵计算示例 python 示例生成样例散点数据图显示按极角排序的结果根据排序点计算向量转向并连成凸包 基本…...

【海外云手机】静态住宅IP集成解决方案

航海大背景下&#xff0c;企业和个人用户对于网络隐私、稳定性以及跨国业务的需求日益增加。静态住宅IP与海外云手机的结合&#xff0c;提供了一种创新的集成解决方案&#xff0c;能够有效应对这些需求。 本篇文章分为三个部分&#xff1b;静态住宅优势、云手机优势、集成解决…...

最新!CSSCI(2023-2024)期刊目录公布!

【SciencePub学术】据鲁迅美术学院7月16日消息&#xff0c;近日&#xff0c;南京大学中国社会科学研究评价中心公布了中文社会科学引文索引&#xff08;CSSCI&#xff09;&#xff08;2023—2024&#xff09;数据库最新入选目录。 C刊一般指CSSCI来源期刊&#xff0c;即南大核心…...

C语言 | Leetcode C语言题解之第237题删除链表中的节点

题目&#xff1a; 题解&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/void deleteNode(struct ListNode* node) {struct ListNode * p node->next;int temp;temp node->val;node->val…...

linux LED代码设计

设计目标&#xff1a; 写RGB LED灭、亮、闪烁等效果&#xff0c;不同颜色也需要设置 #include <iostream> #include <unistd.h> // 对于usleep() #include <fcntl.h> // 对于open(), close() #include <sys/ioctl.h> // 对于ioctl() #include <li…...

Jvm基础(一)

目录 JVM是什么运行时数据区域线程私有1.程序计数器2.虚拟机栈3.本地方法栈 线程共享1.方法区2.堆 二、对象创建1.给对象分配空间(1)指针碰撞(2)空闲列表 2.对象的内存布局对象的组成Mark Word类型指针实例数据&#xff1a;对齐填充 对象的访问定位句柄法 三、垃圾收集器和内存…...

深入理解FFmpeg--软/硬件解码流程

FFmpeg是一款强大的多媒体处理工具&#xff0c;支持软件和硬件解码。软件解码利用CPU执行解码过程&#xff0c;适用于各种平台&#xff0c;但可能对性能要求较高。硬件解码则利用GPU或其他专用硬件加速解码&#xff0c;能显著降低CPU负载&#xff0c;提升解码效率和能效。FFmpe…...

新的铸造厂通过 PROFIBUS 技术实现完全自动化

钢铁生产商某钢以其在厚钢板类别中极高的产品质量而闻名。其原材料&#xff08;板坯连铸机&#xff09;在钢铁厂本地生产&#xff0c;该厂最近新建了一座垂直连铸厂。该项目的一个主要目标是从一开始就完全自动化这座新工厂和整个铸造过程&#xff0c;以高成本效率实现最佳产品…...

【UE5.1】NPC人工智能——04 NPC巡逻

效果 步骤 一、准备行为树和黑板 1. 对我们之前创建的AI控制器创建一个子蓝图类 这里命名为“BP_NPC_AIController_Lion”&#xff0c;表示专门用于控制狮子的AI控制器 2. 打开狮子蓝图“Character_Lion” 在类默认值中将“AI控制器类”修改为“BP_NPC_AIController_Lion” 3…...

计算机视觉主流框架及其应用方向

文章目录 前言一、计算机视觉领域的主要框架1、深度学习框架1.1、TensorFlow1.2、PyTorch 2、神经网络模型2.1、卷积神经网络&#xff08;CNN&#xff09;2.2、循环神经网络&#xff08;RNN&#xff09; 二、框架在计算机视觉任务中的应用1、TensorFlow1.1、概述&#xff1a;1.…...

群晖 搭建alist 记录

docker搭建 使用docker-compose 创建一个 docker-compose.yml version: 3.5services:qbittorrent:image: linuxserver/qbittorrent:latestcontainer_name: qbittorrent# network_mode: hostenvironment:- PUID1000- PGID100- TZAsia/Shanghai- WEBUI_PORT8181 # 将外部端口…...

【北航主办丨本届SPIE独立出版丨已确认ISSN号】第三届智能机械与人机交互技术学术会议(IHCIT 2024,7月27)

由北京航空航天大学指导&#xff0c;北京航空航天大学自动化科学与电气工程学院主办&#xff0c;AEIC学术交流中心承办的第三届智能机械与人机交互技术学术会议&#xff08;IHCIT 2024&#xff09;将定于2024年7月27日于中国杭州召开。 大会面向基础与前沿、学科与产业&#xf…...

深入浅出WebRTC—NACK

WebRTC 中的 NACK&#xff08;Negative Acknowledgment&#xff09;机制是实时通信中处理网络丢包的关键组件。网络丢包是常见的现象&#xff0c;尤其是在无线网络或不稳定连接中。NACK 机制旨在通过请求重传丢失的数据包来减少这种影响&#xff0c;从而保持通信的连续性和质量…...

简单工厂模式、工厂模式和抽象工厂模式的区别

简单工厂模式、工厂模式和抽象工厂模式都是创建型设计模式&#xff0c;它们之间在目的、实现方式和适用场景上存在显著的区别。以下是对这三种模式的详细比较&#xff1a; 一、定义与目的 简单工厂模式&#xff08;Simple Factory Pattern&#xff09; 定义&#xff1a; 简单工…...

JVM-垃圾回收与内存分配

目录 垃圾收集器与内存分配策略 引用 对象的访问方式有哪些?&#xff08;句柄和直接指针&#xff09; Java的引用有哪些类型? 如何判断对象是否是垃圾? 请列举一些可作为GC Roots的对象? 对象头了解吗? mark word&#xff08;hashcode、分代、锁标志位&#xff09;、…...

Jolt路线图

1. 引言 a16z crypto团队2024年7月更新了其Jolt路线图&#xff1a; 主要分为3大维度&#xff1a; 1&#xff09;链上验证维度&#xff1a; 1.1&#xff09;Zeromorph&#xff1a;见Aztec Labs团队2023年论文 Zeromorph: Zero-Knowledge Multilinear-Evaluation Proofs from…...

NEEP-EN2-2019-Text4

英二-2019-Text4摘自赫芬顿邮报《The Huffington Post》2018年6月的一篇名为“Let’s Stop Pretending Quitting Straws Will Solve Plastic Pollution”的文章。 以下为个人解析&#xff0c;非官方公开标准资料&#xff0c;可能有误&#xff0c;仅供参考。&#xff08;单词解释…...

docker 部署wechatbot-webhook 并获取接口实现微信群图片自动保存到chevereto图库等

功能如图&#xff1a; docker部署 version: "3" services:excalidraw:image: dannicool/docker-wechatbot-webhook:latestcontainer_name: wechatbot-webhookdeploy:resources:limits:cpus: 0.15memory: 500Mreservations:cpus: 0.05memory: 80Mrestart: alwayspor…...

OpenWrt安装快速入门指南

在刷新 OpenWrt 固件之前&#xff0c;建议进行以下准备&#xff1a; 1、不要急于安装&#xff0c;慢慢来。如果在安装过程中出现奇怪之处&#xff0c;请先找到答案&#xff0c;然后再继续。 2、准备好设备的精确型号&#xff0c;以便能够选择正确的OpenWrt固件。 3、手上有关…...

AIGC Kolors可图IP-Adapter-Plus风格参考模型使用案例

参考: https://huggingface.co/Kwai-Kolors/Kolors-IP-Adapter-Plus 代码环境安装: git clone https://github.com/Kwai-Kolors/Kolors cd Kolors conda create --name kolors python=3.8 conda activate kolors pip install -r requirements.txt python3 setup.py install…...

从零开始学量化~Ptrade使用教程(七)——期权相关操作

期权交易 可点击证券代码右侧的选&#xff0c;进入期权选择菜单。通过选择标的商品&#xff0c;认购期权和认沽期权中间的选项&#xff08;包括代码、成交价、幅度%、隐波%、内在价值、时间价值等&#xff09;&#xff0c;以及认购期权或认沽期权&#xff0c;选择所需的期权标的…...

TeamViewer关闭访问密码或固定一组密码不变

TeamViewer的新UI界面变化较大&#xff0c;网上的一些信息已经不再有效&#xff0c;更新后的访问密码在如下图所示&#xff1a; 演示的版本为7.21.4—— 设置每次你的设备访问的密码...

iMazing 3 换手机后苹果游戏数据还有吗 换iPhone怎么转移游戏数据

当你想要更换手机&#xff0c;无论是选择升级到最新款iPhone&#xff0c;或者换到“经典”旧款iPhone&#xff0c;单机游戏数据的转移总是让人发愁。本文将详细介绍换手机后苹果游戏数据还有吗&#xff0c;以及换iPhone怎么转移游戏数据&#xff0c;确保你能无缝继续你的游戏体…...

wordpress数据库主机填什么/营销技巧和营销方法培训

修复表中的名字 # Write your MySQL query statement below select user_id, CONCAT(Upper(left(name, 1)), Lower(substring(name, 2))) name from Users order by user_id;使用方法&#xff1a;CONCAT(str1,str2,…) 返回结果为连接参数产生的字符串。如有任何一个参数为NU…...

电商网站维护费用/推广网站公司

1、点击开始运行输入命令 regedit&#xff0c;进入注册表 2、HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\ Wds\rdpwd\Tds\tcp&#xff0c; 修改PortNamber值&#xff0c;&#xff08;默认值是3389&#xff09; 3、HKEY_LOCAL_MACHINE\SYSTEM\Curren…...

网站开发难度和小程序开发难度/搜索引擎广告案例

一、Autoit 上传文件、1.常用语法- WinActivate("title") 聚焦到指定活动窗口- ControlFocus ( "title", "窗口文本", controlID) 设置输入焦点到指定窗口的某个控件上&#xff1b;- WinWait ( "title" , "窗口文本&qu…...

建设中小企业网站/精准推广引流5000客源

2019独角兽企业重金招聘Python工程师标准>>> 开源IDE,LightTable&#xff0c;比较小巧&#xff0c;居然有种完爆我大Sublime的赶脚&#xff0c;可惜全是英文的&#xff0c;特此记录一些用法。 其实就是它自带的帮助文档&#xff0c;不过全是英文&#xff0c;全当练翻…...

临安做网站的公司/100种找客户的方法

对大多数交易员来说&#xff0c;策略的制定仅仅是一种手段&#xff0c;是获利的必要路径。交易系统开发的过程&#xff0c;相对最终投入使用&#xff0c;是比较艰难的&#xff1a;通常&#xff0c;实际交易远比制定交易策略要更有意思。 不过&#xff0c;这会使得交易员采取各…...

如何给局域网 做网站/友链交换网站

选择我们的理由&#xff1a;流量多 月享1500G超出流量不断网,每天50G(通常个人手机每月才30G左右流量)不拉网线&#xff0c;不插卡&#xff0c;三网随意切换 移动-联通-电信通用&#xff0c;开机自动优选当地3网较好的网络&#xff0c;也可以手动一键切换多人共享 支持32(随…...