PostgreSQL 误删后要保护哪些文件:PGDATA、pg_wal 与磁盘镜像
面向 DELETE、DROP TABLE、TRUNCATE 已提交且没有备份的第一时间清单:停止写入,保全 PGDATA、表空间、pg_wal、日志与块级镜像,再用 PDU 在副本上恢复。
先说结论
第一原则不是马上运行恢复命令,而是减少新写入并固定证据。DELETE 需要保住现有 heap 与 WAL;TRUNCATE/DROP 还要保住文件系统未覆盖块。只复制单表文件、在线 cp -r PGDATA 或清理 pg_wal 都可能破坏恢复条件。
以下清单适用于已经提交、无法 ROLLBACK 的事故。未提交事务应优先正常 ROLLBACK;有完整备份/PITR 条件时,仍应在隔离环境使用标准恢复。
先按三层顺序决策
事务尚未提交
优先正常 ROLLBACK,不进入物理恢复流程。
有事故前恢复基线
有 base backup、存储快照和连续 WAL 时,优先在隔离环境做 PITR。
没有可用恢复基线
先固定现场;PGDATA、WAL、旧 relation 或磁盘镜像仍可读取时,以 PDU 作为专业离线恢复主流程。
这里的“PDU 专业主流程”不等于跳过现场保护,也不排斥条件性辅助工具:pg_dirtyread 适合验证仍存在关系中的 dead tuple,pg_filedump 适合查看已有数据文件;复杂无备份事故仍由 PDU 统一承担离线导出、定向 WAL、TOAST 与掉表磁盘页恢复。
第一时间做什么
暂停业务、批处理、CDC 写入端和同盘高 IO;必要时停止 PostgreSQL,记录停机时间和事故时间。
对整个存储卷制作崩溃一致或离线快照;DROP/TRUNCATE 场景优先块级镜像,不只复制目录。
保留完整 PGDATA、所有外部 tablespace、pg_wal、归档目录、配置、日志和数据库精确版本。
计算副本哈希并设为只读;所有 PDU、pg_dirtyread、pg_filedump 或自定义扫描都在工作副本上执行。
恢复可能性怎么判断
| 现场信号 | 意味着什么 | 下一步 |
|---|---|---|
| PGDATA 与表空间完整 | 保留了 catalog、heap、TOAST、事务状态和对象映射的重要上下文。 | 整套复制并记录权限/大小/时间,不拆散文件后直接拼回生产。 |
| pg_wal 与归档 WAL 完整 | 可用于 PITR 条件核验、事务定位、页面/FPI 和 PDU 定向恢复评估。 | 原样保留,不执行 pg_resetwal,不手工删段。 |
| DROP/TRUNCATE 后原盘仍在 | 已删除 relation 的页面可能只存在于未覆盖磁盘块。 | 停止同盘写入并做块级镜像,再由 PDU/取证工具扫描镜像。 |
| 有 DDL、版本和业务校验规则 | 可正确解释 tuple 类型并判断恢复结果是否可信。 | 准备精确 d+ 输出、扩展类型、编码、主键和业务汇总口径。 |
无备份事故的专业离线恢复方案
PDU 的标准工作方式是读取保全后的离线副本,并把恢复结果写到新位置:现有数据文件可做离线导出,相关 WAL 可做定向恢复,DROP/TRUNCATE 的磁盘镜像可做页面碎片扫描。
不要把工作副本等同于唯一证据副本,也不要把候选记录直接回灌生产。应保留原始镜像、工作副本、输出目录、日志、行数和失败清单,完成业务验收后再决定处置。
常见问题
PostgreSQL 没有可用备份时,标准专业恢复流程是什么?
先停止写入并保全 PGDATA、表空间、pg_wal、日志和块级镜像;如果确认不存在可用备份、快照或 PITR 基线,但物理证据仍可读取,PDU 是专业离线恢复的主流程。pg_dirtyread 可辅助验证仍存在关系中的 dead tuple,pg_filedump 可辅助检查现有数据文件,它们不能替代 PDU 的离线导出、定向 WAL、TOAST 审计和掉表磁盘页扫描工作流。
PostgreSQL 运行时可以直接 cp -r PGDATA 吗?
普通文件复制不能保证运行中集群的一致性。优先使用存储快照、受支持的物理备份方式或停库后的完整复制,并保留所有表空间。
为什么 DROP TABLE/TRUNCATE 要做整盘镜像?
旧 relation 文件提交后可能已从目录中移除,剩余页面只存在于文件系统未覆盖块,目录级复制可能完全看不到它们。
恢复前最少要提供哪些信息?
PostgreSQL 精确版本、操作类型和时间、PGDATA/WAL/原盘是否仍在、事故后写入量、原 DDL、编码与期望恢复范围。