Page tree
Skip to end of metadata
Go to start of metadata


部分写(Partial writes)情形:


假设数据库块(或page)大小设置为16kb,操作系统层IO的最小单位为4kb。

首先,数据库的commit操作可以确保日志(redo/wal)已经落盘,和数据文件是否落盘无关。

当16kb大小的数据块落盘时,如果在刚完成4kb写入的时候发生了crash,那么这个数据块实际上是corruption的;

但是在日志中,当前的事务已经正常完成。

这就是partial writes的情况。


以下是三种数据库对此种情况的处理手段。


Oracle

MySQL

PostgreSQL

官方文档未提及相关内容

innodb_doublewrite

full_page_writes


1

on


doublewrite buffer是在system表空间中的一块存储区域。

在pages写到他们正确的数据文件之前,它们要先从InnoDB buffer pool中flush到doublewrite buffer中。

 所以,如果发生了partial writes,InnoDB可以从doublewrite buffer中找到完整的pages,以进行实例恢复。

 虽然写了两次,但是性能不会下降一半。因为doublewrite buffer写操作是一个大的顺序IO,只执行一次fsync()。

对于每一个page,在检查点之后的第一次修改时,将整个page都写入到WAL中。

 这样的话,如果发生了partial writes,可以从WAL中得到完整的page,以进行实例恢复。

 这样做的劣势是会增大WAL的大小,降低WAL大小的方式是增大检查点的触发时间间隔。

  • No labels