zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

Postgresql 如何降低 wal 占用磁盘空间,降低磁盘存储成本

2023-02-18 16:23:53 时间

POSTGRESQL WAL 的存储一直是一个值得讨论的问题,到底一个POSTGRESQL 在极端的情况下,可以用多少的空间来存储WAL 日志。这里不是要讨论逻辑复制槽,也不是讨论ARCHIVE ,这里要讨论是一种极端的方法,尝试将POSTGRESQL WAL占用的磁盘空间最小化。

这里主要针对的对象是,单机的POSTGRESQL ,不想通过专业的人员来进行维护的场景,如果说目前的方案需要一个场景,这就是这篇文字要面对的场景。这个场景主要面对的是一些,线下的场景,这些场景中的POSTGRESQL 并没有专业的维护人员,更不要提DBA ,这些系统可能和一些应用系统统一安装,并且可能长时间无法进行维护。

这个方案中需要一个基准,就是系统在采用方法后,产生的WAL 日志的数量和不使用这样的方案产生的数量的差异,来对比实际上我们的方案后的效果。

这里我们在测试前,可以看到我们有 20 个文件,然后我们在对这个系统进行压测,并查看产生多少wal 日志。

首先在测试前记录日志的起点 然后在测试后,记录压测后的WAL 的记录点

同时通过命令我们对刚才压测期间的日志进行分析,查看整体日志记录的内容和消耗。

准备工作完毕后,我们开始降低POSTGRESQL 日志的方法的讨论。

1 full page

众所周知,在POSTGRESQL WAL 为了保证日志的在系统crash后,有最后一次checkpoint 前的数据的完整的页面,需要在必要的时刻,在数据页面未写入完全的时候,通过日志来先还原最后checkpoint前的页面。那么我们将这个部分观点后,看看,WAL 能节省多少。

先说一下测试的流程

1 产生新的wal log

2 记录 wal log lsn 号

3 对数据库进行压测

4 记录产生的新的记录号

5 对于整体的日志产生进行分析。

在测试完毕后,我们对比,单纯打开和关闭 full page 的产生的 wal 日志的总量。 这里注意有一种重要的指标 FPI ,FPI 就是 full page insert 的意思,这里可以看到,整体的日志量的产生,主要在 fpi ,产生的日志量占总体的wal 日志的 96%.

那么此时第一个问题 full page 关闭后,对日志的影响的大概,大家心里也会有数,full page 的确是wal 日志中记录的数据的大头。

2 延长checkpoint 的时间的方法

这个想法是基于减少checkpint 中full page 的原因,如果减少了checkpoint 那么自然full page 的量也会减少。

我们调整两个参数,尝试降低checkpoint的 次数,影响checkpoint的次数的主要有两个部分 1 checkpoint timeout 2 max_wal_size

调整 上面两个参数变小,max_wal_size 为设置的wal size 的两倍,时间为1分钟

调整上面的参数变大, max_wal_size 为 80G ,时间为 5分钟

从上图可以看到, xlog type 中的 record size 为 0 ,相对调整变小的的两个参数,xlog 的 record size为 114 。

3 提高 hot update 的几率

hot update 如果还有不清楚的可以看下面的文字,里面有详细的介绍什么hot update, 相关的优点等等

https://www.cybertec-postgresql.com/en/hot-updates-in-postgresql-for-better-performance/

提高hot update 的几率有助于减少页面分割,以及由于页面分割减少或索引减少重写的问题后,整体的WAL 日志也会减少相关的日志量,尤其针对UPDATE 逻辑较多的业务。 如何提高 HOT UPDATE的几率

1 提高填充因子,在经常UPDATE 表的百分比,这里测试表的填充因子是 100%, 针对表可以调整到90% ,85% ,极端的可以调整到70%。具体看业务和业务中对UPDATE 的使用率。

2 修改值,也即使UPDATE 的值,不能是索引本身

4 注意 wal_keep_segments

一般这样的情况下,需要查看wal_keep_segemnts ,主要还是为了保证物理复制时,出现网络或主机故障时,能保留足够的 wal 日志,这里可以将这个位置直接写入 0 ,不进行任何保留。

5 直接将wal_level 变更为minimal

我们可以看看在修改为这样的方式后,可以减少多少的日志量,下图可以对比上面的同样的图,下面图中第一个是 minimal 第二个是 logical 的方式,可以看到两个record size 的区别,明显差了一个位数。

6 消减已经存在的WAL 日志的方法,可以通过 select pg_switch_wal() 来完成。

以上为总结的可以快速的减少单机的POSTGRESQL 的WAL 日志的方法,注意这里仅仅是为单机设置,如果是用作服务器的方式,还是老老实实将需要打开的参数打开。