可重复读级别下,为什么读不到别的事务已提交的数据?MVCC(多版本并发控制)是 InnoDB 的答案。

一、事务的 ACID

  • 1.1 Atomicity——redo log(重做日志)
  • 1.2 Consistency——由其他三个保证
  • 1.3 Isolation——MVCC + 锁
  • 1.4 Durability——redo log

二、四种隔离级别

  • 2.1 READ UNCOMMITTED——脏读
  • 2.2 READ COMMITTED——不可重复读
  • 2.3 REPEATABLE READ(InnoDB 默认)——幻读(部分解决)
  • 2.4 SERIALIZABLE——串行化

三、MVCC 的核心组件

  • 3.1 隐藏列——DB_TRX_ID(事务 ID)、DB_ROLL_PTR(回滚指针)、DB_ROW_ID
  • 3.2 undo log——多版本的数据来源
  • 3.3 Read View——一致性视图

四、Read View 的生成规则

  • 4.1 m_ids——活跃事务 ID 列表
  • 4.2 min_trx_id——最小活跃事务 ID
  • 4.3 max_trx_id——下一个待分配的事务 ID
  • 4.4 creator_trx_id——当前事务 ID
  • 4.5 可见性判断算法

五、RC 与 RR 的 Read View 差异

  • 5.1 RC——每次查询生成新的 Read View
  • 5.2 RR——事务开始时生成一次 Read View
  • 5.3 这就解释了不可重复读的差异

六、当前读与快照读

  • 6.1 快照读——普通 SELECT,基于 MVCC
  • 6.2 当前读——SELECT ... FOR UPDATE / UPDATE / DELETE,基于锁
  • 6.3 当前读能看到别的事务已提交的数据

七、幻读的解决——间隙锁

  • 7.1 RR 下 MVCC 能部分解决幻读
  • 7.2 当前读时幻读仍存在
  • 7.3 间隙锁(Gap Lock)——锁定记录之间的间隙
  • 7.4 Next-Key Lock——记录锁 + 间隙锁

八、总结

  • MVCC = undo log + Read View + 隐藏列
  • RR 隔离级别的实现——快照读靠 MVCC,当前读靠 Next-Key Lock