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

MySQL--深入理解MVCC机制原理

什么是MVCC?

MVCC全称 Multi-Version Concurrency Control,即多版本并发控制,维持一个数据的多个版本,主要是为了提升数据库的并发访问性能,用更高性能的方式去处理数据库读写冲突问题,实现无锁并发。

什么是快照读和当前读?

  • 快照读:不加锁非阻塞读,快照读要求数据库隔离级别不能是串行化,否则会退化到当前读,快照读是基于多版本并发控制的,因为是基于多版本并发控制,所以快照读可能读取的不是最新的数据。
  • 当前读:当前读就是读取最新的数据版本,快照读读取的时候,会对读取的数据加锁,读取的时候其他事务不能修改当前数据。

MVCC和快照读、当前读的关系?

MVCC 多版本并发控制,而快照就是数据的一个版本,MVCC 的无锁并发就是依赖快照读机制实现的。

MVCC的实现原理?

MVCC 实现依赖于数据库记录中的三个隐式字段、undo日志、Read View 版本链,本篇讨论皆基于 MySQL 的 InnoDB 存储引擎。

三个隐式字段:

隐式字段,是我们正常来看看不到的字段,数据库的每行数据除了我们看到的字段之外,还有三个我们看不到的字段。

  • DB_TRX_ID:记录当前事务最后一次修改的事务ID,即事务 ID,事务 ID 是递增的。
  • DB_ROW_ID:隐藏的自增主键ID,如果数据库没有主键ID,数据库会自动生成一个 6个字节的 DB_ROW_ID。
  • DB_ROLL_PTR:回滚指针,指向上一个数据版本。

简单图例:

在这里插入图片描述

undo log 日志:

我们都知道undo log 日志是回滚日志,是数据库保证数据一致性的一个支撑,当出现异常情况时候,通过 undo log 日志来进行数据回滚,其实它还有其他作用,undo log 又分为两种,如下:

  • insert undo log,insert 操作时候产生的日志,只会在发生异常需要进行回滚的时候使用,事务提交后,undo log 就没有用处了,就会被丢弃。
  • update undo log 和 delete undo log,这两类 undo log 不仅在事务回滚时候要用到,同时在快照读的时候也会用到。

undo log 也会记录一条版本链表,每次修改数据的时候,数据库会先把当前数据拷贝一份到 undo log中,然后再对数据进行修改,最在undo log 中最新修改的数据副本会在链的头部,同时它有一个回滚指针指向他的上一个版本。

Read View:

Read View 是事务执行快照读产生的视图,在事务执行快照读的时候,系统会以当前时刻生成一个快照,以此来维护系统此时活跃的事务id,用来做可见性判断,当某个事务进行快照读的时候,我们根据 Read View 来判断当前事务可以读取哪个版本的数据,然后就去该数据的 undo log 里面找数据,当然也可能是读取最新的数据。

Read View 遵守可见性规则,它的三个属性如下:

  • trx_list:用来维护 Read View 生成时候系统活跃的事务ID,是一个列表。
  • up_limit_id:活跃事务ID中最小的ID。
  • low_limit_id:Read View 生成时候,系统将要分配的下一个事务ID。

可见性算法主要是把要修改的数据的最新版本的事务ID,即DB_TRX_ID取出来,与当前系统中活跃的其他事务ID去对比,而Read View 就维护了这些活跃的事务ID,如果在 Read View 中找不到合适条件的数据记录,就会去 undo log 日志根据回滚指针 DB_ROLL_PTR 来找数据记录直到找到为止。

Read View 的比较流程如下:

注意事务ID 是递增的。

  • 第一步,比较 DB_TRX_ID < up_limit_id, 是否小于活跃事务 Read View中最小的事务ID,如果小于,则当前事务能看到 DB_TRX_ID 所在的记录,否则进入第二个判断。
  • 第二步,比较 DB_TRX_ID >=low_limit_id, 是否大于等于下一个将要发生的事务ID,如果大于等于则代表 DB_TRX_ID 所在的记录在 Read View生成后才出现的,那对当前事务肯定不可见,否则进入第三个判断。
  • 第三步, 判断 DB_TRX_ID 是否在活跃事务 Read View 之中,如果在,则代表我 Read View 生成时刻,你这个事务还在活跃,还没有Commit,你修改的数据,我当前事务也是看不见的,如果不在,则说明,这个事务在 Read View 生成之前就已经 Commit 了,因为第一步、第二步已经判断了是否小于最小活跃事务ID和是否是将要发生的事务ID,两者都不是,同时又不在 活跃事务 Read View 中,只能说明在这个事务 Read View 在当前是事务发生之前了,当前事务理所当然能够看到。

简易流程如下:

在这里插入图片描述

