如何备份应用数据库(并确保能真正恢复)
要备份应用数据库,请按计划把它导出为文件(对于 Postgres,标准工具是 pg_dump),把副本存放在与数据库分开的地方,并定期把某个备份恢复到一个空数据库中,以证明它确实可用。在任何有风险的改动之前,再多做一次备份。你的代码备份(无论是 GitHub 仓库还是导出文件)都不包含数据。
本指南面向运行小型应用、希望不再担心丢失数据的人。示例使用 Postgres,因为大多数 AI 构建的应用都用它,但这些原则适用于任何数据库。
备份必须覆盖什么
应用不只是数据库。请清楚每一份备份分别保护哪一部分。
| 内容 | 存放位置 | 如何备份 |
|---|---|---|
| 代码 | 项目文件、Git | GitHub 同步或项目导出 |
| 数据(用户、记录) | 数据库 | 按计划进行数据库转储 |
| 上传的文件 | 对象存储 | 复制存储桶,或在别处保留原件 |
| 密钥和设置 | 项目设置、服务商控制台 | 使用并保持更新的密码管理器 |
数据是无法重新创建的部分。代码可以重写,设置可以重新输入;但客户的订单无法重来。
第 1 步:确定你能承受丢失多少数据
两个问题决定了你的备份方案:
- 你能承受丢失多少最近的数据? 如果你每天备份一次,而数据库在傍晚出现故障,你就会丢失当天的改动。对于个人小应用,这没有问题;但对于接收订单的应用,可能就不行了。
- 恢复期间应用能停机多久? 小型数据库几分钟就能恢复,大型数据库可能需要长得多的时间。在真正需要之前,你最好先知道这一点。
对于大多数小型应用,每天自动备份,加上风险操作前的手动备份,是一个合理的起点。涉及资金或健康数据的应用,应该更频繁地备份,或使用支持时间点恢复的托管数据库(即能恢复到任意时刻,而不仅仅是上一次备份)。
第 2 步:检查你的主机已经提供了什么
许多托管数据库服务商会自动备份。请确认:
- 你的套餐是否开启了备份,备份多久运行一次?
- 备份保留多长时间?
- 能否恢复到某个时间点,还是只能恢复到每日快照?
- 你能下载备份,还是只能在他们的系统内恢复?
服务商备份很有用,但它们与数据库存在同一个单点故障:账户。如果账户被关闭、暂停,或者项目被删除,备份也可能一并消失。因此,你还需要保存一份自己的副本。
第 3 步:用 pg_dump 生成转储
pg_dump 会把 Postgres 数据库导出为文件。它读取的是一致性快照,因此应用在导出时可以继续运行。
下面是一个典型命令,使用应用中已有的环境变量里的连接字符串:
pg_dump "$DATABASE_URL" --format=custom --no-owner --file=backup-2026-09-29.dump
各个选项的作用:
--format=custom写出一个可由pg_restore读取的压缩文件,并允许之后只恢复单个表。如果你想要可读的.sql文件,请改用--format=plain。--no-owner省略所有权相关的命令,使恢复到另一个数据库时更简单。- 文件名中的日期能让不同的备份互不混淆。
pg_dump 的版本应与你的数据库 Postgres 版本相同或更新。较旧的 pg_dump 可能会拒绝运行。
如果你用 AI 构建,又不想直接操作命令行,可以这样提问:
使用 pg_dump 的自定义格式为应用数据库创建一份备份,文件名中包含今天的日期。不要输出连接字符串或任何密钥。完成后告诉我文件名和大小。
第 4 步:自动化
手动备份很容易被遗忘。请用你的环境支持的方式实现自动化:
- 你的数据库服务商提供的定时备份(如果有的话)。
- 一个定时任务,运行在服务器或 CI 服务上,执行
pg_dump并把文件上传到存储。 - 一个托管的备份服务,连接到你的数据库。
无论选哪种,都要让它在备份失败时通知你。备份任务悄无声息地失败了三个月,是最典型的恐怖故事。
第 5 步:把副本存放到别处
一条经验法则常被称为 3-2-1:三份数据副本,存放在两种不同类型的存储上,其中一份异地保存。对于小型应用,一个实用的版本是:
- 线上数据库
- 服务商自带的自动备份
- 你自己的转储文件,存放在另一个账户中的独立对象存储桶里
此外:
- 限制访问。 备份包含每一位用户的数据。应像对待线上数据库一样对待它。
- 制定保留策略。 例如,每日备份保留两周,每月备份保留一年。旧备份要有计划地删除,并记住:隐私法律可能要求你在用户提出请求时删除其个人数据。
- 永远不要把备份提交到 Git。 仓库中的转储文件就是一个等待发生的数据泄露。
第 6 步:测试恢复
备份的价值取决于你最近一次成功恢复的时间。至少每隔几个月测试一次,并且在备份流程有任何改动之后也要测试:
- 创建一个新的空数据库。测试时绝不要覆盖线上数据库。
- 把最新的备份恢复到其中:
pg_restore --no-owner --dbname="$TEST_DATABASE_URL" backup-2026-09-29.dump
如果是纯文本 .sql 文件,请改用 psql "$TEST_DATABASE_URL" -f backup.sql。
- 检查每个表是否存在,将行数与线上数据库比较,并查看几条最近的记录。
- 如果可以,让应用的一个副本指向它,并尝试登录。
- 记录恢复花了多长时间。那就是你真实的恢复时间。
第 7 步:在有风险的改动之前备份
在以下操作之前,立即做一次全新的备份:
- 运行会删除或重命名列的数据库迁移
- 批量导入数据
- 让 AI 代理对数据模型做大幅改动
- 删除旧记录
在 AI 构建的应用中,代理可能会作为某个功能的一部分修改表结构。检查点和版本控制可以回滚代码,但无法恢复已删除的行。在重大改动前花三十秒做一次备份,成本很低,却是很好的保险。
常见错误
- 以为 Git 或代码导出就是备份。 它们只有代码,没有数据。
- 从不测试恢复。 很多备份直到真正需要时才发现是空的、不完整的,或者根本无法读取。
- 把备份和数据库放在同一个账户里。 一旦这个账户被入侵或关闭,两者都会丢失。
- 忘记上传的文件。 数据库只保存文件的路径,图片本身存放在存储中。
- 在备份脚本中留下密钥。 应从环境变量读取连接字符串,而不是把它写在脚本文本里。参见如何保护 API 密钥安全。
备份与 Mythex
Mythex 项目可以拥有专用的 Postgres 数据库,其连接信息会注入到工作区和已发布的应用中。Mythex 文档中没有描述数据库备份或恢复功能,因此请自行规划:让代理生成转储文件,下载并妥善保存,尤其是在重大改动之前。项目导出(Pro)包含你的代码,但密钥和 node_modules 不包括在内;它不包含数据库中的数据行。详见文档中的 Database 和 Data ownership。如需进一步了解数据库本身,请阅读什么是 Postgres。
备份检查清单
- 已确定能承受丢失多少数据,以及能停机多久
- 已检查数据库服务商提供了哪些自动备份
- 你自己的转储按计划运行,失败时会通知你
- 副本与数据库分开存放,并限制访问
- 已写下保留策略
- 上传的文件与数据库一样得到备份
- 已在空数据库中测试恢复,并核对了行数
- 每次有风险的改动之前都做了备份
常见问题
我应该多久备份一次应用数据库?
按照你能承受丢失多少数据来决定。对大多数小型应用来说,每天自动备份是合理的最低要求,并在任何有风险的操作之前手动备份一次,例如迁移、导入数据或上线大功能。
导出代码等于备份数据吗?
不等于。代码导出或 GitHub 仓库保存的是应用的文件,而不是数据库中的数据行。你的用户、订单和帖子都存在数据库里,需要单独备份。
什么是 pg_dump?
pg_dump 是 Postgres 自带的标准命令行工具,用于把数据库导出为文件。它可以输出纯 SQL,也可以输出压缩的自定义格式;对应的恢复工具分别是:SQL 文件用 psql,自定义格式用 pg_restore。
我怎么知道备份能用?
恢复一次。把备份加载到一个单独的空数据库中,检查表是否存在,行数和最近几条记录是否与线上数据一致。从未恢复过的备份只是一种猜测。
数据库备份应该存放在哪里?
放在与数据库本身分开的地方,最好由另一家服务商或另一个账户保管,并且只限你本人访问。备份包含所有用户的数据,应与线上数据库同样谨慎地对待。