MVCC原理
定义
MVCC(Multi-Version Concurrency Control)多版本并发控制,是数据库控制并发访问的一种手段。
注意事项
-
MVCC只在 读已提交(RC) 和 可重复读(RR) 这两种事务隔离级别下才有效。
-
是 数据库引擎(InnoDB) 层面实现的,用来实现读写冲突时不用加锁,提高访问性能。
原理
通过版本链(undo log)和一致性视图实现MVCC。
版本链
- 版本链是一条链表,链接的是每条数据曾经的修改记录。
- 每修改一次记录,就会插入一条undo日志,并且roll_point指针会指向上一条记录。
InnoDB的隐藏列
InnoDB的聚簇索引记录会包含3个隐藏字段:
- trx_id: 记录修改此数据的事务id,此事务id是自增的。只有这个事务对表里的数据发生改变时,比如insert,update,delete,才会分配这个唯一的事务id。
- roll_pointer: 回滚指针,指向上一次修改记录的指针。
- row_id(非必须): 隐含的自增id,当有主键或者有不允许为null的unique键时,不包含此字段
一致性视图(ReadView)
当执行查询sql时,会生成一致性视图,它由执行查询时所有未提交事务id数组(m_ids)和已创建的最大事务id组成,查询的数据结果需要跟readView进行对比,从而得到快照结果。
min_id是指所有未提交事务中最小的id。
max_id是指当前已创建的最大事务id。
注意:
- 读提交是在每一次select的时候生成ReadView的
- 可重复读是在第一次select的时候生成ReadView的
- 对比的顺序是根据回滚指针从最新的undo log开始,通过版本链,直到找到符合的记录。
版本链比较规则
-
如果落在绿色部分(trx_id<min_id),表示这个版本是已提交的事务生成的,这个数据是可见的。
-
如果落在红色部分(trx_id>max_id), 表示这个版本是由将来启动的事务生成的,肯定是不可见的。
-
那如果落在黄色部分(min_id<=trx_id<=max_id),那就包括两种情况:
a.若trx_id在数组中,表示这个版本是由还没提交的事务生成的,是不可见的。
b.若trx_id不在数组中,表示这个版本是已经提交了的事务生成的,是可见的。