MySQL存储引擎InnoDB多版本并发控制(MVCC)

注:文章并未完全深入,只对MVCC稍作总结,如发现问题,请帮忙指出,多谢。

多版本并发控制MVCC


一、理解

  MVCC(Multi-Version Concurrency Control 多版本并发控制),根据字面意思来理解,用于并发状况下的数据库数据访问控制。多版本指的是为每次的数据修改保存一个备份。不同备份对事务表现出不同的可见性。控制主要是指对保存的多版本的可见性的控制。
  备份的作用:1、回滚时使用;2、并发事务读一致性保证。


二、实现

1、每行中的三个隐藏字段

  • 一个6字节的DB_TRX_ID,该字段标识插入或者更新该行的最后一个事务的ID(注:删除也被当做更新对待,专门有一个bit的标志位标识是否删除)。
  • 一个7字节的DB_ROLL_PTR,该字段表示一个指针,存储的是地址,指向rollback segment中保存着的undo log record。
  • 一个6字节的DB_ROW_ID,该字段表示一个行ID,每插入一个新行,该字段的值就加1。

2、字段具体功能

(1)对于DB_TRX_ID,首先要知道read view这个概念

·read view: 读视图,是事务做的快照,记录当前活跃的其它事务信息。
·read view快照时间点:对于Repeatable Read隔离级别,在第一个SELECT开始时创建快照。对于Read Committed隔离级别,每个SELECT请求均会创建快照。

每个事务都会创建一个read view,记录当前系统的活跃事务信息,其中有两个比较关键,一个是up_limit_id(表示快照中活跃事务的最小ID),另一个是low_limit_id(表示快照中活跃事务的最大ID+1)。
·up_limit_id、low_limit_id 怎么理解比较好?我把它们称为绝对可见性上下限,up_limit_id表示绝对可见上限(但凡小于该值的,绝对是可见的),low_limit_id表示绝对不可见下限(但凡是高于该值的,绝对是不可见的)。

·可见性:
  在事务访问行数据的时候,会将该行所记录的事务ID(curr_trx_id 当前记录ID)与up_limit_id和low_limit_id比较。如果curr_trx_id < up_limit_id,那么row对该事务可见。如果curr_trx_id >= low_limit_id,那么row对该事务不可见。
  当up_limit_id <= curr_trx_id < low_limit_id,这个时候要将curr_trx_id和快照中的up_limit_id到low_limit_id的所有值进行比较,如果和其中某个值相等,则对当前事务不可见,否则对当前事务可见。也就是说,在执行快照的时候,事务还在活跃,并未提交,当然不可见。如果不可见怎么取呢,这个时候DB_ROLL_PTR就发挥作用了

(2)DB_ROLL_PTR 当行数据对当前访问的事务不可见,这个时候就要去DB_ROLL_PTR指针指向的地址中去找该行对应修改前行记录,遍历链表(链表记录着历次修改的值),取其中的DB_TRX_ID再来进行上述比较,直到找到一条对当前事务可见的记录。

(3)DB_ROW_ID 在创建的表没有指定主键的情况下,InnoDB会自动创建包含row ID值的聚簇索引,如果指定了主键,DB_ROW_ID字段值不会出现在任何索引中。也就是说,以InnoDB作为存储引擎,不指定主键的话,row ID就是主键。


三、MVCC有什么作用

1、最重要的一点,高并发读写阻塞问题得到缓解,使得读-写并发操作之间无需加锁,提升并发性能。
2、可以解决脏读、幻读问题。


四、总结

1、MVCC是为了并发读-写操作无需加锁而生,以此提高并发性能。
2、MVCC需要进行快照读Read View来记录并发活跃事务。
3、多版本是指对数据的每次修改都保存一个备份。
4、保存的备份记录在undo log中。
5、通过可见性算法来确定记录对事务是否可见。
6、MVCC具体实现需要三个隐藏字段配合DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID

参考:
https://dev.mysql.com/doc/refman/5.7/en/innodb-multi-versioning.html
https://blog.csdn.net/SnailMann/article/details/94724197
https://segmentfault.com/a/1190000012650596
https://my.oschina.net/xinxingegeya/blog/505675

你可能感兴趣的:(MySQL,数据库,MySQL,InnoDB,MVCC)