29.2. 预写式日志(WAL)
预写式日志(WAL)是一种确保数据完整性的标准方法。 有关它的详细描述可以在大多数(如果不是全部的话)有关事务处理的书中找到。简而言之, WAL的中心思想是对数据文件的修改(它们是表和索引的载体) 必须是只能发生在这些修改已经记录到日志之后,也就是说, 在描述这些变化的日志记录刷新到永久存储器之后。如果我们遵循这个过程, 那么就不需要在每次事务提交的时候都把数据页刷新到磁盘, 因为在出现崩溃的情况下可以用日志来恢复数据库: 任何尚未附加到数据页的记录都将先从日志记录中重做(这叫向前滚动恢复,也叫 REDO)。
Tip: 因为WAL在崩溃之后恢复数据文件内容, 所以日志文件系统对于数据文件或WAL文件的可靠存储是完全没有必要的。实际上, 日志记录开销会降低性能,尤其是日志记录导致文件系统data 刷新到磁盘。幸运地,在记录日期期间的数据刷新可以经常用一个文件系统挂载选项禁用, 例如,在Linux ext3文件系统上的
data=writeback
。在崩溃后日志文件系统确实提高了启动速度。
使用WAL显著地减少了磁盘写的次数,因为只有日志文件需要刷新到磁盘以保证事务提交了, 而不是事务修改的所有数据文件。日志文件是顺序写的,所以同步日志的开销要远比同步数据页的开销小。 对于许多小事务修改数据存储的许多不同位置更是如此。另外,当服务器正在处理许多小的并发事务时, 日志文件的一个fsync
足以提交许多事务。
WAL还提供了数据库在线备份和时间点恢复的可能,就像Section 24.3 里描述的那样。通过归档的 WAL 文件,可以将数据库恢复到 WAL 文件包含的任意时刻: 只需要简单地安装以前的数据库物理备份,然后重放 WAL 到希望的时间点。另外, 物理备份还不必是数据库状态的一个即时快照(如果其制作花了较长时间的话), 因为 WAL 日志的重放将修复任何内部的不一致。