MVCC
全称就是 多版本并发控制,是MySQL用来解决读写冲突的一种手段,可以实现读写不阻塞。
存在于读已提交和可重复读的情况下,读未提交不需要加锁直接读最新数据,而串行化普通select都给你加锁
MVCC依赖什么实现的?
1.数据库的隐藏字段:
rollback_pointer 回滚指针
trx_id:最近修改该行数据的事务ID
2.undo log版本链:记录的是事务变更前的数据

3.readView:快照读情况下生成的一个读视图,生成的一个快照,用来解决数据的可见性问题,有以下
字段
trx_ids:生成readview时当前系统还获活跃的事务ID集合
low_limit_id:应该分配给下一个事务的ID
up_limit_id:没提交事务中的最小ID
creator_trx_id:创建该read view的事务ID
ps: trx_ids=[up_limit_id,low_limit_id)

MVCC是如何判断数据的可见性的?
1.首先先判断本条数据是否由本事务产生(trx_id=creator_trx_id),如果是,那么就一定是可见,毕
竟是自己产生的
2.再判断**本条数据**的事务ID是否小于没提交事务的最小ID,如果是,那就可见,因为说明这数据已经被
其它事务所提交了,本事务是可见的
3.再判断本条数据是否在活跃事务集合中,如果不在,那么说明该数据已经被其他事务所提交
如果本条数据不存在的话,那么就会根据rollback pointer和undo log去找上一个版本的数据,然后重复
以上判断
readview产生时机
1.可重复读的情况下,只在事务第一次快照读时产生readview,后面会复用这个快照如果事务启动时选择
了with consistent snapshot,事务启动时就建立快照
2.读已提交的情况下,每次快照读都产生新的readview
二级索引在索引覆盖时如何使用MVCC?
隐藏字段在聚簇索引上,所以二级索引不回表要怎么使用MVCC?二级索引中,用了一个额外的名
page_max_trx_id来表示修改过该页的最大事务ID,然后用readview里的up_limit_id即没提交的事务中的
最小ID去和它比对,发现比它大,那么说明该页的数据是可见的。如果不可见,就需要回表。
所以我们可以得出一个结论,即使用到了索引覆盖,也不一定不回表