MVCC机制是为了提高数据库的并发性能,通过不加锁的形式,实现读写并发的问题,也就是读不影响写,写不影响读
1.Read View
在介绍MVCC机制之前,先介绍一下Read View,Read View就是快照,就是某一个时刻的数据,Read View里面有四个重要的字段:
读已提交:每次执行select语句时,都会从数据库中拿取最新的快照,读取最新的数据
可重复读:只会读取事务开启后创建的那个快照的数据

creator_trx_id:创建该Read View的事务的事务id
**m_ids:**创建Read View时,MySQL中活跃且擅未提交的事务id列表
**min_trx_id:**创建Read View时,MySQL中的的活跃且没提交的事务id列表中的最小id,也就是m_ids中的最小值
**max_trx_id:**不是m_ids中的最大值,而是创建事务时,MySQL给下一个事务的id值
而对于InnoDB存储引擎中,它的聚簇索引记录都包含了两个隐藏列,trx_id和roll_pointer
trx_id:每当有一个事务对这条记录进行写操作时对应的事务id,MVCC机制就是通过trx_id来判断这个版本的快照对于当前事务来说是否可见
roll_pointer:roll_pointer就是一个执行旧版本的指针,每次对某条聚簇索引记录的数据进行写操作时,此时是不会直接覆盖旧数据的,而是会把旧版本的记录写到undo log日志中,然后通过roll_pointer将所有的旧版本形式通过链表的形式连接起来,所以通过这个roll_pointer就可以找到这个记录修改前的版本数据1

2.MVCC机制原理
首先,有了上面的基础,我们就可以将Read View里面的事务id分为三段:
第一段:当trx_id<min_trx_id,说明当前事务未提交
第二段:当trx_id>max_trx_id,说明当前事务未开始
第三段:当min_trx_id<trx_id<max_trx_id,说明当前事务id处于活跃且未提交的事务中

下面,就来介绍一下MVCC机制
当在一个事务中执行select语句时,现根据当前要查询的聚簇索引记录中的trx_id来判断当前版本快照数据是否对当前这个事务可见
如果记录的trx_id<Read View中的min_trx_id,说明这个版本的记录是在创建这个Read View之前已提交的事务生成的,此时该版本的记录对当前事务是可见的
如果记录的trx_id>Read View中的max_trx_id,说明这个版本的记录是在创建这个Read View之后,才启动事务生成的,此时该版本的数据对当前事务是不可见的
如果记录的min_trx_id<trx_id<max_trx_id,此时就要判断trx_id是否存在于m_ids
- 如果trx_id存在于m_ids列表中,说明生成该版本记录的事务还处于活跃当中且该事务还未提交,则此时这个版本的记录对于当前事务是不可见的
- 如果trx_id不存在于m_ids列表中,说明生成版本记录的活跃事务已经提交,则此时这个版本的记录对于当前事务是可见的
当事务遇见可见的版本记录时,此时直接读取该版本的记录即可,把这条记录返回给select
如果事务遇见不可见的版本记录时,会根据roll_pointer指针指向的undo log日志里面的Read View中的事务id和roll_pointer去寻找另一个版本的数据,然后重复整套Read View判断逻辑,直到找到可见版本的记录,便返回给select即可