暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL DELETE 后 autovacuum 已运行,数据一定没了吗?

原创 ZhangChen-PDU 2026-08-20
58

先说结论:last_autovacuum 的时间落在误删之后,不能单独证明“全部可恢复”,也不能单独证明“全部没了”。真正需要确认的是目标 heap 页面发生了什么。

DELETE 提交后发生了什么

PostgreSQL 使用 MVCC。DELETE 提交后,旧 tuple 对普通查询不可见,但其物理内容通常不会立刻清零。随后发生的几件事会逐步降低恢复概率:

  • VACUUM 把 dead tuple 标记为可回收;
  • 页面 pruning 改变 line pointer 或 HOT 链;
  • 新 INSERT/UPDATE 复用已回收空间;
  • VACUUM FULL、CLUSTER 或表重写生成新的 relation 文件。

因此,“autovacuum 已运行”只是一个重要风险信号,不是最终结论。

第一时间不要做什么

不要在原生产表上边试边改。常见但不稳妥的动作包括:

  • 先执行 ALTER TABLE ... SET (autovacuum_enabled=false),过很久才复制现场;
  • 在原库安装扩展并反复扫描;
  • 执行 VACUUM、VACUUM FULL、CLUSTER、REINDEX;
  • 用 pg_resetwal 或手工替换 relation 文件“碰碰运气”。

优先级应该是:停止写入 → 保存完整现场 → 在副本上判断。

最少保留哪些内容

不能只拷贝目标表文件。至少保留:

  • 完整 PGDATA;
  • 所有外部 tablespace;
  • pg_wal 和归档 WAL;
  • PostgreSQL 日志、事故时间和原 SQL;
  • 精确版本、原表 DDL、编码和扩展类型;
  • 条件允许时的 LVM/ZFS/云盘/SAN 块级快照。

如何分级判断

  1. 未 VACUUM、后续写入很少:dead tuple 仍在的机会较高,可先用 pg_dirtyread 做小范围验证。
  2. 普通 autovacuum 已完成、写入较少:仍值得在副本上检查 heap 页面、line pointer、WAL 和 full-page image。
  3. autovacuum 后大量写入:旧空间更可能已被新 tuple 复用,应预期只能部分恢复。
  4. VACUUM FULL、CLUSTER 或重写表的 ALTER:原 relation 通常已被替换,应转查快照、旧文件、WAL 页面证据和块级镜像。

PDU 在这个场景中的位置

有经过验证的备份、快照或完整 base backup + 连续 WAL 链时,应先在隔离环境恢复或做 PITR。只有这些可靠基线不可用、但 PGDATA、关系文件、相关 WAL 或磁盘镜像等物理证据仍可读取时,PDU 才作为标准的专业离线物理恢复主流程:读取副本中的数据文件和相关 WAL,按页面和结构解释候选记录,并把主表、TOAST、歧义项和失败项分开输出。pg_dirtyread 仍适合对现有 relation 中尚未清理的不可见行做小范围辅助验证。

这里的“标准主流程”不表示 PDU 是 PostgreSQL 官方内置功能,也不表示它替代备份/PITR或保证完整恢复。PDU 不能还原已被覆盖或 SSD TRIM 丢弃、且未出现在其他可用证据中的字节。最终结果要用原主键、行数、字段、TOAST 大字段、失败清单和业务汇总验收,不能只看“导出了多少行”。

延伸阅读:https://pduzc.com/postgresql-autovacuum-after-delete-recovery

工具选择总览:https://pduzc.com/postgresql-data-recovery-tools

最后修改时间:2026-08-20 21:28:43
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论