MVCC,全称多版本并发控制。
1、作用: 用于在并发读写的场景下,解决了读写冲突问题,实现事务隔离级别。
1.1、在读已提交隔离级别下,解决了脏读的问题
1.2、在可重复读隔离级别下,解决了不可重复读和幻读问题。
2、组成部分: MVCC的实现依赖于隐藏字段、Undo log和Read View读视图。
2.1、隐藏字段: 每一行数据都有三个隐藏字段 ,但是mysql将它们没有显示出来。其中最重要的是trx_id和roll_pointer.
2.1.1、tra_id指的是这条数据是被那个事务id修改。
2.1.2、roll_pointer是指向这条数据修改前的上一条数据的指针。
2.2、Undo log:对该行数据每次更新后,都会将旧值放到一条undo日志中,随着更新次数的变多,所有版本都会被roll_pointer属性连成一个链表。所以也被成为版本链。
2.3、Read View 读视图: 在事务开启后,进行快照读操作时,就会生成当前数据库的一个快照。上面记录了一个数组,记录了当前的活跃事务id,即还没有提交事务的id。
什么是ReadView
在MVCC机制中,多个事务对同一个行记录进行更新会产生多个历史快照,这些历史快照保存在Undo log里。如果一个事物想要查询这个行记录,需要读取到哪个版本的行记录呢?这时就需要用到ReadView了,它帮我们解决了行的可见性问题。
ReadView就是事务在使用MVCC机制进行快照读操作时产生的读视图。当事务启动时,会生成数据库系统当前的一个快照,InnoDB为每个是我构造了一个数组,用来记录并维护系统当前活跃事务的ID
在读已提交隔离级别下
每次执行快照读之前都生成一个ReadView读视图
在可重复读隔离级别下
只在第一次进行快照读时生成一个ReadView读视图,之后每次读取数据都使用这个视图。
MVCC能否解决幻读?如何实现的?