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

# 重启恢复

重启网关不会丢失代理状态。对话、记录、计划任务、后台任务记录和排队的出站消息都会保存在磁盘上，而在轮次中途被中断的工作会在网关重新启动后被检测并自动恢复。恢复始终处于启用状态，通常不需要手动干预。基础设施重试次数耗尽，或缺少持久化的消息操作权限声明，可能会隔离某个会话，直到你检查或替换它。

本页介绍了重启后哪些内容会保留、如何检测中断的工作，以及自动恢复看起来是什么样子。

## 重启后会保留什么

| 状态           | 存储                  | 重启后的行为                |
| ------------ | ------------------- | --------------------- |
| 对话历史         | 每个代理的 SQLite 数据库    | 不变；会话从已存储的记录继续        |
| 被中断的主会话轮次    | 每个代理的 SQLite 会话行和记录 | 启动几秒后自动恢复或协调          |
| 子代理运行        | SQLite（共享状态数据库）     | 启动时恢复注册表；被中断的运行会恢复    |
| 后台任务         | SQLite（共享状态数据库）     | 启动时协调；孤立的运行会被恢复或标记为丢失 |
| 排队的出站传送      | SQLite 传送队列         | 重启后排空；未传送的回复会重试       |
| 已计划的（cron）作业 | SQLite cron 存储      | 计划会保留；调度器在启动时重新启用     |
| 重启后续         | SQLite 重启标记         | 向请求重启的会话分发一次性后续操作     |
| 网关终端 PTY     | 进程内存                | 随旧进程结束；终端会话不会恢复       |

## 优雅重启会先进行排空

请求的重启（`openclaw gateway restart`、需要重启的配置变更，或网关更新）不会立即终止正在进行中的工作。网关会停止接受新的工作，然后等待活跃的代理回合和后台任务完成，最长等待一个排空预算（默认 5 分钟）。因此，大多数重启根本不会中断任何内容。

只有无法在排空预算内完成的工作（或任何被强制重启或崩溃中断的运行）才会被终止——并且在此之前，每个受影响的会话都会被标记为可恢复。

## 主机休眠与进程冻结

当网关主机从休眠中唤醒、虚拟机恢复运行，或进程在长时间暂停后继续运行时，网关会在约 30 秒内检测到冻结。它会重启频道连接，并刷新缓存的健康状态和在线状态，以便客户端无需等待过时的套接字或快照过期。

macOS 应用和 Linux companion 会与本地网关协作，在主机休眠前准备一个短暂的挂起租约，并在唤醒后恢复该租约。应用主机休眠时，远程网关不会被挂起。通过 `gateway.suspend.*` 进行的主动挂起会让恢复保持延迟状态，直到控制器恢复网关。

## 如何检测中断的工作

三个相互补充的机制会标记那些回合未能完成的会话：

* \*\*在回合接纳时：\*\*对于现有主会话中的普通文本回合，网关会在模型或 `before_agent_reply` 钩子执行前，在一个 SQLite 事务中追加用户消息、将会话标记为运行中，并记录其恢复交付声明。控制 UI 会在返回 `started` 确认之前执行此操作；频道调度则会在准备好的回合接管代理运行时执行此操作。
  命令、附件、每回合覆盖设置、待处理交付、先前的中止提示、由插件拥有的会话，以及带有执行钩子的回合，会使用各自专用的接纳路径。
  如果安装了 `before_agent_reply` 钩子，接纳过程会记录足够的阶段状态，以区分已完成的静默结果与存在歧义的副作用窗口。恢复调度会执行一个由普通用户触发的代理回合，因此当前加载的 `before_agent_reply` 钩子会按照其正常触发规则运行。对于先前钩子结果存在歧义的情况，会使用支持安全重启的工具恢复，而不是重放不受限制的副作用。
* \*\*在关闭时：\*\*在重启排空期间，每个存在活动运行的会话都会在运行被中止前，于会话存储中写入恢复标记。
* \*\*在启动时：\*\*网关会扫描会话存储，查找那些仍声称处于运行状态、但在新进程中没有活动所有者的会话。这可以捕获未执行任何关闭代码的硬崩溃和强制终止。同时还会清理过时的会话记录锁文件。

## 自动恢复

启动几秒后，网关会为每个已标记的会话重新派发一条合成的系统消息，告知代理其上一轮因重启而中断，并要求其从现有记录中继续。如果最终回复已经生成但尚未送达，则会包含其文本，以便代理直接发送，而不是重新执行工作。

