数据韧性架构

wesgine 三层 SQLite 数据模型与 10 条韧性不变量。


三层 DB 架构

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

层文件内容损坏影响
meta.dbCell 元数据配置、Agent、Skill 状态不影响 sessions/state
sessions.db会话数据Memory、Sessions不影响 meta/state
state.db运行时状态Traces、Observe、Cron不影响 meta/sessions

INV-RESIL-03:单 Layer 损坏不扩散。


Cell 数据目录

{DataDir}/cells/{ID}/
├── meta.db
├── sessions.db
├── state.db
├── skills/
├── knowledge/
├── workspace/{actor}/
├── .scratch/{runID}/
└── .cell.lock

10 条韧性不变量

INV-RESIL-01:Boot 永远成功

无论何种数据损坏,Boot 都返回 nil error。降级是合法状态。

唯一的 boot 失败:ErrCellLocked(进程竞争,非数据问题)。

INV-RESIL-02:Run 永远可用

Runtime().Run() 永远可用。降级只影响历史数据访问。

INV-RESIL-03:单层不扩散

sessions.db 损坏不影响 memory/observe;state.db 损坏不影响 sessions。

INV-RESIL-04:进程排他锁

同一 Cell 同一时刻只有一个写入者:

flock .cell.lock

INV-RESIL-05:快照验证

每次快照后立即 PRAGMA quick_check,损坏快照丢弃。

INV-RESIL-06:Journal 只追加

Journal 文件没有 seek/truncate,只有 O_APPEND 写入。

INV-RESIL-07:损坏文件保留

损坏 DB 归档到 corrupt/ 目录供诊断,不直接删除。

INV-RESIL-08:mmap 禁用

PRAGMA mmap_size=0

消除整类 SQLITE_IOERR_MMAP 故障。

INV-RESIL-09:VACUUM 禁止自动

VACUUM 中断 = 全损。只在 SQLiteBackup(VACUUM INTO)中使用。

INV-RESIL-10:迁移全幂等

任何迁移重跑 N 次结果一致(含多语句 ADD COLUMN)。


快照与备份

SQLiteBackup

resilience.SQLiteBackup(srcPath, dstPath)

使用 VACUUM INTO 原子快照,快照后立即 quick_check。

禁止的备份方式

# ❌ 忽略 -wal / -shm,或只拷一个文件
cp cell.db cell.db.bak

# ✓ 使用 SQLiteBackup

Cell 有 meta.db / state.db / sessions.db 三个数据库,必须全部备份。


降级启动

当某一层数据库损坏时:

Boot
 ↓ meta.db 损坏?
 ↓ 标记 Degraded,继续启动
 ↓ sessions.db 损坏?
 ↓ 标记 Degraded,继续启动
 ↓ 所有层就绪
 ↓ Boot 返回 nil

降级 Cell:


DSN 配置

所有 SQLite 连接必须包含:

?_pragma=mmap_size(0)&_pragma=journal_mode(WAL)

相关文档