为什么事务的隔离级别设置为可重复读时,不管其他事务有没有变更过数据,当前事务都可以读到相同的数据记录呢?这就是Mysql的MVCC机制,在读已提交的事务隔离级别下也有用到MVCC机制。MVCC全称Multi-Version Concurrency Control

比如下面这个演示:
可重复读

前置概念介绍

undo日志

undo日志是指某条数据发生变更时,操作它的事务会在事务提交前将变更前数据保存到undo日志中,并使用trx_idroll_pointer两个隐藏字段将undo日志串联起来,形成一个版本链。
undo

一致性视图(read-view)

在可重复读的隔离级别下,开始事务时,执行任意查询语句(不需要是当前表)时会生成当前事务的一致性视图,该视图在事务提交前是不会变化的(在读已提交的事务隔离级别下,每次执行查询语句都会重新生成)

  • 视图组成
    所有未提交事务的trx_id数组+已创建的最大事务的trx_id,其中trx_id在事务执行变更操作时才真正生成。

MVCC

版本比对规则

根据生成的一致性视图从版本链(undo日志)中查找可见数据。
若一致性视图如下图例所示为[20,30],30。
根据一致性视图将事务id划分为三个区间: (0,20), [20,30], (30, +∞)
第二区间划分说明: 20为数组中最小的事务id,30为服务端已创建的最大事务id。
可见规则如下:

  • 若版本链中的trx_id处于第一区间,则认为是可见的。
  • 若版本链中的trx_id处于第三区间,则认为是不可见的。
  • 若版本链中的trx_id处于第二区间,判断是否处于数组中,如果处于数组中且当前事务id不等于trx_id则认为不可见,反之可见。

图示说明

mvcc