什么是MVCC,一文搞懂MySQL的MVCC机制

article/2025/9/15 12:34:35

MVCC是什么

MVCC,即Multi-Version Concurrency Control (多版本并发控制)。它是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。

数据库中同时存在多个版本的数据,并不是整个数据库的多个版本,而是某一条记录的多个版本同时存在,在某个事务对其进行操作的时候,需要查看这一条记录的隐藏列事务版本id,比对事务id并根据事物隔离级别去判断读取哪个版本的数据。

数据库隔离级别读已提交、可重复读 都是基于MVCC实现的,相对于加锁简单粗暴的方式,它用更好的方式去处理读写冲突,能有效提高数据库并发性能。

我们先回顾一下事务的相关概念,以便更好的理解mvcc的实现原理

MySQL的事务

redo log

redo log重做日志,是记录物理数据变化的日志,使用数据库DML对数据的修改操作,都会产生redo log,可以保证事务的持久性

undo log

undo log是回滚日志,有两个作用:提供回滚操作多行版本控制(MVCC)

在数据修改的时候,不仅记录了redo,还记录了相对应的undo,如果因为某些原因导致事务失败或回滚了,可以借助undo进行回滚,

undo log和redo log记录物理日志不一样,undo log主要记录的是数据的逻辑变化,它是逻辑日志

可以认为执行insert时会对应在undo log中记录一条delete语句,并且会记录这个版本的事务id(txid),执行update语句会有一条update语句来使之数据恢复到上个版本。

当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚

多行版本控制的时候,也是通过undo log来实现的

当读取的某一行被其它事务锁定时,它可以从undo log中分析出该行记录以前的数据是什么。从而提供该行版本信息。

并且undo log的内容变更也会记录到redo log中,从而实现undo log的持久化

总而言之就是undo log提供了一种数据库快照的功能,通过事务id和undo log我们可以找到历史版本的数据

MySQL事务的隔离级别

SQL标准中定义了四个隔离级别:

  • READ-UNCOMMITTED(读取未提交):最低的隔离级别,允许读取尚未提交的数据变更,可能导致脏读、幻读、不可重复读;
  • READ-COMMITTED(读取已提交):允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读任有可能发生
  • REPAATABLE-READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据本身是被本身事务所修改的,可以阻止脏读和不可重复读,但幻读仍有可能发生
  • SETIALIZABLE(可串行化):最高的隔离级别,完全服从ACID原则,所有事务单个依次执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读,不可重复读以及幻读。

MVCC原理

事务版本号

事务每次开启前,都会从数据库获取一个自增长的事务ID,可以从事务ID判断事务的执行先后顺序

隐式字段

对于InnoDB存储引擎,每一行记录都有两个隐藏列trx_idroll_ptr,如果表中没有主键和非NULL唯一键时,则还会有第三个隐藏的主键列row_id

MySQL行记录中除了记录业务数据外,还有隐藏的 trx_idroll_ptr

  • trx_id:表示最近修改的事务的id,每次一个事务对某条聚集索引记录进行改动时,都会把该事务的事务id赋值给trx_id隐藏列,新增一个事务时,trx_id就会递增,因此trx_id能够表示事务开始的先后顺序
  • roll_ptr:指向上一个版本的地址,每次对某条聚集索引记录进行改动时,都会把旧版本写入undo log中,然后这个隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息。

版本链

MySQL的每行记录逻辑上其实是一个链表

演示说明:


update user set name = '肉蟹宝1' where id = 1 

这个链表存在于undo log中,和最新版本的数据不在一起

每次更新后,都会将旧值放在一条undo log中,就算是该记录的一个旧版本,随着更新次数的增多,所有的版本都会被roll_ptr属性连接成一个链表,我们把这个链表称为版本链,版本链的头节点就是当前记录最新的值

另外,每个版本中还包含生成该版本时对应的事务id(trx_id)

ReadView

说完了undo log 和版本链,再来说说ReadView,前面我们说过MVCC只在read_commited和repeatable_read两个隔离级别下工作,而read_commited和repeatable_read的区别不同就在于它们生成的ReadView的策略不同

对于使用read_commited和repeatable_read隔离级别的事务来说,都必须保证读到已经提交了的事务修改过的记录,也就是说假如另一个事务已经修改了记录但未提交,是不能直接读取最新版本的记录的

核心问题就是:需要判断一下,版本链中哪个版本是当前事务可见的

为此InnoDB提出了一个ReadView的概念,这个ReadView中有一个id列表,trx_ids来存储系统中当前活跃着的读写事务,也就是begin了但是还未commit或rollback的事务

