数据韧性

wesgine 的三层数据库架构确保单层损坏不扩散,Cell Boot 永远成功,数据可恢复。

三层 SQLite

每个 Cell 使用三个独立的 SQLite 数据库:

数据库内容损坏影响
meta.dbCell 元数据、Agent 配置丢失配置,可重建
state.db运行时状态、Traces、Cron丢失历史记录
sessions.db会话、消息、记忆丢失对话和记忆

隔离保证

单层损坏不扩散(INV-RESIL-03):

Boot 永远成功

Cell Boot 永远返回 nil error(INV-RESIL-01):

无论数据如何损坏,Cell 总能启动。损坏的层进入降级(Degraded)状态,其他层正常工作。唯一的 Boot 失败是 ErrCellLocked(进程竞争,非数据问题)。

降级行为

正常 Cell:
  meta.db ✅ → state.db ✅ → sessions.db ✅

降级 Cell(sessions.db 损坏):
  meta.db ✅ → state.db ✅ → sessions.db ⚠️ Degraded
  
  Runtime().Run() 仍然可用 ← 新对话正常
  Memory().List() 返回空    ← 历史记忆不可访问
  Sessions().List() 返回空  ← 历史会话不可访问

进程排他锁

同一 Cell 同一时刻只有一个写入者(INV-RESIL-04):

快照与备份

自动快照

# 触发快照
POST /cells/{id}/checkpoint

快照使用 VACUUM INTO(原子操作),每次快照后自动 PRAGMA quick_check,损坏快照直接丢弃。

导出备份

# 完整导出
GET /admin/cells/{id}/export

# 导入恢复
POST /admin/cells/import

SQLite 安全配置

wesgine 对 SQLite 使用严格的安全配置:

配置值原因
mmap_size0禁用 mmap,消除 SQLITE_IOERR_MMAP
VACUUM仅在 Backup 中VACUUM 中断 = 数据全损
JournalWAL 模式只追加,不 truncate

迁移

所有 schema 迁移必须幂等(INV-RESIL-10)——重跑 N 次结果一致。

主 DB 迁移

平台核心表通过 internal/db/migrations/*.sql 管理,按文件名排序执行。

辅助 Migrate()

各子系统独立管理自己的表,使用 CREATE TABLE IF NOT EXISTS + ALTER TABLE ADD COLUMN(吞 duplicate column 错误)策略。

损坏恢复

当数据库损坏时:

  1. 损坏文件归档到 corrupt/ 目录(不直接删除)
  2. 创建全新的空数据库
  3. Cell 以降级模式启动
  4. 新数据写入新库

损坏文件保留供运维诊断(INV-RESIL-07)。