PostgreSQL 备份不是生成一个文件就结束,能恢复、能校验、能跨版本演练,才算有用。
\n
我以前也犯过一个错:看到备份目录里每天都有 .dump 文件,就以为 PostgreSQL 已经安全了。后来做恢复测试才发现,某次脚本环境变量没展开,导出的不是目标库;还有一次文件大小正常,但恢复账号权限不够,临时库根本建不起来。备份真正有价值,是从恢复成功那一刻开始的。
家庭服务器上的数据库通常不大,正适合把备份流程做得清楚一点。我的目标不是企业级复杂方案,而是关键时刻能把服务恢复到可用状态。
pg_dump 适合日常逻辑备份
小规模 PostgreSQL 我会优先保留逻辑备份。pg_dump 生成的文件更方便跨机器、跨存储和跨主版本迁移。常见做法是使用自定义格式:
docker exec db pg_dump -U app -d appdb -Fc -f /backup/appdb-$(date +%F).dump自定义格式配合 pg_restore 更灵活,可以查看内容、选择恢复对象,也适合恢复到临时库验证。备份脚本里要明确库名、账号、输出路径和日志路径,不要只写一条看不出目标的命令。文件名里带日期还不够,我会额外记录生成时间、数据库名、镜像版本和应用版本。
pg_restore 必须定期演练
备份文件没有恢复过,就只能算“疑似可用”。我的恢复演练会放在临时容器或临时库里,不覆盖运行库。流程大致是:创建空库,恢复 dump,跑应用启动检查,再抽查几张关键表。确认没问题后,才把这次备份标记为可用。
docker exec db createdb -U app appdb_restore_test
docker exec db pg_restore -U app -d appdb_restore_test --clean --if-exists /backup/appdb-2026-06-13.dump
docker exec db psql -U app -d appdb_restore_test -c "\\dt"恢复演练还会暴露字符集、扩展、权限和版本差异。比如应用用了某个扩展,但临时库没装;或者备份账号能导出,却没有恢复需要的权限。越早发现,越不至于在真实故障里临时补课。
目录快照不能替代逻辑备份
直接打包 data 目录或做存储快照,可以保留现场,但它对一致性要求更高。数据库运行中直接复制 data 目录,风险很大。除非使用明确支持的快照流程,否则我不会把它当唯一备份。更稳妥的做法是逻辑备份为主,存储快照作为辅助现场保留。
如果确实做目录级备份,要记录数据库当时是否停机、是否完成检查点、镜像版本是什么、恢复时需要怎样的容器环境。否则拿着一份目录回到新机器上,很可能因为版本或权限不一致启动失败。
主版本升级前先恢复到新版本
PostgreSQL 主版本升级不能只改镜像标签。我的做法是先用旧版本导出,再用新版本临时容器恢复。恢复后让应用连接临时库,跑最基本的读写动作。只有这一步成功,才安排正式维护窗口。
升级时还要保留旧镜像标签、旧 Compose、最近一次可恢复备份和回滚步骤。家庭服务器也会遇到“升级后应用插件不兼容”这种情况,能快速回到旧版本,比在凌晨研究错误日志重要得多。
校验备份不能只看文件存在
备份检查至少包括四项:文件大小是否合理,生成时间是否符合计划,校验值是否记录,最近一次恢复演练是否成功。文件大小突然变小,往往比脚本报错更早暴露问题。校验值则能防止传输或存储过程中文件损坏。
ls -lh ./backup
sha256sum ./backup/appdb-*.dump
docker compose logs --tail=120 db我会把每次演练结果写进维护记录:备份文件名、恢复目标、是否成功、失败原因、下一次要改什么。这里还要记录恢复耗时。家庭服务器里数据量一开始很小,几年后可能已经翻了很多倍,恢复从几分钟变成一小时,就会影响维护窗口安排。
恢复演练结束后,临时库也要清理干净,避免应用误连到测试库。保留记录即可,不要把一次演练留下的临时账号、临时端口和临时数据目录长期放在运行环境里。
PostgreSQL 备份恢复不需要写成很重的流程,但一定要闭环。能导出、能恢复、能校验、能在主版本升级前演练,这四件事做到,家庭服务器里的数据库就踏实很多。
此处评论已关闭