历史版本。 PostgreSQL 7.4 已结束支持。 请参阅 当前版本手册.
第 25 章 预写式日志(WAL)
预写式日志(WAL)是一种标准的事务日志方法。它的详细描述可以在大多数(即使不是全部)关于事务处理的书中找到。简言之,WAL 的核心概念是:对数据文件(表和索引所在之处)的更改必须只在这些更改已被记录之后写入,也就是在日志记录已刷写到永久存储之后。如果遵循这一过程,就不需要在每次事务提交时把数据页刷写到磁盘,因为我们知道一旦发生崩溃,可以用日志恢复数据库:尚未应用到数据页的任何更改将先从日志记录中重做(这是前滚恢复,也称 REDO),然后由未提交事务所做的更改将从数据页中移除(后滚恢复,UNDO)。
25.1. WAL 的优势 #
使用 WAL 的第一个明显好处是大幅减少磁盘写入次数,因为在事务提交时只需要把日志文件刷写到磁盘;在多用户环境中,许多事务的提交可以通过对日志文件的一次
fsync() 完成。此外,日志文件是顺序写入的,因此同步日志的代价远小于刷写数据页的代价。
下一个好处是数据页的一致性。事实是,在 WAL 之前,PostgreSQL 从不能保证崩溃后的一致性。在 WAL 之前,写入期间的任何崩溃都可能导致:
- 索引行指向不存在的表行
- 索引行在分裂操作中丢失
- 由于数据页部分写入,表或索引页内容完全损坏
索引的问题(问题 1 和 2)或许可以通过额外的
fsync() 调用修复,但如果没有
WAL,如何处理最后一种情况并不明显;WAL 在需要时会把整个数据页内容保存在日志中,以确保崩溃后恢复的页面一致性。