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

MVCC多版本并发控制相关面试题整理

多版本并发控制是一种用于支持并发事务的数据库管理系统技术,它允许多个事务同时访问数据库,而不会相互干扰或导致数据不一致。MVCC通过在数据库中维护不同版本的数据来实现这一目标,从而允许每个事务看到一致的数据库快照。

并发导致的问题

数据库并发是指在同一时间内,多个事务同时对数据库进行读取和写入操作的能力。以下是三种常见的数据库并发场景:

  1. 读-读并发: 多个事务同时对数据库进行读取操作,彼此之间不涉及写入操作。
  2. 读-写并发: 多个事务同时进行读取和写入操作,存在线程安全问题,会产生脏读、不可重复读、幻读。
  3. 写-写并发: 多个事务同时进行写入操作,可能涉及操作同一条数据,导致数据丢失,事物 1 事物 2 同时更新一条记录时,事物 1 提交,事物 2 也提交,事物 1 回滚后导致覆盖掉了事物 2 的更新。

最早的数据库系统,只有读读之间可以并发,读写,写读,写写都要阻塞。引入多版本之后,只有写写之间相互阻塞(MySQL 自动对涉及的数据行加上即排他锁),其他三种操作都可以并行,这样大幅度提高了InnoDB的并发度。

实现 MVCC

InnoDB 会向数据库中的每行记录增加三个字段:
DB_ROW_ID:隐藏的自增 ID(主键),6字节,如果有主键,则不会包含该列,如果没有主键,会根据DB_ROW_ID 产生一个聚餐索引。
DB_TRX_ID:事务ID,6字节,记录插入或 最后一次更新这条记录的事务 ID,MySQL InnoDB 里面每个事务都会有一个唯一事务 ID,它在事务开始的时候会跟 InnoDB 的事务系统申请的,并且严格按照顺序递增的。
DB_ROLL_PTR:回滚指针,7字节,指向上个版本数据在 undo log 里的位置。

版本链

新 insert 的数据没有 undo log,**DB_ROLL_PTR **字段为空。 当要 update 数据的时候,会先创建 undo log,以及指向该 undo log 的回滚指针 roll_ptr,并且会将 roll_ptr 更新到 **DB_ROLL_PTR **字段中,更新数据的 DB_TRX_ID 属性为当前的事务 ID 。当某条数据被多次修改时,该数据会存在多个版本,通过 DB_ROLL_PTR 链接形成一个类似版本链的概念。
演示文稿1.jpg

当前读和快照读

当前读(Current Read): 当前读是一种读取操作,事务在执行读取时会读取数据库的当前状态,包括其他事务已经提交的变更。当前读允许事务读取最新的实时数据,但也可能受到其他并发事务的影响,可能发生不可重复读等问题。常见的 update/insert/delete、还有 select … for update、select … lock in share mode 都是当前读。
快照读(Snapshot Read): 快照读是一种读取操作,事务在执行读取时会获得一个数据库的快照或一个特定时间点的数据视图。也就是 MVCC 生成的 ReadView。在整个事务执行期间,这个数据视图保持一致,即事务看到的是事务开始时数据库的快照,不受其他事务的影响。用于普通的 select 的语句。

一致性视图(ReadView)

