MySQL 事务隔离与 MVCC
可重复读级别下,为什么读不到别的事务已提交的数据?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
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 谜思录!