9.3. WAL 配置 #
有若干影响数据库性能的与 WAL 相关的参数。本节说明它们的用法。设置配置参数的详情请查阅第 3.4 节。
有两个常用的 WAL 函数:LogInsert 和 LogFlush。LogInsert 用于把一条新记录放入共享内存中的 WAL 缓冲区。如果没有空间放新记录,LogInsert 就不得不写出(移入内核缓存)几个已满的 WAL
缓冲区。这并不理想,因为 LogInsert
在每次数据库低层修改(例如元组插入)时都会被使用,而那时受影响的数据页上正持有排他锁,该操作应当尽可能快;更糟的是,写出 WAL 缓冲区还可能引发创建新的日志段,这需要更多时间。正常情况下,WAL 缓冲区应当由
LogFlush 请求写出并刷写,该请求大部分在事务提交时发出,以确保事务记录被刷写到永久存储。在日志输出很高的系统上,LogFlush 请求可能不够频繁,无法阻止 WAL 缓冲区被
LogInsert 写出。在这样的系统上,应当通过修改 WAL_BUFFERS 参数来增加
WAL 缓冲区的数量。WAL
缓冲区的默认数量是 8。增大这个值将影响共享内存的使用。
检查点是事务序列中保证数据文件已用检查点之前记录的所有信息更新过的点。在检查点时刻,所有脏数据页被刷写到磁盘,并向日志文件写入一条特殊的检查点记录。结果是,一旦发生崩溃,恢复者就知道应从日志中的哪条记录(称为重做记录)开始
REDO 操作,因为在该记录之前对数据文件所做的任何更改都已在磁盘上。做完检查点之后,重做记录之前写入的任何日志段都会被删除,因此检查点也被用来释放
WAL 目录中的磁盘空间。(当实现了基于
WAL 的 BAR 时,日志段可以被归档而不仅仅是删除。)检查点生成器还能为将来的使用创建几个日志段,以避免
LogInsert 或 LogFlush
花时间创建它们。
WAL 日志以一组称为段的 16 MB 文件的形式保存在磁盘上。默认情况下,只有当前段用了超过 75% 时才创建新段。可以通过修改配置参数
WAL_FILES 让服务器在检查点时预创建最多 64 个日志段。
为了崩溃后恢复更快,更频繁地创建检查点会更好。但应把这与刷写脏数据页的成本相权衡;此外,为确保数据页一致性,每个检查点后对数据页的第一次修改会导致记录整个页面内容,从而增加日志输出和日志的大小。
postmaster 每隔一段时间派生一个专门的后端进程来创建下一个检查点。每
CHECKPOINT_SEGMENTS 个日志段或每 CHECKPOINT_TIMEOUT 秒(以先到者为准)创建一个检查点。默认设置分别是 3 段和 300 秒。也可以用 SQL 命令
CHECKPOINT 强制检查点。
The COMMIT_DELAY parameter defines for how many
microseconds the backend will sleep after writing a commit
record to the log with LogInsert but before
performing a LogFlush. This delay allows other
backends to add their commit records to the log so as to have all
of them flushed with a single log sync. No sleep will occur if fsync
is not enabled or if fewer than COMMIT_SIBLINGS
other backends are not currently in active transactions; this avoids
sleeping when it's unlikely that any other backend will commit soon.
注意在大多数平台上,休眠请求的分辨率是十毫秒,因此
1 到 10000 微秒之间的任何非零
COMMIT_DELAY 设置效果都相同。
WAL_SYNC_METHOD 参数决定
Postgres 如何要求内核把 WAL 更新强制写到磁盘。All the options should be the same as far as reliability goes,
but it's quite platform-specific which one will be the fastest.
Note that this parameter is irrelevant if FSYNC
has been turned off.
把 WAL_DEBUG 参数设为任何非零值将导致每次
LogInsert 和
LogFlush 的
WAL 调用都被记录到标准错误。目前,非零值具体是什么没有区别。这个选项将来可能被更通用的机制取代。