域名

你真的可以讲明白MVCC多版本控制机制吗?

字号+作者:益华科技来源:IT科技类资讯2025-11-05 14:08:16我要评论(0)

多事务操作同一行数据的时候,就会出现各种并发问题,mysql通过四种隔离级别来解决这些问题,读未提交隔离级别是最宽松的,基本没有做隔离,所以实现起来很简单;读提交隔离级别是每次执行语句包括查询和更新语

多事务操作同一行数据的真的制机制时候,就会出现各种并发问题,可讲mysql通过四种隔离级别来解决这些问题,明白

读未提交隔离级别是多版最宽松的,基本没有做隔离,本控所以实现起来很简单;读提交隔离级别是真的制机制每次执行语句(包括查询和更新语句)的时候都会生成一个一致性视图,从而保证当前事务可以看到其他事务提交后的可讲数据;可重复读隔离级别的实现是每个事务在开启的时候都会生成一个一致性视图,当其他事务有提交后也不会影响当前事务中的明白数据,要保证这一点mysql是多版通过多版本控制机制MVCC来实现的。可串行化隔离级别的本控隔离级别比较高,是真的制机制通过加锁来实现,所以mysql有一套锁机制。可讲

读提交和可重复读隔离级别都是明白依赖于MVCC多版本控制机制实现,今天我们就来讨论mysql中的多版MVCC多版本控制机制。

一、源码库本控MVCC多版本控制机制

MVCC机制是通过read-view机制与undo log版本链比对机制,使得不同的事务会根据数据版本链对比规则读取同一条数据在版本链上的不同版本数据。

1.undo log版本链

事务在开启的时候首先会申请一个事务id:ransaction id。

事务对某行数据做修改操作的时候,Mysql会保留修改前的数据undo回滚日志,并且把事务id:ransaction id赋值给版本记录中的字段trx_id。

把这些undo log日志串联起来形成一个历史记录版本链,如图:

注意这里的版本记录不是真实物理存在的,真实物理存在只有最新的一条记录,其他历史记录都是通过回滚日志推导出来的。

2.read-view机制

可重复读隔离级别和读提交隔离级别是通过生成一个一致性视图来实现,这个一致性视图就是read-view。

(1) 一致性视图是什么

一个事务启动的时候,innodb会为这个事务构造一个数组,用来保存这个事务的启动瞬间正在活跃的免费信息发布网所有事务id。“活跃”指的是启动了,但是没提交。

数组里面id最小的值即为低水位,最大的值+1记为高水位,这便是一致性视图。

每个事务在做查询的时候会根据一致性视图的可见性规则去undo log版本链中推导对应的数据。

(2) 一致性视图的可见性规则

a. 如果当前事务id落在绿色部分,表示这个版本是已提交的事务或者是当前事务自己生成的,这个数据是可见的;

b. 如果当前事务id落在红色部分,表示这个版本是由将来启动的事务生成的,是肯定不可见的;

c. 如果当前事务id落在黄色部分,企商汇那就包括两种情况:

若 row trx_id在数组中,表示这个版本是由还没提交的事务生成的,不可见;若 row trx_id不在数组中,表示这个版本是已经提交了的事务生成的,可见。

二、案例

图中事务A查询的i是什么?我们先来分析一下。

按照从上到下事务开启的顺序,每个事务对应的一致性视图如下:

事务A的一致性视图数组[11]事务B的一致性视图数组[11,12]事务C的一致性视图数组[11,12,13]

事务A在查询的那个时刻,undo log版本链是:

复制{trx_id=11,id=1,i=10,roll_pointer=0}>>>{trx_id=13,id=1,i=11,roll_pointer=1}>>>{trx_id=12,id=1,i=12,roll_pointer=2} “{}” 代表的是版本记录 “>>>” 代表的是回滚日志undo log1.2.3.

事务A在查询的时候,事务B和事务C属于未来事务,对事务A是不可见的。因此事务A查询的数据是通过最新的数据记录根据undo log不断向前回滚才得到的数据:i=10。

再看一个案例:

事务A查询1结果是什么?

事务A查询2结果是什么?

由一致性视图可见性规则分析,对事务A来说,事务B是未来事务,对事务A是不可见的,因此查询结果i=10。

查询2的结果i=12,为什么呢?先来看看两个概念:

在可重复读隔离级别中这种通过回滚日志找到对应版本记录的读取方式就是一致性读,而不需要回滚,永远只需要读取最新版本记录的方式就是当前读。事务中如果有更新语句的话,更新语句都是以当前读的方式读取到版本记录中最新数据,然后再进行更新操作,因此上图中的查询结果为i=12。