读已提交(Read Committed)、可重复读(Repeatable Read) 隔离级别下的快照读的区别?

读已提交(Read Committed)、可重复读(Repeatable Read) 隔离级别下的快照读最大的区别就是生成 Read View 时机不同。

  • 可重复读(Repeatable Read) 隔离级别下,一个事务只有在第一次读取数据的时候生成一个Read View,Read View 记录当前活跃的事务ID,后面继续读取数据时候,如果用到快照读,那他使用的还是第一次读取时候的 Read View,这也是为什么可重复读(Repeatable Read) 隔离级别下,看不到别的事务的修改记录的原因。
  • 读已提交(Read Committed) 隔离级别下,事务开启后,每次使用快照读的时候,都会重新生成一个活跃事务ID,第一读取和第二次读取使用的不是同一个 Read View,那第二次读取的时候,第一次读取时候的 Read View 中的某些事务可能已经提交了,那在第二次快照读的时候就可以看到了,这也是在读已提交(Read Committed) 隔离级别下可以看到别的事务提交的记录的原因 。

MVCC解决了什么问题?

想要知道MVCC解决了什么问题,我们要先知道数据库多个事务并发访问会有什么问题,数据库并发访问场景如下:

  • 读读并发:多个事务同时读取同一份数据,不存在问题,无需进行并发控制。
  • 读写并发:多个事务同时读写同一份数据,有线程安全问题,可能会脏读、幻读、不可重复度问题。
  • 写写并发:多个事务同时对同一份数据写,可能会有更新丢失的情况。

而MVCC 就是解决以上三种并发中的读写并发问题,是一种无所并发控制,可以解决脏读、不可重复读问题,可以解决部分场景的幻读问题。

什么是幻读?MVCC可以解决幻读问题吗?

MVCC 可以解决快照读的幻读问题,MVCC 机制是依赖 快照读、undo log、Read View 来实现的,可以解决快照读的幻读问题,但是不能解决 update、delete 的幻读问题,因为这些操作是当前读。

以下讨论基于可重复读(Repeatable Read) 隔离级别。

当前读幻读演示:

时间事务A事务B
1开始事务
2第一次查询:select * from user where id > 1;
3开始事务
4执行insert: INSERT INTO user(id, user_name, user_code, age, address, hobby)VALUES(6, ‘赵六’, ‘TC-00000006’, 26, ‘广西’, ‘羽毛球’);
5提交事务
6第二次查询:select * from user where id > 1;
7修改数据:update user set name = ‘赵六国’ where id = 6;
8第三次查询:select * from user where id >1;
9提交事务

流程解释:

  • 在第2个时间点的时候,快照读,可以得到 id 大于 1的数据。
  • 在第6个时间点的时候,虽然时间点4插入了一条 id 为6的数据,并且在时间点5提交了事务,但是时间点6还是查询不到 id 为6的这条数据,查询结果和第2个时间点的查询结果没有区别。
  • 在第7个时间点的时候,查询结果就有了变化,因为 update 操作是当前读,而事务B在第5个时间点已经提交了一条 id 为6的数据,根据当前读的规则,此刻是可以读取到 id 为6 的数据,也就可以更新 id 为 6 的数据。
  • 第8个时间点的时候,执行第三次查询,此时是基于当前最新版本查询的,所以会查询到事务B提交的 id 为6的数据,对比第一次、第二次查询,多出了 id 为6的数据,这就是幻读

当前读的幻读问题怎么解决?

加锁解决,关于锁的介绍,传送门如下:

MySQL–锁机制详解

#共享锁
SELECT * FROM user LOCK IN SHARE MODE;  
# 排他锁
SELECT * FROM user FOR UPDATE; 
# 排他锁
INSERT INTO  user 
# 排他锁
UPDATE user 
# 排他锁
DELETE FROM  user 

注意:INSERT、UPDATE 、DELETE 操作数据库默认加排他锁。

解决幻读问题演示:

时间事务A事务B
1开始事务
2第一次查询:select * from user where id > 5 lock in share mode;
3事务A显示加了间隙锁
4开始事务
5执行insert: INSERT INTO user(id, user_name, user_code, age, address, hobby)VALUES(6, ‘赵六’, ‘TC-00000006’, 26, ‘广西’, ‘羽毛球’);
6阻塞了,处于等待状态
7select * from user where id > 5
8提交事务
9事务A提交了,释放了间隙锁,事务B 执行 INSERT 操作
10提交事务
  • 在第2个时间点的时候,使用 lock in share mode 语法显示加锁了,不仅表中存在的数据加锁了,而且还给 id>5 的区间加了间隙锁
  • 因为时间点2的操作,给 id>5 的区间加了间隙锁 ,所以事务B 在时间点5的时候执行 INSERT 操作的时候,出现了阻塞。
  • 因为时间点5的 INSERT 操作被阻塞了,所以这次查询的数据跟时间点2的查询结果完全一致。
  • 事务B想要执行 INSERT 成功,必须要等待事务A 提交事务释放锁,这就解决了幻读问题。

