数据备份与恢复
WesCraft 的数据安全架构基于 wesgine 的三层 SQLite 韧性模型,支持自动降级、快照验证和完整的 Cell 导出/导入。
数据目录结构
WesCraft 的所有数据存储在 XDG 规范目录下:
$XDG_DATA_HOME/wescraft/
│ # macOS: ~/Library/Application Support/wescraft/
│ # Linux: ~/.local/share/wescraft/
│
├── hypervisor.db # Hypervisor 层:Cell 注册表
│
├── cells/personal/ # Cell 数据(个人版)
│ ├── meta.db # Layer 1: Cell 元数据
│ ├── sessions.db # Layer 2: 会话与记忆
│ ├── state.db # Layer 3: 运行时状态(Traces/Observe)
│ ├── knowledge/ # 知识库文件
│ ├── skills/ # Tier C 技能包
│ ├── .scratch/ # 临时计算域(Run 结束后 GC)
│ └── .cell.lock # 进程排他锁
│
├── wescraft.db # 应用层数据
│ # 页面、Block、收集箱、任务、文件索引等
│ # 12+ 表 + 2 FTS5 虚拟表 + 触发器
│
└── db/wescode_auth.db # 登录 session(跨 Cell 共享)
三层 SQLite 架构
| 层 | 数据库 | 内容 | 损坏影响范围 |
|---|---|---|---|
| Layer 1 | meta.db | Cell 元数据、Agent 配置 | 不影响 sessions/state |
| Layer 2 | sessions.db | 会话、消息、记忆 | 不影响 meta/state |
| Layer 3 | state.db | 运行时追踪、观测数据 | 不影响 meta/sessions |
INV-RESIL-03:单层损坏不扩散。sessions.db 损坏不影响 memory/observe;state.db 损坏不影响 sessions。
Cell Export / Import
导出整个 Cell
# 通过 API 导出
GET /cells/{cellID}/export
→ 返回 tar.gz 流
# 通过管理端点导出
GET /admin/cells/{cellID}/export
→ 返回 tar.gz 流
导出包含:
| 内容 | 包含 | 说明 |
|---|---|---|
| meta.db | ✅ | Cell 元数据 |
| sessions.db | ✅ | 会话和记忆 |
| state.db | ✅ | 运行时状态 |
| workspace/ | ✅(可选跳过) | 工作区文件 |
| knowledge/ | ✅ | 知识库 |
| skills/ | ✅ | 技能包 |
| .scratch/ | ❌ | 永不包含 |
导入 Cell
# 从 tar.gz 恢复
POST /admin/cells/import
Content-Type: application/gzip
Body: <tar.gz 文件>
Query: ?overwrite=1 # 可选:覆盖已存在的 Cell
使用场景
- 设备迁移:换电脑时完整迁移工作数据
- 定期备份:脚本化定期导出,防止数据丢失
- 团队分发:管理员配置好 Cell 后分发给成员
数据库安全
进程排他锁
INV-RESIL-04:同一 Cell 同一时刻只有一个写入者。通过 flock(.cell.lock) 实现:
Cell 目录/
└── .cell.lock # 进程级排他锁
如果遇到 ErrCellLocked 错误,说明有其他进程正在使用该 Cell。
mmap 禁用
INV-RESIL-08:PRAGMA mmap_size=0 消除整类 SQLITE_IOERR_MMAP 故障。WesCraft 的所有 SQLite 连接都禁用了 mmap。
VACUUM 安全
INV-RESIL-09:VACUUM 中断等于全损。WesCraft 不执行自动 VACUUM,只在 SQLiteBackup(VACUUM INTO)中使用。
快照验证
PRAGMA quick_check
INV-RESIL-05:每次快照后立即执行 PRAGMA quick_check,损坏的快照直接丢弃:
-- 快照验证流程
VACUUM INTO '/path/to/snapshot.db' -- 原子快照
PRAGMA quick_check -- 完整性验证
-- 验证失败 → 丢弃快照 + 告警
SQLiteBackup
使用 VACUUM INTO 实现原子快照,是唯一安全的备份方式。
禁止的备份方式:
| 方式 | 问题 |
|---|---|
cp *.db | 忽略 -wal / -shm,数据不一致 |
| 只拷单个 DB | Cell 有 meta/sessions/state 三个 DB |
VACUUM | 中断等于全损 |
损坏恢复
Boot 永远成功
INV-RESIL-01:无论何种数据损坏,Boot 都返回 nil error。降级是合法状态:
启动 → 检测到损坏 → 降级启动(标记 Degraded)→ 新请求正常处理
唯一的 boot 失败是 ErrCellLocked(进程竞争,非数据问题)。
INV-RESIL-02
Runtime().Run() 永远可用。降级只影响历史数据访问,不影响新请求处理。
损坏文件保留
INV-RESIL-07:损坏的 DB 文件归档到 corrupt/ 目录供诊断,不直接删除:
cells/personal/
├── meta.db # 当前(可能是新建的)
├── sessions.db
├── state.db
└── corrupt/
├── meta.db.20260914_200000 # 损坏的原始文件
└── sessions.db.20260901_...
Journal 只追加
INV-RESIL-06:Journal 文件没有 seek/truncate,只有 O_APPEND 写入。保证故障恢复数据的完整性。
迁移管理
INV-MIGRATE-01 机制
wescraft.db 的每一次 schema 变更对应一个 MigrationStep:
// internal/store/appdb_migrations.go
type MigrationStep struct {
Version int
Name string
Migrate func(tx *sql.Tx) error
}
Boot 时执行流程:
1. 读取 PRAGMA user_version
2. 按序执行未应用的步骤
3. 每步一个事务:DDL + PRAGMA user_version = N + commit
4. 全部成功 → DB 可用
降级策略
迁移步骤失败
→ 关闭 DB
→ 归档旧文件为 .migration-failed
→ 清除 -wal / -shm
→ 重新打开全新 DB
→ 再次执行完整迁移链
→ 第二次失败 → fatal error
代价:丢失页面、数据库、采集箱、任务、文件索引等数据。但远好过启动崩溃——用户可以重新配置。
wescraft.db 迁移
当前 V1 迁移包含:
| 内容 | 数量 |
|---|---|
| 业务表 | 12+ |
| FTS5 虚拟表 | 2 |
| 触发器 | 若干 |
| 索引 | 若干 |
RebuildFTS:每次 boot 时执行 FTS5 重建安全网,确保全文搜索索引与数据一致。
迁移与幂等
INV-RESIL-10:所有迁移全幂等。任何迁移重跑 N 次结果一致。FTS5 虚拟表使用 sqlite_master 存在性检查(部分 SQLite 构建不支持 CREATE VIRTUAL TABLE IF NOT EXISTS)。
备份建议
定期备份
# 方式一:Cell Export(推荐)
curl -o backup-$(date +%Y%m%d).tar.gz \
http://localhost:3100/admin/cells/personal/export
# 方式二:文件级备份(注意三件套)
# 必须同时备份 .db + .db-wal + .db-shm
cp -a ~/Library/Application\ Support/wescraft/ \
~/Backups/wescraft-$(date +%Y%m%d)/
备份清单
| 文件 | 必须备份 | 说明 |
|---|---|---|
hypervisor.db | ✅ | Cell 注册信息 |
cells/personal/meta.db | ✅ | Cell 元数据 |
cells/personal/sessions.db | ✅ | 会话和记忆 |
cells/personal/state.db | ⚠️ | 可重建但包含历史追踪 |
wescraft.db | ✅ | 应用层核心数据 |
cells/personal/knowledge/ | ✅ | 知识库文件 |
cells/personal/skills/ | ⚠️ | 可重装 |
config.yaml | ✅ | 用户配置 |
恢复流程
- 停止 WesCraft
- 替换数据目录下的文件
- 启动 WesCraft
- 系统自动检测数据状态
- 必要时执行迁移或降级启动
注意事项
- 不要在运行时直接复制 DB 文件:使用 Cell Export 或先停止应用
- 备份三件套:
.db+.db-wal+.db-shm必须同时备份 - 测试恢复:定期测试备份的可恢复性
- 异地存储:重要数据建议异地备份(云存储/外部硬盘)