张喜硕学长以前讲过一篇MySQL RR 与 锁,在本周又看到了RR的问题,里面提到了RR是通过MVCC实现的,但是自己对此却没什么印象,翻了翻学长的博客也没讲过,就学习一下,做个记录。
MVCC
MVCC 即多版本并发控制技术,简单的理解就是一份数据保存了多份。
用于多事务环境下,对数据读写在不加读写锁的情况下实现互不干扰,从而实现数据库的隔离性,在事务隔离级别为Read Commit 和 Repeatable read中使用到。
在InnoDB中,MVCC其实是通过undo log来实现的,但使用undo log解释起来较为复杂,所以普遍的解释是:每行记录的后面保存了两个隐藏的列,DB_TRX_ID(数据行的版本号)和DB_ROLL_PT(删除版本号),这两列保存的是系统版本号,每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。下面看看进行不同的操作时(以下内容取RR隔离级别,当然RC也是同理,只不过select的选定范围不同),InnoDB的行为:
SELECT
InnoDB会根据以下两个条件检查每行记录:
InnoDB只查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。
行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。
INSERT
InnoDB为新插入的每一行保存当前系统版本号作为数据行版本号。