启动协调会使用指数退避，最多重试三次临时性失败。除此之外，每个中断的主会话周期都有三个已计费自动派发尝试的持久化预算，并会跨越网关重启保留。OpenClaw 会在派发前扣除一次尝试；如果网关在接受请求前明确拒绝，则退还该次尝试；如果派发后的结果不确定，则保留该次扣费，以避免重复执行工作。已经占有会话的前台工作会让自动恢复暂停，直到该工作结束。

持久化预算耗尽后，会话会被标记为墓碑，而不是无限循环。检查失败的会话，并使用 `/new` 或 `/reset` 启动替代会话。`openclaw doctor --fix` 可以修复与墓碑冲突的过时中止标志，但不会重新启用该恢复周期。

每次重试都会复用一个持久化派发标识符，因此连接失败产生歧义时不会两次启动同一恢复流程。已完成的 Control UI 回合也会保留有界的持久化幂等墓碑，使重新连接的出站队列能够在不重新执行请求的情况下将其回收。

仅使用 message-tool 的回复会使用第二个持久化关联。在同一会话的终端发送到达频道之前，网关会在确切的会话和源回合上记录一项未解决的交付意图。已确认的提供商成功会将其解析为持久化的已交付回执；已确认的失败则会将其清除。恢复流程会完成已交付的回执，而不会重新运行工具。如果崩溃导致提供商结果未知，恢复流程会使用可安全重启的工具继续，使模型能够检查并报告这一歧义，而不会重放外部效果。

已交付的回复也会连同其源消息 ID 一起镜像到文字记录中。终端镜像使用不同的回执键，因此使用相同提供商幂等键的进度发送无法掩盖终端标记。较早回合的进度发送和回执无法完成当前回合。只有持久化的频道入口声明才能恢复消息操作权限。恢复运行会保留原始的源交付模式和源关联，包括请求者身份以及任何相同频道／线程限制，因此即使恢复期间再次发生重启，相同回执仍保持权威性。无法重建频道权限的仅使用 message-tool 的回合会被标记为墓碑，因为 OpenClaw 在没有原始频道入口声明的情况下无法安全创建消息操作权限。终端通知会指示用户使用 `/new` 或 `/reset` 启动替代会话。

恢复之前，网关会对文字记录末尾进行分类，以选择继续运行时的工具限制。已中止的回合本身就是中断，因此会尽最大努力根据提供商或工作进程记录的中止详情继续运行：
部分流式文本会保留在文字记录中，继续运行会从其下方的消息开始，而遗留的工具调用会从下一次提供商负载中删除，并限制为可安全重启的工具，除非经过审计确认可以安全重放。提供商失败、已完成的助手末尾、空文字记录以及过时的待处理批准也会从现有文字记录继续。具有歧义副作用的状态会使用可安全重启的工具；否则，模型会判断哪些工作已完成、哪些工作仍待完成，并可以向用户报告任何不确定性。

OpenClaw 还可以重建中断的只读 [Code Mode](/tools/code-mode) 工作。Code Mode 会将这些运行标记为可安全重启，并在执行之前拒绝产生副作用的目录或命名空间工具调用。如果重启发生在 `wait` 控制上，新网关会根据其文字记录重建该回合，并强制重建的执行保持可安全重启，即使模型省略或清除了该标志。主机会将整个重建回合过滤为经过审计的只读核心工具和明确可安全重放的插件工具，包括 Code Mode 在重启后被禁用的情况。不可安全重放或不匹配的 Code Mode 检查点仍会继续运行以供模型协调，但不会使用 Code Mode 控制，并会受到可安全重启的工具限制。

### 子代理

子代理运行会持久化到共享的 SQLite 状态数据库中，因此子代理注册表会随进程一同保留。启动时会恢复注册表，并携带原始任务上下文继续已中断的子代理会话。适用两个安全阀：

* 若运行在 2 小时之前被中断，则会直接完成归档而不是恢复，因此整夜停机的网关不会让过时的工作“复活”。
* 如果某个会话反复恢复失败，则会被标记为卡死并加上墓碑，以免恢复无限循环。

### 后台任务

[后台任务注册表](/automation/tasks) 由 SQLite 支持，并会在启动时以及定期周期内进行协调：已完成运行记录的持久化结果会被恢复，而其所属进程已消失的运行会在宽限期后被标记为丢失，而不是永远挂起。

### 代理请求的重启

