29.2. 预写式日志(WAL)

预写式日志(WAL) 是一种实现事务日志的标准方法。有关它的详细描述可以在大多数(如果不是全部的话) 有关事务处理的书中找到。简而言之,WAL 的中心思想 是对数据文件的修改(它们是表和索引的载体)必须是只能发生在这些修改已经记录到日志之后, 也就是说,在描述这些变化的日志记录刷新到永久存储器之后。如果我们遵循这个过程, 那么就不需要在每次事务提交的时候都把数据页刷新到磁盘,因为在出现崩溃的情况下 可以用日志来恢复数据库:任何尚未附加到数据页的记录都将先从日志记录中重做 (这叫向前滚动恢复,也叫REDO)。

Tip: 因为WAL在数据库崩溃后会保存数据库文件内容, 所以日志文件系统没有必要完全保存数据库文件或WAL文件。 事实上,日志开启会降性能,特别是在当日志记录引起系统数据 被写入到磁盘时。幸运的是,在当可以通过一个文件挂载选项关闭时, 数据才会刷新,例如,data=writeback在Linux的ext3文件系统。 在崩溃后,日志系统能够提高启动速度。

使用 WAL 的第一个主要的好处就是显著地减少了磁盘写的次数。 因为在日志提交的时候只有日志文件需要刷新到磁盘以保证交易承诺,而不是事务修改的所有数据文件。 日志文件是顺序写的,所以同步日志的开销要远比同步数据页的开销小。 对于许多小事务修改数据存储的许多不同位置更是如此。 此外,当服务器正在处理许多小并发交易,一个fsync可 足以提交许多交易。

WAL 还提供了数据库在线备份和恢复的可能, 就像Section 24.3里描述的那样。 通过归档的 WAL 文件,可以将数据库恢复到 WAL 文件包含的任意时刻: 只需要简单地安装以前的数据库物理备份,然后重放 WAL 到希望的时间点。 另外,物理备份还不必是数据库状态的一个即时快照(如果其制作花了较长时间的话), 因为 WAL 日志的重放将修复任何内部的不一致。