MySQL:简述多版本并发控制MVCC

news2024/9/22 13:33:15

一、MVCC的概念

1、MVCC

数据库并发场景有三种,分别为:
(1)读读:不存在任何问题,也不需要并发控制。
(2)读写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读、幻读、不可重复读。
(3)写写:有线程安全问题,可能存在更新丢失问题。

MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。是一种用来解决读写冲突的无锁并发控制,也就是为事务分配单项增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照,所以MVCC可以为数据库解决以下问题:
(1)在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能;
(2)解决脏读、幻读、不可重复读等事务隔离问题,但是不能解决更新丢失问题。

2、当前读

像共享锁、排它锁、update、insert、delete这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。

-- 共享锁
select lock in share mode();
-- 排他锁
select ... for update;

3、快照读

像不加锁的select操作就是快照读,即不加锁的非阻塞读。快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读。

快照读的实现是基于多版本并发控制,即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本。

二、MVCC的实现原理

MVCC模块在MySQL中的具体实现是由三个隐式字段、Undo日志、ReadView三个组件来实现的。

MVCC 的实现方式:本质上,MVCC 就是用 UndoLog 链表实现。事务以排它锁的方式修改原始数据,把修改前的数据存放于 UndoLog,通过回滚指针与数据关联,如果修改成功,什么都不做,如果修改失败,则恢复 UndoLog中的数据。

1、隐式字段

InnoDB 每个聚簇索引都有 4 个隐藏字段,分别是主键(ROW_JD),最近更改的事务ID(TRX_ID),UndoLog 的指针(隔离核心),索引删除标记(当删除时,不会立即删除,而是打标记,然后异步删除)。本质上,MVCC 就是用 UndoLog 链表实现。
(1)DB_ROW_JD:6字节,隐藏的主键,如果数据表没有主键,那么innodb会自动生成一个6字节的row_id。
(2)DB_TRX_ID:6字节,最近修改事务id,记录创建这条记录或者最后一次修改该记录的事务id,是MVCC的核心。
(3)DB_ROLL_PTR:7字节,回滚指针,指向这条记录的上一个版本,用于配合UndoLog,指向上一个旧版本。
在这里插入图片描述

2、UndoLog

UndoLog被称之为回滚日志,表示在进行insert,delete,update操作的时候产生的方便回滚的日志。
(1)当进行insert操作的时候,产生的UndoLog只在事务回滚的时候需要,并且在事务提交之后可以被立刻丢弃。
(2)当进行update和delete操作的时候,产生的UndoLog不仅仅在事务回滚的时候需要,在快照读的时候也需要,所以不能随便删除,只有在快照读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除。

当数据发生更新和删除操作的时候都只是设置一下老记录的deleted_bit,并不是真正的将过时的记录删除,因为为了节省磁盘空间,innodb有专门的purge线程来清除deleted_bit为true的记录,如果某个记录的deleted_id为true,并且DB_TRX_ID相对于purge线程的ReadView可见,那么这条记录一定是可以被清除的。

下面我们来看一下UndoLog生成的记录链
1、假设有一个事务编号为1的事务向表中插入一条记录,那么此时行数据的状态为:
在这里插入图片描述
2、假设有第二个事务编号为2对该记录的name做出修改,改为lisi。
(1)在事务2修改该行记录数据时,数据库会对该行加排他锁,然后把该行数据拷贝到undolog中,作为旧记录,即在undolog中有当前行的拷贝副本。
(2)拷贝完毕后,修改该行name为lisi,并且修改隐藏字段的事务id为当前事务2的id,回滚指针指向拷贝到undolog的副本记录中。
(3)事务提交后,释放锁。
在这里插入图片描述
3、假设有第三个事务编号为3对该记录的age做了修改,改为32。
(1)在事务3修改该行数据的时,数据库会对该行加排他锁。然后把该行数据拷贝到undolog中,作为旧纪录,发现该行记录已经有undolog了,那么最新的旧数据作为链表的表头,插在该行记录的undolog最前面。
(2)拷贝完毕后,修改该行age为32岁,并且修改隐藏字段的事务id为当前事务3的id,回滚指针指向刚刚拷贝的undolog的副本记录。
(3)事务提交,释放锁。
在这里插入图片描述
从上述的一系列图中,大家可以发现,不同事务或者相同事务的对同一记录的修改,会导致该记录的undolog生成一条记录版本线性表,即链表,undolog的链首就是最新的旧记录,链尾就是最早的旧记录。

3、ReadView

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

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

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

Read View中的三个全局属性:
(1)trx_list:一个数值列表,用来维护Read View生成时刻系统正活跃的事务ID(1,2,3)。
(2)up_limit_id:记录trx_list列表中事务ID最小的ID(1)。
(3)low_limit_id:Read View生成时刻系统尚未分配的下一个事务ID(4)。

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

