19.5. 预写日志

有关调整这些设置的其他信息,请参见Section 30.4

19.5.1. Settings

  • wal_level ( enum )
    • wal_level确定将多少信息写入 WAL。默认值为replica,它将写入足够的数据以支持 WAL 归档和复制,包括在备用服务器上运行只读查询。 minimal删除所有日志记录,但从崩溃或立即关闭中恢复所需的信息除外。最后,logical添加支持逻辑解码所需的信息。每个级别都包括所有较低级别记录的信息。该参数只能在服务器启动时设置。

minimal级别,可以安全地跳过一些批量操作的 WAL 日志记录,这可以使这些操作更快(请参见Section 14.4.7)。可以应用此优化的操作包括:

CREATE TABLE AS
CREATE INDEX
CLUSTER
COPY进入在同一事务中创建或截断的表

但是最少的 WAL 不能包含足够的信息来从基本备份和 WAL 日志中重建数据,因此必须使用replica或更高版本来启用 WAL 归档(archive_mode)和流复制。

logical级别中,记录的信息与replica相同,另外还包括允许从 WAL 中提取逻辑变更集所需的信息。使用logical级别将增加 WAL 量,特别是如果为REPLICA IDENTITY FULL配置了许多表并且执行了许多UPDATEDELETE语句时。

在 9.6 之前的版本中,此参数还允许值archivehot_standby。这些仍被接受,但已 Map 到replica

  • fsync ( boolean )
    • 如果启用此参数,则 PostgreSQL 服务器将通过发出fsync()系统调用或各种等效方法(请参见wal_sync_method)来尝试确保更新已物理写入磁盘。这样可以确保在 os 或硬件崩溃后,数据库集群可以恢复到一致的状态。

虽然关闭fsync通常可以提高性能,但是在断电或系统崩溃的情况下,这可能导致无法恢复的数据损坏。因此,仅当您可以轻松地从外部数据重新创建整个数据库时,才建议关闭fsync

关闭fsync的安全情况的示例包括从备份文件中初始加载新数据库集群,使用数据库集群处理一批数据(此后将丢弃并重新创建数据库)或只读数据库。经常重新创建且不用于故障转移的克隆。单独使用高质量的硬件不足以关闭fsync

为了在将fsync从关闭更改为打开时进行可靠的恢复,必须将内核中所有已修改的缓冲区强制为持久存储。这可以在集群关闭或fsync开启时通过运行initdb --sync-only,运行sync,卸载文件系统或重新引导服务器来完成。

在许多情况下,为非关键事务关闭synchronous_commit可以提供关闭fsync的许多潜在性能优势,而不会带来数据损坏的风险。

只能在postgresql.conf文件或服务器命令行中设置fsync。如果您关闭此参数,也可以考虑关闭full_page_writes

  • synchronous_commit ( enum )
    • 指定在命令向 Client 端返回“成功”指示之前,事务提交是否将 awaitWAL 记录写入磁盘。有效值为onremote_applyremote_writelocaloff。安全的默认设置为on。如果为off,则在向 Client 端报告成功与 true 确保事务安全以防止服务器崩溃之间可能会有延迟。 (最大延迟是wal_writer_delay的三倍。)与fsync不同,将此参数设置为off不会造成数据库不一致的风险:os 或数据库崩溃可能会导致一些最近的据称已提交的事务丢失,但是数据库状态会就像那些 Transaction 被彻底中止一样。因此,当性能比事务的持久性更重要时,关闭synchronous_commit可能是一个有用的选择。有关更多讨论,请参见Section 30.3

如果synchronous_standby_names为非空,则此参数还控制事务提交是否将 await 其 WAL 记录复制到备用服务器。当设置为on时,提交将一直 await,直到当前同步备用数据库的答复指示他们已接收到事务的提交记录并将其刷新到磁盘。这样可以确保事务不会丢失,除非主备用数据库和所有同步备用数据库都遭受数据库存储损坏。当设置为remote_apply时,提交将一直 await,直到当前同步备用数据库的答复指示他们已接收到事务的提交记录并应用了该记录后,该记录才可在备用数据库上的查询中看到。当设置为remote_write时,提交将一直 await,直到当前同步备用数据库的答复指示它们已接收到事务的提交记录并将其写出到 os 中。即使 PostgreSQL 的一个备用实例崩溃,此设置也足以确保数据保存,但即使备用数据库遭受 os 级崩溃,此设置也足以确保数据保存,因为数据不一定已到达备用数据库上的稳定存储。最后,设置local导致提交 await 本地刷新到磁盘,但不 await 复制。当使用同步复制时,这通常不是所希望的,但出于完整性考虑而提供。