下面两种查询方式也是当前读:

复制select k from t where id=1 lock in share mode; select k from t where id=1 for update;1.2.3.

以上便是MVCC机制,按照其规则,这种机制只有在可重复读隔离级别和读提交隔离级别下才会有。

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 深入了解电脑网络628错误代码的原因和解决方法(解析网络连接问题中的628错误代码,助您顺利上网)

    深入了解电脑网络628错误代码的原因和解决方法(解析网络连接问题中的628错误代码,助您顺利上网)

    2025-11-05 13:43

  • 如何在Ubuntu 15.04系统中安装Logwatch

    如何在Ubuntu 15.04系统中安装Logwatch

    2025-11-05 13:42

  • 在Ubuntu上安装类Winamp的音频播放器Qmmp 0.9.0

    在Ubuntu上安装类Winamp的音频播放器Qmmp 0.9.0

    2025-11-05 11:37

  • 【教程】让你一分钟认识GitHub

    【教程】让你一分钟认识GitHub

    2025-11-05 11:30

网友点评
精彩导读
Ubuntu Snappy Core团队在6号上午展开了一场趣味讨论,而我们也因此而获知这款Linux发行版将通过何种方式在内核模块中加入对基于Snappy的操作系统的支持。这场讨论是从Geoffrey J. Teale向Ubuntu Snappy的开发者们提出“是否可以通过一个框架的形式,为基于Snappy Core的系统添加Linux内核模块”开始的。当前为Ubuntu Snappy系统添加内核模块的方法,是将它们打包到一个标准快照中,然后通过“sudo insmod”命令手动注入内核包。Geoffrey J. Teale说到:“我想的是如何部署小众的ZFS,因为硬件是现成的,并且不需要什么特殊的驱动,基本上只需要像对待内核模块那样部署ZFS和SPL就可以了。假如我必须做一个自定义镜像才能使用snappy,反而会减少Ubuntu Core作为平台的价值(Ubuntu Server用起来会更轻松)”。Zygmunt Krynicki在快速回答中建议Mr. Teale将他自己的内核roll到Ubuntu Snappy系统的内核中,以确保内核模块是可加载的。而据Mr. Krynicki所述,或许还需要一个定制的框架或应用,才能在操作系统中部署ZFS用户空间。紧接着,Mark Shuttleworth也加入了讨论,并且说到:“既然你想要ZFS,就将它当做一个标准,恰当地包括在Ubuntu中好了”。对于Mr. Teale和所有需要在Ubuntu Linux中支持这款强力的艺术级ZFS文件系统的用户来说,这显然是最好不过的消息了。毕竟在当前,ZFS只是作为一个FUSE_module(用户空间文件系统模块)而存在于Ubuntu之中。

Ubuntu Snappy Core团队在6号上午展开了一场趣味讨论,而我们也因此而获知这款Linux发行版将通过何种方式在内核模块中加入对基于Snappy的操作系统的支持。这场讨论是从Geoffrey J. Teale向Ubuntu Snappy的开发者们提出“是否可以通过一个框架的形式,为基于Snappy Core的系统添加Linux内核模块”开始的。当前为Ubuntu Snappy系统添加内核模块的方法,是将它们打包到一个标准快照中,然后通过“sudo insmod”命令手动注入内核包。Geoffrey J. Teale说到:“我想的是如何部署小众的ZFS,因为硬件是现成的,并且不需要什么特殊的驱动,基本上只需要像对待内核模块那样部署ZFS和SPL就可以了。假如我必须做一个自定义镜像才能使用snappy,反而会减少Ubuntu Core作为平台的价值(Ubuntu Server用起来会更轻松)”。Zygmunt Krynicki在快速回答中建议Mr. Teale将他自己的内核roll到Ubuntu Snappy系统的内核中,以确保内核模块是可加载的。而据Mr. Krynicki所述,或许还需要一个定制的框架或应用,才能在操作系统中部署ZFS用户空间。紧接着,Mark Shuttleworth也加入了讨论,并且说到:“既然你想要ZFS,就将它当做一个标准,恰当地包括在Ubuntu中好了”。对于Mr. Teale和所有需要在Ubuntu Linux中支持这款强力的艺术级ZFS文件系统的用户来说,这显然是最好不过的消息了。毕竟在当前,ZFS只是作为一个FUSE_module(用户空间文件系统模块)而存在于Ubuntu之中。