详解MVCC

一、什么是MVCC

    MVCC,即多版本并发控制协议,一种并发控制方法,多用于数据库管理系统中,实现对数据库的并发访问。

    MySql的innodb中使用MVCC来实现非阻塞并发读,无需加锁,提高读写性能。

    通常来讲,MVCC是通过维持一个数据库的多个版本,使得读写没有冲突,因而快照读是实现它的基础。

二、MVCC能解决什么问题

    在数据库并发场景中,存在如下三种情况:

①读读  没有线程安全问题

②读写  有线程安全问题,可能造成脏读、幻读、不可重复读(首先你要明白会有什么样的问题)

③写写  有线程安全问题,可能存在更新丢失的问题

    而MVCC的存在,则可以为数据库解决上述第二种情况,并且是通过无锁技术实现的。

三、MVCC的实现原理(innodb)

1、多版本

    为事务分配单项增长的时间戳,为每个修改保存一个版本,版本与事务时间戳相关联。(为数据的每个修改保存一个版本,当数据过期时,记录过期时间)

2、一个前提

    只能在快照读的情况下生效,数据库隔离级别为RC或者RR

这里补充一下RC和RR生成快照的区别:

在RC隔离级别下,每次快照读都会新生成一个新的read view

在RR隔离级别下,每次快照读读读取的都是在事务内第一次进行快照读时生成的read view

这也就是RC会读到别的事务提交的修改的原因

3、实现

    三个隐藏字段(针对每行记录)、undolog、read view

1)隐藏字段

DB_TRX_ID          隐藏主键

DB_ROLL_PTR    最后一次修改的事务ID

DB_ROW_ID         回滚指针,配合undolog,指向上一个版本

2)undolog

在insert、update、delete的时候会记录的逻辑日志,方便回滚

3)read view

事务在执行快照读操作时产生的读视图,系统通过产生读视图时的活跃事务id来做可见性判断

①可见性算法

前面说到对于每一个事务(数据的每个修改)有一个DB_TRX_ID,那么当前事务能够读到的数据,需要它的read view的属性与改数据记录的DB_TRX_ID进行比较来判断可见性,如果不可见,那么需要通过DB_ROLL_PTR取出undolog中的DB_TRX_ID链来遍历,直到找到符合条件的DB_TRX_ID,这个DB_TRX_ID所在的旧记录就是当前事务所能读到的数据

②可见性规则

read view中维护有三个全局属性

trx_list: 生成read view时的活跃事务id列表

up_limit_id: trx_list中最小的事务id

low_limit_id: 生成read view时,系统即将分配的下一个事务的id

如果DB_DRX_ID<up_limit_id,那么当前事务能够读到DB_DRX_ID所在事务的记录

如果DB_DRX_ID>=low_limit_id,那么DB_DRX_ID所在事务记录对当前事务不可见

如果DB_DRX_ID包含在trx_list中,则DB_DRX_ID所在事务记录对当前事务不可见

如果DB_DRX_ID不包含在trx_list中,则DB_DRX_ID所在事务记录对当前事务可见

MVCC通过上述机理,我们能够在RC的情况下,避免脏读、幻读、不可重复读(实际上幻读需要加上间隙锁机制来实现),同时也实现了并发无阻塞的读写。MVCC可以看作是行锁的一个变种。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值