From ebc140e2d1218521b2ca79de4953cee55cbf2c41 Mon Sep 17 00:00:00 2001 From: openclaw-314 Date: Wed, 16 Sep 2026 10:47:45 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=96=B0=E5=A2=9E=20openclaw=20?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=E4=B8=8E=E7=BB=B4=E6=8A=A4=E6=89=8B=E5=86=8C?= =?UTF-8?q?=EF=BC=88Node=2022=E2=86=9226=20/=20OpenClaw=202026.9.4=20/=20?= =?UTF-8?q?=E6=B8=85=E7=90=86=E4=B8=8E=E5=AD=98=E5=82=A8=E7=BB=93=E8=AE=BA?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/openclaw-升级与维护.md | 302 ++++++++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 docs/openclaw-升级与维护.md diff --git a/docs/openclaw-升级与维护.md b/docs/openclaw-升级与维护.md new file mode 100644 index 0000000..5dd6991 --- /dev/null +++ b/docs/openclaw-升级与维护.md @@ -0,0 +1,302 @@ +# openclaw 升级与维护运维手册(bk02) + +> 主机:**bk02** / `xuan-asus-nj`(Debian 12 bookworm,`192.168.3.14`,tailscale `100.115.195.192`) +> 组件:OpenClaw Gateway(用户级 systemd)+ tailscale serve(HTTPS 入口) +> 版本: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 serve,443 终止 TLS) + ↓ 转发到本机回环 +bk02: node 进程 127.0.0.1:18789 (openclaw gateway) + ↓ +存储:~/.openclaw/state/openclaw.sqlite(共享状态) + ~/.openclaw/agents//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 /dist/index.js gateway --port 18789` | +| 插件 | 8 个 enabled:dingtalk-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 被截断」的已知 bug(nodejs/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//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**(原始 1387KB,Brotli),9 个资源并发 **0.16–0.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 ` | 交互确认;非交互环境需 `--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//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..` | +| 卸载插件(含目录) | `openclaw plugins uninstall --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.16–0.79s,服务端本身 < 10ms。