mysql Mvcc解析

一、什么是mvcc

    mvcc(multiversion concurrency control),多版本并发控制,主要是在事务的读已提交和可重复读情况下发挥作用。

    它主要通过在更新的行加三个字段:

    1、最近一次修改事务id(DBTRXID)

    2、回滚指针,指向undolog的记录(DBROLLPTR )

    3、DBROWID,唯一标识

二、mvcc原理

    1、先从更新操作开始,如某一时刻,事务10000对一条记录进行修改,那么它将会把当前记录保存在undolog中,然后再更新该条记录的事务id,和回滚指针,最后更新该列需要需改的数据。这里补充一个小知识点,每次都会写入一条回滚日志,那这个回滚日志何时回收呢?在mysql编程在不需要的时候才删除。也就是说,系统会判断,当没有事务再需要用到这些回滚日志时,回滚日志会被删除。

    2、在开启事务时,会将当前活跃的事务(已经开启了事务,但是还没有提交)的事务 ID 放在一个数组里面,同时记录数组里面最小的事务 ID 为「低水位」,记录当前系统已经创建的事务ID 的最大值加一为「高水位」。这三者组成了一个事务的一致性视图(read-view)。当事务要查询某个记录的数据时,实际上就是拿该记录的事务ID(包括历史版本的事务ID)和这个一致性视图进行比较,直到某个版本的数据是可见的为止

    读取的记录的事务ID小于低水位,说明这个版本的数据在开启本事务前已经提交,是可见的,直接返回这个数据 

    读取的记录的事务ID大于高水位,说明这个版本的数据在开启本事务后提交的,不可见,从记录中取出 DBROLLPTR 指向的记录并读取其事务 ID,开始下一轮的判断 

    读取的记录的事务ID介于低水位和高水位中间,此时判断事务ID是否在一致性视图的事务数组中: 如果不在,说明这个版本的数据在开启本事务前已经提交,是可见的,直接返回这个数据 如果在,说明这个版本的数据是由开启事务后的其他活跃事务提交的,对本事务是不可见的,因此需要从记录中取出 DBROLLPTR 指向的记录并读取其事务 ID,开始下一轮的判断  

    这里个人简单的总结一下,当时看mysql编程实战的时候,总有些不懂,这个视图到底是个什么东西,看了上述的文章,才明白。再读未提交的情况下,不采用mvcc机制。这也就是读提交操作当地做了什么操作使得可以读已经提交。就是通过上面所说的视图。这里,也可以发现读已提交和可重复读的区别,读提交的视图是在每次查询的时候生成的,因此一个事务,或许有多个“版本”的视图,因此,当每次查询的时候读已提交可以保证这个事务是“最新”的。而可重复读,视图的创建在第一个select,可以保证后续的事务提交对本事务没影响。

   但这里有一个问题需要注意,update、insert、delete都会有一个隐式的查询操作,但它们都是当前读(快照读不加锁,对于非唯一索引或普通字段,很容易引起冲突),读取的都是最近的数据,但问题是一旦其他事务删除了记录(添加),这可能会引起幻读。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容