在日常管理数据库的时候,最让人紧张的情况就是不小心把数据删掉了——比如执行 DELETE 语句时忘了加 WHERE 条件,或者手滑运行了 TRUNCATE,甚至一不小心把整张表用 DROP TABLE 给删了,这些操作都可能让系统服务中断,也可能导致用户的数据彻底找不回来。
不过好在 PostgreSQL 提供了不少办法来应对这种意外,关键是要动作快、方法对。
这篇文章会介绍三种常见的恢复手段,并以可以直接运行的代码为主,帮助你在出问题后尽快把数据救回来。
一、用事务回滚(适合还没提交的删除)
如果你是在一个事务里删的数据,而且还没有提交,这种情况最容易处理:
-- 开始一个事务
BEGIN;
-- 错误地删了数据(举个例子)
DELETE FROM users WHERE created_at < '2025-01-01';
-- 发现错了!马上回滚
ROLLBACK;
-- 检查数据是不是还在
SELECT COUNT(*) FROM users;⚠️ 注意:只要执行了 COMMIT,这个办法就不管用了。二、用时间点恢复(PITR)——生产环境最稳的办法
前提是你已经打开了 WAL 日志归档功能,并且有定期做的完整备份。
第一步:改配置文件(postgresql.conf)
wal_level = replica
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/wal_archive/%f'改完之后需要重启 PostgreSQL 才能生效。
第二步:做一次完整的备份
# 用 pg_basebackup 命令
pg_basebackup -D /backup/base_$(date +%Y%m%d) -Ft -z -P -U postgres第三步:模拟误删,并记下准确的时间
-- 假设在 2026-04-08 16:30:00 删错了
DELETE FROM orders WHERE status = 'pending';
COMMIT;第四步:开始恢复操作
- 先停掉 PostgreSQL 服务
- 清空当前的数据目录(但要保留
pg_wal这个文件夹) - 把之前备份的内容复制回数据目录
- 在数据目录里新建一个空文件,名字叫
recovery.signal - 编辑
postgresql.auto.conf文件,加上下面这两行配置:
restore_command = 'cp /var/lib/postgresql/wal_archive/%f %p'
recovery_target_time = '2026-04-08 16:29:50'- 启动数据库,系统会自动把日志重放到指定时间点之前,数据就恢复好了。
三、从 WAL 日志里找回数据(没有备份时的最后办法)
如果你没开 PITR 功能,但 WAL 日志文件还在(比如还没被 VACUUM 清理掉),可以用像 walminer 这样的工具尝试恢复:
安装 walminer(需要自己编译)
git clone https://github.com/ChristophBerg/walminer.git
cd walminer
make && make install解析日志,生成还原用的 SQL 语句
-- 加载扩展
CREATE EXTENSION walminer;
-- 告诉工具要分析哪个 WAL 文件
SELECT walminer_wal_add('/var/lib/postgresql/16/main/pg_wal/0000000100000000000000A1');
-- 查看某段时间里对 orders 表的 DELETE 操作(假设表 OID 是 16384)
SELECT * FROM walminer_change(
'2026-04-08 16:25:00',
'2026-04-08 16:35:00',
'public.orders',
'DELETE'
);
-- 工具可能会输出像这样的 INSERT 语句
-- INSERT INTO orders VALUES (1001, 'pending', '2026-04-01');
-- INSERT INTO orders VALUES (1002, 'pending', '2026-04-02');把这些 INSERT 语句在数据库里执行一遍,就能把之前删掉的数据重新加回去。
建议和总结
- 基本要求:一定要定期做完整备份,并开启 WAL 日志归档,这是保护数据最基本的做法。
- 小心 VACUUM:它会真正清除旧数据。所以一旦发现删错了,最好立刻停止写入操作,避免原来的数据被覆盖掉。
- 对特别重要的表,可以考虑用
pgaudit插件记录所有操作,或者用触发器把每次变化都存下来,这样多一层保障。
用上面这三种方法,大多数因为手误造成的数据丢失都能成功恢复。记住:别慌张,快速判断情况,恢复完一定要检查结果,这才是面对问题时最重要的做法。