哪些Postgresql WAL文件可以安全地从WAL存档文件夹中删除?

10

现状

我已经在运行Postgres的数据记录计算机上设置了WAL归档,将其设置为独立的内部硬盘。包含WAL归档的硬盘正在填满,我想将所有WAL归档文件(包括初始基本备份)移出并存档到外部备份驱动器中。

目录结构如下:

D:/WALBACKUP/ 是所有WAL文件(00000110000.CA00000004等)的父文件夹

D:/WALBACKUP/BASEBACKUP/ 包含初始基本备份的.tar文件

我的问题是:

  • 我是否可以安全地移动除当前WAL归档文件(000000000001.CA0000..等)以外的每个WAL文件(包括基本备份),并将它们移动到另一个硬盘中?(请注意,数据库正在运行且接收数据)

谢谢!

5个回答

19

WAL归档

您可以使用pg_archivecleanup命令从归档中删除WAL(而不是pg_xlog),以便于给定基本备份不需要的WAL。

一般建议使用PgBarman或类似工具来自动化基本备份和WAL保留。这样更容易、减少错误。

pg_xlog

永远不要手动从pg_xlog中删除WAL。如果产生了过多的WAL,则可能有以下问题:

  • 您的wal_keep_segments设置使WAL保留;
  • 您已开启archive_mode并设置了archive_command,但它没有正确工作(检查日志);
  • 您的checkpoint_segments设置太高,因此WAL生成过量;或者
  • 您有一个复制槽(参见pg_replication_slots视图)阻止了WAL的删除。

应解决导致WAL保留的问题。如果更改设置后似乎没有发生任何事情,请运行手动CHECKPOINT命令。

如果您必须删除WAL以启动离线服务器,则可以使用pg_archivecleanup。它知道如何仅删除服务器本身不需要的WAL...但它可能会破坏基于归档的备份、流复制等功能。因此,除非必须,否则不要使用它。


谢谢提供的信息。pgbarman似乎是一个值得考虑的转换工具,未来会考虑使用。祝好! - undercurrent
在我的情况下,它是逻辑复制。 - Luciano Andress Martini
pglogical扩展(Google Cloud复制)也可以防止pg删除wal文件。 - x-yuri
@x-yuri 是的,因为它维护复制槽。 - Craig Ringer
但是在从archive_mode=on更改为off之后,手动删除整个pgbackup/archive目录是安全的,对吗? - undefined
显示剩余2条评论

10

WAL文件是增量的,所以简单的答案是:您不能抛弃任何文件。解决方案是创建一个新的基本备份,然后所有以前的WAL文件都可以被删除。

WAL文件包含修改表的个别语句,因此,如果您丢弃了一些较旧的WAL文件,则恢复过程将失败(它不会在缺少WAL文件时静默地跳过),因为数据库的状态无法可靠地恢复。您可以将WAL文件移动到其他位置,而不会干扰WAL进程,但是如果您需要从过去某个时间点恢复数据库,则必须从单个位置重新提供所有WAL文件;如果您的磁盘空间不足,则可能意味着从您具有足够空间存储基本备份和所有WAL文件的某个位置进行恢复。这里的主要问题是,在发生事故后能否快速执行以恢复完整的数据库。

另一个问题是,如果您无法确定需要更正的问题发生在哪里/何时,则唯一选择是从基本备份开始,然后重放所有WAL文件。这个过程并不难,但是如果您有一个旧的基本备份和许多WAL文件要处理,那么这只会花费很多时间。

通常情况下,您的最佳方案是每隔x个月创建一个新的基本备份,并使用该基本备份收集WAL。在每次新的基本备份之后,您可以删除旧的基本备份及其随后的WAL或将它们移动到廉价的离线存储(DVD、磁带等)中。在发生重大事故的情况下,您可以快速从最近的基本备份和相对较少的WAL文件中将数据库恢复到已知的正确状态。


当你说你不能扔掉任何文件时,是指“如果你删除一些wal文件,你将无法恢复数据库”吗?我打算保留所有的wal文件,但将它们存储在一个.zip文件中。恢复过程将需要一个更大的RAID阵列来容纳所有的WAL文件和原始的基本备份。这样做是否有效?我认为Postgres仅需要前一个WAL文件才能创建下一个文件(连续的文件按顺序命名/链接)。如果我将所有以前的备份文件移动到外部驱动器,归档会突然失效吗? - undercurrent
请查看更新的答案。这不仅涉及到WALs如何收集的问题,更重要的是在最短时间内从灾难中恢复的实用性。 - Patrick
谢谢提供最新信息。那种方法听起来不错! - undercurrent

7
我们采用的一种解决方案是每晚执行 pg_basebackup。这将创建一个基本备份,随后我们可以使用 pg_archivecleanup 清理所有“旧”的WAL文件,然后再使用类似于以下内容的命令来进行备份:
"%POSTGRES_INSTALLDIR%\bin\pg_archivecleanup" -d %WAL_backup_dir% %newestBaseFile%

幸运的是,我们还没有遇到过需要恢复的情况,但理论上应该可以正常工作。


3

如果有人通过搜索如何安全清理复制架构下的WAL目录而找到此处,请考虑下面的情况:可能会有离线副本的遗留问题,例如,未使用的副本插槽等待副本上线,从而在主数据库上保留大量的WAL档案。

在我们的案例中,由于硬件故障,我们遇到了副本出现故障的问题,我们不得不重新创建副本以及其在主数据库上的replica_slot,但是忘记清除先前使用过的副本插槽。一旦我们清空了它,PSQL就会清除未使用的WAL,并且一切正常。


1
You can add the script to automatically clean or remove pg_wal files. This will work in pg-11 version. If you want to use other psql version the you can simply replace the command "/usr/pgsql-11/bin/pg_archivecleanup" to /usr/pgsql-12/bin/pg_archivecleanup or 13 as per your wish. 

#!/bin/bash

/usr/pgsql-11/bin/pg_controldata -D /var/lib/pgsql/11/data/ > pgwalfile.txt


/usr/pgsql-11/bin/pg_archivecleanup -d /var/lib/pgsql/11/data/pg_wal  $(cat pgwalfile.txt | grep "Latest checkpoint's REDO WAL file" | awk '{print $6}')

pg_archivecleanup -d /var/lib/postgresql/data/pgdata/pg_wal $(pg_controldata | grep "Latest checkpoint's REDO WAL" | cut -d: -f2 | tr -d [:space:]) - Alain Pannetier
我可以通过以下步骤删除存档的 WAL(Write Ahead Log)吗:首先,发出“CHECKPOINT”命令。然后运行“pg_dump”。最后,在/Archived目录中找到比“CHECKPOINT”命令产生的任何WAL文件都旧的WAL文件。这是否可能? - padjee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接