三、MVCC的整体处理流程

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

具体流程如下:
(1)先拿该行记录的事务ID-4去跟Read View中的up_limit_id-1相比较,判断是否小于,通过对比发现不小于,所以不符合条件。
(2)继续判断事务4是否大于等于low_limit_id-5,通过比较发现也不大于,所以不符合条件。
(3)继续判断事务4是否处理trx_list列表中,发现不再次列表中,那么符合可见性条件。所以事务4修改后提交的最新结果对事务2的快照是可见的,因此,事务2读取到的最新数据记录是事务4所提交的版本,而事务4提交的版本也是全局角度的最新版本。

如下图所示:
在这里插入图片描述

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

因为Read View生成时机的不同,从而造成RC(读未提交)、RR(读已提交)级别下快照读的结果的不同。

1、RR(读已提交)级别

在RR(读已提交)级别下,某个事务对某条记录的第一次快照读会创建一个快照即Read View,将当前系统活跃的其他事务记录起来,此后在调用快照读的时候,还是使用的是同一个Read View,所以只要当前事务在其他事务提交更新之前使用过快照读,那么之后的快照读使用的都是同一个Read View,所以对之后的修改不可见。

2、RR(读已提交)级别

在RR(读已提交)级别下,快照读生成Read View时,Read View会记录此时所有其他活动和事务的快照,这些事务的修改对于当前事务都是不可见的,而早于Read View创建的事务所做的修改均是可见。

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

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

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

相关文章

App弱网测试是怎么测试的!

一、网络测试的一般流程 step1&#xff1a;首先要考虑网络正常的情况 ① 各个模块的功能正常可用 ② 页面元素/数据显示正常 step2&#xff1a;其次要考虑无网络的情况 ① APP各个功能在无网络情况下是否可用 ② APP各个页面之间切换是否正常 ③ 发送网络请求时是否会…

算法力扣刷题记录 九十【739. 每日温度】

前言 单调栈第一篇。单调栈解题思路如何&#xff1f; 一、题目阅读 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会…

2024 Python3.10 系统入门+进阶(十):Python字典及其常用操作详解

目录 一、初始化1.1 {}--直接创建字典1.2 dict()函数--创建字典1.3 fromkeys()方法--创建一个新字典 二、元素访问2.1 使用中括号[]语法2.2 get()方法--获取字典中指定键的值2.3 setdefault()方法--获取字典中指定键的值 三、新增和修改3.1 直接赋值3.2 update()方法--更新字典…

RabbitMQ练习(Routing)

1、RabbitMQ教程 《RabbitMQ Tutorials》https://www.rabbitmq.com/tutorials 2、环境准备 参考&#xff1a;《RabbitMQ练习&#xff08;Hello World&#xff09;》和《RabbitMQ练习&#xff08;Work Queues&#xff09;》。 确保RabbitMQ、Sender、Receiver、Receiver2容器…

人工智能训练师一级(高级技师)、二级(技师)考试指南

随着经济快速发展&#xff0c;人工智能技术在制造业、交通运输、农业、医疗健康、金融服务、物流配送以及城市服务等多个领域得到了广泛的应用。不仅带来产业的转型升级&#xff0c;更是对具备相应技能的人工智能训练师需求的激增。 根据教育部发布的《关于做好职业教育“…

BugKu练习记录:把猪困在猪圈里

题目&#xff1a; 用base64解码 再对应猪圈密码解码&#xff0c;得到答案 t h i s i s p i g p a s s w o r d

house of pig

文章目录 house of pig介绍&#xff1a;利用条件&#xff1a;利用流程&#xff1a; 例题&#xff1a;利用&#xff1a; 总结&#xff1a; house of pig 介绍&#xff1a; House of Pig 是一个将 Tcache Stash Unlink Attack 和 FSOP 结合的攻击&#xff0c;同时使用到了 Larg…

MQ专题:事务消息的实现方式

方案 事务消息投递的过程 step1&#xff1a;开启本地事务step2&#xff1a;执行本地业务step3&#xff1a;消息表t_msg写入记录&#xff0c;status为0&#xff08;待投递到MQ&#xff09;step4&#xff1a;提交本地事务step5&#xff1a;若事务提交成功&#xff0c;则投递消息…

【原创教程】电气电工13:按钮开关指示灯篇

按钮开关在电气电工工作中,看似简单,但是有些细节问题,我们还是要注意的。电气电工工作是一个完整的体系,任何一件事疏忽,都会埋下安全隐患。 首先我们来看下 开关按钮的定义: 按钮开关是指利用按钮推动传动机构,使动触点与静触点按通或断开并实现电路换接的开关。按…

