↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本。 PostgreSQL 7.1 已结束支持。 请参阅 当前版本手册.

第 9 章 预写式日志(WAL)

Author

Vadim Mikheev 和 Oliver Elphick

9.1. 总体描述 #

预写式日志(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).

9.1.1. WAL 的直接收益 #

使用 WAL 的第一个明显好处是大幅减少磁盘写入次数,因为在事务提交时只需要把日志文件刷写到磁盘;在多用户环境中,许多事务的提交可以通过对日志文件的一次 fsync() 完成。此外,日志文件是顺序写入的,因此同步日志的代价远小于刷写数据页的代价。

下一个好处是数据页的一致性。事实是,在 WAL 之前,PostgreSQL 从不能保证崩溃后的一致性。在 WAL 之前,写入期间的任何崩溃都可能导致:

  1. 索引元组指向不存在的表行
  2. 索引元组在分裂操作中丢失
  3. 由于数据页部分写入,表或索引页内容完全损坏

索引的问题(问题 1 和 2)或许可以通过额外的 fsync() 调用修复,但如果没有 WAL,如何处理最后一种情况并不明显;WAL 在需要时会把整个数据页内容保存在日志中,以确保崩溃后恢复的页面一致性。

9.1.2. 未来的收益 #

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 日志文件。数据库文件副本和归档的日志文件可以像崩溃后恢复那样用于恢复。每次制作新的数据库文件副本后,旧的日志文件就可以删除。实现这一功能需要记录数据文件和索引的创建与删除;还需要开发一种复制数据文件的方法(操作系统的复制命令并不合适)。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.