18.5. 预写式日志

参阅第 29.4 节获取调整这些设置的额外信息。

18.5.1. 设置

wal_level (enum)

wal_level决定有多少信息被写入到WAL中。 默认值是最小的,其中写入唯一从崩溃或立即关机中恢复的所需信息。 archive补充WAL归档需要的日志记录; hot_standby进一步增加在备用服务器上运行只读查询所需的信息; 最终logical增加支持逻辑编码所必需的信息。 每个级别都包括所有更低级别记录的信息。这个参数只能在服务器启动时设置。

最小级别中,安全地忽略一些批量操作的WAL-日志, 这可以使那些操作快很多(参阅第 14.4.7 节)。 这种优化可以应用到:

CREATE TABLE AS
CREATE INDEX
CLUSTER
COPY into tables that were created or truncated in the same transaction

但是最小的WAL不包含从基本的备份和WAL日志中重建数据的足够信息, 所以archive或者更高级别必须用来启动WAL归档 (archive_mode)和流复制。

hot_standby级别,相同的信息被记录为archive, 加上需要重建从WAL运行的事务状态信息。 为了在备用服务器上启用只读查询,主库上wal_level必须设置为 hot_standby或更高, 必须启动备库上的hot_standby。 使用hot_standbyarchive级别之间的性能几乎没有可测量的差异 ,如果任何生产的影响是明显的,则是值得欢迎的。

logical级别,记录和hot_standby相同的信息, 加上允许从WAL中提取逻辑修改所需的信息。使用logical 级别将增加WAL的量,尤其是如果为REPLICA IDENTITY FULL 分配了许多表,并且执行了许多UPDATEDELETE语句。

fsync (boolean)

如果打开这个选项,那么PostgreSQL服务器将在好几个地方使用fsync()系统调用 (或等价调用,参见wal_sync_method)来确保更新已经物理上写到磁盘中。 这样就保证了数据库集群将在操作系统或者硬件崩溃的情况下恢复到一个一致的状态。

当关闭fsync时通常是性能利益, 这可能会导致发生断电或系统崩溃时不可恢复数据丢失。 如果你可以很容易的从外部数据中创建您的整个数据库, 因此关闭fsync是明智的。

关闭fsync安全情况的例子包括备份文件中新的数据库集群的初始加载, 数据库被丢弃和重新创建之后,使用数据库集群批处理数据, 或者为只读数据库克隆被频繁重建并且不用于故障转移。 为了关闭fsync高质量硬件本身是不充分的。

当改变fsync从关闭到打开时,对于可靠的恢复, 必须强制内核中所有被修改的缓冲区到持久存储。 当集群宕机或当fsync通过运行initdb--sync-onlysync, 卸载文件系统,或重新启动服务器的时候,再完成这项工作。

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

fsync只能在postgresql.conf文件里或者服务器命令行里设置。 如果这个参数被关闭,那么请考虑把full_page_writes也关闭了。

synchronous_commit (enum)

命令返回"成功"指示给客户端之前,指定是否事务提交将等待WAL记录被写入到磁盘。 有效值是on,remote_write, localoff。 默认情况下,安全设置是on。 当off时,当成功报告给客户端, 并当该事务真正保证是安全的,不会在服务器崩溃的时候,可以有一定的延时(最大 延迟wal_writer_delay的3倍)。 不同于fsync,将此参数设置为off不会产生任何数据库不一致的风险: 操作系统或数据库崩溃可能导致丢失一些最近提交的事务, 但数据库状态将是一样的,正如该事务已经彻底终止。 因此,当性能比准确事务耐久性更重要时,关闭synchronous_commit是有效选择。 获取更多讨论请参阅第 29.3 节

如果设置synchronous_standby_names, 该参数控制是否事务提交将等待它的WAL记录被复制到备用服务器。 当设置on的时候, 提交将等待直到回复当前同步备库表明它已收到事务提交记录,并刷新到磁盘。 这确保事务不会丢失,除非主库和备库遭受他们的数据库存储崩溃。 当设置为remote_write,事务将等待 直到当前同步备库的答复表明它已经收到事务的提交记录,并且写入到备用操作系统, 但是数据并不一定在备库中达到稳定存储。 即使PostgreSQL备库实例崩溃,但并非备库遭受操作系统级的崩溃,此设置足以 确保数据的保存。

当同步复制使用时, 通常是明智的,要么等待本地刷新到磁盘和WAL记录的复制,要么 允许异步提交事务。然而,该设置local可用于 希望等待本地刷新到磁盘上的事务,而不是同步复制。 如果不设置synchronous_standby_names, 设置on, remote_writelocal 提供相同的同步级别:事务提交只能等待本地刷新到磁盘。

