什么是MVCC,MVCC的作用是什么?

MVCC在MySQL的可重复读和读已提交隔离级别中用于解决脏读和不可重复读问题。它提供快照读和当前读两种方式,快照读通过ReadView和数据的隐藏字段(事务ID、回滚指针)实现,而当前读则读取最新数据。MVCC利用回滚日志(undolog)保存历史版本,且在适当时候由purge线程清除。ReadView在事务执行快照读时生成,用于判断数据的可见性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MVCC:多版本并发控制。在MySQL中用以可重复读和读已提交隔离级别的实现,解决了脏读和不可重复度的问题。

MVCC提供了两种读操作:

  1. 快照读:在第一次访问数据时,给当前数据拍一张照,之后读取的内容都是快照上的内容,而不是最新更改过的数据。当我们在使用像 select 等不需要加锁的操作时,使用的就是快照读。

即当前读读取的数据不是最新版本而是旧版本的

  1. 当前读:使用select * for update(排他锁),insert,delete,update,select lock in share mode(共享锁)等使用的就是当前读,读取的都是最新数据

MVCC的实现原理


当前读就是很普通的读操作,所以实现原理重点在于快照读是如何实现的

MVCC依赖于三个字段(TRX_ID事务ID,ROLL_PTR回滚指针,ROW_ID隐藏主键字段 ), undo log ,Read View 进行实现。

三个隐藏字段:

每一行数据都含有三个隐藏字段:

  1. TRX_ID事务ID:记录最近修改当条数据的事务ID。

  1. ROLL_PTR回滚指针:指向当前记录上个版本的指针。

  1. ROW_ID隐藏主键字段:隐藏的主键字段,当我们没有给数据指定主键时,他就是主键。

这三个字段配合 undo log 实现的MVCC的快照读。

undo log

undo log:回滚日志,事务日志之一。在insert,update,delete时产生的,方便进行事务的回滚。

使用上述三个字段生成了一份数据链表,如图所示:

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

Read View

第一次select时为当前数据拍张照,之后的select获取到的数据都是这张照片上的数据。

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

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

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

解决的问题


解决脏读问题:每一次select都生成Read View,保证数据都是被commit的。

解决不可重复读问题:只有在第一次select 时才会生成Read View,虽然之后其他事务修改了数据,但是我们依然看到的是第一次生成的Read View中的数据。

解决了部分幻读问题:因为每一个事务是可以看到被自己修改了的数据的。

MVCC可以无锁的解决事务并发冲突提高了数据库的并发读写效率

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值