9.3 9.4 9.5 9.6 10 11 12 13 14 15 Current(16) 17
问题报告 纠错本页面

30.6. WAL内部 #

WAL会自动启用;管理员无需采取任何操作, 只需确保满足WAL文件的磁盘空间需求, 并完成任何必要的调优(请参阅第 30.5 节)。

WAL记录在每次写入新记录时被追加到WAL 文件中。插入位置由日志序列号(LSN)描述,它是 WAL中的一个字节偏移量,并随着每条新记录单调递增。 LSN值以数据类型 pg_lsn返回。可以比较 这些值以计算将它们分隔的WAL数据量,因此它们被用来 衡量复制和恢复的进度。

WAL 文件存储在数据目录下的 pg_wal 目录中,作为一组段文件,通常每个文件大小为 16 MB(但可以通过修改 --wal-segsize initdb 选项来更改大小)。每个段被划分为页面, 通常每个页面大小为 8 kB(此大小可以通过 --with-wal-blocksize 配置选项来更改)。WAL 记录头的描述在 access/xlogrecord.h 中;记录内容取决于正在记录的事件类型。 段文件的名称是不断递增的数字,从 000000010000000000000001 开始。数字不会回绕,但要耗尽 可用的数字库存将需要非常非常长的时间。

如果将WAL放置在与主数据库文件不同的磁盘上是有利的。这可以通过将 pg_wal目录移动到另一个位置(当然是在服务器关闭的 情况下)并从主数据目录中的原始位置创建一个指向新位置的符号链接来实现。

WAL的目的是确保在修改数据库记录之前先写入日志, 但这可能会被磁盘驱动器 所破坏,这些驱动器错误地向内核报告写入成功, 实际上它们只是将数据缓存起来而尚未存储到磁盘上。 在这种情况下,电源故障可能会导致不可恢复的数据损坏。 管理员应尽量确保存储PostgreSQLWAL文件的磁盘不会做出这样的错误报告。 (参见第 30.1 节。)

在创建检查点并刷新WAL之后,检查点的位置会保存在文件 pg_control中。因此,在恢复开始时, 服务器首先读取pg_control,然后读取 检查点记录;接着通过从检查点记录中指示的WAL位置向前扫描, 执行REDO操作。由于在检查点之后的首次页面修改时(假设 full_page_writes未被禁用),数据页面的 全部内容会被保存到WAL中,因此自检查点以来更改的所有页面 都会被恢复到一致的状态。

为了解决pg_control损坏的情况,我们应该支持以逆序扫描现有的 WAL段的可能性——从最新到最旧——以找到最新的检查点。这尚未实现。 pg_control足够小(小于一个磁盘页面),因此它不会受到部分写入 问题的影响,并且截至目前,还没有因无法读取pg_control本身 而导致数据库故障的报告。因此,尽管理论上它是一个薄弱环节,但pg_control 在实际中似乎并不是一个问题。