流程说明:

  1. 获取事务自己的版本号,即事务ID
  2. 获取Read View
  3. 查询得到的数据,然后Read View中的事务版本号进行比较。
  4. 如果不符合Read View的可见性规则, 即就需要Undo log中历史快照;
  5. 最后返回符合规则的数据

演示说明:

提交了trx_id是2的记录后,接着新建trx_id为3的事务,修改name的值,但是事务还没有提交

update user set name = '肉蟹宝 2 ' where id = 1 

则此时的版本链是:

显然,此时的trx_ids为[3]

如果另一个事务查询id为1的记录,因为trx_ids当前只有trx_id为3的事务,而trx_ids的意义是记录未完成的事务。在这里,事务未完成,所以该条记录不可见,继续查询下一条,结果返回肉蟹宝1

此时我把trx_id为3的事务提交了,并且新建了一个trx_id为4的事务,修改name,且不提交事务

update user set name = '肉蟹宝 3 ' where id = 1 

这时的版本链就是:

read-committed —— 每次查询数据前都生成一个 ReadView

trx_ids 将更新为[ 4 ],版本链通过 trx_id 对比查找到的结果就是肉蟹宝2

repeatable-read —— 在第一次查询数据时生成一个 ReadView,之后的读都复用之前的。

不会有重建的 ReadView , trx_ids 还是 [ 3 ],MySQL 认为事务3未完成,所以 select 的结果是肉蟹宝1。第2次 select 结果和第1次一样,所以叫可重复读。

小结

从上边的描述中我们可以看出来,所谓的MVCC--多版本并发控制指的就是在使用read-commited、repeatable-read这两种隔离级别的事务在执行select操作时,访问记录的版本链的过程。这样子就可以使不同的事务的读-写、写-读作并发执行,从而提升系统性能。

read-commited、repeatable-read这两个隔离级别的很大一个不同就是:生成ReadView的时机不同

read-commited 在每一次进行select操作时都会生成一个ReadView,而repeatable-read只在第一次进行普通select操作时生成一个ReadView,之后的查询操作都重复使用这个ReadView

参考与感谢:

深入理解MYSQL的MVCC机制

javaguide


http://chatgpt.dhexx.cn/article/JVFXFEKO.shtml

相关文章

对MVCC全面解析

简介 MVCC(Multi-Version Concurrency Control)即多版本并发控制。 MVCC的实现原理 我们在了解MVCC之前,首先先了解一下几个比较常见的锁。 读锁:也叫共享锁、S锁,若事务T对数据对象A加上S锁,则事务T可…

【MySQL】MVCC机制

什么是MVCC MVCC 英文全称:Multi-Version Concurrency Control,Mysql的事务隔离性就是主要靠MVCC机制来实现的。对一行数据的读和写默认是不会通过加锁互斥来保证隔离性的,这样避免了频繁的加锁互斥,而在串行化隔离级别为了保证较…

一文精通MVCC机制

MVCC(Multi-Version Concurrency Control)多版本并发控制机制 使用串行化隔离级别时,mysql会将所有的操作加锁互斥,来保证并发安全。这种方式必然降低并发性能。mysql在读已提交和可重复读隔离级别下,对一行数据的读和写两个操作默认是不会通…

数据库的MVCC机制

MVCC 1. 什么是MVCC MVCC (Multiversion Concurrency Control),多版本并发控制。顾名思义,MVCC 是通过数据行的多个版 本管理来实现数据库的 并发控制 。这项技术使得在InnoDB的事务隔离级别下执行 一致性读 操作有了保 证。换言…

MySQL之MVCC机制

1. MVCC概念 MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。 在Mysql的InnoDB引擎中就是指在…

【MySQL进阶-05】深入理解mvcc机制(详解)

MySql系列整体栏目 内容链接地址【一】深入理解mysql索引本质https://blog.csdn.net/zhenghuishengq/article/details/121027025【二】深入理解mysql索引优化以及explain关键字https://blog.csdn.net/zhenghuishengq/article/details/124552080【三】深入理解mysql的索引分类&a…

MVCC及实现原理

!首先声明,MySQL 的测试环境是 5.7 前提概要 什么是 MVCC什么是当前读和快照读?当前读,快照读和 MVCC 的关系MVCC 实现原理 隐式字段undo日志Read View整体流程MVCC 相关问题 RR 是如何在 RC 级的基础上解决不可重复读的&#xf…

4gl程式debug常用技巧