软件测试面试题!收藏起来,每天看一看,月薪20K!

初级测试总结题&#xff01;必背&#xff01;必背&#xff01;必背&#xff01; 1&#xff09;软件的概念&#xff1f; 软件是计算机系统中与硬件相互依存的一部分&#xff0c;包括程序、数据以及与其相关文档的完整集合。 2&#xff09;软件测试的概念&#xff1f; 使用人…

讲透一个强大的算法模型,Transformer

Transformer 模型是一种基于注意力机制的深度学习模型&#xff0c;广泛应用于自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;如机器翻译、文本生成和语义理解。 它最初由 Vaswani 等人在2017年的论文《Attention is All You Need》中提出。它突破了传统序列模型&am…

搬运5款实用工具,帮你更好地完成各种任务

​ 在日常工作和生活中&#xff0c;使用各种工具来提升效率和简化任务变得尤为重要。本文将介绍几款实用的工具&#xff0c;帮助你更好地完成各种任务。 1. 自动化脚本——AutoHotkey ​ AutoHotkey是一款功能强大的自动化脚本编写工具&#xff0c;可以用来自动执行日常任务&…

【网络安全】漏洞挖掘

漏洞描述 Spring框架为现代基于java的企业应用程序(在任何类型的部署平台上)提供了一个全面的编程和配置模型。 Spring Cloud 中的 serveless框架 Spring Cloud Function 中的 RoutingFunction 类的 apply 方法将请求头中的“spring.cloud.function.routing-expression”参数…

餐饮_零售_麻辣烫_水果店_零食店_生鲜店等收银系统

介绍 多商户多门店的Sass收银系统。适用于餐饮_零售_麻辣烫_水果店_零食店_生鲜店等收银系统&#xff0c;包含windows收银pos端、商家小程序管理端、商家运营端、电子会员、电子小票 软件架构 收银Pos&#xff1a;vue2、node、electron、sqlite、antd 后端服务&#xff1a;spri…

【如何用本机的Navicat远程连接到ubuntu服务器上的mysql】

文章目录 版本一、ubuntu服务器安装mysql5二、远程连接——mysql配置1.创建新mysql用户2.修改配置文件3.查看端口是否开启 三、远程连接——Navicat 版本 mysql:5.7.32 服务器&#xff1a;ubuntu20.04 PC:win10 一、ubuntu服务器安装mysql5 因为ubuntu20.04默认mysql其实是my…

Windows超好用的命令行工具--Cmder 赶紧把cmd丢了吧!

简介 Cmder 是一个现代化的命令行工具可以智能提示&#xff0c;高亮显示文件夹… 1. 官网地址&#xff1a;Cmder下载地址 2. 滑倒最下面可以看到以下按钮 3. 解压到自己想要保存的地址&#xff08;⚠️记住这个路径&#xff09; 比如我解压到了C:\Cmder\Cmder.exe(⚠️不推…

变天了!24岁硕士年薪50万元,博士年薪200万起!人才缺口100万

从上海交大硕士毕业的00后表示&#xff0c;“24岁硕士毕业时年薪50万元&#xff0c;到了30岁大概能升到P7(注&#xff1a;职级名称&#xff09;&#xff0c;那时就能年薪百万了。” 他今年入职腾讯&#xff0c;担任AI算法工程师&#xff0c;成为AI风口下第一批就业的年轻人。 …

CUDA 内核函数

文章目录 一、简介二、实现代码三、实现效果参考资料 一、简介 CUDA为我们提供了可扩展的编程模型&#xff1a;它的核心是三个关键的抽象——线程组的层次结构、共享内存和阻塞同步——它们只是作为一组最小的语言扩展暴露给外部使用人员。这些抽象提供细粒度数据并行性和线程并…

MyBatis的学习————上篇

目录 一、MyBatis简介 1、MyBatis的历史 2、MyBatis的特性 3、和其它持久化层技术的比较 二、搭建MyBatis 1、开发环境 ​编辑2、创建Maven工程 3、创建MyBatis核心配置文件 4、创建mapper接口 5、创建Mybatis的映射文件 6、测试功能 7、功能优化 8、修改和删除方…

重生奇迹MU最合适PK的几个职业

重生奇迹MU是一款备受玩家青睐的经典游戏&#xff0c;其中的PK系统更是吸引了众多玩家的关注。在众多职业中&#xff0c;哪些职业最适合PK呢&#xff1f; PK作为重生奇迹MU的一种娱乐方式&#xff0c;已成为该游戏核心系统之一&#xff0c;并在多年的流行中仍能带给玩家许多乐…