什么是MVCC
多版本并发控制,读取数据时通过一种类似快照方式将数据保存下来,这样读锁就和写锁不冲突了,不同的事物session会看到自己特定版本的数据——版本链
MVCC只在READ COMMITED和REPEATABLE READ 两个隔离级别下工作,应为READ UNCOMMITED总是读取最新的数据行,而不是符合当前事务的数据行。儿SERIALIZABLE则会对读取所有的行都加锁。
在聚簇索引记录中有两个必要的隐藏列:
trx_id:用来存储每次对某条聚簇索引记录进行修改的事物Id。
roll_pointer:每次对那条聚簇索引记录有修改的时候,都会把老版本写入undo日志中。这个roll_pointer就是存储了一个指针,他指向这条聚簇索引记录的上一个版本位置,通过它来获取上一个版本的记录信息。(插入操作的undo日志没有这个属性,因为它没有老版本)
读已提交和可重复读的区别在于生成read_view的策略不同
开始事物时创建readView,readView维护当活动的事物id,即未提交的事物id,排序生成一个数据。
读取数据,读取数据中的事物id(获取的是事物id最大的记录),对别readView,如果在readView的左边,则可以访问(在左边意味着该事务已经提交)。如果在readView的右边或者在readView中,不可以访问,获取roll_pointer,取上一个版本重新对比(左边意味着已经提交,在readView生成之后出现,在readview中意味着该事务还未提交);
读已提交隔离级别下的事物在每次查询时都会生成一个独立的readview,而可重复读隔离级别下则在第一次读取的时候生成一个readview,之后的读都重复用之前的readview
这就是mysql的MVCC,通过版本链,实现多版本,可并发读-写,写-读。通过生成readview策略的不同实现不同的隔离级别。