> ## Documentation Index
> Fetch the complete documentation index at: https://starforge.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 备份与恢复

> 真正必须活下来的是什么，以及哪些丢了也没关系。

三档。知道一样东西属于哪一档，就知道它值得投入多少精力。

## 第一档 —— 不可替代

| 什么                                              | 在哪                                  | 说明                                            |
| ----------------------------------------------- | ----------------------------------- | --------------------------------------------- |
| 数据库                                             | Postgres，或 SQLite 的 `FORGE_DB_PATH` | 全部作业记录、配额、rubric、模型版本、审计条目。丢了它丢的是平台的记忆，不是它的文件 |
| `<root>/runs/**/out`                            | 存储根                                 | checkpoint、导出、评测报告。没有任何东西能重建它们                |
| `<root>/state`                                  | 存储根                                 | 控制平面台账                                        |
| 对象存储                                            | 你的 S3 bucket                        | 数据集、作业包、归档。按 bucket 备份，不要通过平台备份               |
| `FORGE_WEB_JWT_SECRET` 和 `FORGE_SECRET_ENC_KEY` | 你的密钥管理系统                            | 丢了加密密钥，所有存储的集成凭据都读不出来了                        |

## 第二档 —— 丢了很贵，但能重建

| 什么                      | 丢了的代价                             |
| ----------------------- | --------------------------------- |
| `<root>/cache/hf`       | 每个作业重新下载权重。内网链路上这可能比训练还贵          |
| `<root>/cache/datasets` | 下次使用时从对象存储重新拉取                    |
| `<root>/runs/**/logs`   | 作业终态之后就是唯一一份，但一次 run 被理解之后它很少再是关键 |

## 第三档 —— 不用管

`<root>/cache/corpora`、`<root>/packages`（启用对象存储时）、
以及已完成 run 的 `<root>/runs/**/work`。全都能重建，磁盘紧张时本来也会被回收。

## 备份数据库

<Tabs>
  <Tab title="Postgres">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    pg_dump --format=custom --file=starforge-$(date +%F).dump "$FORGE_DB_URL"
    ```

    schema 迁移在启动时自动执行，所以把 dump 恢复到更新的构建上会被向前迁移。
    把 dump 恢复到**更旧**的构建上不受支持——记下每个 dump 来自哪个版本。
  </Tab>

  <Tab title="SQLite">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    sqlite3 .forge/web.db ".backup 'starforge-$(date +%F).db'"
    ```

    用 `.backup` 而不是直接拷文件：对一个活着的 SQLite 数据库执行 `cp` 可能拷到一次撕裂的写入。
  </Tab>
</Tabs>

## 恢复

<Steps>
  <Step title="停掉控制台">
    或者先进维护模式让作业排空——见[维护模式](/zh-Hans/ops/maintenance)。
  </Step>

  <Step title="同时恢复数据库和存储根">
    两者必须彼此一致。数据库里引用了一个从更旧快照恢复出来的 run 目录，
    结果就是它显示出一些并不存在的产物。
  </Step>

  <Step title="恢复密钥">
    尤其是 `FORGE_SECRET_ENC_KEY`。没有原来那把，存储的集成凭据解出来什么都不是，
    每个用户都得重新关联一遍。
  </Step>

  <Step title="启动，然后检查">
    `GET /api/version` 有响应、作业列表能渲染、某个已完成的 run 仍然能看到它的产物。
  </Step>
</Steps>

<Warning>
  演练一次恢复。没有人恢复过的备份只是一个假设，而它的失败方式——
  在事故处理过程中才发现加密密钥丢了——是最贵的那一种。
</Warning>

## 不在范围内的

平台之外的训练数据，以及容器镜像。两者都归别人备份：
你推送过的数据集，事实来源是对象存储；镜像的事实来源是你的镜像仓库。
