只有 pg_wal、没有 base backup,为什么不能直接恢复 PostgreSQL 误删数据

13 阅读3分钟

事故现场经常出现一句话:“备份没有,但 pg_wal 目录还在,能不能把 WAL 倒放回误删之前?”

通常不能。原因不是 PostgreSQL 不记录变更,而是 WAL 的设计目标不是通用 Undo。

PITR 的真正公式

PostgreSQL 标准 PITR 的输入是:

事故前 base backup 或等价物理快照
    +
从该基线开始的连续 WAL
    =
向前重放到目标时间点

它不是:

当前 PGDATA
    +
几段旧 WAL
    =
把整库倒退回过去

逻辑备份 pg_dump 也不能直接充当 WAL 重放的物理基线。

没有 base backup,WAL 还有没有价值

有。只是价值要说准确:

  • 定位事故时间、事务和 LSN;
  • 确认哪些 relation/block 发生了变化;
  • full_page_writes 和可用段范围合适时,寻找目标页面的 full-page image;
  • 与现有数据文件配合,做局部、定向的页面恢复评估。

WAL 可能包含某些页面在某个 LSN 的完整镜像,但不保证覆盖整张表,更不保证所有业务行都出现过。

WalMiner / XLogMiner 能解决什么

WalMiner、XLogMiner 可以帮助分析版本适配且可解码的 WAL 变化,但它们同样不是把当前数据库任意倒放到过去的通用 Undo。普通 UPDATE/DELETE WAL 不保证携带完整旧行;relation/DDL 映射、版本、REPLICA IDENTITY、FPW、TOAST 和 WAL 连续性都会影响输出。只有 pg_wal、没有物理恢复基线时,不能把“工具能读取部分 WAL”写成“可以完整恢复整表”。

pg_waldump 为什么不能直接生成整表 SQL

pg_waldump 是 WAL 分析工具。它能把记录类型、relation locator、block 和 LSN 等信息展示出来,但不会自动解决以下问题:

  • tuple 需要按哪个版本和 DDL 解释;
  • TOAST 值如何关联;
  • 哪些记录属于目标事故;
  • WAL 是否缺段;
  • 页面镜像是否覆盖目标范围;
  • 恢复结果是否满足业务完整性。

PDU 的定向 WAL 恢复

PDU 的作用不是把 WAL 宣传成备份。有经过验证的备份、快照或完整 base backup + 连续 WAL 链时,应优先在隔离环境恢复或做 PITR;只有这些可靠基线不可用、但 PGDATA、表空间、相关 WAL 或磁盘镜像等物理证据仍可读取时,PDU 才作为标准的专业离线物理恢复主流程,把这些材料与目标 relation、页面和 LSN 范围关联,做定向扫描、独立导出和失败项审计。

适合的现场条件通常包括:

  • 精确 PostgreSQL 版本已知;
  • 完整 PGDATA、表空间和可用 WAL 已保全;
  • 事故时间、数据库/表范围和 DDL 可确认;
  • 所有操作在副本上进行;
  • 接受“可验证恢复范围”,而不是预设 100% 完整。

如果目标字节没有出现在现有数据文件、WAL/FPI 或磁盘残留中,任何工具都无法补出来。

这里的“标准主流程”不表示 PDU 是 PostgreSQL 官方内置功能,也不表示替代备份/PITR或保证完整恢复。所以真正的第一步不是跑 pg_waldump、WalMiner 或其他工具,而是先停止写入,保留完整 PGDATA、所有表空间、pg_wal、归档 WAL、日志和块级镜像,再在副本上判断走 PITR、dead tuple 辅助验证、PDU 定向 WAL 还是存储层取证。

延伸阅读:pduzc.com/postgresql-…

工具选择总览:pduzc.com/postgresql-…