当隔离级别为 RR 时:每开启一个事务,数据库系统会给这个事务分配一个事务 ID,这个 ID 是自增的,所以事物 ID 越大事物越新,当这个事务执行 select 语句的时候,会生成一个当前时间点的事务快照读视图ReadView, ReadView 包含几个属性:
m_ids
创建当前 ReadView 时,系统活跃事务 id 升序的列表,即还未提交的事物 id 列表。
m_low_limit_id (不可见范围的最小(low)id
创建当前 ReadView 时,将要分给下一个事物的 id,也就是当前系统最大事务版本号+1。
m_up_limit_id(可见范围的最大(up)id
创建当前ReadView 时,系统正处于活跃事务最小版本号
m_creator_trx_id
创建当前ReadView的事务 id
代码位置: mysql-8.1.0\storage\innobase\read\read0read.cc
image.png
image.png

可见性判断

当某个事务执行快照读的时候,会创建一个 ReadView 读视图,并且用这个 ReadView 判断当前事务能够看到哪个版本的数据。可能是当前最新的数据,也有可能是该行数据的 undo log(版本链) 里面的某个版本的数据。一个事务启动后,判断某个版本的数据能否被该事务访问,判断流程如下:
1、 如果被访问版本的 DB_TRX_ID 与 该事务创建的 ReadView 中的 m_creator_trx_id 值相同,说明就是当前这个事务在访问它自己修改过的数据。
2、 如果被访问版本的 DB_TRX_ID < ReadView 中的 m_up_limit_id(低水位),表明被访问版本的事务在当前事务生成 ReadView 前已经提交,所以该版本可以被当前事务访问。
3、 如果被访问版本的 DB_TRX_ID >= ReadView 中的 m_low_limit_id(高水位),表明被访问版本的事务在当前事务生成 ReadView 后才开启,所以该版本不可以被当前事务访问。
4、 m_low_limit_id > DB_TRX_ID >= m_up_limit_id <= 之间,这种情况就说明这个数据有可能是在当前事务开始的时候还没有提交的,可以分情况判断:

  • 如果 DB_TRX_ID 不在 m_ids 列表中,说明创建 ReadView 时生成该版本的事务已经被提交,该版本可以被访问。
  • 如果 DB_TRX_ID 在 m_ids 中,则说明read view产生的时候数据还没有提交,但是如果 DB_TRX_ID == creator_trx_id ,那么说明这个数据就是当前事务自己生成的,该版本可以被访问。
  • 如果 DB_TRX_ID 在m_ids 中,且 DB_TRX_ID 不等于creator_trx_id那就说明read view产生的时候数据还没有提交,又不是自己生成的,所以这种情况下,该版本不能被访问。

以上三种情况是通过二分法进行查找判断的。
5、如果该版本的条件都不满足ReadView 的条件时,则通过当前版本的 DB_ROLL_PTR 找到上一个版本,再来和ReadView 条件匹配,直到找到一条满足条件的历史数据,找不到则返回空结果。

RC/RR级别快照读

RC/RR 级别生成 ReadView 的时机是不同的:

  • RR 级别下的某个事务对某条记录进行的第一次 select 会创建一个快照 Read View,此后在调用快照读的时候,使用的还是同一个ReadView,所以只要当前事务在其他事务提交更新之前使用过快照读,那么之后的快照读使用的都是同一个Read View,所以对之后的修改不可见.
  • RC 级别下事务中每次 select 都会生成一个快照和 ReadView,这就是我们在 RC 级别下的事务中可以看到别的事务提交更新的原因。

总之在 RC 隔离级别下,每次快照读都会生成最新的 ReadView;而在 RR 级别下,则是同一个事务中的第一个快照读才会创建ReadView,之后的快照读获取的都是同一个 ReadView。所以说 RR 在 RC 的基础上通过生成 Read View 的时机不同从而解决了不可重复读的问题。

数据删除和purge 线程

而对于删除,其实就是一种特殊的更新,InnoDB 在 info_bits 中用一个标记位 delete_flag 标识是否删除,并不真正将过时的记录删除。当我们在进行判断时,会检查下 delete_flag 是否被标记,如果是,会有专门的 purge 线程来清理。

什么是记录锁,什么是间隙锁?什么是 Next-Key Locks?

记录锁、间隙锁(也称为范围锁)、以及临键锁是三种不同类型的锁,用于管理并发事务的访问,InnoDB 的锁是加上在索引上的。

  1. 记录锁(Record Locks)

这种锁直接应用在数据库表中的记录(行)上。当一个事务请求对某一行的记录进行写操作时,系统可能会给该记录加上记录锁,防止其他事务同时修改同一行。这确保了在给定时间只有一个事务能够修改该记录,从而维护数据的一致性。

  1. 间隙锁(Gap Locks)

间隙锁锁定的是两个记录之间的间隙,左开右开的区间。这主要用于防止其他事务在间隙中插入新的记录,从而确保范围查询的一致性,其它事务在这个间隙做删除操作也会被锁阻塞的。如果一个事务执行范围查询操作并使用了间隙锁,它将锁定查询范围内的所有记录以及这些记录之间的空隙,防止其他事务在这个范围内插入新的记录。间隙锁是可重复读RR隔离级别下特有的。
比如语句select * from user where age>1 and age<10 for update,将会锁住age在(1,10)的范围区间,此时其他事务对该区间的操作都会被阻塞

  1. 临键锁(Next-Key Locks

是通过算法将记录锁间隙锁组合, 锁住的是左开右闭的区间。

MVCC 解决幻读了吗?

快照读(普通 select 语句)的时候,是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,在执行第一个查询语句后,会创建一个 Read View,后续的查询语句利用这个 Read View,通过这个 Read View 就可以在 undo log 版本链找到事务开始时的数据,所以事务过程中每次查询的数据都是一样的,即使中途有其他事务插入了新纪录,是查询不出来这条数据的,所以就很好了避免幻读问题。
当前读(select … lock in share mode、select … for update、insert、 update、 delete 等语句)时,这些语句执行前都会查询最新版本的数据,是通过 Next-Key Locks(记录锁+间隙锁,只在)方式解决了幻读,因为当执行这些语句的时候,会自动加上 Next-Key Locks,如果有其他事务在 Next-Key Locks 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好了避免幻读问题。
如果事务中都使用快照读,那么就不会产生幻读现象;但是如果快照读和当前读混用,就会产生幻读。

临键锁一定解决了幻读问题吗?

按照 MySQL 官方的说法,即使在可重复读的情况下,幻读仍然是可能的。官方说法https://bugs.mysql.com/bug.php?id=63870,所以有更高的隔离级别出现。

相关文章:

MVCC多版本并发控制相关面试题整理

多版本并发控制是一种用于支持并发事务的数据库管理系统技术&#xff0c;它允许多个事务同时访问数据库&#xff0c;而不会相互干扰或导致数据不一致。MVCC通过在数据库中维护不同版本的数据来实现这一目标&#xff0c;从而允许每个事务看到一致的数据库快照。 并发导致的问题…...

02-鸿蒙学习之4.0todoList练习

02-鸿蒙学习之4.0todoList练习 代码 /*** 1:组件必须使用Component装饰* 2.Entry 装饰哪个组件&#xff0c;哪个组件就呈现在页面上* 3.被Entry 装饰的入口组件。build&#xff08;&#xff09;必须有且仅有一个根 ** 容器 ** 组件* 其他的自定义组件&#xff0c;build() 中…...

springsecurity5.7.x和springsecurity6.x配置文件对比

springsecurity5和springsecurity6如何要实现多种登录方式,自定义登录方式都是一样的操作步骤,主要有四个步骤。 一、自定义登录用户实体实现springsecurity中的UserDetails接口 二、自定义登录用户实现类实现springsecurity中的UserDetailsService接口 三、自定义登录用户au…...

brat文本标注工具——安装

目录 一、Linux系统安装 1. centOS系统 2. Ubuntu系统 3. macOS系统 4.说明 二、Google Chrome安装 1. 打开命令行&#xff0c;切换到管理者权限 2. 安装依赖 3. 下载Google浏览器的安装包 4. 安装Google Chrome 三、yum更新 四、Apache安装 安装Apache 启动Apac…...

麒麟操作系统网桥配置

网桥概念&#xff1a; Bridge 是 Linux 上用来做 TCP/IP 二层协议交换的设备&#xff0c;其功能可 以简单的理解为是一个二层交换机或者 Hub&#xff1b;多个网络设备可以连接 到同一个 Bridge&#xff0c;当某个设备收到数据包时&#xff0c;Bridge 会将数据转发 给其他设备。…...

禁奥义·SQL秘籍

sql secret scripts sql 语法顺序、执行顺序、执行过程、要点解析、优化技巧。 1、语法顺序 如上图所示&#xff0c;为 sql 语法顺序与执行顺序对照图。其具体含义如下&#xff1a; 0、select&#xff1a; 用于从数据库中选取数据&#xff0c;即表示从数据库中查询到的数据的…...

浅谈用户体验测试的主要功能

用户体验(User Experience&#xff0c;简称UX)在现代软件和产品开发中变得愈发重要。为了确保产品能够满足用户期望&#xff0c;提高用户满意度&#xff0c;用户体验测试成为不可或缺的环节。本文将详细探讨用户体验测试的主要功能&#xff0c;以及它在产品开发过程中的重要性。…...

2021年6月3日 Go生态洞察:Fuzzing技术的Beta测试

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

全新Self-RAG框架亮相,自适应检索增强助力超越ChatGPT与Llama2,提升事实性与引用准确性

全新Self-RAG框架亮相,自适应检索增强助力超越ChatGPT与Llama2,提升事实性与引用准确性 1. 基本思想 大型语言模型(LLMs)具有出色的能力,但由于完全依赖其内部的参数化知识,它们经常产生包含事实错误的回答,尤其在长尾知识中。 为了解决这一问题,之前的研究人员提出了…...

句子相似度计算

文章目录 https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2 这里使用预训练的 nreimers/MiniLM-L6-H384-uncased 模型&#xff0c;并在 1B 句对数据集上微调。 如果你使用 sentence-transformers pip install -U sentence-transformers可以这样使用模型 impor…...

高级IO select 多路转接实现思路

文章目录 select 函数fd_set 类型timeval 结构体select 函数的基本使用流程文件描述符就绪条件以select函数为中心实现多路转接的思路select 缺陷 select 函数 int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); selec…...

C++学不会?一篇文章带你快速入门

1. 命名空间 1.1 命名空间的概念 C命名空间是一种用于避免名称冲突的机制。它允许在多个文件中定义相同的函数、类或变量&#xff0c;而不会相互干扰。 1.2 命名空间的定义 namespace是命名空间的关键字&#xff0c;后面是命名空间的名字&#xff0c;然后后面一对 {},{}中即…...

【加密相册】 隐私协议

【加密相册】隐私协议 1.个人信息的收集和使用 我们的应用程序不会收集用户的个人信息&#xff0c;包括姓名、地址、电子邮件地址、电话号码等。我们不会追踪用户的位置信息或共享用户的个人信息。 2. 非个人化信息的收集和使用 我们的应用程序可能会收集一些非个人化信息&a…...

超越基础:释放 Systemd 的全部潜力【systemd 二】

&#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 超越基础&#xff1a;释放 Systemd 的全部潜力【systemd 二】 前言第一&#xff1a;系统服务高级管理高级服务配置&#xff1a;环境变量设置&#xff1a;服务单元文件的高级选…...

Flask学习二:项目拆分、请求与响应、cookie

教程 教程地址&#xff1a; 千锋教育Flask2框架从入门到精通&#xff0c;Python全栈开发必备教程 老师讲的很好&#xff0c;可以看一下。 项目拆分 项目结构 在项目根目录下&#xff0c;创建一个App目录&#xff0c;这是项目下的一个应用&#xff0c;应该类似于后端的微服…...

6、Qt延时的使用

一、sleep() 1、说明 QThread类中如下三个静态函数&#xff1a; QThread::sleep(n); //延迟n秒 QThread::msleep(n); //延迟n毫秒 QThread::usleep(n); //延迟n微妙 这种方式使用简单&#xff0c;但是会阻塞线程&#xff0c;有界面时界面会卡死&#xff0c;一般在非GUI线…...

《Effective C++》条款26

尽可能延后变量定义式的出现时间 string test(const string& passwd) {string s;if (s.size() < MinLenth){throw logic_error("passwd is too short");} } 这段代码的问题是&#xff1a;如果抛出了异常&#xff0c;那么定义的string对象将面临毫无意义的构造…...

np.random.uniform() 采样得到的是一个高维立方体,而不是球体,为什么?

在代码中&#xff0c;采样是通过以下方式完成的&#xff1a; samples self.center np.random.uniform(-self.radius, self.radius, (num_samples, len(self.center))) 这里&#xff0c;np.random.uniform函数在每个维度独立地生成了一个介于-self.radius和self.radius之间的…...

1 时间序列模型入门: LSTM

0 前言 循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一种用于处理序列数据的神经网络。相比一般的神经网络来说&#xff0c;他能够处理序列变化的数据。比如某个单词的意思会因为上文提到的内容不同而有不同的含义&#xff0c;RNN就能够很好…...

1-Python与设计模式--单例模式

23种计模式之 前言 &#xff08;5&#xff09;单例模式、工厂模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式、(7)代理模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式、桥梁模式、&#xff08;11&#xff09;策略模式、责任链模式、命令模式、中介者模…...

Rust之构建命令行程序(一):接受命令行参数

开发环境 Windows 10Rust 1.73.0 VS Code 1.84.2 项目工程 这次创建了新的工程minigrep. IO工程&#xff1a;构建命令行程序 这一章回顾了到目前为止你所学的许多技能&#xff0c;并探索了一些更标准的库特性。我们将构建一个与文件和命令行输入/输出交互的命令行工具&#…...

Go 谈论了解Go语言

一、引言 Go的历史回顾 Go语言&#xff08;通常被称为Go或Golang&#xff09;由Robert Griesemer、Rob Pike和Ken Thompson在2007年开始设计&#xff0c;并于2009年正式公开发布。这三位设计者都曾在贝尔实验室工作&#xff0c;拥有丰富的编程语言和操作系统研究经验。Go的诞生…...

《C++PrimerPlus》第9章 内存模型和名称空间

9.1 单独编译 Visual Studio中新建头文件和源代码 通过解决方案资源管理器&#xff0c;如图所示&#xff1a; 分成三部分的程序&#xff08;直角坐标转换为极坐标&#xff09; 头文件coordin.h #ifndef __COORDIN_H__ // 如果没有被定义过 #define __COORDIN_H__struct pola…...

uniapp上架app store详细攻略

目录 uniapp上架app store详细攻略 前言 一、登录苹果开发者网站 二、创建好APP 前言 uniapp开发多端应用&#xff0c;打包ios应用后&#xff0c;会生成一个ipa后缀的文件。这个文件无法直接安装在iphone上&#xff0c;需要将这个ipa文件上架app store后&#xff0c;才能通…...

面试:线上问题处理

文章目录 在处理线上问题时&#xff0c;你的排查思路和步骤是什么线上偶发性问题如何处理和跟踪当系统出现大量错误日志时&#xff0c;你会如何分析和解决问题在高并发场景中&#xff0c;如何排查和解决线程安全问题当系统出现大规模的故障时&#xff0c;你的应急处理和恢复策略…...

Vue3中快速Diff算法

在Vue3中&#xff0c;快速Diff算法主要用于优化虚拟DOM的更新过程&#xff0c;减少不必要的DOM操作&#xff0c;提高性能。以下是对Vue3源码中快速Diff算法的解读&#xff1a; 首先&#xff0c;我们需要引入Vue3的相关包&#xff1a; import { reactive, toRefs, watch } fro…...

ROS2+STM32小车红外对射光电计数器模块资料

数据&#xff1a;一个周长内有20个孔洞或者20个分隔。外径&#xff1a;6.8cm 图片不是实物图&#xff0c;是示意图 因为没有串口&#xff0c;所以不可能会发送出数字的&#xff0c;就是通过电压变化次数来计算距离或者其他数据 有遮挡时&#xff0c;输出高电平&#xff0c;无遮…...

Android设计模式--桥接模式

闻正言&#xff0c;行正道&#xff0c;左右前后皆正人 一&#xff0c;定义 将抽象部分与实现部分分离&#xff0c;使它们都可以独立地进行变化 二&#xff0c;使用场景 从模式的定义中&#xff0c;我们大致可以了解到&#xff0c;这里的桥接的作用其实就是连接抽象部分与实现…...

1、分布式锁实现原理与最佳实践(一)

在单体的应用开发场景中涉及并发同步时&#xff0c;大家往往采用Synchronized&#xff08;同步&#xff09;或同一个JVM内Lock机制来解决多线程间的同步问题。而在分布式集群工作的开发场景中&#xff0c;就需要一种更加高级的锁机制来处理跨机器的进程之间的数据同步问题&…...

Autosar通信实战系列03-NM模块要点及其配置介绍

本文框架 前言1. NM模块要点介绍1.1 NM基本功能介绍1.2 NM协同功能介绍2. NM配置2.1 NmGlobalConfig配置2.2 NmChannelConfigs配置前言 在本系列笔者将结合工作中对通信实战部分的应用经验进一步介绍常用,包括但不限于通信各模块的开发教程,代码逻辑分析,调测试方法及典型问…...