备份与灾难恢复
备份什么、如何恢复,以及如何为故障做规划。
ObjectOS 本身是无状态的 —— 运行时可以从容器镜像重建。**备份针对的是 ObjectOS 所 依赖的数据,而不是 ObjectOS 本身。**请围绕这些数据集规划恢复。本页的所有内容同样 适用于 Community 和 Enterprise。
备份什么
| 资产 | 归属 | 备份策略 |
|---|---|---|
| 业务数据库 | 客户 | 数据库原生备份(托管服务用 PITR);每季度测试一次恢复 |
编译后的产物(objectstack.json) | 应用/发布团队 | 把每个已发布的产物存放在不可变存储中;绝不覆盖 |
密钥基线 —— 首先是 OS_SECRET_KEY | 客户的密钥管理器 | 托管备份这些值本身;按策略确定轮换周期 |
对象/文件存储(启用 storage 能力时) | 客户 | 存储桶版本控制 + 按需跨区域复制 |
本地存储上的上传文件(OS_STORAGE_LOCAL_ROOT) | 客户 | 与数据库相同的计划,这样记录及其附件会恢复到同一个时间点 |
| 客户自管的身份提供商 | IdP 厂商 | 厂商原生方式 |
**没有
OS_SECRET_KEY的数据库备份是不完整的备份。**每个存储的密钥 —— 加密的 设置、secret字段、数据源凭据 —— 都用这一个密钥加密。在没有原始密钥的情况下 恢复的数据库会保留这些值,但它们将永远无法读取。在生成密钥的当天就托管备份它, 并把密钥和数据库视为一个备份单元。
一个设置了 OS_DATABASE_URL 和 OS_SECRET_KEY 的容器,其文件系统本身不需要备份:
它的缓存都可以重建 —— 缓存的产物每次读取时都会依据其完整性固定值重新校验,所以
丢失缓存只会多一次获取,绝不会影响正确性。使用默认值运行的单台主机则不同:
它的主目录保存着 SQLite 数据库、上传的文件和自行生成的加密密钥,所以要把它纳入
你的文件备份。
数据库备份
根据驱动选择策略:
| 驱动 | 推荐做法 |
|---|---|
| PostgreSQL | 持续 WAL 归档 + 基础备份;时间点恢复。对于小型数据库,pg_dump --format=custom 是可行的逻辑备份 |
| MySQL | 二进制日志归档 + 完整转储;时间点恢复 |
| MongoDB | 副本集快照;用 oplog 实现 PITR |
| SQLite(单节点 / 桌面) | WAL 模式 + 通过 VACUUM INTO 或在线备份 API 做热快照;可选用 Litestream 做持续复制 —— 参见下文的 SQLite 部署 |
无论使用哪种驱动,都要验证:
- 备份能在客户的 RPO 内完成;
- 一个全新的数据库可以用同一个产物启动 ObjectOS 并提供服务;
- 至少每季度端到端地演练一次恢复测试。
SQLite 部署
SQLite 是默认驱动,对于单节点的 ObjectOS 是正当的生产选择 —— 桌面应用、小团队 的内部工具、边缘 / 本地部署的一体机、评估环境。代价是结构性的:SQLite 只允许单个 写入者,所以它不适合多节点 ObjectOS、高并发写入吞吐量或共享数据库的部署。对于 这些场景,请使用 PostgreSQL。
当你确实在生产环境中运行 SQLite 时,让它安全的配置和备份方案是配套的:
运行时配置
- 运行时让基于文件的 SQLite 保持 WAL 模式(读者不会阻塞写入者;崩溃安全)。这
意味着数据库旁边的
app.db-wal可能保存着尚未写入app.db的已提交写入 —— 在运行时运行期间,绝不要单独复制app.db。 PRAGMA synchronous=NORMAL是常见的桌面/单节点默认值 —— 搭配 WAL 是安全的, 而且比FULL快得多。- 把数据库文件放在本地磁盘上。在运行时运行期间,不要把它放在 NFS、SMB 上, 或者放在由 Dropbox / OneDrive / iCloud 同步的文件夹中 —— SQLite 的锁在这些地方 不可靠,这是 SQLite 部署损坏最常见的原因。
热快照(无停机)
在你用 SQLite 的在线备份 API 或 VACUUM INTO 制作快照时,运行时会继续提供服务:
VACUUM INTO '/var/backups/objectos/db-2026-05-27T13-00Z.sqlite';按与你的 RPO 相匹配的频率调度它(cron、systemd 定时器或进程内调度器)。给每个 快照标上产生它的产物版本,这样你就可以把数据库和产物一起回滚(参见下文的 产物版本管理)。
异地副本
本地快照无法在磁盘损坏后幸存。把每个快照推送到持久存储:
- 服务器 / 虚拟机:推送到 S3 或任何兼容 S3 的存储桶(你很可能已经为
storage能力配置了一个)。 - 桌面应用:把快照写入用户控制的同步文件夹(OneDrive / iCloud / Google Drive)—— 在这里是可以接受的,因为与活动数据库不同,快照文件是已关闭且不可变的。
持续复制(更低的 RPO)
如果要在不放弃 SQLite 的前提下实现一分钟以内的 RPO,就在 ObjectOS 进程旁边运行 Litestream。它把 WAL 流式传输到兼容 S3 的存储,并支持 时间点恢复。当单节点 SQLite 部署需要接近零的数据丢失时,这是推荐的路径。
恢复
停止运行时,用选定的快照替换数据库文件(或者运行 litestream restore),确保旁边
没有残留过期的 -wal 或 -shm 文件,然后针对产生该快照的同一个产物版本启动运行时。
产物版本管理
把已发布的产物视为不可变的。给每个产物标上编译它所用的发布 id(例如
objectstack-2026-05-24.json)。恢复到一个已知良好的业务状态,通常意味着:
- 把数据库恢复到选定的时间点。
- 把 ObjectOS 重新指向当时在线的产物版本。
- 重启运行时。
如果你原地覆盖产物,即使数据库备份完美无缺,你也会失去干净回滚的能力。
RPO/RTO 规划
客户部署的一个可行的起始目标:
| 类别 | RPO | RTO | 备注 |
|---|---|---|---|
| 评估 / 演示 | 尽力而为 | 尽力而为 | SQLite 快照即可 |
| 桌面应用 / 小团队单节点 | ≤ 1 小时(快照)或 ≤ 数秒(Litestream) | 数分钟 | SQLite + WAL + 定时 VACUUM INTO + 异地副本 |
| 单租户生产 | ≤ 15 分钟 | ≤ 1 小时 | 带 PITR 的托管 PostgreSQL + 预热镜像 |
| 多租户 / 受监管 | ≤ 5 分钟 | ≤ 30 分钟 | 高可用数据库 + 多可用区 ObjectOS + 经过测试的运行手册 |
更严格的目标需要 ObjectOS 容器本身之外的平台变更(高可用数据库、多可用区入口、 预热副本)。
值得演练的故障模式
- **数据库长时间不可用。**从 ObjectStack 17.0 起,这是有约定的行为,而不是只能
期望的事情:只要某个数据驱动没有响应,
/api/v1/ready就返回 503,所以就绪探针 会把 Pod 标记为未就绪。要演练的是恢复 —— 数据库恢复后副本会重新加入,并且 不需要任何重启就能察觉。对象所绑定的数据源如果在启动时无法连接,现在会让启动 失败,所以要在应用副本滚动之前确认你的恢复已经完成。 - **产物回退。**回滚产物指针;数据不受影响。
- **密钥轮换。**轮换
OS_AUTH_SECRET会使所有会话失效。在维护窗口期间进行,或在 各副本之间错开进行。 - **区域故障。**如果客户要求区域故障转移,业务数据库、密钥管理器和入口都需要跨 区域。ObjectOS 本身可以在任何能获取到镜像的地方运行。
恢复演练
在上线之前,在一台临时主机上演练这一流程,并在任何存储变更之后再演练一次。 一个你从未恢复过的备份只是一种希望,而不是备份。
-
准备一台干净的主机,使用与制作备份时相同的镜像版本。
-
恢复数据库 —— 用提供商的快照,或者:
pg_restore --clean --if-exists -d "$OS_DATABASE_URL" backup-2026-07-14.dump -
提供原始的密钥。
OS_SECRET_KEY和OS_AUTH_SECRET必须是托管备份的原始值, 绝不能是新生成的值。如果你使用本地存储,也要恢复上传的文件。 -
针对同一个产物版本启动,并验证:
curl -fsS https://app.example.com/api/v1/health curl -fsS https://app.example.com/api/v1/ready然后端到端地证明恢复成功:用一个真实账户登录,打开一条在备份之前就存在的 记录,并读取一个加密设置的值 —— 这才会用到
OS_SECRET_KEY。
运行手册中要记录什么
- 每个数据集的备份计划、保留期和值班联系人。
- 分步的恢复流程(先数据库,再产物,然后启动 ObjectOS)。
- 用于确认恢复后的数据库一致的验证查询。
- 同时覆盖 ObjectOS 镜像和产物版本的回滚计划(参见 升级与回滚)。
- 面向客户可见事件的沟通模板。
企业版额外提供
- **把上一个镜像摘要与备份保存在一起。**恢复到某个时间点,就是恢复到当时正在运行 的摘要,而在物理隔离的站点上,上一个摘要可能是唯一的副本 —— 参见 物理隔离。
- **
OS_LICENSE_KEY属于密钥基线。**恢复后的部署会用交给它的许可证启动,而多组织 姿态没有许可证会拒绝启动。 - **在副本滚动之前完成恢复。**捆绑的技术栈会在任何副本启动之前运行它的一次性迁移, 所以当技术栈启动时,数据库必须已经完整。