当前位置: 首页 > news >正文

PostgreSQL 数据误删恢复技术指南

一、核心原理:为什么数据能恢复?

​ 在 PostgreSQL 中,执行 DELETE 操作后,数据并不会立即从磁盘上物理擦除。PostgreSQL 使用多版本并发控制(MVCC)机制,删除操作仅仅是给数据行打上了一个“已删除”的标记(在事务 ID 层面标记为 xmax)。

只有当 VACUUM(自动清理或手动清理)进程运行并扫描该表时,这些被标记为“已删除”的物理空间才会被真正回收和覆盖。因此,恢复的关键在于与 VACUUM 进程赛跑


二、紧急止损:黄金三步

一旦发现误删,必须立即执行以下操作以锁定现场,防止数据被彻底清理。

  1. 立即停止应用写入
    防止新数据写入覆盖掉被标记为删除的旧数据页。
  2. 禁用自动清理
    这是最关键的一步。必须针对受影响的表关闭 autovacuum。
-- 将 'your_table_name' 替换为实际表名 ALTER TABLE your_table_name SET (autovacuum_enabled = false);

​ 3.锁定表
防止其他会话对表进行操作,确保数据文件处于静止状态。

BEGIN; LOCK TABLE your_table_name IN ACCESS EXCLUSIVE MODE; -- 保持事务开启,不要提交或回滚,直到恢复完成


三、恢复方案 A:使用 pg_dirtyread 插件(推荐)

如果数据库允许安装扩展,这是最安全、最直观的方法。该插件允许用户读取被标记为删除但仍存在于磁盘上的“脏”数据。

  1. 安装插件
    需在目标数据库中执行(需超级用户权限):
CREATE EXTENSION pg_dirtyread;

2.查询被删数据
使用插件提供的函数读取数据。你需要明确指定表的字段结构。

SELECT * FROM pg_dirtyread('your_table_name') AS t(id int, name text, create_time timestamp) -- 必须与表结构一致 WHERE (SELECT pg_xact_commit_timestamp(xmax)) IS NOT NULL; -- 筛选被删除的行
  • xmax:表示删除该行的事务 ID。如果 xmax 不为 0,说明该行已被删除。
  • pg_xact_commit_timestamp(xmax):可选,用于查看删除发生的时间。

​ 3.数据回写
确认查询到的数据无误后,将其插回原表或新表。

INSERT INTO your_table_name (id, name, create_time) SELECT id, name, create_time FROM pg_dirtyread('your_table_name') AS t(id int, name text, create_time timestamp) WHERE (SELECT pg_xact_commit_timestamp(xmax)) IS NOT NULL;


四、恢复方案 B:底层十六进制解析(硬核方案)

如果无法安装插件,可以通过查询底层页面数据来手动还原。PostgreSQL 将数据存储在 8KB 的页面中,heap_page_items函数可以读取页面的原始字节流。

  1. 获取原始数据
    查询被删除行的十六进制数据。
SELECT lp, t_attrs FROM heap_page_item_attrs(get_raw_page('your_table_name', 0), 'your_table_name'::regclass) WHERE t_xmax != 0; -- 筛选已删除行

2.解析十六进制数据
查询结果中的t_attrs字段通常以\x开头,这是十六进制编码的文本。

  • 文本字段:例如\x48656c6c6f对应Hello
  • 整数字段:通常占用 4 字节,需注意大小端序(PostgreSQL 使用小端序)。例如01 00 00 00对应整数1

为了简化手动解析的痛苦,建议创建一个辅助函数来批量转换:

CREATE OR REPLACE FUNCTION hex_to_text(hex_str text) RETURNS text AS $$ BEGIN -- 去除 \x 前缀并转换 RETURN convert_from(decode(substring(hex_str FROM 3), 'hex'), 'UTF8'); EXCEPTION WHEN OTHERS THEN RETURN hex_str; -- 转换失败返回原值 END; $$ LANGUAGE plpgsql;


五、恢复方案 C:基于 WAL 日志的时间点恢复

如果数据已经被 VACUUM 清理,或者上述方法无效,且数据库开启了归档模式,可以使用时间点恢复。

  1. 确认配置
    确保postgresql.conf中开启了归档:
archive_mode = on archive_command = 'cp %p /path/to/archive/%f'

2.执行恢复

  • 停止数据库服务。
  • 使用pg_basebackup恢复基础备份。
  • 配置recovery.signalpostgresql.auto.conf,指定恢复目标时间:
restore_command = 'cp /path/to/archive/%f %p' recovery_target_time = '2026-04-08 09:00:00' -- 误删前的时间点
  • 启动数据库,PG 将重放日志直到指定时间点。


六、善后工作:恢复配置

数据恢复完成后,务必记得重新开启自动清理,否则表膨胀会导致性能严重下降。

-- 重新开启自动清理 ALTER TABLE your_table_name RESET (autovacuum_enabled);


七、总结与建议

方案适用场景难度风险
pg_dirtyread未执行 VACUUM,可安装插件
底层解析未执行 VACUUM,无法安装插件中(需人工解析)
WAL 日志已执行 VACUUM,有归档配置极高高(需停机恢复)
备份还原有定期pg_dump备份中(数据可能回退)
http://www.jsqmd.com/news/1112774/

相关文章:

  • 网站关键词SEO排名是什么意思?
  • Claude Code 实战指南:AI 代码助手如何提升 Python Flask 开发效率
  • 酷安UWP桌面版:在Windows上畅享酷安社区的完整体验
  • Insta360 AI剪辑技术解析:从语义理解到智能成片
  • Honey Select 2专业增强套件:自动化翻译、去码与高级插件配置实战指南
  • 程序代码行数统计脚本
  • 【Linux】章11 管理网络安全(RH134知识点问答题)
  • 理论都会,实战就废?7个分析模板,帮你打通任督二脉
  • 机器学习模型生产部署:从服务化到漂移监控的四层实战体系
  • 三进制太玄经·八十一首(坤至乾·每行一卦·配原文)
  • 从Hello World到部署上线,ChatGPT辅助编程全流程拆解,含17个避坑清单与3个私藏Prompt模板
  • 2026年企业安全基建的误区、重构与最优解
  • 从0开始学AI Agent:设计一个coding agent,Java佬必看
  • 郴州火锅排行榜|客观实测,理性就餐选型指南
  • 开源AI创作工作台infinite-canvas:一站式可视化无限画布部署与使用指南
  • AutoRaise终极指南:3分钟实现macOS鼠标悬停自动激活窗口,提升300%工作效率
  • 推算术:中华传统阴阳数理思维的文化探析
  • AOT 的使用以及 .NET 与 Go 互相调用
  • 从对话到行动:基于LangChain构建AI Agent的实战指南
  • ASP.NET Core Kestrel服务器HTTPS配置与传输安全加固实战指南
  • apate文件伪装工具:如何在3秒内绕过格式限制的完整指南
  • 一文看懂PCIe 20年狂飙史与硬核避坑指南
  • 图片分类与对象识别
  • Orca ADE:多智能体并行编程,突破AI开发效率瓶颈
  • Java毕业设计-基于 SpringBoot 的社区康养管理系统的设计与实现 基于 SpringBoot 的社区老人康养综合中心管理系统(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • LeetCode 264.丑数II
  • 第一出:record 类型
  • 从确定性代码到非确定性Agent:AI Agent工程的核心挑战与实战指南
  • react hook 原理
  • 2026年健康早餐新选择:揭秘最受欢迎的苦荞片品牌