Files
openclaw-config/docs/openclaw-升级与维护.md
T

303 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# openclaw 升级与维护运维手册(bk02)
> 主机:**bk02** / `xuan-asus-nj`Debian 12 bookworm`192.168.3.14`tailscale `100.115.195.192`
> 组件:OpenClaw Gateway(用户级 systemd+ tailscale serveHTTPS 入口)
> 版本:OpenClaw `2026.8.1` → **`2026.9.4`**;运行 Node `/usr/bin/node 22.23.1` → **nvm `v26.8.2`**
> 更新:2026-09-16(本次为实测记录,含命令、证据与踩坑)
>
> ⚠️ 本文不写明文口令。凭据位置见 §7。
---
## 1. 架构总览
```
浏览器 / App
↓ https://bk02.baiji-algieba.ts.net tailscale serve443 终止 TLS
↓ 转发到本机回环
bk02: node 进程 127.0.0.1:18789 openclaw gateway
存储:~/.openclaw/state/openclaw.sqlite(共享状态)
~/.openclaw/agents/<id>/agent/openclaw-agent.sqlite(每 agent 会话/记忆)
```
| 项 | 值 |
|---|---|
| 服务单元 | `openclaw-gateway.service`**用户级** systemd`systemctl --user` |
| 监听 | `127.0.0.1:18789`+ `[::1]:18789`),不直接对外 |
| 对外入口 | `gateway.tailscale.mode = serve``https://bk02.baiji-algieba.ts.net` |
| 启动命令 | `/home/yangxuan/.nvm/versions/node/v26.8.2/bin/node --max-old-space-size=3913 <openclaw>/dist/index.js gateway --port 18789` |
| 插件 | 8 个 enableddingtalk-connector、feishu、memory-core、ollama、openclaw-weixin、searxng 等 |
| 状态目录 | `~/.openclaw`(本次清理前 2.6G,清理后 1.5G) |
---
## 2. 本次升级:2026.8.1 → 2026.9.4
### 2.1 阻塞点:Node 版本(先踩后解)
`openclaw update` 直接拒绝,原文:
```
Node 22.23.1 at /usr/bin/node is too old for openclaw@2026.9.4.
The requested package requires >=24.16.0 <25 || >=26.1.0
```
关键点:**gateway 服务实际用的是系统 `/usr/bin/node`22.23.1**,而 nvm 里的 `v25.9.0` **也不被支持**(要求排除整个 25.x)。
| Node | 版本 | 满足 2026.8.1 | 满足 2026.9.4 |
|---|---|---|---|
| 系统 `/usr/bin/node`(升级前在用) | 22.23.1 | ✅ | ❌ |
| nvm | v25.9.0 | ✅ | ❌(25.x 被排除) |
| nvm | **v26.8.2**(本次采用) | — | ✅ |
### 2.2 执行步骤(可复现)
```bash
# 1) 装 Node 26(用户级,不动系统 node —— 同机还有 VS Code Server 等依赖它)
export NVM_DIR=$HOME/.nvm; . $NVM_DIR/nvm.sh
nvm install 26 # → v26.8.2
nvm alias default 26 # 让新 shell 与 gateway 版本一致
# 2) 全局安装新版本(必须放行 install scripts,否则原生模块不构建,见 §3.1)
nvm use 26
npm i -g openclaw@2026.9.4 \
--allow-scripts=openclaw,@google/genai,koffi,tree-sitter-bash,protobufjs
# 3) 用官方命令重建服务定义,让 gateway 切到 Node 26
systemctl --user stop openclaw-gateway
openclaw daemon install # 自动检测并替换不支持的 Node,见下
```
`openclaw daemon install` 会自己发现并修掉旧 Node,原文输出:
```
Node 22.23.1: node:sqlite truncates TEXT at embedded NUL (nodejs/node#61954); use 24.16+/26.1+
Replacing unsupported Gateway service Node 22.23.1 (/usr/bin/node) with ~/.nvm/versions/node/v26.8.2/bin/node
Previous unit backed up to: ~/.config/systemd/user/openclaw-gateway.service.bak
```
> **顺带修掉一个数据隐患**Node 22 的 `node:sqlite` 存在「TEXT 遇内嵌 NUL 被截断」的已知 bugnodejs/node#61954)。
> 升级前每条含空字符的消息都可能被静默截断 —— 换到 Node 26 后不再发生(历史已截断的数据无法自动还原)。
```bash
# 4) 同步插件到同版本(doctor 会逐个点名)
openclaw plugins update feishu
openclaw plugins update @openclaw/searxng-plugin@2026.9.4
openclaw plugins update @openclaw/deepseek-provider@2026.9.4
openclaw gateway restart
```
### 2.3 验收证据(实测)
| 验证项 | 结果 |
|---|---|
| 版本 | `OpenClaw 2026.9.4 (3a9d69d)` |
| 运行 Node | `/proc/<pid>/exe → v26.8.2/bin/node` |
| 服务状态 | `active``NRestarts=0` |
| 启动日志 | `[gateway] ready``[tailscale] serve enabled: https://bk02.baiji-algieba.ts.net/` |
| 插件 | 6→8 个加载,`feishu`/`searxng`/`deepseek``2026.9.4` |
| 远端首页 | HTTP/2 **200**ttfb ≈ **0.139s** |
| 前端资源 | 压缩后 **348KB**(原始 1387KBBrotli),9 个资源并发 **0.160.79s** |
| WS 端点 | **200** |
| 数据完整性 | 12 个 agent 全在、36 个 SQLite 库、自动完成 v16/v17 状态迁移 |
---
## 3. 踩坑清单(复现时必读)
### 3.1 npm 11 会静默拦下 install scripts
首次 `npm i -g openclaw@2026.9.4` 虽然「成功」,但这些脚本**没执行**:
```
openclaw (postinstall: postinstall-bundled-plugins.mjs)
koffi (install: cnoke.cjs --prebuild) ← 原生模块
tree-sitter-bash (install: node-gyp-build) ← 原生模块
protobufjs / @google/genai
```
**必须带 `--allow-scripts=...` 重装**,否则运行时才暴露缺模块。
### 3.2 服务里的 Node 路径是硬编码的
`ExecStart` 记录的是绝对路径与具体 Node 版本目录。手工改 systemd 容易漏(`PATH` 环境变量里也含版本号),**优先用 `openclaw daemon install` 重建**,它会连带更新 `PATH`、保留原有 `Environment=` 注入。
### 3.3 两个命令需要显式 `--force`
| 命令 | 不加 force 的表现 |
|---|---|
| `openclaw gateway stop` | 拒绝:「This stops the operator's running gateway service… re-run with `--force`」 |
| `openclaw plugins uninstall <id>` | 交互确认;非交互环境需 `--force`**没有** `--non-interactive` 这个参数) |
---
## 4. 存储结论:只能用 SQLite(不能换 PG/MySQL
官方文档 `llms-full.txt` 原文:
> **SQLite remains the supported runtime store.** Preparation for PostgreSQL should improve the existing store owners and their tests **before adding a driver or configuration option**.
即 PG 支持**连驱动和配置项都还没有**,仅处于前瞻设计阶段。旁证:
| 检查 | 结果 |
|---|---|
| 官方文档 `mysql` / `mariadb` 命中 | **0 次 / 0 次** |
| 官方文档 `postgres` 命中 | 6 次,全在「Preparing for another database backend」一节 |
| 代码里 PostgreSQL/MySQL 字样来源 | **SQL 语法高亮方言**CodeMirror / kysely dialect)与报错文案,**非存储后端** |
| 实际驱动 | `node:sqlite`Node 内置,无外部依赖) |
| 存储位置 | `state/openclaw.sqlite` + `agents/<id>/agent/openclaw-agent.sqlite`(共 36 个库) |
**但是**:本机 docker 里的 pgsql / mysql **可以作为 agent 的工具数据源**(配置里 `"MySQL":{"enabled":true}` + `sql-toolkit`),这与「openclaw 自身存储」是两层,互不影响。
> 结论:想提升存储层,**升级 Node 比换数据库更实在**(§2.2 的 NUL 截断 bug 就是典型)。
---
## 5. 清理历史版本配置 / 缓存 / 残留
### 5.1 官方清理入口
| 目标 | 命令 | 备注 |
|---|---|---|
| 迁移「回滚原始文件」 | `openclaw update cleanup --dry-run` → 停机后 `openclaw update cleanup` | 官方专用于清理 upgrade 残留 |
| agent 库 VACUUM | `openclaw doctor --session-sqlite compact --session-sqlite-all-agents` | 需停机 |
| 共享状态库压缩 | `openclaw doctor --state-sqlite compact --json` | 需停机,会设置 `auto_vacuum=INCREMENTAL` |
| 列表/删除历史会话 | `openclaw sessions` | |
| 继承文件迁移 | `openclaw doctor --fix` | 会归档为 `<源>.migrated.<sha256>.<id>` |
| 卸载插件(含目录) | `openclaw plugins uninstall <id> --force` | |
停机维护的官方推荐顺序:
```bash
openclaw backup create --verify # 先备份(必做)
openclaw gateway stop --force
openclaw doctor --session-sqlite compact --session-sqlite-all-agents
openclaw doctor --state-sqlite compact --json
openclaw gateway start
```
### 5.2 本次清理成效(实测)
| 项目 | 手段 | 释放 |
|---|---|---|
| npm 缓存 | `npm cache clean --force` | **1.7 GB** |
| 旧版 Node 25(含 openclaw 2026.8.1 | `nvm uninstall 25.9.0` | **1.5 GB** |
| `memory-lancedb`disabled 插件) | `openclaw plugins uninstall memory-lancedb --force` | **950 MB** |
| 旧版本 UI 资源缓存 | 核对当前 build 引用后删旧 hash 目录 | **28 MB** |
| SQLite 空闲页 | 上述两个 compact | 2.9 MB |
| 重复 skill 目录 | 全量比对后移出 | 20 KB |
| 验证失败的备份包 | 删除 | 378 MB |
**根分区 26G/109G (26%) → 24G/109G (23%)**`~/.openclaw` 2.6G → 1.5G。
共享状态库 compact 实测输出(可作判据基线):
```json
{ "before": { "autoVacuum": 0, "dbSizeBytes": 15339520, "freelistPages": 435 },
"after": { "autoVacuum": 2, "dbSizeBytes": 12771328, "freelistPages": 0 },
"reclaimedBytes": 2568192, "integrityCheck": "ok" }
```
### 5.3 不能动的东西(官方设计,删了会出问题)
| 路径 | 为什么保留 |
|---|---|
| `openclaw.json.bak` + `.bak.1`~`.bak.4` | 官方**配置备份环**:任何配置写入都会轮转(`--fix` 亦然) |
| `openclaw.json.last-good` | 解析失败时的自动恢复源 |
| `openclaw.json.pre-update` | 升级前备份 |
| `agents/*/agent/*.sqlite` | 当前会话/记忆数据 |
| `~/.openclaw/.git` | 配置备份仓库(见 §6 |
### 5.4 边界:`update cleanup` 拒绝清理的那 525MB
`agents/*/session-sqlite-import-archive/` 下有 654 个 `*.imported-*`(约 **525MB**),是 2026-08-31 会话从 JSONL 迁入 SQLite 时的归档。官方 cleanup **拒绝清理**
```
Candidates: 0 bytes; verification required: 550782825; protected: 0; blocked: 0
原因: historical-manifest-without-import-proof
```
- `doctor --session-sqlite validate` / `dry-run` 均返回 `0 target(s)`:没有待导入的遗留源
- `compact` 报告 `archived-unreferenced-jsonl=0`openclaw 认为这些归档**仍被清单引用**
- 独立验证:`session_transcript_archives` 表用 **`archive_blob` BLOB 把内容存在库内**,全表**不引用外部文件路径** ⇒ 这些 JSONL 确如文档所述「**not runtime fallbacks**」(非运行时依赖),**删除不影响运行**,但会**永久失去降级回旧 JSONL 版本的能力**
**结论:暂不清理**(保留 525MB 换历史恢复能力)。若将来确认不需要降级,可手动删除该目录 —— 但官方不背书,删前务必备份迁移凭证 `session-sqlite-migration-runs/`
---
## 6. 备份、配置仓库与回滚
### 6.1 备份
```bash
openclaw backup create --verify --output ~/openclaw-backups
```
⚠️ 若 workspace 下存在**仅大小写不同**的重复目录(本次为 `skills/Obsidian``skills/obsidian`),`--verify` 会因 *portable path collision* **失败**。处理方式:
```bash
diff -r skills/obsidian skills/Obsidian # 确认内容一致(本次仅 .clawhub/origin.json 的安装元数据不同)
mv skills/Obsidian ~/openclaw-backups/removed-skills/ # 移出而非删除
```
### 6.2 配置仓库(Gitea
| 项 | 值 |
|---|---|
| 仓库 | `~/.openclaw`(工作区内的 git 仓库,分支 `314` |
| remote | `https://gitea.climbcube.cn/yangxuan/openclaw-config.git` |
| 自动提交 | `auto-commit-config.sh`,每 6 小时 `git add -A` + commit + push,无变更则跳过 |
| 提交信息 | `auto: sync OpenClaw config <时间>` / `auto: agent DB backup <日期>` |
**体积治理(本次)**`.git` 曾达 199M / 249 次提交。根因**不是** SQLite`.gitignore` 已忽略 `*.sqlite`),而是 workspace 里的大数据文件被自动提交并推送:
```
90.2 MB workspace-juaner/data/私聊_王芳.json
36.9 MB workspace-juaner/data/私聊_王芳.jsonl
11.7 MB agents/*/session-sqlite-import-archive/*.imported-*
```
⚠️ **隐私提示**`.gitignore` 原未忽略 `workspace-*/data/`,导致私聊内容进入 git 历史并推送到 Gitea。
已加固 `~/.openclaw/.gitignore`
```gitignore
workspace-*/data/
agents/*/session-sqlite-import-archive/
```
`git rm -r --cached`(保留本地文件)使既有大文件脱离跟踪,后续提交不再增长。**历史重写(filter-repo)未做**,如需彻底清除需另行评估(会与 remote 冲突,需 force push)。
### 6.3 回滚
```bash
# 服务定义
cp ~/.config/systemd/user/openclaw-gateway.service.bak ~/.config/systemd/user/openclaw-gateway.service
nvm install 25.9.0 && nvm exec 25.9.0 npm i -g openclaw@2026.8.1
systemctl --user daemon-reload && systemctl --user restart openclaw-gateway
```
> 注意:本次已删除 nvm `v25.9.0`1.5G)与 `memory-lancedb`**回滚需重新下载**`~/openclaw-backups/` 内的验证备份(351MB,不含 workspace)仍可恢复数据。
---
## 7. 凭据与密钥位置(不含明文)
| 用途 | 位置 |
|---|---|
| gateway 认证 | `~/.openclaw/openclaw.json``gateway.auth`password 模式) |
| 机主登录 | 由机主掌握;本机 `~` 用户 `yangxuan` |
| 模型 / 渠道密钥 | `~/.openclaw/.env``openclaw.json``secrets` 段(systemd 以 `OPENCLAW_SERVICE_MANAGED_ENV_KEYS` 注入) |
| 备份包 | `~/openclaw-backups/*.tar.gz`(含凭据,勿外发) |
---
## 8. 遗留观察点
1. **`.git` 仍为 199M** —— 索引清理只阻止未来增长,历史未重写。
2. **525MB 迁移归档保留**(§5.4),如需释放需人工决策。
3. **skill 重名冲突 5 条**`weather`/`obsidian`/`blogwatcher`/`mcporter`/`baidu-text-translate`):workspace 覆盖 bundled,属**设计内优先级行为**,非错误,可不管。
4. **gateway 重启频率**:升级前曾出现单日 5 次重启(2026-09-15),重启后 20 秒内 RPC 会达 1.5–4.4s(冷启动),稳态 0 次慢调用。若再遇「打开很慢」,先查是否落在重启窗口。
5. **链路**wit01 ↔ bk02 走 DERP 中继(`MappingVariesByDestIP: true`,对称 NAT),实测首屏 0.160.79s,服务端本身 < 10ms。