PostgreSQL 归档失败 & WAL 堆积原因分析(基于 pgBackRest)


PostgreSQL 归档失败 & WAL 堆积原因分析(基于 pgBackRest)

1. 背景

集群采用 pgBackRest 作为备份与归档管理工具,所有 Base Backup 与 WAL 文件统一存储在 NFS 目录中,由 pgBackRest 负责维护 仓库(repository) 的完整性与元数据。


2. 正常归档流程(pgBackRest)

  1. PostgreSQL 在 WAL 切换时执行 archive_command,调用 pgbackrest archive-push

  2. pgbackrest archive-push 会:

    • 检查仓库元数据是否一致(archive.infobackup.info 等)。
    • 将 WAL 复制到 NFS 仓库下的 archive/<cluster-name>/...
    • 更新归档索引,确认该 WAL 已归档。
  3. 命令返回 0 → PostgreSQL 判定归档成功,可以清理旧 WAL。


3. 删除 NFS 文件的影响

手工删除 NFS 上的备份或 WAL 文件,不仅仅是“文件丢了”,而是 破坏了 pgBackRest 仓库的完整性

  • 元数据损坏

    • pgBackRest 的仓库中有两个关键元数据文件:

      • backup.info:记录所有 Base Backup 集的起止 LSN、依赖关系。
      • archive.info:记录归档的 WAL 序列及起始位置。
    • 当 NFS 中的历史 WAL 或 Base Backup 被直接删除后,backup.info/archive.info 与实际文件内容对不上,仓库立即被判定为“损坏”。

  • 归档失败

    • pgbackrest archive-push 在写入新 WAL 前,会强制校验仓库一致性。
    • 一旦发现元数据不完整(缺 WAL 或缺 Base Backup),就直接报错退出,返回非 0。
    • PostgreSQL 接收到非 0 → 认定归档失败。
  • WAL 堆积

    • 因为 PostgreSQL 没有确认 WAL 被归档成功,它不会清理 pg_wal 中的旧 WAL。
    • 从 14 号起,所有 WAL 一直无法清理,磁盘空间迅速上涨,导致 WAL 堆积。

4. 为什么“删历史文件”影响“新归档”

这是因为:

  • pgBackRest 并不是简单复制文件,而是 管理整个仓库的一致性
  • 新归档的 WAL 需要被记录在 archive.info 里,但如果前序 WAL/Backup 集缺失,仓库状态就不合法。
  • 所以 删历史文件 = 破坏仓库元数据 = 新归档直接失败
  • 正确做法:只能用 pgbackrest expire 命令删除过期文件,而不是 rm

5. 根因总结

NFS 上的备份/WAL 文件被手工删除 → pgBackRest 仓库元数据与实际文件不一致 → pgBackRest 主动判定归档失败 → PostgreSQL 无法清理 WAL → pg_wal 持续膨胀。


6. 解决方案

  1. 重建仓库

    • 暂停归档,清理损坏仓库。
    • 重新执行一次 pgbackrest backup 生成新的 Base Backup。
    • 重新启用 archive-push
  2. 管理规范

    • 禁止直接操作 NFS 文件。
    • 使用 pgbackrest expire 管理过期备份与 WAL。
    • 监控 pgbackrest checkarchive-push 日志,避免归档失败长时间未发现。

✅ 对外说明可以简化为一句话:
由于手工删除了 NFS 上的历史备份文件,导致 pgBackRest 仓库元数据损坏,从而使归档判定失败,引起 PostgreSQL WAL 无法清理并持续堆积。


要不要我帮你画一个 pgBackRest + PostgreSQL 归档流程图(含失败路径),方便在复盘会上展示?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值