该参数可以在任何时候被改变;对于任何事务的行为 是由该设置提交生效时确定的。 因此,它是可能的,并且有用的, 有一些事务同步提交,其他的异步提交。 例如,为了使单一多语句事务异步提交,缺省是相反的, 在事务中发出SET LOCAL synchronous_commit TO OFF命令。

wal_sync_method (enum)

用来向磁盘强制更新WAL数据的方法。如果fsync是关闭的, 那么这个设置就没有意义,因为所有WAL文件更新都不会强制输出。 可能的值是:

  • open_datasync (用带 O_DSYNC选项的open()打开WAL文件)

  • fdatasync(每次提交的时候都调用fdatasync())

  • fsync (每次提交的时候都调用fsync())

  • fsync_writethrough (每次提交的时候调用fsync()强制写出任何磁盘写缓冲区)

  • open_sync(用带O_SYNC选项的open()写WAL文件)

如果可用的话,该open_*选项也使用O_DIRECT。 并非所有这些选择在所有平台上都可用。 默认值是平台支持的上面列表中的第一个方法, 除了fdatasync在Linux上是缺省的。 缺省的也不一定理想; 为了创建安全配置或达到最佳性能, 可能要改变这个设置或你的系统配置的其他方面, 将在第 29.1 节中讨论。 这个参数只能在postgresql.conf文件或服务器命令行上设置。

full_page_writes (boolean)

打开这个选项的时候,PostgreSQL服务器在检查点之后对页面的第一次写入时将整个页面写到 WAL 里面。 这么做是因为在操作系统崩溃过程中可能只有部分页面写入磁盘, 从而导致在同一个页面中包含新旧数据的混合。在崩溃后的恢复期间, 由于在WAL里面存储的行变化信息不够完整,因此无法完全恢复该页。 把完整的页面影像保存下来就可以保证正确存储页面, 代价是增加了写入WAL的数据量。因为WAL重放总是从一个检查点开始的, 所以在检查点后每个页面第一次改变的时候做WAL备份就足够了。 因此,一个减小全页面写开销的方法是增加检查点的间隔参数值。

把这个选项关闭会加快正常操作的速度, 但是可能导致系统崩溃后不可恢复的数据损坏或者无记载数据损坏, 它的危害类似于fsync,只是比较小而已。并且在建议参数相同的情况下关闭这个选项。

关闭这个选项并不影响即时恢复(PITR)的WAL使用(参阅第 24.3 节)。

这个选项只能在postgresql.conf文件里或者服务器命令行设置。缺省是on

wal_log_hints (boolean)

当这个参数是on时,PostgreSQL 服务器在检查点后第一次修改该页面期间,将每个磁盘页的全部内容都写入到WAL中, 即使没有所谓的提示信息的关键修改。

如果启用了数据校验和,那么总是WAL记录提示信息的更新,并且忽略此设置。 你可以使用这个设置测试如果你的数据库启用了数据校验和, 那么会有多少额外的WAL记录发生。

这个参数只能在服务器启动时设置。缺省值是off

wal_buffers (integer)

使用已经写入磁盘的WAL数据共享内存的数量。-1的默认设置选择大小等于 shared_buffers的1/32nd(大约3%), 但不小于64kB也不超过一个WAL段大小, 通常16MB。如果自动选择过大或过小,则可以手动设置这个值。 但任何小于32kB的正值将 当作32kB处理。 这个参数只能在服务器启动时设置。

WAL缓冲区的内容每次事务提交时写入到磁盘, 这样非常大的值不可能提供显著的好处。 但是,当有许多客户端都同时提交时,设置该值至少为几兆可以提高繁忙服务器的写入性能, 在多数情况下,由-1的缺省设置选择自动调整应给予合理的结果。

wal_writer_delay (integer)

声明WAL写入进程的活动轮回的延迟。在每一轮回中写入进程将刷新WAL到磁盘。 然后,它会休眠wal_writer_delay毫秒,并重复。 默认值是200毫秒(200ms)。注意, 在许多系统上,睡眠延迟的有效分辨率为10毫秒; 把wal_writer_delay的值 设置为一个不是10的倍数的数值与设置为下一个10的倍数是一样的效果。 这个参数只能在postgresql.conf文件或服务器命令行上设置。

commit_delay (integer)

