OpenClaw 从 9.6 降级到 7.35:插件版本不匹配与 SQLite 不兼容的处理记录
背景
9 月 26 日晚上,我把 OpenClaw 从 2026.9.6 降级到 2026.7.35。
起因是性能。9.6 上线后,网关内存常态性顶到 1.5 GiB 的警戒线,会话列表偶发两秒多的慢查询,微信、WebChat、控制台的响应都明显变慢。这不是个例:上游 issue #155191 报告 9.5 起存在 native 内存泄漏,至今未关闭;#157791 报告 9.6 启动后 RSS 快速冲破 1.5 GiB;而 9.6 的 release notes 里没有任何内存或性能修复条目——等热修没有明确时间表。
权衡之后选择退回 7.x LTS 线,先保证稳定,等上游修复性能问题再考虑升级。
升级的文章很多,降级的很少。但降级的风险高于升级:升级有官方迁移脚本兜底,降级则要面对「新版本写入的数据、旧版本无法识别」的问题。这次实际遇到两个,以下分别记录。
问题一:插件与运行时版本不匹配
现象
切换到 7.35 并启动后,网关正常运行,但 tavily(搜索)、deepseek、volcengine(火山)三个插件全部异常,对应功能不可用。
原因
这三个插件安装于 9.x 时期,代码依赖 9.x 的运行时 API。降级后运行时回到 7 月版本,插件仍为 9 月版本,接口签名对不上,加载即失败。
该问题的实际影响大于后续的 SQLite 问题,因为它是显性的:功能当场失效,且报错位置分散。排查期间,部分错误表现为某个模型渠道返回 400/401,极易误导方向——实际上需要检查的是订阅状态和端点配置,与插件无关的错误会消耗大量时间。
处理步骤
处理原则是卸载干净后重装,不做就地升级——版本跨度较大时,就地升级的可靠性不足。
这里有一个前提要先说清楚:网关起不来的状态下,openclaw plugins 系列命令不可用。这些命令需要与运行时交互(升级期间就出现过 plugins update 报 runtime application failed 的情况),运行时本身是坏的,命令自然跟着失败。所以修复分两个阶段:网关起不来时用离线手段处理,网关恢复后再用 CLI 重装。
阶段一:网关起不来(离线处理)
第一步:直接编辑配置,禁用问题插件。
不经过任何 OpenClaw 命令,用编辑器打开 ~/.openclaw/openclaw.json,找到 plugins.entries 段(本例有 32 个条目),把出问题的插件改为 false:
"plugins": {
"entries": {
"deepseek": { "enabled": false },
"volcengine": { "enabled": false },
"tavily": { "enabled": false }
}
}
找不到对应条目就直接新增,改完确认 JSON 语法合法(python3 -m json.tool < openclaw.json 可以快速校验)。
第二步:手动清理已安装插件的残留。
独立安装的插件存放在 ~/.openclaw/npm/projects/ 目录,目录名带 hash 后缀:
ls ~/.openclaw/npm/projects/
# 例如:openclaw-deepseek-provider-2481ed984b
直接删除(或改名加后缀,保留可恢复性)目标插件目录。本次实际操作就是改名隔离,目录至今保留着 .bak96-20260927014540 后缀:
mv ~/.openclaw/npm/projects/openclaw-deepseek-provider-2481ed984b{,.bak}
注意:目录名与插件 ID 不一定完全对应(如 volcengine 的目录名含生成流水号),用 hash 或关键词模糊匹配即可。内置(stock)插件不在这个目录,只需第一步的配置禁用。
第三步:启动网关并核对。
openclaw status # 确认网关能正常启动
openclaw plugins list # 确认目标插件已消失,或 Status 为 disabled
阶段二:网关恢复后(CLI 重装)
第四步:用 CLI 重装匹配版本的插件。
此时运行时已恢复正常,plugins 命令可用:
openclaw plugins install <插件规格> # npm 包名 / 路径 / git 仓库 / clawhub: 包
openclaw plugins enable deepseek # 配置中重新启用
openclaw plugins list # 核对 Version 已更新、Status 为 enabled
若安装过程中报错,用 openclaw plugins doctor 查看加载失败原因。
步骤顺序不可调换。若不先清理残留,新安装的版本可能被旧文件覆盖,出现「装了但仍是旧版」的情况,这类问题排查成本很高;若不先禁用即启动,失败的插件会干扰启动过程,使错误来源难以区分。
小结
- 降级前的检查清单应包含插件兼容性,与 schema 兼容性同等重要。公开资料普遍只讨论数据兼容,插件这一层容易遗漏;
- 诊断方向的判断依据:三个功能无关的插件同时失效,共同依赖(运行时版本)发生变化的概率远大于三个插件各自出问题。此时应优先核对版本依赖,而非逐个排查插件。
问题二:SQLite 跨版本不兼容
三层不兼容
9.6 与 7.35 之间存在存储架构差异:9.6 将会话历史写入 openclaw-agent.sqlite;7.35 的会话存储为 sessions.json 加 jsonl 转录文件,源码中不读取该 sqlite 库。
实测不兼容分三层,严重程度依次递增:
- state 库:
user_version为 18,7.35 支持 1。启动时报uses newer schema version错误,但进程不退出,status可正常输出; - agent 会话库:schema 版本 23,7.35 直接跳过读取。
sessions list返回空,38 个会话静默消失——无报错、无崩溃。此类静默失效若不主动验证,难以发现; - 启动检测:网关启动时被主动拦截,报错
Refusing to run automatic gateway startup migrations because this binary is older than the config last written by ...。7.35 内置降级检测,需设置OPENCLAW_ALLOW_OLDER_BINARY_DESTRUCTIVE_ACTIONS=1方可继续。
为何放弃「导出再导入」
初始方案是将旧库会话导出,再导入新版本。调研后放弃,原因有二。
其一,工具不匹配。9.6 的 sessions export-trajectory 导出的是脱敏轨迹,不是可还原的会话数据;而 7.35 没有对应的导入目标——它的会话存储根本不是 sqlite,导出数据无处可放。
其二,价值排序。跨版本数据搬运的风险与工作量都不小,而数据分两类:会话历史属于过程记录,MEMORY.md 与 memory/*.md 下的记忆文件才是持续使用的资产。前者可放弃,后者必须完整迁移。
实际方案
- 旧会话原样保留:完整备份 sqlite 库(含 38 个会话),7.35 不读取即不读取,将来回到 9.x 仍可找回;
- 记忆文件直接迁移:
MEMORY.md、memory/*.md等纯文本 rsync 到新环境,执行openclaw memory index重建向量索引。实测 93 个文件、1668 个 chunk,耗时约两个半小时,期间系统正常使用,仅记忆检索暂时不可用; - 配置字段转换:生产配置中 6 处字段 7.35 不识别(
meta.migrations、ui.prefs、modelPolicy与fastModeDefault、controlUi.sessionObserver、memory.search需迁移为agents.defaults.memorySearch、agents.entries需改为agents.list数组结构),逐项修剪后通过config validate。
小结
- 降级的数据策略应是「迁移知识文本,不迁移数据库」。数据库结构跟随版本,知识以 markdown 形式存在时,迁移主动权始终在自己手里;
- 重建索引的成本可控。本地 embedding 模型处理 1668 个 chunk 耗时约两小时,后台执行,不阻塞其他功能;
- 对静默失效保持警惕:不报错不等于正常。降级后必须主动验证会话列表、记忆检索、定时任务是否完好。本次即发现 cron 定时任务表在重启后被清空,最终从当日备份库中找回 5 个任务。
两个附带发现
配置存在双源。 openclaw.json 是配置源头,agents/<id>/agent/models.json 是运行时派生文件,两者可能不一致。排查模型渠道报错时曾耗时数小时,最终定位为派生文件中 provider 级 baseUrl 仍指向已废弃端点——修改源头文件不会立即生效,需重启使运行时重新生成。排查模型配置问题时,两个文件需同时核对。
MCP 服务器为网关级单实例。 所有会话共享同一进程,并非每会话独立。本次遇到两例:其一,MCP 服务器可执行文件目录被整体删除,报 write EPIPE,重装后恢复;其二,设备码授权在命令行侧完成、token 已写入缓存后,网关侧进程仍持有旧的 pending 状态,mcp reload 不生效,需终止进程强制重建连接。
结语
降级至 7.35 后运行稳定,性能问题消失。代价同样明确:会话历史暂不可读、配置做了 6 处裁剪、三个插件重装。
流程上,本次正确的是先备份(配置、数据库、镜像三件套)再操作,以及用配置变体二分法预检兼容性;不足在于未提前核查插件兼容性,使其成为耗时最长的问题。
下次若再执行降级,检查清单应为五项:镜像是否存在、schema 是否兼容、插件是否对版、配置能否通过 validate、备份是否完整。五项全部确认后再动手。