17.5. 预写式日志

又见 Section 26.3 获取 WAL 调节的细节。

17.5.1. 设置

fsync (boolean)

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

不过,使用 fsync() 会对性能有影响: 在事务提交的时候,PostgreSQL 必须等待操作系统吧预写日志刷新到磁盘上。 在关闭 fsync 的时候,操作系统可以尽可能优化缓冲,排序和推迟写动作。 这样可以显著提高性能。不过,如果系统崩溃,最后提交的几个事务的结果可能部分或者全部丢失。 最糟糕的情况是可能出现不可恢复的崩溃。 (数据库服务器本身并不是这里的风险因素。 只有一个操作系统级别的崩溃会导致毁坏数据的风险。)

因为涉及的风险太高,fsync 的设置没有普适的原则。 有些管理员总是关闭 fsync,而其它一些只是在批量装载的时候关闭它, 因为这个时候,如果出现了错误,那么就有个明确的重新开始的点, 而另外一些管理员总是打开 fsync。 缺省是打开fsync,目的是最大限度的可靠性。 如果你信任你的操作系统,你的硬件,以及你的工具公司(或者你的备份电池), 你可以考虑关闭 fsync

这个选项只能在服务器启动或者 postgresql.conf 文件里设置。 如果这个选项是 off,那么考虑把 guc-full-page-writes 也关闭了。

wal_sync_method (string)

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

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

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

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

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

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

不是在所有系统上都能使用上面四种选项。 支持的最靠上的选项是缺省。 如果 fsync 关闭,那么这个设置无关。 这个选项只能在服务器启动的时候和在postgresql.conf文件里设置。

full_page_writes (boolean)

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

把这个选项关闭会加快正常操作的速度,但是可能导致系统崩溃或者掉电之后的数据库损坏, 它的危害比较小,但是类似 fsync。 如果你有减小部分页面写入风险的硬件支持(比如电池供电的磁盘控制器), 或者文件系统软件支持(比如,Reiser4),并且他们可以把风险降低到一个可以接受的低范畴, 那么你可以关闭这个选项。

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

这个选项只能在服务器启动的时候设置,或者在 postgresql.conf 里设置。 缺省是 on

wal_buffers (integer)

放在共享内存里用于 WAL 数据的磁盘页面缓冲区的数目。 这个设置只需要大到能保存下一次事务生成的 WAL 数据即可, 因为这些数据在每次事务提交都会写入磁盘。 这个选项只能在服务器启动的时候设置。

增大这个参数可能导致 PostgreSQL 要求更多的 System V 共享内存,可能超过你的操作系统的缺省配置。必要时,参阅 Section 16.4.1 获取如何调节这些参数的信息。

commit_delay (integer)

向 WAL 缓冲区写入记录和将缓冲区刷新到磁盘上之间的时间延迟,以微秒计。 一个非零的延迟允许多个事务共用一个 fsync() 系统调用提交, 如果系统负载足够搞,那么在给出的间隔里,其它的事务可能已经准备好提交了。 但是如果没有其它事务准备提交,那么这个间隔就是在浪费时间。 因此,这个延迟只是在一个服务器进程写其提交日志时,至少 commit_siblings 个其它事务在活跃的情况下执行。 缺省是零(无延迟)。

commit_siblings (integer)

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

17.5.2. 检查点

checkpoint_segments (integer)

在自动的 WAL 检查点之间的最大距离,以日志文件段(每个段通常 16 兆大)计。 缺省是三。这个选项只能在服务器启动或者在 postgresql.conf 文件里设置。

checkpoint_timeout (integer)

在自动 WAL 检查点之间的最长时间,以秒计。缺省是 300 秒。 这个选项只能在服务器启动的时候或者在 postgresql.conf 文件里设置。

checkpoint_warning (integer)

如果因为填充检查点段文件发生的检查点的间隔比这个数值表示的秒数更多, 那么向服务器日志发送一个消息。缺省是 30 秒。零则关闭警告。

17.5.3. 归档

archive_command (string)

用来将一个完整的 WAL 文件序列归档执行的 shell 命令。 如果这是一个空字串(缺省),那么 WAL 归档就关闭。字串中任何 %p 都被要归档的文件的绝对路径代替, 而任何 %f 都只被该文件名代替。如果你需要在命令里嵌入真正的 %,写 %%。 有关更多的信息,参阅 Section 23.3.1。 这个选项只能在服务器启动的时候在 postgresql.conf 文件里面设置。

有一点很重要:这个命令必须是当且仅当成功的时候才返回零。比如:

archive_command = 'cp "%p" /mnt/server/archivedir/"%f"'
archive_command = 'copy "%p" /mnt/server/archivedir/"%f"'  # Windows