# 30.5. WAL Configuration
There are several WAL-related configuration parameters that affect database performance. This section explains their use. ConsultChapter 20for general information about setting server configuration parameters.
Checkpointsare points in the sequence of transactions at which it is guaranteed that the heap and index data files have been updated with all information written before that checkpoint. At checkpoint time, all dirty data pages are flushed to disk and a special checkpoint record is written to the log file. (The change records were previously flushed to the WAL files.) In the event of a crash, the crash recovery procedure looks at the latest checkpoint record to determine the point in the log (known as the redo record) from which it should start the REDO operation. Any changes made to data files before that point are guaranteed to be already on disk. Hence, after a checkpoint, log segments preceding the one containing the redo record are no longer needed and can be recycled or removed. (When WAL archiving is being done, the log segments must be archived before being recycled or removed.)
The checkpoint requirement of flushing all dirty data pages to disk can cause a significant I/O load. For this reason, checkpoint activity is throttled so that I/O begins at checkpoint start and completes before the next checkpoint is due to start; this minimizes performance degradation during checkpoints.
The server's checkpointer process automatically performs a checkpoint every so often. A checkpoint is begun everycheckpoint_timeoutseconds, or ifmax_wal_sizeis about to be exceeded, whichever comes first. The default settings are 5 minutes and 1 GB, respectively. If no WAL has been written since the previous checkpoint, new checkpoints will be skipped even ifcheckpoint_timeout
has passed. (If WAL archiving is being used and you want to put a lower limit on how often files are archived in order to bound potential data loss, you should adjust thearchive_timeoutparameter rather than the checkpoint parameters.) It is also possible to force a checkpoint by using the SQL commandCHECKPOINT
.
Reducingcheckpoint_timeout
and/ormax_wal_size
导致检查点更频繁地发生。这允许更快的崩溃后恢复,因为需要重做的工作更少。但是,必须在这一点与更频繁地刷新脏数据页的成本增加之间取得平衡。如果满的_页_写已设置(默认设置),还有另一个因素需要考虑。为了确保数据页的一致性,在每个检查点之后对数据页的第一次修改会导致记录整个页的内容。在这种情况下,较小的检查点间隔会增加 WAL 日志的输出量,部分否定使用较小间隔的目标,并且无论如何都会导致更多的磁盘 I/O。
检查点相当昂贵,首先因为它们需要写出所有当前脏缓冲区,其次因为它们会导致额外的后续 WAL 流量,如上所述。因此,明智的做法是将检查点参数设置得足够高,这样检查点就不会经常发生。作为对检查点参数的简单完整性检查,您可以设置检查点_警告范围。如果检查点之间的距离比checkpoint_warning
秒,将向服务器日志输出一条消息,建议增加max_wal_size
.此类消息的偶尔出现不会引起警报,但如果经常出现,则应增加检查点控制参数。批量操作,如大复制
如果您没有设置,传输可能会导致出现许多此类警告max_wal_size
足够高。
为了避免大量的页面写入淹没 I/O 系统,在检查点期间写入脏缓冲区会分散一段时间。该时期由检查点_完成_目标,它作为检查点间隔的一部分给出(通过使用配置checkpoint_timeout
)。调整 I/O 速率,以便检查点在给定分数时完成checkpoint_timeout
秒已过去,或之前max_wal_size
超过,以较早者为准。使用默认值 0.9,可以预期 PostgreSQL 会在下一个计划检查点之前完成每个检查点(大约是最后一个检查点持续时间的 90%)。这会尽可能分散 I/O,以便检查点 I/O 负载在整个检查点间隔内保持一致。这样做的缺点是延长检查点会影响恢复时间,因为需要保留更多的 WAL 段以便可能用于恢复。担心恢复所需时间的用户可能希望减少checkpoint_timeout
这样检查点会更频繁地出现,但仍会在检查点间隔内分散 I/O。或者,checkpoint_completion_target
可以减少,但这会导致 I/O 时间更密集(在检查点期间)和 I/O 时间减少(在检查点完成之后但在下一个计划检查点之前),因此不建议这样做。虽然checkpoint_completion_target
可以设置为最高 1.0,通常建议将其设置为不高于 0.9(默认值),因为检查点除了写入脏缓冲区之外还包括其他一些活动。设置为 1.0 很可能导致检查点未按时完成,这会由于所需 WAL 段数量的意外变化而导致性能损失。
在 Linux 和 POSIX 平台上检查点_冲洗_后允许强制操作系统在可配置的字节数后将检查点写入的页面刷新到磁盘。否则,这些页面可能会保存在操作系统的页面缓存中,从而导致在同步
在检查点结束时发出。此设置通常有助于减少事务延迟,但也会对性能产生不利影响;特别是对于大于共享_缓冲区,但小于操作系统的页面缓存。
WAL 段文件的数量pg_wal
目录取决于min_wal_size
,max_wal_size
以及在之前的检查点周期中生成的 WAL 数量。当不再需要旧的日志段文件时,它们将被删除或回收(即,重命名为按编号顺序成为未来的段)。如果,由于对数输出率的短期峰值,max_wal_size
超过,不需要的段文件将被删除,直到系统回到这个限制之下。低于该限制,系统会回收足够的 WAL 文件来满足下一个检查点之前的估计需求,并删除其余文件。该估计值基于先前检查点周期中使用的 WAL 文件数量的移动平均值。如果实际使用量超过估计值,移动平均值会立即增加,因此它在一定程度上适应了峰值使用量而不是平均使用量。min_wal_size
将回收的 WAL 文件数量降至最低以供将来使用;即使系统处于空闲状态并且 WAL 使用估计表明需要很少的 WAL,也总是会回收那么多 WAL 以供将来使用。
独立于max_wal_size
, 最近的沃尔_保持_尺寸兆字节的 WAL 文件加上一个额外的 WAL 文件一直保留。此外,如果使用 WAL 归档,则在归档之前无法删除或回收旧段。如果 WAL 归档无法跟上 WAL 生成的速度,或者如果归档命令
反复失败,旧的 WAL 文件将累积在pg_wal
直到情况得到解决。使用复制槽的慢速或故障备用服务器将产生相同的效果(请参阅第 27.2.6 节)。
在归档恢复或待机模式下,服务器会定期执行重启点,这类似于正常操作中的检查点:服务器将其所有状态强制写入磁盘,更新pg_control
文件指示已经处理过的 WAL 数据不需要再次扫描,然后回收任何旧的日志段文件在pg_wal
目录。重启点不能比主节点上的检查点更频繁地执行,因为重启点只能在检查点记录处执行。达到检查点记录时触发重新启动点,如果至少checkpoint_timeout
自上次重启点以来已经过去了几秒,或者 WAL 大小即将超过max_wal_size
.但是,由于对何时可以执行重新启动点的限制,max_wal_size
在恢复期间通常会超过一个检查点周期的 WAL。(max_wal_size
无论如何都不是硬限制,因此您应该始终留出足够的空间以避免磁盘空间不足。)
有两个常用的内部 WAL 函数:XLogInsertRecord
和XLogFlush
.XLogInsertRecord
用于将新记录放入共享内存中的 WAL 缓冲区。如果没有新记录的空间,XLogInsertRecord
将不得不写入(移动到内核缓存)一些填充的 WAL 缓冲区。这是不可取的,因为XLogInsertRecord
用于在受影响的数据页上持有排他锁时的每个数据库低级修改(例如,行插入),因此操作需要尽可能快。更糟糕的是,写入 WAL 缓冲区还可能会强制创建新的日志段,这需要更多时间。通常,WAL 缓冲区应该由一个XLogFlush
请求,大部分是在事务提交时发出的,以确保事务记录被刷新到永久存储。在具有高日志输出的系统上,XLogFlush
请求的发生频率可能不足以阻止XLogInsertRecord
从不得不写。在这样的系统上,应该通过修改沃尔_缓冲区范围。什么时候满的_页_写已设置,系统很忙,设置wal_buffers
更高将有助于在每个检查点之后的这段时间内平滑响应时间。
这犯罪_延迟参数定义组提交领导进程在获得锁定后将休眠多少微秒XLogFlush
,而组提交追随者在领导者后面排队。此延迟允许其他服务器进程将其提交记录添加到 WAL 缓冲区,以便所有这些都将被领导者最终的同步操作刷新。如果没有睡眠将不会发生同步未启用,或者如果少于犯罪_兄弟姐妹其他会话当前处于活动事务中;当任何其他会话不太可能很快提交时,这可以避免睡觉。请注意,在某些平台上,睡眠请求的分辨率为 10 毫秒,因此任何非零提交延迟
设置在 1 到 10000 微秒之间会产生相同的效果。另请注意,在某些平台上,睡眠操作可能需要比参数请求的时间稍长的时间。
既然目的提交延迟
是允许每个刷新操作的成本在并发提交的事务中分摊(可能以事务延迟为代价),有必要在可以智能地选择设置之前量化该成本。成本越高,效果越好提交延迟
预计将在一定程度上增加交易吞吐量。这皮克_测试_同步程序可用于测量单个 WAL 刷新操作所需的平均时间(以微秒为单位)。程序报告的单次 8kB 写入操作后刷新所需的平均时间的一半的值通常是最有效的设置提交延迟
, so this value is recommended as the starting point to use when optimizing for a particular workload. While tuningcommit_delay
is particularly useful when the WAL log is stored on high-latency rotating disks, benefits can be significant even on storage media with very fast sync times, such as solid-state drives or RAID arrays with a battery-backed write cache; but this should definitely be tested against a representative workload. Higher values ofcommit_siblings
should be used in such cases, whereas smallercommit_siblings
values are often helpful on higher latency media. Note that it is quite possible that a setting ofcommit_delay
that is too high can increase transaction latency by so much that total transaction throughput suffers.
Whencommit_delay
is set to zero (the default), it is still possible for a form of group commit to occur, but each group will consist only of sessions that reach the point where they need to flush their commit records during the window in which the previous flush operation (if any) is occurring. At higher client counts a “gangway effect” tends to occur, so that the effects of group commit become significant even whencommit_delay
is zero, and thus explicitly settingcommit_delay
tends to help less. Settingcommit_delay
can only help when (1) there are some concurrently committing transactions, and (2) throughput is limited to some degree by commit rate; but with high rotational latency this setting can be effective in increasing transaction throughput with as few as two clients (that is, a single committing client with one sibling transaction).
Thewal_sync_methodparameter determines how PostgreSQL will ask the kernel to force WAL updates out to disk. All the options should be the same in terms of reliability, with the exception offsync_writethrough
, which can sometimes force a flush of the disk cache even when other options do not do so. However, it's quite platform-specific which one will be the fastest. You can test the speeds of different options using thepg_test_同步程序。请注意,此参数无关紧要,如果同步
已关闭。
启用沃尔_调试配置参数(前提是 PostgreSQL 已经编译支持它)将导致每个XLogInsertRecord
和XLogFlush
WAL 调用被记录到服务器日志中。将来,此选项可能会被更通用的机制所取代。
将 WAL 数据写入磁盘有两个内部函数:XLogWrite
和issue_xlog_fsync
.什么时候追踪_沃尔_io_定时启用时,总时间XLogWrite
写和issue_xlog_fsync
将 WAL 数据同步到磁盘被计为wal_write_time
和wal_sync_time
在皮克_统计_沃尔, 分别。XLogWrite
通常由XLogInsertRecord
(当 WAL 缓冲区中没有新记录的空间时),XLogFlush
和 WAL 编写器,将 WAL 缓冲区写入磁盘并调用issue_xlog_fsync
.issue_xlog_fsync
通常由XLogWrite
将 WAL 文件同步到磁盘。如果wal_sync_method
或者是open_datasync
或者开放同步
,写操作在XLogWrite
保证将写入的 WAL 数据同步到磁盘和issue_xlog_fsync
什么也没做。如果wal_sync_method
或者是数据同步
,同步
, 或者fsync_writethrough
,写操作将 WAL 缓冲区移动到内核缓存和issue_xlog_fsync
将它们同步到磁盘。无论设置track_wal_io_timing
, 次数XLogWrite
写和issue_xlog_fsync
同步 WAL 数据到磁盘也算作wal_write
和wal_sync
在pg_stat_wal
, 分别。