InnoDB 事务的实现原理

2020-04-22  本文已影响0人  java后端领域

InnoDB 事务的实现

事务四大特性ACID

  1. 原子性(A):事务中的操作要不全部执行,要不全部不执行。如果执行到一半,宕机重启,已执行的一半要回滚回去

  2. 一致性(C):各种约束条件,比如主键不能为空、参照完整性

  3. 隔离性(I):多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其他事务的运行效果

  4. 持久性(D):一旦事务提交了,数据不能丢。比如提交了,但是数据没有刷到磁盘,宕机时,要保证将数据持久化到磁盘

InnoDB宕机时也保证数据的持久性和原子性,分为 3 个阶段

实现前提:Checkpoint 机制

​ 基于两张表:活跃事务表和脏页表,定时将这两张表进行拍快照,存到 redolog 中

  1. 活跃事务表:存的是所有没提交的事务集合,每条记录由 事务 ID + lastLSN(该事务的最后一条日志的 LSN,用于进行回滚操作)

    tx_id lastLSN
  2. 脏页表:当前所有未刷到磁盘上的 Page 集合(包括提交和未提交的事务),每条记录由 page_no 和 recoveryLSN(Page 第一次变成脏页时的 LSN,用于将后面的所有修改都刷磁盘)

    page_no recoveryLSN

1. 分析阶段:

2. 进行 Redo

​ 从 redolog 中的最后一次 checkpoint 快照,从脏页快照中的所有脏页记录中得到最小的 recoveryLSN,作为 firstLSN, 遍历 redoLog,将对于的 Page 全部刷一次磁盘(包括提交和未提交的 Page),已提交的Page 重新刷磁盘不会有问题(幂等性:因为 Page 中记录有个字段pageLSN最后一次修改的LSN,当更新时发现请求的 LSN<=pageLSN,忽略)。

​ redo 后,可能会存在需要回滚的Page 数据(未提交的数据),通过 Undo 进行恢复

3. 进行 Undo

​ 通过分析阶段找到未提交的集合,参考个最后一个日志逆序遍历,生成逆向的 SQL 语句,在 redoLog 的尾部进行追加。(不存在物理的回滚,全部都是正向的 commit)

总结

  1. 通过 undo log + redo log + checkpoint(活跃事务表和脏表)实现事务的 原子性(A)+ 持久性(D)
  2. 通过 MVCC+ 锁实现了事务的隔离性(I)和并发性
上一篇下一篇

猜你喜欢

热点阅读