当代理自身触发重启时（应用配置更改、更新网关，或显式重启请求），在进程退出前会先将一个重启哨兵写入 SQLite。启动后，网关会将结果回传到发起该操作的聊天，并派发一个一次性的续接回合，让代理在相同的频道和线程中，精确地从离开的地方继续。

哨兵的类型化 SQLite 列是重启处理的权威来源；其 `payload_json` 值仅作为重放／调试影子。运行时会直接读取、写入并清除 SQLite 状态，不使用文件回退。在存储切换期间，启动时以及通过 Doctor 会执行有界状态迁移，以保留旧进程在更新后留下的、经过验证的 `restart-sentinel.json`。迁移会验证类型化行，并在正常的重启处理继续之前移除源文件。

## 安全阀与可观测性

* **崩溃循环断路器：** 在 5 分钟内发生 3 次非正常启动后，断路器会跳闸，在下一次启动时禁止自动启动旁路服务，从而避免崩溃的网关进一步放大自身问题。持续稳定运行的安全模式网关会在完整的非正常启动窗口结束后重新检查断路器，然后恢复延迟的频道自动启动，无需再次重启网关。

  断路器跳闸时，**控制平面仍会启动**，但频道插件（以及其他自动启动的旁路服务）会保持停止状态，直到操作员手动解除抑制，或完整时间窗口结束且期间没有发生非正常启动。恢复过程会保留操作员手动停止的频道，以及任何独立的开发模式抑制状态。网关日志如下：
  `channel autostart suppressed by crash-loop breaker; refusing automatic
  start for <channel>… Start a channel manually with: openclaw gateway call
  channels.start --params '{"channel":"<id>"}'`

  操作员恢复 SOP：

  1. 确认网关进程正在运行（`openclaw gateway status` / LaunchAgent
     或 systemd 单元仍在运行）。出现“频道断开连接”通常意味着自动启动被抑制，而不是网关已停止。

  2. 检查频道状态：`openclaw channels status`（必要时添加 `--probe`）。如果网关本身正常运行，请查找已停止/未连接的账户。

  3. 在强制恢复频道之前，先修复导致非正常启动的根本原因（错误配置、插件启动时崩溃、缺少密钥）。

  4. 在抑制仍然生效时手动启动频道：

     ```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
     openclaw gateway call channels.start --params '{"channel":"<id>"}'
     # 可选：{"channel":"<id>","accountId":"<account>"}
     ```

     `channels.start` 是一个**手动**覆盖操作；它不会为其他频道禁用断路器。

  5. 或者让健康的网关持续运行，直到完整的非正常启动窗口结束。同一进程会记录重启循环断路器已恢复，并启动延迟的已配置频道。
     如果在该窗口结束并经过一次健康监控间隔后仍未出现该消息，请检查网关日志，并在重启前运行 `openclaw doctor`。

  另请参阅[网关](/gateway)（安全模式段落），了解相同的控制平面与频道自动启动分离机制。

* **主会话尝试预算：** 每个中断周期允许 3 次计费的自动调度尝试；耗尽后，该会话会被标记为墓碑状态，直到经过检查并替换。

* **指标：** 恢复活动通过 [Prometheus](/gateway/prometheus) 导出为 `openclaw_session_recovery_total` 和 `openclaw_session_recovery_age_seconds`。

* **日志：** 恢复决策会记录在 `main-session-restart-recovery` 和 `subagent-interrupted-resume` 子系统下。

* **回复钩子：** 恢复的轮次会在正常的用户触发规则下运行当前已加载的 `before_agent_reply` 钩子。自动传递的回复也会在频道传递前运行正常的 `reply_payload_sending` 钩子，并携带恢复后的会话、运行、账户和对话上下文。

## 未恢复的内容

* 因其他所有者已经负责处理而被排除在主会话恢复之外的会话：subagent 会话（subagent 恢复）、cron 会话（调度器会按计划重新运行）以及由 ACP 管理的会话（已连接的 IDE 或客户端负责恢复）。
* 从未被接纳的工作：在排空窗口期间到达的消息会因明确的重启错误而被拒绝，而不是被静默排入一个即将退出的进程。
* Gateway 终端 PTY，包括由操作员和代理拥有的终端。它们是进程本地的，并会在 Gateway 重启时结束。
* 独立的嵌入式轮次无法接管存在待处理重启恢复的主会话，因为它们不共享 Gateway 的生命周期所有者。请通过 Gateway 运行该轮次，或在那里使用 `/new` 或 `/reset` 重置它。
