Postgresql——WAL(Write-AHead Logging,预写式日志)

Posted 晟数

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Postgresql——WAL(Write-AHead Logging,预写式日志)相关的知识,希望对你有一定的参考价值。

WAL——Write-AHead Logging,预写式日志

1.目的:

保证数据库的可靠性

2.概述

Write-AHead Logging即WAL是一套保证数据完整性的标准。简要地说,WAL中心概念是数据文件(这里涉及到表和索引)修改必须在这些动作被记录之后,即 描述这些修改操作的日志记录被刷到永久存储中。如果我们遵循这个过程,我们不需要在每次事务提交时刷数据页到磁盘,因我我们知道一旦发生崩溃,我们可以使用日志回复数据库,任何还没有被应用到数据页面的改变可以根据其日志记录重做(这是前滚恢复,也被称为REDO) 。

因为WAL存储在数据库崩溃后的内容,日志文件系统不需要数据文件或者WAL文件的可靠存储。事实上,日志预写回降低性能,特别是日志文件会引起文件系统数据被刷到磁盘中。

3.WAL配置

这里有几个WAL预写配置参数影响数据库性能。

1)检查点checkpoint

检查点是在事务序列中的点,这种点保证被更新的堆和索引数据文件的所有信息在该检查点之前已被写入。在检查点时刻,所有脏数据页被刷写到磁盘,并且一个特殊的检查点记录将被写入到日志文件(修改记录之前已经被刷写到WAL文件)。

简单说,每次数据写入磁盘之前,都需要先写入WAL文件。检查点就是周期检查WAL日志的写入情况,并打一个标记。标记之前的部分代表已经写入磁盘,而未标记的部分表示还没有写入磁盘。未写入磁盘的数据就是恢复的对象(REDO记录)

2)检查点触发条件

服务器的检查点进程常常自动地执行一个检查点。

a)检查点在每checkpoint_timeout秒开始

b)超过 max_wal_size时开始

一般默认的设置分别是 5 分钟和 1 GB

如果从前一个检查点,以来没有WAL被写入,则即使过了checkpoint_timeout新的检查点也会被跳过( 如果正在使用WAL归档并且你想对文件被归档频率设置一个较低的限制来约束 潜在的数据丢失,你应该调整archive_timeout 参数而不是检查点参数)。也可以使用SQL命令 CHECKPOINT来强制一个检查点。降低checkpoint_timeout和/或max_wal_size会导致检查点更频繁地发生。

检查点的代价相对比较昂贵,首先是因为它们要求写出所有当前为脏的缓冲区,正如以上讨论的,第二个原因是它们会导致额外的WAL流量。因此比较明智的做法是将检查点参数设置得足够高,这样检查点就不会过于频繁地发生。 你可以设置checkpoint_warning参数作为对于你的检查点参数的一种简单完整性检查。

如果检查点的发生时间间隔比checkpoint_warning秒还要接近,一个消息将会被发送到服务器日志来推荐你增加max_wal_size。如果你没有把max_wal_size设置得足够高,那么在进行如大型COPY传输等批量操作的时候可能会导致出现大量类似的警告消息。

3)checkpoint_completion_target(检查点完成目标)

为了避免大批页面写入对I/O系统产生的冲击,一个检查点中对脏缓冲区的写出操作被散布到一段时间上。这个时间段由checkpoint_completion_target控制,它用检查点间隔的一个分数

默认值为0.5,PostgreSQL被期望能够在下一个检查点启动之前的大约一半时间内完成每个检查点。

在一个接近于正常操作期间最大I/O的系统上,你可能希望增加checkpoint_completion_target来降低检查点的I/O负载。但这种做法的缺点是被延长的检查点将会影响恢复时间,因为需要保留更多WAL段来用于可能的恢复操作。尽管checkpoint_completion_target可以被设置为高于1.0,但最好还是让它小于1.0(也许最多0.9),因为检查点还包含除了写出脏缓冲区之外的其他一些动作。1.0的设置极有可能导致检查点不能按时被完成,这可能由于所需的WAL段数量意外变化导致性能损失。

4)checkpoint_flush_after

在 Linux 和 POSIX 平台上,checkpoint_flush_after允许强制 OS 超过一个可配置的字节数后将检查点写入的页面刷入磁盘。否则,这些页面可能会被保留在 OS 的页面缓存中,当检查点结束发出fsync时就会导致大量刷写形成延迟。这个设置通常有助于减小事务延迟,但是它也可能对性能带来负面影响,尤其是对于超过shared_buffers但小于 OS 页面缓存的负载来说更是如此

5)min_wal_size、max_wal_size

pg_wal目录中的 WAL 段文件数量取决于min_wal_size、max_wal_size以及在之前的检查点周期中产生的 WAL 数量。当旧的日志段文件不再被需要时,它们将被移除或者被再利用(也就是被重命名变成数列中未来的段)。如果由于日志输出率的短期峰值导致超过max_wal_size,不需要的段文件将被移除直到系统回到这个限制以下。

低于该限制时,系统会再利用足够的 WAL 文件来覆盖直到下一个检查点之前的需要。这种需要是基于之前的检查点周期中使用的 WAL 文件数量的移动平均数估算出来的。

 

作者:昵称PG-Two(人送外号-pg二姐),西安电子科技大学研究生毕业,负责数据库pg后端开发应用,18年11月在合肥pg分享会上认识德哥,开始了与pg之旅~

以上是关于Postgresql——WAL(Write-AHead Logging,预写式日志)的主要内容,如果未能解决你的问题,请参考以下文章

如何遏制 PostgreSQL WAL 的疯狂增长

PostgreSQL崩溃恢复读取WAL

一款PostgreSQL WAL日志解析工具: wal2json

postgresql如何维护WAL日志/归档日志

PostgreSQL的xlog/Wal归档及日志清理

PostgreSQL的xlog/Wal归档及日志清理