MVCC可以解决更新丢失问题吗?

MVCC 解决的是读写并发问题,而更新丢失是写写并发问题,MVCC不能解决更新丢失问题,更新丢失依赖数据库的隔离级别来解决。

如有不正确的地方请各位指出纠正。

相关文章:

MySQL--深入理解MVCC机制原理

什么是MVCC&#xff1f; MVCC全称 Multi-Version Concurrency Control&#xff0c;即多版本并发控制&#xff0c;维持一个数据的多个版本&#xff0c;主要是为了提升数据库的并发访问性能&#xff0c;用更高性能的方式去处理数据库读写冲突问题&#xff0c;实现无锁并发。 什…...

数据挖掘简介与应用领域概述

数据挖掘&#xff0c;作为信息技术领域中的重要分支之一&#xff0c;旨在从大量数据中发现潜在的模式、关联和趋势&#xff0c;以提取有用的信息和知识。在信息爆炸时代&#xff0c;大量数据的积累成为了常态&#xff0c;数据挖掘技术的出现填补了人们处理这些数据的空白&#…...

瑞熙贝通打造智慧校园实验室安全综合管理平台

一、建设思路 瑞熙贝通实验室安全综合管理平台是基于以实验室安全&#xff0c;用现代化管理思想与人工智能、大数据、互联网技术、物联网技术、云计算技术、人体感应技术、语音技术、生物识别技术、手机APP、自动化仪器分析技术有机结合&#xff0c;通过建立以实验室为中心的管…...

openstack调整虚拟机CPU 内存 磁盘 --来自gpt

在OpenStack中调整虚拟机&#xff08;即实例&#xff09;的CPU、内存&#xff08;RAM&#xff09;和磁盘大小通常涉及到以下几个步骤&#xff1a;首先&#xff0c;确定你要修改的实例名称或ID&#xff1b;其次&#xff0c;根据需要调整的资源类型&#xff0c;使用相应的命令进行…...

【IC设计】Verilog线性序列机点灯案例(三)(小梅哥课程)

声明&#xff1a;案例和代码来自小梅哥课程&#xff0c;本人仅对知识点做做笔记&#xff0c;如有学习需要请支持官方正版。 文章目录 该系列目录设计目标设计思路RTL及Testbench代码RTL代码Testbench代码 仿真结果上板视频 该系列目录 Verilog线性序列机点灯案例(一)&#xff…...

【打工日常】使用Docker部署团队协作文档工具

一、ShowDoc介绍 ​ShowDoc是一个适合IT团队共同协作API文档、技术文档的工具。通过showdoc&#xff0c;可以方便地使用markdown语法来书写出API文档、数据字典文档、技术文档、在线excel文档等等。 响应式网页设计&#xff1a;可将项目文档分享到电脑或移动设备查看。同时也可…...

(一)Neo4j下载安装以及初次使用

&#xff08;一&#xff09;下载 官网地址&#xff1a;Neo4j Graph Database & AnamConnect data as its stored with Neo4j. Perform powerful, complex queries at scale and speed with our graph data platform.https://neo4j.com/ &#xff08;二&#xff09;安装并配…...

QT for Mcu的学习建议

QT for MCU&#xff08;微控制器单元&#xff09;是一个相对较新的领域&#xff0c;它允许在资源受限的微控制器上运行Qt框架&#xff0c;从而为嵌入式设备带来丰富的用户界面和跨平台的开发体验。以下是一些建议&#xff0c;可以帮助你开始学习Qt for MCU&#xff1a; 理解Qt…...

【C语言初阶(五)】数组

❣博主主页: 33的博客❣ ▶文章专栏分类: C语言从入门到精通◀ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; 目录 1. 前言2.一维数组的概念3.一维数组的创建和初始化3.1数组的创建3.2数组的初始化3.3数组的类型 4.一维数组的使用4.1数组下标4.2数组元素打印4.4数组元…...

词令微信小程序怎么添加到我的小程序?

微信小程序怎么添加到我的小程序&#xff1f; 1、找到并打开要添加的小程序&#xff1b; 2、打开小程序后&#xff0c;点击右上角的「…」 3、点击后底部弹窗更多选项&#xff0c;请找到并点击「添加到我的小程序」&#xff1b; 4、添加成功后&#xff0c;就可以在首页下拉我的…...

【PyTorch】基础学习:在Pycharm等IDE中打印或查看Pytorch版本信息

【PyTorch】基础学习&#xff1a;在Pycharm等IDE中打印或查看Pytorch版本信息 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1…...

