没恢复过的备份只能叫‘候选文件’
备份任务显示成功、目录里每天多一个压缩包,都不能证明数据能回来。文件可能在写入中被复制、密码无人知道、版本不兼容,或者备份与原数据库一起放在同一块磁盘。数据库备份的完成标准是:在不碰生产的隔离环境里,能按文档恢复并通过业务检查。 先确定两个目标:RPO 是最多能接受丢多久数据,RTO 是故障后多久需要恢复服务。个人内容站可能接受一天数据和数小时恢复;订单系统通常不能。目标不同,频率与技术方案也不同。
SQLite 不要在写入中随手 cp
SQLite 看起来只有一个文件,但 WAL 模式可能还有 -wal 与 -shm,运行中直接复制主文件可能得到不一致快照。优先使用 SQLite 提供的在线备份能力或命令行 .backup,让数据库在写入期间生成一致副本。
sqlite3 /var/lib/myapp/app.db '.backup /var/backups/myapp/app-2026-08-14.db'
sqlite3 /var/backups/myapp/app-2026-08-14.db 'PRAGMA integrity_check;'预期 integrity_check 返回 ok。备份目录不要位于公开静态目录,也不要让应用用户随意覆盖所有历史副本。复制前若选择停机方式,就明确停止应用、确认没有写入、复制数据库及相关文件、再启动并验证,不能靠猜。
PostgreSQL 用逻辑备份时记录版本和角色
pg_dump 能在数据库继续使用时导出一致快照,适合单库迁移与常规逻辑备份。自定义格式便于 pg_restore 选择对象和并行恢复:
pg_dump --format=custom --file=/var/backups/myapp/app-2026-08-14.dump myapp
pg_restore --list /var/backups/myapp/app-2026-08-14.dump | head数据库级备份不一定包含全局角色与权限,按恢复目标另外保存角色定义。记录 PostgreSQL 主版本、扩展和编码。数据量很大或 RPO 很短时,需评估物理备份和 WAL 归档,不能无限依赖每天一次 pg_dump。
备份链包含数据之外的关键资产
网站恢复通常还需要用户上传、环境配置模板、Caddy 配置、服务 unit、Compose 文件和部署版本记录。密钥是否进入备份要明确:不备份可能无法解密数据,备份则必须加密并限制访问。代码可从仓库重建,但要记录准确提交或镜像 digest。 把清单分为必须恢复、可以重建、可以丢弃。日志通常只需保留调查窗口,缓存可以重建,数据库和上传则必须有一致时间点。
采用 3-2-1 时别只数副本数量
至少保留多份副本、使用不同介质,并有一份异地。服务器本地备份方便快速恢复,但磁盘损坏或账号被入侵时可能一起消失;对象存储或另一台受控机器保存异地副本。所有副本都在同一云账号下,也存在账号级风险。 为备份设置每日、每周、每月保留,而不是一直累积直到磁盘满。删除过期备份前先列出候选并确认最近成功副本,监控备份年龄、体积异常和上传失败。
恢复演练必须隔离且带业务验收
新建临时目录或独立数据库,不覆盖生产。记录开始时间,恢复备份,运行完整性检查,再启动一个指向恢复副本的临时应用。检查文章数量、最新记录、登录、上传文件和关键查询,而不是只看数据库进程启动。 演练结束记录实际 RTO、缺失步骤和凭证问题,再安全清理临时副本。至少每季度演练一次,数据库大版本升级、备份脚本修改或目录调整后立即再演练。
完成标准
你能指出最近成功备份、它的校验结果、异地位置、保留期限、恢复负责人和上次演练用时。下一篇把备份放进实际发布流程:健康检查、切换与快速回滚。
参考来源
- SQLite Online Backup APISQLite Documentation
- PostgreSQL Backup and RestorePostgreSQL Documentation
- pg_dumpPostgreSQL Documentation