指南

如何备份应用数据库(并确保能真正恢复)

要备份应用数据库,请按计划把它导出为文件(对于 Postgres,标准工具是 pg_dump),把副本存放在与数据库分开的地方,并定期把某个备份恢复到一个空数据库中,以证明它确实可用。在任何有风险的改动之前,再多做一次备份。你的代码备份(无论是 GitHub 仓库还是导出文件)都不包含数据。

本指南面向运行小型应用、希望不再担心丢失数据的人。示例使用 Postgres,因为大多数 AI 构建的应用都用它,但这些原则适用于任何数据库。

备份必须覆盖什么

应用不只是数据库。请清楚每一份备份分别保护哪一部分。

内容存放位置如何备份
代码项目文件、GitGitHub 同步或项目导出
数据(用户、记录)数据库按计划进行数据库转储
上传的文件对象存储复制存储桶,或在别处保留原件
密钥和设置项目设置、服务商控制台使用并保持更新的密码管理器

数据是无法重新创建的部分。代码可以重写,设置可以重新输入;但客户的订单无法重来。

第 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 步:测试恢复

备份的价值取决于你最近一次成功恢复的时间。至少每隔几个月测试一次,并且在备份流程有任何改动之后也要测试:

  1. 创建一个新的空数据库。测试时绝不要覆盖线上数据库。
  2. 把最新的备份恢复到其中:
pg_restore --no-owner --dbname="$TEST_DATABASE_URL" backup-2026-09-29.dump

如果是纯文本 .sql 文件,请改用 psql "$TEST_DATABASE_URL" -f backup.sql。

  1. 检查每个表是否存在,将行数与线上数据库比较,并查看几条最近的记录。
  2. 如果可以,让应用的一个副本指向它,并尝试登录。
  3. 记录恢复花了多长时间。那就是你真实的恢复时间。

第 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。

我怎么知道备份能用?

恢复一次。把备份加载到一个单独的空数据库中,检查表是否存在,行数和最近几条记录是否与线上数据一致。从未恢复过的备份只是一种猜测。

数据库备份应该存放在哪里?

放在与数据库本身分开的地方,最好由另一家服务商或另一个账户保管,并且只限你本人访问。备份包含所有用户的数据,应与线上数据库同样谨慎地对待。

Mythex · Pricing · 用 AI 构建任何东西 · 网站和应用模板 · Mythex 对比 · AI 应用构建术语表 · 免费的 AI 应用构建工具 · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 繁體中文(香港) 繁體中文(台灣)