pg_wal full 时重启 Postgres 的解决方案

Solutions for restarting Postgres when pg_wal full

这个问题是我之前发布的关于最大化 Postgres pg_wal 目录(用于培训目的)的有效方法的问题的后续问题:.

我现在想知道启动 Postgres 服务器和 运行 一旦分区已满的可能解决方案是什么,因为 pg_wal 已满。

我对不涉及向分区添加额外磁盘 space 的解决方案很感兴趣。

这是我在与同事讨论时遇到的另外两个解决方案:

  1. 将整个 pg_wal 目录移动到另一个具有足够可用磁盘的分区 space 并从 $PGDATA 指向这个新位置(好的,这是一种额外的磁盘 space解决方案)
  2. 通过删除所有已存档的 WAL 重新获得磁盘 space(pg_wal/archive_status 中应存在具有相同名称且后缀为 .done 的文件)

使用 pgBackRest 我手动 运行 archive-push 命令,然后从 pg_wal 目录中删除了 WAL,但在启动 Postgres 时出现以下错误:

2022-06-01 13:54:47 UTC [9334]: user=,db=,app=,client=LOG:  invalid primary checkpoint record
2022-06-01 13:54:47 UTC [9334]: user=,db=,app=,client=PANIC:  could not locate a valid checkpoint record

显然我删除了太多文件,但我想知道是否可以使用基于相同想法的干净解决方案。

问题

有没有一种方法可以清理 pg_wal 而不必在关闭后重新启动 Postgres 因为 pg_wal 已满?

I'm interesting in solutions that do not involve adding extra disk space to the partition.

嗯,那你排除了正确的解决方法,就是在WAL文件系统上增加磁盘space。

您的第一个解决方案(移动 pg_wal 并将符号 link 放入数据目录)是完全可行的。但是正如您所说,这需要额外的磁盘 space,那么为什么不扩展实际的 WAL 文件系统呢?

你的第二个想法不值得称赞。的确,标记为 .done 的 WAL 段可以删除,但 PostgreSQL 无论如何都会在下一个检查点自动执行此操作,因此在任何给定时间都不应该有很多这样的段。正如您所注意到的,手动修改数据目录并不是一个好主意;破坏数据库的危险太高了。

pg_resetwal 手中接过手。当 运行 在崩溃的数据目录上时,此可执行文件将删除 WAL 并将 PostgreSQL 置于可以启动它的状态,但它 会导致数据损坏 pg_resetwal 旨在作为让损坏的服务器启动的绝望措施,以便您可以挽救一些数据。

您可能不需要太多 space 就可以再次 运行ning,因此您应该只需要删除少量具有相应“.done”条目的文件,而不是全部他们中的。一旦系统 运行ning 它应该自行完成并清理剩余的部分。如果你只删除了最老的那几个,它可能一开始就不会造成问题。但是鉴于您已经删除了太多,您应该能够手动将重要的从存档中复制回 pg_wal。

您可以改为删除(实际上,先复制到其他地方,然后再删除)任何回收的提前 WAL 文件,这些文件已经存档,然后重命名为未来的名称以备重用。问题是如何在崩溃的实例中高可信度地识别它们。

我所做的是在与数据目录相同的分区中的某个地方保存一个带有一些随机乱码的文件(以破坏透明压缩,如果正在使用的话)作为“镇流器”。然后如果我运行遇到这种紧急情况,我只是删除镇流器文件,然后尝试记住稍后重新创建它。