SDN网络简单认识(2)——南向接口

目录 一、概述 二、南向接口与南向协议 2.1 南向接口&#xff08;Southbound Interfaces&#xff09; 2.2 南向协议&#xff08;Southbound Protocols&#xff09; 2.3 区别与联系 三、常见南向协议 2.1 OpenFlow 2.2 OVSDB&#xff08;Open vSwitch Database Manageme…...

如何保存缓存和MySQL的双写一致呢?

如何保存缓存和MySQL的双写一致呢&#xff1f; 所谓的双写一致指的是&#xff0c;在同时使用缓存(如Redis)和数据库(如MySQL)的场景下,确保数据在缓存和数据库中的更新操作保持一致。当对数据进行修改的时候&#xff0c;无论是先修改缓存还是先修改数据库&#xff0c;最终都要保…...

第十三篇:复习Java面向对象

文章目录 一、面向对象的概念二、类和对象1. 如何定义/使用类2. 定义类的补充注意事项 三、面向对象三大特征1. 封装2. 继承2.1 例子2.2 继承类型2.3 继承的特性2.4 继承中的关键字2.4.1 extend2.4.2 implements2.4.3 super/this2.4.4 final 3. 多态4. 抽象类4.1 抽象类4.2 抽象…...

PyTorch学习笔记之基础函数篇(四)

文章目录 2.8 torch.logspace函数讲解2.9 torch.ones函数2.10 torch.rand函数2.11 torch.randn函数2.12 torch.zeros函数 2.8 torch.logspace函数讲解 torch.logspace 函数在 PyTorch 中用于生成一个在对数尺度上均匀分布的张量&#xff08;tensor&#xff09;。这意味着张量中…...

C++/CLI学习笔记3(快速打通c++与c#相互调用的桥梁)

c/cli变量和操作符 3.1:什么是变里 变量是存储数据以便应用程序临时使用的内存位置&#xff0c;具有名称、类型和值。变量值在应用程序执行期间可能改变&#xff0c;变量名也是。变量使用前必须声明&#xff0c;即指定类型和提供名称。变量的类型决定了值的范围以及能执行的操…...

unity

Unity官方下载_Unity最新版_从Unity Hub下载安装 | Unity中国官网 Unity Remote - Unity 手册 登陆账号&#xff0c;找到一个3d 免费资源 3D Animations & Models | Unity Asset Store unity 里面window->package Manager 里面可以看到自己的asset &#xff0c;下载后…...

考研复习C语言初阶(3)

目录 一.函数是什么? 二.C语言中函数的分类 2.1库函数 2.2自定义函数 三.函数的参数 3.1实际参数&#xff08;实参&#xff09; 3.2 形式参数&#xff08;形参&#xff09; 四.函数的调用 4.1 传值调用 4.2 传址调用 五. 函数的嵌套调用和链式访问 5.1 嵌套调用 5…...

CCF 202009-3 点亮数字人生(拓扑排序)

题目背景 土豪大学的计算机系开了一门数字逻辑电路课&#xff0c;第一个实验叫做“点亮数字人生”&#xff0c;要用最基础的逻辑元件组装出实际可用的电路。时间已经是深夜了&#xff0c;尽管实验箱上密密麻麻的连线已经拆装了好几遍&#xff0c;小君同学却依旧没能让她的电路正…...

Docker笔记-进入运行中的镜像,查看日志等操作

docker搭建好后&#xff0c;查看运行的docker镜像&#xff1a; docker ps -a 进入运行的容器&#xff0c;命令如下&#xff1a; docker exec -it <容器ID> /bin/bash # 或者&#xff0c;直接用容器里面的命令&#xff0c;比如mysql镜像 docker exec -it <容器ID>…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

命令行关闭Windows防火墙

命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)​方法二:CMD命令…...

C#最佳实践:为何优先使用as或is而非强制转换

C#最佳实践&#xff1a;为何优先使用as或is而非强制转换 在 C# 的编程世界里&#xff0c;类型转换是我们经常会遇到的操作。就像在现实生活中&#xff0c;我们可能需要把不同形状的物品重新整理归类一样&#xff0c;在代码里&#xff0c;我们也常常需要将一个数据类型转换为另…...

【系统架构设计师-2025上半年真题】综合知识-参考答案及部分详解(回忆版)

更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20~21题】【第…...

后端下载限速(redis记录实时并发,bucket4j动态限速)

✅ 使用 Redis 记录 所有用户的实时并发下载数✅ 使用 Bucket4j 实现 全局下载速率限制&#xff08;动态&#xff09;✅ 支持 动态调整限速策略✅ 下载接口安全、稳定、可监控 &#x1f9e9; 整体架构概览 模块功能Redis存储全局并发数和带宽令牌桶状态Bucket4j Redis分布式限…...