1、带参数的D: ‘MISC’表示具体料号传入 2、指定行数设置断点 比如我要在程式axmt360中的211行开始D 进入Debug界面后按ctrlD 弹出界面 输入b 行数 点OK 出现上面表示已设置OK,然后点cancel或叉叉退出 最后点下面按扭,程式跑到210行时自…

【OpenGL】十五、OpenGL 绘制三角形 ( 绘制 GL_TRIANGLE_FAN 三角形扇 )

文章目录 一、绘制 GL_TRIANGLE_FAN 三角形1、绘制 3 个点的情况2、绘制 4 个点的情况3、绘制 5 个点的情况4、绘制 6 个点的情况 二、相关资源 一、绘制 GL_TRIANGLE_FAN 三角形 GL_TRIANGLE_FAN 的绘制规则是 , 以第 1 1 1 个点作为顶点 , 第 1 , 2 , 3 1,2,3 1,2,3 个点组…

Unity3D笔记十八 GL图像库

作者:PEPE 出处:http://pepe.cnblogs.com/ 1、绘制2D图像的时需要使用GL.LoadOrtho()方法来将图形映射到平面中。 2、所有绘制相关的内容都要写在OnPostRender()方法中。 3、有关GL图像库的脚本需要绑定到Hierarchy视图中Camera上,否则无法…

Mapbox GL插件之echartsLayer

Mapbox GL除了本身的api具有的功能以外,还能够集成各种开源的类库。 ECharts 是一个使用 JavaScript 实现的开源可视化库,涵盖各行业图表,百度公司开发的,同时其中也有一些地图的效果。 Mapbox GL的echarts插件,在gith…

【OpenGL】十八、OpenGL 绘制多边形 ( 绘制 GL_POLYGON 模式多边形 )

文章目录 一、绘制 GL_POLYGON 模式多边形二、多边形绘制顺序分析三、相关资源 一、绘制 GL_POLYGON 模式多边形 使用 glBegin(GL_POLYGON) 设置绘制多边形 , 不管有几个点 , 都按照指定的顺序连接起来 ; 注意 : 这些点组成的多边形必须是凸多边形 , 不能是凹多边形 ; 代码示例…

gl_FragCoord 的含义

gl_FragCoord 表示当前片元着色器处理的候选片元窗口相对坐标信息,是一个 vec4 类型的变量 (x, y, z, 1/w), 其中 x, y 是当前片元的窗口坐标,OpenGL 默认以窗口左下角为原点, 在 着色器中通过布局限定符可以重新设定原点&#xf…

WebGL着色器内置变量gl_PointSize、gl_Position、gl_FragColor、gl_FragCoord、gl_PointCoord

WebGL着色器内置变量 WebGL中文教程网 本文是WebGL教程(电子书)的2.7节内容 着色器语言在GPU的着色器单元执行,javascript语言、C语言在CPU上执行,任何一种语言的语法规则,整体设计都和它执行的硬件有一定的关系,GPU和CPU执行程…

Unity画线之GL

上一篇中,SetPixel的方法,卡顿严重,暂未解决,又去看了原来的GL画线,自己画图思考了一下适配UI的问题,最终解决。 特此说明,GL画线功能,及Shader均为借鉴,自己做了优化。…

GL823K

下面是另一家SD/TF解码芯片的方案 ![](https://img-blog.csdnimg.cn/20210319145313645.png?x-oss-processimage/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80OTU3MDgwNA,size_16,color_FFFFFF,t_70 13030533945 VX

GL各个表结构总结

NewProgramer EBS GL表结构学习(转) gl_code_combinations:科目组合 字段名 含义 备注 code_combination_id 主键,科目编码ID,自动编号 segment1 分行代码 setgment2 是受益部门 segment3 科目代码 segment4 产品…

初识mapbox GL

一、概述 最近由于项目的需求,借此机会对mapbox GL做了一个系统的学习,同时也对整个学习过程做一个记录,一方面留作自用,另一方面也希望看到此文的人在学习mapbox GL的时候,能够有所启发、有所收获。 二、快速认识 …

支持Genero BDL 4gl语言的编辑器

内测版本出来啦。点此下载: FglDeveloper v1.0 →此版本已下架 还有bug,分享几张截图 模板产生器: 画面产生器: 编辑器各种变量提醒 详细功能小伙伴们下载后体验。

TOPGP5.3:导入jar包并在4GL中引用

查看环境$CLASSPATH 上传引用到的JAR包到以下目录 /u1/topprod/tiptop/ds4gl2/bin/javaad/jar 以上为GP5.3目录,其他版本系统可根据查看到的$CLASSPATH上传到相应目录设置环境变量 GP5.3系统中,$CLASSPATH环境变量的设置存在下图文件中: …