两次写

如果说Insert Buffer带给InnoDB存储引擎是性能上的提升,

那么两次写(double write)带给InnoDB存储引擎的是数据页的可靠性。

部分写

当发生数据库宕机时,可能InnoDB存储引擎正在写入某个页到表中。

而这个页只写了一部分就发生了宕机,这种情况称为部分写失效(partial page write

如果发生写失效,不能通过重做日志恢复?

答:重做日志记录的是对页的物理操作,如果这个页本身已经损坏,

再对其进行重做是没有意义的。

在应用重做日志之前,需要一个页的副本,当出现部分写失效时,先通过页的副本

来还原该页,再进行重做,这就是doublewrite

doublewrite 的组成

doublewrite由两部分组成

  • 内存中的doublewrite buffer,大小为2MB

  • 物理磁盘上共享空间中连续的128个页,即2个区(extent),同样为2MB

    这部分doublewrite是连续的,因此这个过程是顺序写的,开销并不是很大。

脏页刷新的步骤

在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是会通过memcpy函数将脏页

先复制到内存中的doublewrite buffer,之后通过doublewrite buffer再分两次,

每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,

避免缓冲写带来的问题。

在完成doublewrite页的写入后,再将doublewrite buffer中的页写入各个表空间文件中,

此时就是刷新数据到数据库文件上,写入是离散的。

开启与关闭

可通过skip_innodb_doublewrite参数禁止doublewrite功能,这是可能会发生写失效问题。

某些文件系统本身提供了部分写失效的防范机制。如ZFS文件系统。

这种情况下就不用开启doublewrite了。