如果synchronous_standby_names为空,则设置onremote_applyremote_writelocal都提供相同的同步级别:事务提交仅 await 本地刷新到磁盘。

该参数可以随时更改。任何一项事务的行为都由提交时生效的设置决定。因此,使某些事务同步提交而其他事务异步提交是可能且有用的。例如,要使单个多语句事务在默认设置相反时异步提交,请在事务内发出SET LOCAL synchronous_commit TO OFF

  • wal_sync_method ( enum )

    • 强制将 WAL 更新输出到磁盘的方法。如果fsync处于关闭状态,则此设置无关紧要,因为根本不会强制退出 WAL 文件更新。可能的值为:
  • open_datasync(使用open()选项O_DSYNC写入 WAL 文件)

  • fdatasync(每次提交时致电fdatasync())

  • fsync(每次提交时致电fsync())

  • fsync_writethrough(每次提交时调用fsync(),强制通过任何磁盘写缓存进行写操作)

  • open_sync(使用open()选项O_SYNC写入 WAL 文件)

open_ *选项也使用O_DIRECT(如果有)。并非所有这些选择在所有平台上都可用。默认值为平台支持的上述列表中的第一种方法,但fdatasync是 Linux 上的默认方法。默认值不一定理想。可能有必要更改此设置或系统配置的其他方面,以创建崩溃安全配置或实现最佳性能。这些方面在Section 30.1中讨论。此参数只能在postgresql.conf文件或服务器命令行中设置。

  • full_page_writes ( boolean )
    • 启用此参数后,PostgreSQL 服务器会在检查点之后对该页面的首次修改期间将每个磁盘页面的全部内容写入 WAL。这是必需的,因为在 os 崩溃期间正在进行的页面写入可能仅部分完成,从而导致包含新旧数据混合的磁盘页面。通常在 WAL 中存储的行级更改数据不足以在崩溃后恢复期间完全还原此类页面。存储完整的页面映像可确保可以正确还原页面,但是这样做的代价是增加了必须写入 WAL 的数据量。 (由于 WAL 重放总是从检查点开始,因此在检查点之后每页的第一次更改期间执行此操作就足够了.因此,减少全页写入成本的一种方法是增加检查点间隔参数.)

禁用此参数可加快正常操作的速度,但在系统故障后可能会导致不可恢复的数据损坏或静默数据损坏。风险与关闭fsync相似,尽管较小,但应仅根据针对该参数建议的相同情况将其关闭。

禁用此参数不会影响使用 WAL 归档进行时间点恢复(PITR)(请参阅Section 25.3)。

此参数只能在postgresql.conf文件或服务器命令行中设置。默认值为on

  • wal_log_hints ( boolean )
    • 当此参数为on时,PostgreSQL 服务器会将每个磁盘页面的全部内容在检查点之后的第一次修改过程中写入 WAL,即使是非关键性的所谓提示位修改也是如此。

如果启用了数据校验和,则将始终对提示位更新进行 WAL 记录,并且将忽略此设置。如果数据库启用了数据校验和,则可以使用此设置来测试将发生多少额外的 WAL 日志记录。

该参数只能在服务器启动时设置。默认值为off

  • wal_compression ( boolean )
    • 当此参数为on时,当full_page_writes打开或在基本备份期间,PostgreSQL 服务器将压缩写入 WAL 的整页图像。在 WAL 重放期间,压缩的页面图像将被解压缩。默认值为off。只有超级用户可以更改此设置。

