美文网首页
InnoDB 事务的实现原理

InnoDB 事务的实现原理

作者: java后端领域 | 来源:发表于2020-04-22 21:19 被阅读0次

    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. 分析阶段:

    • 找出哪些数据页是脏页:通过checkpoint 的脏页表中的脏页,遍历 redoLog,将遇到的新 Page 加到脏页集合(可能不是脏页,但是利用刷 page 的幂等性保障结果一致)
    • 找出哪些事务没提交:从 checkpoint 开始,假如活跃事务表的未提交事务的集合为 T1,T2,遍历之后的 redoLog,发现有结束标记的,需要从集合删除,如果是新事务并且没有事务结束标识,就加进来,得到最终未提交的事务

    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)和并发性

    相关文章

      网友评论

          本文标题:InnoDB 事务的实现原理

          本文链接:https://www.haomeiwen.com/subject/ajrgihtx.html