跳转到内容

从旧版 SQLite 分片升级

启动时会恢复中断的重新嵌入交换、将 libSQL DiskANN 索引转换为当前 Turso 引擎,然后验证或升级旧版分片 schema。即使存储已有完成的旧版迁移标记,引擎转换仍会运行,并在不重新嵌入的情况下保留已存储向量。每个转换后的数据库会备份为 <database>.pre-tursodb-<timestamp>.bak。

在 macOS 与 Linux 上,多个 OpenCode 会话可通过 Turso 的实验性 multiprocess_wal 共享同一 storagePath(每个进程必须使用相同模式 — 升级后请重启所有会话)。在 Windows 上引擎会拒绝该标志,因此同一时间只能有一个 OpenCode 会话拥有记忆数据库。

tursoMultiprocessWal: false 改为单所有者模式打开:其他进程会以 database is locked 失败,而不是共享存储。若非插件工具会触碰相同文件,这更安全——因为_正在写入_的外部 SQLite 进程会使 Turso 的 WAL 索引过期,随后本进程的下一次写入会静默丢失。tursoAutoHeal(默认 true)在因过期 WAL 索引导致打开失败时,会在验证主数据库副本后,将存储的 -shm/-tshm 索引旁路文件移到 storagePath/recovery/<db>-<timestamp>/ 并重试一次。非空 -wal 永不移动,因此已提交但未检查点的事务得以保留;仅删除缺失或 0 字节的 -wal。并发会话通过 storagePath/recovery/<db>.lock 串行化修复。

升级后首次启动时,opencode-mem 会自动将现有记忆分片数据库迁移为原生 Turso/libSQL 向量格式:

  • 每个分片在重写前备份为 <shard>.db.legacy.bak
  • 进度按分片记录在 <shard>.db.turso-migrate.json
  • 仅在所有分片验证成功后才写入全局标记 .turso-migrated
  • 普通插入与删除不会使已完成的分片迁移失效;启动时仍会检查向量可读且与已存维度匹配
  • 迁移期间请勿对同一 storagePath 运行多个 OpenCode 实例;锁文件(.turso-migrate.lock)可防止并发迁移
  • 手动维度迁移使用 .turso-operation.lock;在迁移完成前,其他插件进程会拒绝新的记忆写入
  • 若 30 分钟内没有进度时间戳更新(若无时间戳则看文件修改时间),锁会过期,即使持有进程仍在运行。该租约使用挂钟时间:向前拨钟超过 30 分钟可能使进行中的操作过早过期;向后拨钟或未来日期的锁可能延长空闲锁寿命。锁带有唯一获取 id,过期清理只删除其检查过的那个文件。迁移过程会发送心跳,一旦发现所有权丢失即中止。过期锁清理会写入日志以便诊断。

若迁移被中断,下次启动会自动从备份恢复。

若分片变得不兼容(例如更改 embeddingDimensions 之后),写入会被阻止,且原始数据库保持不变。请使用 Web UI 的重新嵌入迁移来构建并验证替换项,然后再交换到位。先前的分片仍可作为 <shard>.db.pre-reembed-<pid>-<timestamp>.bak 使用。