启用此参数可以减少 WAL 量,而不会增加不可恢复的数据损坏的风险,但是以在 WAL 日志记录期间进行压缩以及在 WAL 重放期间进行解压缩上花费一些额外的 CPU 为代价。

  • wal_buffers ( integer )
    • 用于尚未写入磁盘的 WAL 数据的共享内存量。默认设置-1 选择等于shared_buffers的 1/32(大约 3%)的大小,但不小于64kB且不大于一个 WAL 段的大小,通常为16MB。如果自动选择太大或太小,可以手动设置此值,但是小于32kB的任何正值将被视为32kB。该参数只能在服务器启动时设置。

WAL 缓冲区的内容在每次事务提交时都会写出到磁盘,因此极大的值不太可能带来显着的好处。但是,将此值设置为至少几个兆字节可以提高繁忙的服务器上的写入性能,该服务器上有许多 Client 端一次提交。在大多数情况下,默认设置为-1 选择的自动调整应该会给出合理的结果。

  • wal_writer_delay ( integer )

    • 指定 WAL 编写器刷新 WAL 的频率。刷新 WAL 后,它将休眠wal_writer_delay毫秒,除非被异步提交的事务唤醒。如果最后一次刷新发生的时间少于wal_writer_delay毫秒,并且此后产生了少于wal_writer_flush_after个字节的 WAL,则 WAL 仅写入 os,而不刷新到磁盘。默认值为 200 毫秒(200ms)。请注意,在许多系统上,睡眠延迟的有效分辨率为 10 毫秒。将wal_writer_delay设置为不是 10 的倍数的值可能与将其设置为下一个 10 的高倍数的结果相同。只能在postgresql.conf文件或服务器命令行中设置此参数。
  • wal_writer_flush_after ( integer )

    • 指定 WAL 编写器刷新 WAL 的频率。如果最后一次刷新发生的时间少于wal_writer_delay毫秒,并且此后产生了少于wal_writer_flush_after个字节的 WAL,则 WAL 仅写入 os,而不刷新到磁盘。如果wal_writer_flush_after设置为0,则将立即刷新 WAL 数据。默认值为1MB。只能在postgresql.conf文件或服务器命令行中设置此参数。
  • commit_delay ( integer )

    • commit_delay添加了开始 WAL 刷新之前的时间延迟(以微秒为单位)。如果系统负载足够高,可以在给定间隔内提交更多事务,则可以通过一次 WAL 刷新来提交大量事务,从而提高组提交吞吐量。但是,对于每个 WAL 刷新,它也会将延迟增加最多commit_delay微秒。因为如果没有其他事务准备好提交就只是浪费了延迟,所以仅当要启动刷新时至少在其他_3 个事务处于活动状态时才执行延迟。同样,如果禁用fsync,则不会执行任何延迟。默认commit_delay为零(无延迟)。只有超级用户可以更改此设置。

在 9.3 之前的 PostgreSQL 发行版中,commit_delay的行为有所不同,效果也差得多:它只影响提交,而不影响所有 WAL 刷新,并且即使 WAL 刷新更早完成也要 await 整个配置的延迟。从 PostgreSQL 9.3 开始,准备刷新的第一个进程将 await 配置的时间间隔,而后续进程仅 await 领导者完成刷新操作。

  • commit_siblings ( integer )
    • 执行commit_delay延迟之前需要的最小并发未清事务数。较大的值使至少一个其他事务更有可能在延迟时间间隔内提交。默认值为五个事务。

