数据韧性
wesgine 的三层数据库架构确保单层损坏不扩散,Cell Boot 永远成功,数据可恢复。
三层 SQLite
每个 Cell 使用三个独立的 SQLite 数据库:
| 数据库 | 内容 | 损坏影响 |
|---|---|---|
meta.db | Cell 元数据、Agent 配置 | 丢失配置,可重建 |
state.db | 运行时状态、Traces、Cron | 丢失历史记录 |
sessions.db | 会话、消息、记忆 | 丢失对话和记忆 |
隔离保证
单层损坏不扩散(INV-RESIL-03):
sessions.db损坏不影响state.db的 Traces 和 Observestate.db损坏不影响sessions.db的会话和记忆meta.db损坏不影响其他两层
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):
- 使用
flock文件锁(.cell.lock) - 防止多进程同时操作同一 Cell
快照与备份
自动快照
# 触发快照
POST /cells/{id}/checkpoint
快照使用 VACUUM INTO(原子操作),每次快照后自动 PRAGMA quick_check,损坏快照直接丢弃。
导出备份
# 完整导出
GET /admin/cells/{id}/export
# 导入恢复
POST /admin/cells/import
SQLite 安全配置
wesgine 对 SQLite 使用严格的安全配置:
| 配置 | 值 | 原因 |
|---|---|---|
mmap_size | 0 | 禁用 mmap,消除 SQLITE_IOERR_MMAP |
| VACUUM | 仅在 Backup 中 | VACUUM 中断 = 数据全损 |
| Journal | WAL 模式 | 只追加,不 truncate |
迁移
所有 schema 迁移必须幂等(INV-RESIL-10)——重跑 N 次结果一致。
主 DB 迁移
平台核心表通过 internal/db/migrations/*.sql 管理,按文件名排序执行。
辅助 Migrate()
各子系统独立管理自己的表,使用 CREATE TABLE IF NOT EXISTS + ALTER TABLE ADD COLUMN(吞 duplicate column 错误)策略。
损坏恢复
当数据库损坏时:
- 损坏文件归档到
corrupt/目录(不直接删除) - 创建全新的空数据库
- Cell 以降级模式启动
- 新数据写入新库
损坏文件保留供运维诊断(INV-RESIL-07)。