数据库与存储
完整规格见 00-product-spec.md
PostgreSQL 的角色
Section titled “PostgreSQL 的角色”PostgreSQL 不是 YZOS 的产品本体,而是给本地 AI 检索加速的索引层:
| 用途 | 说明 |
|---|---|
| 混合检索 | 上层 AI 通过 MCP 查询 memory/knowledge,PostgreSQL 以毫秒级返回 FTS + pgvector 结果 |
| 关系查询 | 活动、AI 工具会话、联系人、语音片段之间的 JOIN |
| Rollup 加速 | 日/周摘要预聚合,避免每次从原始数据重新扫描 |
| 维护操作 | 定时 REINDEX / VACUUM / 一致性对账 |
OKF Markdown 文件是数据真源。数据库损坏或丢失时,可通过对账 ${paths.contexts}/*/knowledge/ 与 memory/ 全量重建。
存储路径可配置:PostgreSQL 数据目录、OKF 文件、原始观察数据、模型权重均可在 config.yaml 的 paths 段单独指定(默认全部展开在 ~/.yzos/ 下)。详见下文“存储路径”与 13-inference-and-dependencies.md 第 3.7 节。
YZOS 采用嵌入式 PostgreSQL 18.4(postgresql_embedded = 0.20.4)搭配 pgvector 0.8.3。PGLite 作为远期轻量化备选。
扩展清单、halfvec 加速、中文全文检索、连接池与版本锁定详见 13-inference-and-dependencies.md 第 6 节。
候选方案对比
Section titled “候选方案对比”方案 A:嵌入式 PostgreSQL(已采用)
Section titled “方案 A:嵌入式 PostgreSQL(已采用)”// paths.database 来自配置,启动时解析为绝对路径let settings = SettingsBuilder::new() .data_dir(config.paths.database) // 默认 ~/.yzos/pg,可迁移到外置存储 .port(0) .username("yzos") .password(&keychain_secret) .temporary(false) .build();| 维度 | 评分(满分 5) |
|---|---|
| pgvector + FTS | 5 分,原生支持 |
| 维护操作 | 5 分,REINDEX / VACUUM / ANALYZE 齐全 |
| Rust 生态 | 5 分,sqlx 成熟 |
| macOS 支持 | 5 分,覆盖 aarch64 与 x86_64 |
| 体积 | 3 分,约 35MB |
方案 B:PGLite
Section titled “方案 B:PGLite”进程内 WASM 版 PostgreSQL,体积小,但桌面端重负载下的表现与 pgvector 性能尚未验证,作为 v2 轻量化备选方案跟踪。
方案 C:SQLite
Section titled “方案 C:SQLite”已排除。多源 JOIN、pgvector、并发写入与维护操作(REINDEX)等能力不足以支撑此场景。
flowchart TD
OBS["Observe"] --> CRY["Crystallize"]
CRY --> OKF["OKF Writer"]
OKF --> FILES["OKF Markdown files (source of truth)"]
FILES --> IDX["Indexer"]
IDX --> PG[("PostgreSQL index")]
FW["File Watcher (manual edits / kb_reorganize)"] -->|"re-index"| IDX
REC["Cron reconcile"] -->|"reconcile"| FILES
REC -->|"reconcile"| PG
写入时索引(实时)
Section titled “写入时索引(实时)”Triage 将事件结晶为 OKF 文件,索引器分块、生成 embedding,并 UPSERT 进 chunks 表。
定时维护(Cron)
Section titled “定时维护(Cron)”| 任务 | 频率 | 操作 |
|---|---|---|
reindex |
每周 | 对 HNSW 与 GIN 索引执行 REINDEX INDEX CONCURRENTLY |
vacuum |
每天 | 对高频表执行 VACUUM ANALYZE |
embedding_refresh |
每周 | 模型升级后重新生成 embedding |
reconcile |
每天 | 对账 OKF 哈希与 PostgreSQL,补建缺失索引 |
rollup_daily |
每天 02:00 | 预聚合日摘要 |
rollup_weekly |
每周一 03:00 | 预聚合周摘要 |
上层 AI 调用 MCP 工具,PostgreSQL 执行混合检索(向量与全文检索的 RRF 融合),返回 chunks 及对应的 OKF 文件路径。
PostgreSQL 配置
Section titled “PostgreSQL 配置”-- 必需CREATE EXTENSION IF NOT EXISTS vector; -- pgvector 0.8.3CREATE EXTENSION IF NOT EXISTS pg_trgm;
-- 推荐CREATE EXTENSION IF NOT EXISTS pg_stat_statements;CREATE EXTENSION IF NOT EXISTS btree_gin;
-- 第二阶段:中文全文检索(需要预编译的 pg_jieba)-- CREATE EXTENSION IF NOT EXISTS pg_jieba;max_connections = 20shared_buffers = 256MBwork_mem = 16MBmaintenance_work_mem = 512MB -- HNSW 索引构建需要更大内存hnsw.scan_mem_multiplier = 2wal_level = minimalfsync = onPostgreSQL 仅监听 127.0.0.1,密码存于 macOS Keychain。
YZOS 将索引数据、真源文件、模型权重、原始观察数据分散到各自独立可配置的目录,方便用户按需管理模型体积与磁盘压力。
paths: home: ~/.yzos database: /Volumes/Data/yzos-pg # PostgreSQL data_dir(L3 索引) contexts: ~/.yzos/contexts # OKF 真源(L1),通常留在系统盘便于同步 observations: /Volumes/Data/yzos-obs # L4 截图/屏录(体积大) models: /Volumes/SSD/yzos-models # GGUF / ONNX / sherpa voice: ${paths.observations}/../voice # 可独立拆分,默认 ${home}/voice logs: ~/.yzos/logs runtime: ~/.yzos/run # socket、pid
storage: min_free_gb: 10 # Preflight 分别检查 database 与 models 所在磁盘 pg_max_size_gb: 8 # 可选软上限,超限时 cron 告警路径与 PostgreSQL 的关系
Section titled “路径与 PostgreSQL 的关系”| 路径键 | 数据层 | PostgreSQL 是否持有 | 典型体量 | 推荐挂载 |
|---|---|---|---|---|
paths.contexts |
L1 OKF | 索引(chunk 元数据 + 路径) | 小,增长缓慢 | 系统盘 / iCloud |
paths.database |
L3 索引 | PostgreSQL 自身文件 | 中等,随使用增长 | 快盘(可外置) |
paths.observations |
L4 原始数据 | 元数据行 + 外部 file_path 引用 |
大 | 大容量盘 |
paths.models |
模型 | 无(仅 manifest 哈希) | 约 3.5 GB 以上 | 外置 SSD |
PostgreSQL 中的 file_path、transcript_path、audio_path 等字段存储解析后的绝对路径(或相对 paths.home 的路径,读取时归一化)。换机迁移时:
- 保持
paths.*一致,或 - 迁移数据后批量
UPDATE路径前缀,或 - 不同步 L4,仅从真源重建 OKF 与 PostgreSQL。
pub struct ResolvedPaths { pub home: PathBuf, pub database: PathBuf, // -> postgresql_embedded data_dir pub contexts: PathBuf, pub observations: PathBuf, pub models: PathBuf, pub models_llm: PathBuf, pub runtime: PathBuf,}
impl ResolvedPaths { pub fn resolve(cfg: &PathsConfig) -> Result<Self>; pub fn persist_to_config_kv(pool: &PgPool) -> Result<()>; // paths_resolved JSON}- 守护进程在 Booting 阶段先完成路径解析,再创建或打开 PostgreSQL(
paths.database必须存在且可写)。 yzos paths verify在 Preflight 之前检查各目录权限与storage.min_free_gb。- 修改
paths.database不会自动迁移已有的 PostgreSQL 文件;需执行yzos db migrate-data --to <new>(规划中的 CLI 命令)或手动迁移目录后重启。
磁盘规划参考
Section titled “磁盘规划参考”| 配置档 | models | database | observations | 说明 |
|---|---|---|---|---|
| 默认 16GB Mac | 外置 32GB SSD | 系统盘,约 2GB | 系统盘,上限 20GB | 模型与截图从主盘分离 |
| 单机大容量 | 同盘 ${home}/models |
同盘 | 同盘 | 默认布局 |
| 双机同步 | 各机本地 models |
各机本地 pg |
各机本地 | 仅同步 contexts 与 overrides |
- PostgreSQL 密码:macOS Keychain
- HTTP API secret:Keychain
- 推理 API Key:Keychain
config.json仅存非敏感配置
| 数据 | 默认保留期 | 清理方式 |
|---|---|---|
| 活动截图 | 360 天 | Cron 清理 |
| 语音片段 | 90 天 | Cron 清理 |
| AI 工具会话快照 | 180 天 | Cron 清理 |
| OCR 帧 | 跟随截图 | 级联删除 |
| Memory / Knowledge(OKF) | 永久 | 仅维护任务整理 |
| PostgreSQL 索引 | 跟随 OKF | 由 reconcile 重建 |
| Rollup 摘要 | 永久 | - |