前置知识
MVCC
多版本并发控制(Multi-Version Concurrency Control)是MySQL的InnoDB引擎实现隔离级别的一种具体方式。用于实现提交读和可重复读。
术语
TRX_ID:Transaction ID 是指事物开始的时候被分配的版本号(即属于当前事务自己独有的身份证)。
ROLL_PTR:Roll Pointer 用于将一个数据行的版本快照连接起来的指针(例如,TRX_ID为1时属性id=1,然后TRX_ID=5时更新id=5,此时的ROLL_PTR指向TRX_ID=1),用于回滚操作。
ReadView
MVCC 中维护了一个 ReadView 结构,主要包含了当前系统未提交的事务列表 TRX_IDs {TRX_ID_1, TRX_ID_2, ...},还有该列表的最小值 TRX_ID_MIN 和 最大值TRX_ID_MAX。
在进行 SELECT 操作时,根据数据行快照的 TRX_ID 与 TRX_ID_MIN 和 TRX_ID_MAX 之间的关系,从而判断数据行快照是否可以使用:
-
TRX_ID < TRX_ID_MIN,表示该数据行快照时在当前所有未提交事务之前进行更改的,因此可以使用。
-
TRX_ID > TRX_ID_MAX,表示该数据行快照是在事务启动之后被更改的,因此不可使用。
-
TRX_ID_MIN <= TRX_ID <= TRX_ID_MAX,需要根据隔离级别再进行判断:
-
提交读:如果要读取的数据还存在于TRX_ID事务列表中,表示该数据行快照对应的事务还未提交,则该快照不可使用。否则表示已经提交,可以使用。
-
可重复读:都不可以使用。因为如果可以使用的话,那么其它事务也可以读到这个数据行快照并进行修改,那么当前事务再去读这个数据行得到的值就会发生改变,也就是出现了不可重复读问题。
可重复读隔离级别则在第一次读的时候会生成一个ReadView,之后的读都复用之前的ReadView。(会通过ROLL_PTR去查询初始的数据行结果,来保证数据相同)