2022-09-26 InnoDB的两阶段提交

在大多数数据产品中,都会同时使用内存和磁盘,内存提供了更好的性能但是遇到程序崩溃、机器崩溃则会丢失数据,磁盘提供了持久化的保证但是性能较差。为了保证内存和磁盘的一致性,往往需要日志来保证(将随机写转换成顺序写),对于对一致性要求更高的场景,使用WAL保证,而有时候为了追求更高的性能,也会使用写后日志,比如Redis的AOF日志。

在遇到需要事务的场景,存在UndoLog、RedoLog、UndoLog+RedoLog三种比较经典的WAL,然而单独使用一种Log是无法保证新旧数据都能有持久化数据,除非将磁盘真正使用的数据作为其中一种数据的来源,但是那样只能使用单事务,而且事务的提交会和内存刷盘的操作绑定,为了减少这个问题,就需要UndoLog+RedoLog(内存数据的持久化和事务解耦),这样才能保证新旧数据都持久化,随时可以提交和回滚,那样内存的数据可以长久不刷盘,等到某个时间点再一起提交,这样大大提高了事务场景的存储性能。

本篇将详细讨论一下InnoDB的两阶段提交的实现,通过之前的学习,已经明白了一个关键点,那就是要想保证内存数据的不丢失,必须需要WAL,而事务场景下必须将数据的UndoLog和RedoLog都持久。为了保证binlog和redolog的一致性,使用两阶段提交

两阶段提交的流程:

1.将磁盘的数据加载到内存

2.在事务开始时,对UndoLog(旧数据)进行持久化

3.在内存中对数据进行修改

4.完成RedoLog中关于新数据的持久化;此时已经保证了事务可随时提交或者回滚(准备完成)

6.Binlog的提交

7.完成事务的提交


内存中数据的修改必须在Undo之后,这样才能保证使用UndoLog恢复内存数据

Binlog必须在准备阶段之后,因为如果先Binlog,然后发生内存崩溃,内存的数据将无法恢复

假如在4之前崩溃,可以根据WAL恢复(事务回滚)

假如在5之后崩溃,可以根据binlog进行对比,如果binlog中事务高于redolog,则重写事务,否则

回滚事务

数据的刷盘:内存buffer->操作系统buffer->disk

期间有锁。。后面再看

https://blog.csdn.net/u014710633/article/details/90641489

参考这篇文章,数据库其实也没有保证完全的CIAD,redolog的write和flush是可配的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容