MySQL InnoDB MVCC实现原理

MySQL InnoDB基于MVCC实现了非锁定读(我们也称之为快照读,因为它是基于快照实现的),极大地提交了数据库的并发性。在InnoDB中默认的读取方式都是非锁定读,即不会占用和等待表或记录上的锁。

Innodb基于一致性视图consistent read view实现MVCC,我们通常称之为快照读,在事务开始的时候,需要对MySQL整个库创建一份“快照”,但是这里的快照在实现上并不是对整个库拷贝一份数据,这样显然是不现实的。

其实InnoDB是基于ReadView这个数据结构来实现快照的,ReadView可用用来计算某一条记录对于当前事务是不是可见。

ReadView数据结构中有一下几个核心属性:

对应mysql-server源码位置:storage/innobase/include/read0types.h

  1. 活跃事务集合 m_ids

    当前快照被创建时,活跃(已启动但未提交)的事务集合,

  2. 高水位 m_low_limit_id

    当前系统中的事务的最大id值加一,即下一个开启的事务的id,大于等于该id的事务都是在该快照创建之后开启的事务

  3. 低水位 m_up_limit_id

    当前活跃事务的最小id,小于该id的事务都是已经提交的事务

readview

那么如何判断一条记录对于当前事务是不是可见。

InnoDB对于每一条记录都有维护一个data_trx_id的隐藏列,表示最新更改该行记录的事务id。

InnoDB只需要取出该记录的data_trx_id,基于ReadView数据结构就可以计算出是否可见:

  1. data_trx_id ≥ 高水位,不可见,表示这个数据是由将来的事务更新的
  2. data_trx_id < 低水为,可见,表示这个数据是由已经提交的事务更新的
  3. 介于高水位与低水位之间
    1. 如果在活跃事务集合中,表示尚未提交的事务,不可见
    2. 如果不在,表示事务已经提交了,可见

对于读已提交和可重复读,其一致性快照的定义是不一样的:

  1. 读已提交,对于事务中每一次快照读都会重新计算一下一致性事务
  2. 可重复读,只会在事务开始的第一次快照读创建一致性事务,后续的读取都会使用这个一致性事务
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享