关于 openclaw-backup
openclaw-backup 是备份当前机器或指定主机上 OpenClaw 安装的技能,面向需要保存并核验其状态、数据库、会话和配置的维护者。它通过分步检查、清单和恢复说明降低遗漏风险。
主要功能
- 01检测 OpenClaw 状态目录和数据库
- 02对 SQLite 数据库创建并核验快照
- 03生成官方归档和原始归档
- 04按需单独归档工作区
- 05收集服务元数据并生成校验清单
- 06可选异机复制并核验校验和
适用场景
- 01备份当前机器上的 OpenClaw 安装
- 02通过 SSH 备份远程主机
- 03检查归档是否包含会话记录
- 04为异机备份验证访问控制和文件校验
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ bhagyamudgal/ skills --skill openclaw-backup安装后在 Claude Code 中输入/openclaw-backup确认已加载。
附带文件references/restore-template.mdreferences/sqlite-snapshot.md
详细介绍
每个步骤都以一道关卡结束。关卡是一项会生成证据的检查。未运行的关卡就视为未通过。这项技能旨在防范一种隐蔽故障:归档写入顺利、验证也通过,结果却缺少你需要的内容。
输入
- 无。备份当前机器上的 OpenClaw 安装。
- 主机。传入
user@host,并在每条命令前加上你的 SSH 调用。其他步骤完全相同。
尽可能自动检测。只询问备份目标位置(默认为 ~/backups/<date>-preflight),以及是否要拉取一份副本到本机。
步骤 0:预检
STATE_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
[ -d "$STATE_DIR" ] || { echo "FAIL: no OpenClaw state dir at $STATE_DIR"; exit 1; }
openclaw --version
node --version # v22+ carries node:sqlite, needed in Step 3
du -sh "$STATE_DIR"
df -h "$STATE_DIR"
find "$STATE_DIR" -name '*.sqlite' -not -path '*/node_modules/*' | sort
每次运行都使用 find 查找数据库。OpenClaw 会在不同版本间迁移数据库。2026.7 将记忆数据库从 memory/main.sqlite 移到了 agents/<id>/agent/openclaw-agent.sqlite,因此硬编码路径会悄无声息地找不到任何内容。
定位工作区,它可能位于状态目录之外。检查配置中的 OPENCLAW_WORKSPACE_DIR 和 agents.defaults.workspace。状态目录之外的工作区是单独的归档来源。将其路径记录为 WORKSPACE_DIR;如果它位于状态目录内,并且原始归档已包含它,则留空。
检查主机以确定网关的运行方式。它可能是 systemd 用户单元(例如 openclaw-gateway.service)、systemd 系统单元、pm2、Docker 或 launchd。用户单元的每条命令都需要使用 systemctl --user。普通的 systemctl 会报告“unit not found”,看起来像是服务已停止,实际上服务仍在写入。
只有在可用空间至少为状态目录大小的 2 倍,且数据库列表非空时,才算通过此步骤。
步骤 1:从 --help 读取功能
openclaw backup --help
openclaw backup create --help
--help 是此安装版本的事实依据。docs.openclaw.ai 文档介绍了一个已发布的构建版本可能并不具备的 backup sqlite 子命令,因此文档网站描述的功能可能并不存在于该二进制文件中。
只有在记录了子命令列表后,才算通过此步骤。如果存在 sqlite,优先使用它而不是步骤 3,并在报告中说明。
步骤 2:选择停机模式
询问用户。默认采用零停机模式。步骤 3 会以事务方式快照数据库;数据库是唯一无法承受在线复制的部分。
| 模式 | 代价 |
|---|---|
| 零停机(默认) | 写入原始归档期间,正在改写的文件可能不完整。数据库另行处理。 |
| 短暂停机 | 停机数分钟,该时间段内的消息会丢失。所有产物均处于静止状态。 |
在停止运行中的网关之前,立即调用 preflight-mutations,并提供准确的主机、服务管理器及名称、停止和重启操作、预计停机时间、当前进程和健康状态、恢复命令,以及用户对短暂停机的批准。停止服务前,必须遵循其结果约定。零停机运行无需经过此关卡。
停止服务后,在归档前使用 pgrep -af openclaw 确认进程已退出,并在之后确认服务已恢复且运行正常。
步骤 3:快照所有 SQLite 数据库
加载 ${CLAUDE_SKILL_DIR}/references/sqlite-snapshot.md 并按其说明操作。该文件包含 VACUUM INTO 脚本,并解释了在线 WAL 数据库为何需要使用该脚本。
只有在每个数据库的源文件和快照都报告 integrity_check = ok,且计数显示为 N/N 时,才算通过此步骤。任一数据库未通过其中一项检查,都必须停止运行。报告失败的数据库及其返回的信息。
步骤 4:官方归档
cd "$HOME" && openclaw backup create --verify --output "$BACKUP_DIR/official"
大型安装需要数分钟。请在后台运行并轮询状态。
此归档会排除正在变动的文件:sessions、logs 和 delivery queues 下的 .jsonl、.log、.json、.tmp、.sock、.pid 文件。会话记录是 .jsonl 文件,因此接下来要执行步骤 5。
只有在运行结束时出现 Archive verification: passed,并且你记录了报告中要用的 Skipped N volatile files 计数,才算通过此步骤。没有这条验证信息,就视为归档未经验证。
步骤 5:原始归档,保存会话记录的归档
mkdir -p "$BACKUP_DIR/raw"
tar --use-compress-program="zstd -3 -T0" \
--exclude='*/node_modules' \
--warning=no-file-changed \
-cf "$BACKUP_DIR/raw/openclaw-state-raw.tar.zst" \
-C "$(dirname "$STATE_DIR")" "$(basename "$STATE_DIR")"
echo "EXIT=$?"
node_modules 可重新安装,且通常占总量的三分之一,因此会被排除。其他内容全部保留。步骤 4 丢弃的易变文件正是本步骤的重点。
然后生成证据:
LISTDIR=$(mktemp -d "$BACKUP_DIR/.listings-XXXXXXXX") || exit 1
zstd -t "$BACKUP_DIR/raw/openclaw-state-raw.tar.zst"
tar --use-compress-program="zstd -d" -tf "$BACKUP_DIR/raw/openclaw-state-raw.tar.zst" > "$LISTDIR/rawlist.txt"
LISTING_EXIT=$?
wc -l < "$LISTDIR/rawlist.txt"
grep -c 'sessions/.*\.jsonl' "$LISTDIR/rawlist.txt"
grep -c 'node_modules' "$LISTDIR/rawlist.txt"
rm -rf -- "$LISTDIR"
仅当 zstd -t 通过、列表命令的退出码为 0、在有会话历史记录的安装中会话 .jsonl 数量大于零,且 node_modules 数量为零时,本步骤才算通过。.jsonl 数量为零或 node_modules 数量不为零,都表示排除模式有误。修正后重新运行。记录 tar 的退出状态:0 表示干净通过,1 表示在报告中记录热读取警告,2 或更高则本步骤失败。
步骤 5.5:工作区归档
当 WORKSPACE_DIR 为空时,跳过本步骤:工作区已保存在原始归档中。
mkdir -p "$BACKUP_DIR/workspace"
tar --use-compress-program="zstd -3 -T0" \
--warning=no-file-changed \
-cf "$BACKUP_DIR/workspace/openclaw-workspace.tar.zst" \
-C "$(dirname "$WORKSPACE_DIR")" "$(basename "$WORKSPACE_DIR")"
echo "EXIT=$?"
然后生成证据:
LISTDIR=$(mktemp -d "$BACKUP_DIR/.listings-XXXXXXXX") || exit 1
zstd -t "$BACKUP_DIR/workspace/openclaw-workspace.tar.zst"
tar --use-compress-program="zstd -d" -tf "$BACKUP_DIR/workspace/openclaw-workspace.tar.zst" > "$LISTDIR/workspacelist.txt"
LISTING_EXIT=$?
wc -l < "$LISTDIR/workspacelist.txt"
rm -rf -- "$LISTDIR"
仅当 zstd -t 通过、列表命令的退出码为 0,且列表非空时,本步骤才算通过。记录 tar 的退出状态:0 表示干净通过,1 表示在报告中记录热读取警告,2 或更高则本步骤失败。
步骤 6:元数据
将以下各项保存到 meta/:
- 服务单元文件及其 drop-in 目录。覆盖项位于 drop-in 目录中。记录服务管理器。对于 systemd,将单元目录记录为
UNIT_DIR:即包含单元文件的目录,drop-in 位于<name>.d下。对于 pm2、Docker 或 launchd,不存在单元目录:将定义文件归档到meta/service-def/,保留其基本文件名,将其当前路径记录为SERVICE_DEF_PATH,并记录服务管理器。模板会根据记录的管理器进行恢复。 - 单元引用的环境文件。
openclaw --version、node --version、全局 npm 软件包。- 监听端口、正在运行的 OpenClaw 进程、crontab。
- 每个状态子目录的
du -sh结果,用于检查之后恢复的大小。
仅当上述每一项都已保存到 meta/,或已在报告中注明不可用并说明原因时,本步骤才算通过。
步骤 7:清单和 RESTORE.md
cd "$BACKUP_DIR" && find . -type f ! -name MANIFEST.sha256 -print0 \
| sort -z | xargs -0 sha256sum > MANIFEST.sha256
chmod -R go-rwx "$BACKUP_DIR"
应用权限变更。这些归档包含 API 令牌、消息配对数据和 OAuth 刷新令牌。
将 ${CLAUDE_SKILL_DIR}/references/restore-template.md 渲染为 $BACKUP_DIR/RESTORE.md,并填入步骤 0 中的实际路径、服务名称、单元目录和数据库列表。
仅当 MANIFEST.sha256 列出每个产物、备份目录的权限模式为 0700,且渲染后的 RESTORE.md 不再包含任何 <PLACEHOLDER> 标记时,本步骤才算通过。
步骤 8:异机复制
与受保护内容位于同一磁盘上的备份能防范配置错误,但无法应对磁盘损坏。如果用户希望将副本保存到其他位置,请完成此步骤。
在运行 rsync 之前,请从接收系统确认目标位置启用了静态加密、仅预期的接收方账户可以访问,并且有明确的保留期限和经过测试的删除路径。首次传输前,请将目标主机密钥与已知可信值核对,避免因主机名输入错误或首次连接被拦截而将副本导向其他位置。目标位置缺少上述任一控制措施时,必须阻止传输。
在运行 rsync 前一刻,使用这些证据、准确的源主机和目标主机及路径、所含制品清单和凭据敏感性、接收方、保留期限和删除路径、当前目标状态、校验和及访问控制回读结果,以及用户对异机复制的批准,调用 preflight-mutations。复制前,先执行其结果契约。
rsync -avh --partial -e ssh <source> <destination>
根据清单在接收端进行验证:
grep -v ' \./official/' MANIFEST.sha256 > /tmp/check.sha256 # if official/ was not pulled
sha256sum -c /tmp/check.sha256 # macOS: shasum -a 256 -c
确认校验和输出涵盖非空文件列表后,才能将其视为通过。校验器收到空列表时,会在未检查任何内容的情况下报告成功。
校验和不匹配时,应将该传输卡标记为已失效。保留其 failed 结果和观察到的目标端部分状态,作为不可更改的历史记录。如果传输或回读情况不明确,请将其标记为 reconcile-required,并在规划其他写入前解决该确切文件的问题。每次重试前,都要重新读取确切的源文件和目标端部分文件,并重新检查接收系统的加密、有效访问权限、保留期限和经过测试的删除控制措施。创建一张新卡,仅限于这一个不匹配文件和一次可恢复的 rsync --partial 传输,并附上当前防护措施和预期的校验和回读结果。仅在当前结果为 ready 时重试;随后,在进行任何后续尝试前,将该卡标记为已完成,并记录其权威结果。
复制后,重新检查接收系统的加密和有效访问控制。如果其中任一项与预检证据不符,请保留并报告该副本为敏感的部分状态。复制批准不授权删除。应单独生成补偿性删除卡,并注明确切目标、观察到的故障、删除操作和不存在性回读结果。仅在获得新的明确确认且当前预检结果为 ready 后删除。
只有在每个已检查文件均报告 OK、静态加密仍处于启用状态、有效访问权限仍仅限于已批准的接收方账户,并且保留期限和删除路径仍可用时,才算通过此步骤。只有按照上述新建卡片重试契约处理后,不匹配文件才可解除阻止。安全控制失败时,必须阻止完成,同时保留敏感的部分状态,或单独将其删除。--partial 可让新的传输恢复进行。
不拉取官方归档是合理的。其内容是原始归档的子集。请在报告中说明这一省略。
步骤 9:报告
OPENCLAW BACKUP: <host or "local">
Install: OpenClaw <version>, state dir <path> (<size>)
Service: <unit/manager>, <running|stopped during backup>
Mode: <zero-downtime | brief stop>
Artifacts (<total size>, mode 0700):
official/<name>.tar.gz <size> verification: <passed|NOT VERIFIED>
raw/<name>.tar.zst <size> <N> entries, <M> session transcripts
workspace/<name>.tar.zst <size> <N> entries (omit when the workspace sits inside the state dir)
sqlite/ <size> <X>/<X> databases, integrity ok source + snapshot
meta/ <size> unit + drop-ins, env, inventory
MANIFEST.sha256 + RESTORE.md
Official archive skipped <N> volatile files, covered by the raw archive.
VERIFIED: <what was run, and the evidence each produced>
ASSUMED: <what was inspected but not executed>
NOT DONE: restore has not been rehearsed against this backup
VERDICT: <BACKUP COMPLETE | INCOMPLETE, reason>
只有在步骤 0-8 中每个“只有在……时,才算通过此步骤”的条件,都连同证据列在 VERIFIED 下,或连同未执行的原因列在 ASSUMED 下时,才算通过此步骤。只有全部条件均已验证,才能标记 BACKUP COMPLETE。
以下两项声明须保持准确:
- 校验和未经验证的备份应标记为
INCOMPLETE。 - 在实际针对临时目标执行恢复之前,恢复状态应保持为
NOT DONE。运行备份只能证明归档存在,不能证明它们可以恢复。