commit_delay增加了时间延迟,在WAL刷新启动之前,以微秒测量。 这可以提高通过单一WAL刷新提交大量事务的组提交吞吐量。 如果系统负载足够高,额外事务在给定时间间隔内成为提交。 然而,它也增加了每个WAL刷新的最多commit_delay微秒的延迟时间。 但是如果没有其它事务准备提交,那么这个间隔就是在浪费时间。 如果至少commit_siblings个其它事务是活跃的,当刷新初始化的情况下。 则仅仅只执行一个延迟。 如果禁用fsync,则不执行任何延迟。 缺省commit_delay是零(无延迟)。 只有超级用户可以更改此设置。

PostgreSQL先于9.3发布的版本中, commit_delay表现不同,更别说效能: 它仅影响提交,而不是所有的WAL刷新, 即使WAL刷新尽早完成了,也要等待整个配置延迟。 在PostgreSQL9.3开始, 第一个过程准备刷新等待配置延迟,而随后的过程仅仅等待直到完成刷新操作。

commit_siblings (integer)

在执行commit_delay延迟的时候,要求最少同时打开的并发事务数目。 大一些的数值会导致在延迟期间另外一个事务准备好提交的可能性增大。 缺省是5。

18.5.2. 检查点

checkpoint_segments (integer)

在自动的WAL检查点之间的日志文件段的最大数量(通常每个段16兆字节)。 缺省是3。增加这个参数可以增加崩溃恢复所需要的时间量。 这个选项只能在postgresql.conf文件里或者服务器命令行中设置。

checkpoint_timeout (integer)

在自动WAL检查点之间的最长时间,以秒计。缺省是5分钟(5min)。 增加这个参数可以增加崩溃恢复所需要的时间量。 这个选项只能在postgresql.conf文件或者服务器命令行中设置。

checkpoint_completion_target (floating point)

声明检查点完成的目标,作为检查点之间总时间的分数。缺省是0.5。 这个参数只能在postgresql.conf文件中或者服务器命令行中设置。

checkpoint_warning (integer)

如果由于填充检查点段文件导致的检查点发生时间间隔接近这个参数表示的秒数, 那么就向服务器日志发送一个建议增加checkpoint_segments值的消息。 缺省是30秒(30s)。零则关闭警告。 如果checkpoint_timeout小于checkpoint_warning, 则不产生警告。这个选项只能在postgresql.conf文件里或者服务器命令行中设置。

18.5.3. 归档

archive_mode (boolean)

当启用archive_mode的时候, 已完成的WAL段通过设置archive_command 发送到归档存储。 archive_modearchive_command是独立变量, 以致于archive_command不留归档模式而被改变。 这个参数只能在服务器启动时设置。 当wal_level设置为minimal时,则不启用archive_mode

archive_command (string)

将一个完整的WAL文件序列归档的本地shell命令。 字符串中任何%p都被要归档的文件的绝对路径代替, 而任何%f都只被该文件名代替(非绝对路径都相对于集群的数据目录)。 如果你需要在命令里嵌入%字符就必须双写%%。 有一点很重要:这个命令必须是当且仅当成功的时候才返回零。 参阅第 24.3.1 节获取更多的信息。

这个参数只能在postgresql.conf文件或服务器命令行上。 除非在服务器启动时开启archive_mode,否则忽略它。 如果archive_command是一个空字符串(缺省)而 archive_mode已启用,暂时禁用WAL归档, 但是服务器仍继续堆积WAL段文件期望迅速提供一个命令。 设置archive_command命令什么也不做但返回true /bin/true (Windows上的REM),有效地禁用归档, 但也为了归档恢复打破了所需WAL文件链,所以应该只在特殊情况下使用。

archive_timeout (integer)

archive_command仅在已完成的WAL段上调用。 因此,如果服务器只产生很少的WAL流量(或产生流量的周期很长), 那么在完成事务以及安全归档存储之间将有一个很长的延时。 为了限制未归档数据的逗留时间, 你可以强制服务器以archive_timeout指定的秒数为周期切换到新的WAL段文件。 当这个参数大于零时,服务器将切换到新的段文件,无论从剩余段文件切换过去多少秒, 并且有任何的数据库活动,包含一个单独的检查点(增加checkpoint_timeout 将减少空闲系统上不必要的检查)。 注意,由于强制切换而提早关闭的归档文件仍然与完整的归档文件长度相同。 因此,将archive_timeout —设为很小的值是不明智的,它将导致占用巨大的归档存储空间。 将archive_timeout设置为60秒左右是比较合理的。 如果你想要拷贝主服务器数据更加快速,你应该考虑使用流复制,而不是归档。 这个选项只能在postgresql.conf文件或者服务器命令行里设置。