4. 事务的执行过程@ACD

introduction

事务最出名的特点, 就是那个"要么执行/要么全都不执行(原子性)", "commit一定落盘(持久性)". 这两个重要特性全是靠undo/redo/binlog三者的合作完成的.

"事务改的数据" 是指什么数据?

事务具体怎么执行的方案是InnoDB负责的, InnoDB整出了一个叫做Buffer Pool的东西, 这种东西的原理是把磁盘上的页映射到内存里, 于是虽然磁盘读写比较慢, 但是内存读写却是相当的快 每次事务想要修改某个属性, 我们会先把这个对象从磁盘里加载到内存的Buffer Pool里, 然后我们开始执行事务内容

  • 事务修改的时候直接修改到Buffer Pool, 加锁也是锁住Buffer Pool里的东西, 直到commit之前一直都只是在内存里

  • 每执行一条语句, 这次修改都会直接改对应的内存页

    • 此操作会响应的生出一个相反的语句, 追加到undolog里面, 例如你执行了一条insert, 那么相应的就会有一条delete在undolog里

    • 此操作同样会被记录在redolog里, 我们记录下每一个操作的目的是为了在落盘之前如果宕机了, 就必须恢复之前执行的内容, 并把redolog设置成prepare状态

原子性是怎么做到的

[如果你想回滚] : 也就是事务不要了, 这个时候我们需要将内存恢复原状, 因为这个内存是直接一一对应着磁盘的, 我们想要查盘每次都会先走这个内存, 因此不能就把这个内存搞脏了就放在这儿, 因此我们把undolog执行一遍, 将内存恢复原状

[如果你想commit] : 这个时候我们的修改还停留在内存的buffer pool里, 我们首先写上binlog, 接着执行一条fsync将这些内存里的东西再一次性刷回硬盘里. 并把redolog的状态设置成commit, 代表这条数据已经在硬盘里了

如何保证提交一定落盘

[如果你还没到commit哪一步就crash了] : 我们能在redolog里找到一些状态为prepare的语句, 这些语句应该被撤回, 操作undolog撤回

[如果你已经commit, 但是还没来得及落盘就crash了] : 那么我们同样会在redolog里找到一些状态为prepare语句, 但于此同时binlog里也有这些语句:

  • 如果binlog里有, 说明系统认为这些语句应该被执行

  • 但于此同时redolog状态为prepare, 说明他们还没被执行, 因此执行

Last updated

Was this helpful?