MySQL:MVCC

MVCC(多版本并发控制,Multiversion Concurrency Control)是一种数据库并发控制的策略,指维护一个数据的多个版本,使得读写操作没有冲突。

假设现在同时有四个事务,对同一张表的同一行记录进行操作:

 如图,纵轴为时间线,当前事务5中的两次查询查询的分别是哪个事务版本的记录呢?想确定这个问题就需要用到MVCC了,MVCC最主要的功能就是确定在多个事务并发的情况下,到底该访问哪个版本。

MVCC的具体实现,主要依赖于数据库记录中的隐式字段、undo log日志、readView

MVCC实现原理

我们先来说隐藏字段:

隐藏字段

这里有一张表,表中有id,age,name三个自定义的字段。其实这张表内部还含有三个MySQL提供好的字段:

  • DB_TRX_ID:最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID,自增
  • DB_ROLL_PTR:回滚指针,指向这一条记录的上一个版本,用于配合undo log,指向上一版本
  • DB_ROLL_ID:隐藏逐渐,如果表结构没有指定主键,将会生成该隐藏字段

undo log

当insert的时候,产生的undo log只在回滚时需要,在事务提交后,可被立即删除。而update,delete的时候,产生的undo log日志不仅在回滚时需要,MVCC版本访问也需要,不会被立即删除。

undo log版本链

不同事务或相同事务对同一条记录的修改,会导致该记录的undolog生成一条记录版本链表,链表头部是最新的旧记录,链表尾部是最早的旧记录。

readview

ReadView(读视图)是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id。

当前读:读取的是最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select...lock in share mode(共享锁),select...for update,update,insert,delete(排他锁)都是一种当前读。

快照读:简单的select(不加锁)就是快照读,读取到是记录数据的可见版本,也可能是历史数据,不加锁,是非阻塞读。

  • Read Committed:每次select,都生成一个快照读。
  • Repeatable Read:开启事务后第一个select语句才是快照读的地方。

ReadView中包含了四个核心字段:

字段含义
m-ids当前活跃的事务ID集合

min_trx_id

最小活跃事务ID
max_trx_id

预分配事务ID,当前最大事务ID+1(因为事务ID自增)

creator_trx_idReadView创建的事务ID

ReadView为了哪个获取快照读中最准确的数据,定义了一些数据访问的规则:

 trx_id代表当前事务ID。这个事务ID也可能是历史版本的事务ID。

不同的隔离级别下,生成ReadView的时机不同:

  • READ COMMITED:在事务中每一次执行快照读时生成ReadView
  • REPEATABLE READ:仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值