pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
Vadim Mikheev 和 Oliver Elphick
预写式日志(WAL) 是一种标准的事务日志方法。它的详细 描述可以在大多数(即使不是全部)关于 事务处理的书中找到。简言之,WAL 的 核心概念是:对数据文件(表和索引 所在之处)的更改必须只在这些更改被记录之后 写入——也就是在日志记录已刷写到 永久存储之后。 When we follow this procedure, we do not need to flush data pages to disk on every transaction commit, because we know that in the event of a crash we will be able to recover the database using the log: any changes that have not been applied to the data pages will first be redone from the log records (this is roll-forward recovery, also known as REDO) and then changes made by uncommitted transactions will be removed from the data pages (roll-backward recovery - UNDO).
使用 WAL 的第一个明显好处是 大幅减少磁盘写入次数,因为在事务 提交时只需要把日志文件刷写到磁盘; 在多用户环境中,许多事务的提交 可以通过对日志文件的一次 fsync() 完成。此外,日志文件是 顺序写入的,因此同步日志的代价远小于 刷写数据页的代价。
下一个好处是数据页的一致性。事实是, 在 WAL 之前, PostgreSQL 从不能保证 崩溃后的一致性。在 WAL 之前,写入期间的任何崩溃都可能导致:
索引的问题(问题 1 和 2)或许可以通过额外的 fsync() 调用修复,但如果没有 WAL,如何处理最后一种情况并不 明显;WAL 在需要时会把整个 数据页内容保存在日志中,以确保崩溃后恢复的页面 一致性。
In this first release of WAL, UNDO operation is not implemented, because of lack of time. This means that changes made by aborted transactions will still occupy disk space and that 我们仍需要一个保存事务状态的永久 pg_log 文件,因为 事务标识符不能重用。一旦实现了 UNDO,pg_log 就不再 需要是永久的;可以在关机时删除 pg_log、把它分段 并删除旧段。
有了 UNDO,还可以实现 保存点,允许部分回滚 无效的事务操作(命令输错导致的 解析错误、插入重复的主键/唯一键等), 同时能够继续或提交事务在 出错之前所做的有效操作。目前, 任何错误都会使整个事务无效并 要求中止事务。
WAL 为数据库 在线备份和恢复(BAR)的 新方法提供了机会。要 使用这种方法,需要定期把数据 文件保存到另一块磁盘、磁带或另一台主机,并归档 WAL 日志文件。数据库文件副本和 归档的日志文件可以像 崩溃后恢复那样用于恢复。每次制作新的 数据库文件副本后,旧的日志 文件就可以删除。实现这一 功能需要记录数据文件和索引的创建 与删除;还需要开发一种 复制数据文件的方法(操作系统的复制命令 并不合适)。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。