预写日志 (WAL) 是一种确保数据完整性的标准方法。详细的描述可以在大多数(如果不是全部) 关于事务处理的书籍中找到。简而言之,WAL的核心概念是, 对数据文件(存放表和索引的地方)的更改必须在这些更改被记录之后才被写入, 也就是说,在描述这些更改的WAL记录被刷新到永久存储之后。如果我们遵循这个 程序,我们就不需要在每次事务提交时将数据页刷新到磁盘,因为我们知道在发生 崩溃的情况下,我们可以使用日志恢复数据库:任何尚未应用到数据页的更改都可以 从WAL记录中重做。(这就是前滚恢复,也称为REDO。)
因为WAL在崩溃后恢复数据库文件内容,不需要日志化文件系统作为数据文件或WAL文件的可靠存储。实际上,日志会降低性能,特别是如果日志导致文件系统数据被刷写到磁盘。幸运地是,日志期间的数据刷写常常可以在文件系统挂载选项中被禁用,例如在Linux ext3文件系统中可以使用data=writeback
。在崩溃后日志化文件系统确实可以提高启动速度。
使用WAL会显著减少磁盘写入的次数,因为只需要将
WAL文件刷新到磁盘即可保证事务提交,而不是刷新事务更改的每个数据文件。
WAL文件是顺序写入的,因此同步WAL的成本远低于刷新数据页的成本。
这对于处理许多小型事务并涉及数据存储不同部分的服务器尤其如此。
此外,当服务器处理许多小型并发事务时,一次fsync
WAL文件可能足以提交许多事务。
WAL 还使得支持在线备份和时间点恢复成为可能, 如在 Section 25.3 中所述。通过归档 WAL 数据, 我们可以支持回滚到可用 WAL 数据覆盖的任何时间点:我们只需安装 数据库的先前物理备份,并将 WAL 重放到所需的时间点即可。而且, 物理备份不必是数据库状态的瞬时快照——如果备份是在一段时间内完成的, 那么重放该时间段的 WAL 将修复任何内部不一致性。