19.5.2. Checkpoints

  • checkpoint_timeout ( integer )

    • 自动 WAL 检查点之间的最长时间(以秒为单位)。有效范围是 30 秒至 1 天。默认值为五分钟(5min)。增大此参数可能会增加崩溃恢复所需的时间。只能在postgresql.conf文件或服务器命令行中设置此参数。
  • checkpoint_completion_target ( floating point )

    • 指定检查点完成的目标,占检查点之间总时间的一部分。默认值为 0.5. 此参数只能在postgresql.conf文件或服务器命令行中设置。
  • checkpoint_flush_after ( integer )

    • 在执行检查点时,只要写入的字节数超过checkpoint_flush_after个,就应尝试强制 os 将这些写入操作发布到基础存储中。这样做将限制内核页面缓存中的脏数据量,从而减少在检查点末尾发出fsync时或 os 在后台大批量写回数据时出现停顿的可能性。通常,这将大大减少事务 await 时间,但是在某些情况下,尤其是对于工作负载大于shared_buffers但小于 OS 的页面缓存的情况下,性能可能会下降。此设置在某些平台上可能无效。有效范围介于02MB之间,0禁止强制写回。在 Linux 上默认为256kB,在其他地方为0。 (如果BLCKSZ不是 8kB,则默认值和最大值将按比例缩放.)只能在postgresql.conf文件或服务器命令行中设置此参数。
  • checkpoint_warning ( integer )

    • 如果由于填充检查点段文件而导致的检查点发生的距离比这几秒钟还近(这表明应该提高max_wal_size),则将消息写入服务器日志。默认值为 30 秒(30s)。零禁用警告。如果checkpoint_timeout小于checkpoint_warning,则不会生成任何警告。此参数只能在postgresql.conf文件或服务器命令行中设置。
  • max_wal_size ( integer )

    • 使 WAL 增长到自动 WAL 检查点之间的最大大小。这是一个软限制。在特殊情况下,例如重负载,失败的archive_command或较高的wal_keep_segments设置,WAL 大小可能会超过max_wal_size。默认值为 1 GB。增大此参数可能会增加崩溃恢复所需的时间。此参数只能在postgresql.conf文件或服务器命令行中设置。
  • min_wal_size ( integer )

    • 只要 WAL 磁盘使用率保持低于此设置,旧的 WAL 文件将始终在检查点被回收以备将来使用,而不是被删除。这可以用来确保保留足够的 WAL 空间来处理 WAL 使用率的峰值,例如在运行大型批处理作业时。默认值为 80 MB。此参数只能在postgresql.conf文件或服务器命令行中设置。

19.5.3. Archiving

  • archive_mode ( enum )
    • 启用archive_mode时,通过设置archive_command将完成的 WAL 段发送到存档存储。除了off之外,还有两种模式:onalways。在正常操作期间,这两种模式之间没有区别,但是当设置为always时,也会在存档恢复或待机模式下启用 WAL 存档器。在always模式下,将从存档还原的所有文件或通过流复制复制的所有文件都将被存档(再次)。有关详情,请参见Section 26.2.9

archive_modearchive_command是单独的变量,因此可以在不退出存档模式的情况下更改archive_command。该参数只能在服务器启动时设置。当wal_level设置为minimal时,不能启用archive_mode

  • archive_command ( string )
    • 执行本地 shell 命令以归档完整的 WAL 文件段。字符串中的任何%p替换为要归档文件的路径名,而任何%f则仅替换文件名。 (路径名相对于服务器的工作目录,即集群的数据目录.)使用%%在命令中嵌入实际的%字符。重要的是,只有成功执行命令,命令才返回零退出状态。有关更多信息,请参见Section 25.3.1

此参数只能在postgresql.conf文件或服务器命令行中设置。除非在服务器启动时启用了archive_mode,否则它将被忽略。如果在启用archive_modearchive_command是空字符串(默认值),则将暂时禁用 WAL 归档,但是服务器将 continue 累积 WAL 段文件,以期将很快提供命令。将archive_command设置为仅返回 true 的命令,例如/bin/true(在 Windows 上为REM)有效地禁用了归档,但同时也破坏了存档恢复所需的 WAL 文件链,因此仅应在特殊情况下使用。

  • archive_timeout ( integer )
    • archive_command仅对完整的 WAL 段调用。因此,如果您的服务器只产生很少的 WAL 流量(或在此期间有闲置时间),则在事务完成与将其安全记录到归档存储之间可能会有较长的延迟。要限制未存档数据的旧性,可以设置archive_timeout强制服务器定期切换到新的 WAL 段文件。如果此参数大于零,则从上一次切换分段文件到现在已经过了这么多秒,并且有任何数据库活动(包括单个检查点),服务器将切换到新的分段文件(如果没有,则跳过检查点)数据库活动)。请注意,由于强制切换而提前关闭的存档文件的长度仍然与完全完整的文件的长度相同。因此,使用非常短的archive_timeout是不明智的-它将使您的存档存储空间过大。 archive_timeout分钟左右的设置通常是合理的。如果要比主服务器更快地从主服务器复制数据,则应考虑使用流复制而不是存档。此参数只能在postgresql.conf文件或服务器命令行中设置。