一、什么是mvcc
mvcc(multiversion concurrency control),多版本并发控制,主要是在事务的读已提交和可重复读情况下发挥作用。
它主要通过在更新的行加三个字段:
1、最近一次修改事务id(DBTRXID)
2、回滚指针,指向undolog的记录(DBROLLPTR )
3、DBROWID,唯一标识
二、mvcc原理
1、先从更新操作开始,如某一时刻,事务10000对一条记录进行修改,那么它将会把当前记录保存在undolog中,然后再更新该条记录的事务id,和回滚指针,最后更新该列需要需改的数据。这里补充一个小知识点,每次都会写入一条回滚日志,那这个回滚日志何时回收呢?在mysql编程在不需要的时候才删除。也就是说,系统会判断,当没有事务再需要用到这些回滚日志时,回滚日志会被删除。
读取的记录的事务ID小于低水位,说明这个版本的数据在开启本事务前已经提交,是可见的,直接返回这个数据 。
读取的记录的事务ID大于高水位,说明这个版本的数据在开启本事务后提交的,不可见,从记录中取出 DBROLLPTR 指向的记录并读取其事务 ID,开始下一轮的判断
这里个人简单的总结一下,当时看mysql编程实战的时候,总有些不懂,这个视图到底是个什么东西,看了上述的文章,才明白。再读未提交的情况下,不采用mvcc机制。这也就是读提交操作当地做了什么操作使得可以读已经提交。就是通过上面所说的视图。这里,也可以发现读已提交和可重复读的区别,读提交的视图是在每次查询的时候生成的,因此一个事务,或许有多个“版本”的视图,因此,当每次查询的时候读已提交可以保证这个事务是“最新”的。而可重复读,视图的创建在第一个select,可以保证后续的事务提交对本事务没影响。
但这里有一个问题需要注意,update、insert、delete都会有一个隐式的查询操作,但它们都是当前读(快照读不加锁,对于非唯一索引或普通字段,很容易引起冲突),读取的都是最近的数据,但问题是一旦其他事务删除了记录(添加),这可能会引起幻读。