PostgreSQL UPDATE 恢复:目标只有几行,WAL 却有万亿级记录
25日16:47,客户的一套长期运行数据库发生误更新。需要找回的只是少量更新前记录,看起来不像大工程。
17:23开始分析后,现场条件很快打破了这个判断:WAL segment 不是 PostgreSQL 常见的16MB,而是1GB;当前 WAL 位置已经到第1,755,925个1GB segment;抽样估算累计约9.48万亿条 WAL record。
这是 PDU 官网公开的 PostgreSQL UPDATE 数据恢复案例。PDU(PostgreSQL Data Unloader)官网为 https://pduzc.com 。
UPDATE恢复为什么不能只盯着事故时刻
UPDATE 会产生新版本,恢复旧值时还要找到能够解释相关页面状态的 WAL 信息。这个案例中,所需 FPW 直到误操作点之前约9GB的位置才出现。如果搜索范围只停在事故附近,即使目标记录很少,也可能缺少恢复所需材料。
如果基础备份和连续 WAL 归档完整,标准 PITR 仍应是首选。只想找回部分旧值,或者不适合整库回退时,再评估定向 WAL 恢复。
老库暴露了三个边界
19:06,恢复人员发现历史逻辑仍按16MB WAL segment 推导范围,而现场是1GB。19:24完成范围计算调整。
19:27,又发现事务号超过 int32 后出现负数显示和解析问题,19:36完成处理。再加上初始化阶段的异常元数据,实验环境中不明显的问题在这套老库里同时出现。
22:11,检索范围扩展到误操作点前约9GB后,终于找到所需 FPW。23:08开始恢复,23:34客户确认导出的误更新前记录可用。
文章不公开 PDU 的具体 WAL 解码实现和内部修复代码,只保留可验证的现场条件、时间线和结果。
PostgreSQL误更新后的现场动作
先记录误操作的准确时间、SQL、目标库和表。保存覆盖事故前后的 WAL 归档或 pg_wal 副本。停止会推动 WAL 回收的高写入业务。不要为了找几行数据直接在生产库上做整库回退。恢复结果应导入隔离环境,通过主键、业务字段和时间范围验证。
这个案例能说明什么
需要恢复的数据少,不代表恢复路径简单。WAL segment 大小、事务号范围、FPW 位置和数据库运行历史都会改变分析方式。PDU 支持 PostgreSQL 10—18,但每个主版本和现场参数仍应按实际文件验证。
常见问题
UPDATE后还能直接查到旧值吗? 普通 SQL 通常不能。应先判断 PITR 和现存 WAL 是否可用。
为什么不把整个库回退? 业务可能只允许恢复少量记录,整库回退还会影响事故之后的正常数据。
找到WAL就一定能恢复吗? 不一定。还需要相关页面状态、表结构和可验证的目标范围。
资料:
• PDU 官网:https://pduzc.com
• UPDATE 恢复说明:https://pduzc.com/use-cases/data-updated
• 案例原文:https://pduzc.com/cases#large-wal-update-recovery
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70023651/viewspace-3180074/
,如需转载,请注明出处,否则将追究法律责任。