GBrain 知识库:从 PGLite 到 PostgreSQL 迁移避坑指南

2026-07-10

最近把我的 GBrain 知识库从默认的 PGLite 引擎迁到了 PostgreSQL。起因不算复杂:知识库从十几页长到了百来页,MCP 和 CLI 开始抢锁,经常一个跑着另一个就得等着。

这篇文章把迁移的全过程写下来,重点放在踩坑点上——如果你也在用 GBrain,这些坑你应该也会遇到。

背景:GBrain 的两套引擎

GBrain 是一个 PostgreSQL 原生的个人知识库系统,支持混合 RAG 搜索(关键词 + 向量)。它有两套可插拔的存储引擎:

引擎 默认? 存储方式 适用场景
PGLiteEngine 嵌入式 WASM PostgreSQL,本地文件存储 单机、小规模、快速上手
PostgresEngine 外部 PostgreSQL + pgvector 多设备、大容量、并发操作

PGLite 用 @electric-sql/pglite 在 Node/Bun 进程里跑了一个 WASM 版的 PostgreSQL 17.5,开箱即用——gbrain init 就完了,不用装任何额外服务。所以刚上手时根本不会去想迁移的事。

但知识库和需求都会涨。我经历的时间线:

  • 起步(14 页):PGLite 完全够用
  • 使用一段时间(30-40 页):开始同时用 MCP 和 CLI,发现它们不能并行
  • 知识库继续增长(100+ 页):有了多设备访问需求,PGLite 只能在本地跑

PGLite 的硬伤

PGLite 的限制归纳起来就一个根因:单进程单连接。它本质上是在你的应用进程里内嵌了一个 PostgreSQL 实例,只能有一个进程访问数据文件。具体表现:

  • MCP serve 和 CLI 命令不能同时跑
  • CLI 在同步时,MCP 得停掉
  • 只能本机访问,远程 MCP 用不了
  • 数据量大了以后性能明显下降

PostgreSQL 解决的就是这些问题:多连接、连接池、远程访问、标准索引优化,还可以和系统中其他服务共享同一数据库实例。

迁移执行

GBrain 内置了迁移命令,整体流程分四步走。

准备目标数据库

先在 PostgreSQL 实例上创建 GBrain 专用数据库和用户:

CREATE DATABASE gbrain_db;
CREATE USER gbrain_user WITH PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE gbrain_db TO gbrain_user;

-- 切到新数据库创建 vector 扩展
\c gbrain_db
CREATE EXTENSION IF NOT EXISTS vector;

-- 授权 schema 权限
GRANT CREATE ON SCHEMA public TO gbrain_user;
GRANT USAGE ON SCHEMA pg_catalog TO gbrain_user;

坑 #1:pgvector 扩展是按数据库安装的。 如果你在已有 pgvector 的 PostgreSQL 实例上新建数据库,默认不会自动带 vector 扩展。不配的话迁移虽能成功,但向量搜索会报 function vector_dims() does not exist

执行迁移命令

GBrain 提供了 migrate 命令,一行搞定:

gbrain migrate --to "postgresql://gbrain_user:***@your-server-ip:5432/gbrain_db"

输出大致如下:

Connecting to target (postgres)...
Migrating 37 pages (37 total, 0 already done)...
[===...===] 37/37
Copying links...
[===...===] 37/37

Migration complete. 37 pages transferred.
Config updated to engine: postgres
Original PGLite brain preserved (backup).

Verifying target...
  ok  pages: 37 (matches source)
  WARN embeddings: 33% coverage, 27 missing. Run: gbrain embed --stale
  ok  schema: version 23

注意这里的细节:原始 PGLite 数据不会被删除(config 只是切换引擎指向),所以可以随时回退。

切换配置

迁移命令会自动更新 ~/.gbrain/config.json,把 engine 改成 postgres。但如果通过 MCP 服务器使用 GBrain,还需要在 MCP 配置中显式传入 DATABASE_URL 环境变量:

mcp_servers:
  GBrain:
    command: gbrain
    args: ["serve"]
    env:
      DATABASE_URL: "postgresql://gbrain_user:***@your-server-ip:5432/gbrain_db"
      GBRAIN_EMBED_BASE_URL: "http://your-embed-service:8081"
      GBRAIN_EMBED_API_KEY: "your-key"

坑 #2:环境变量优先级高于 config.json。 GBrain 启动时先检查 DATABASE_URL 环境变量,再读 config.json。Hermes MCP 的进程环境不一定能透传到 gbrain serve,所以必须在 MCP 配置里显式指定。CLI 这边可以加 ~/.bashrc,两边各一份是安全的冗余设计。

迁移后验证

迁移完成后运行验证:

# 验证 CLI 命令正常工作
gbrain stats
gbrain list
gbrain query "关键词"

# 验证 MCP 正常工作(通过 MCP 工具)
gbrain call get_stats '{}'
gbrain call get_health '{}'
gbrain call query '{"query": "测试"}'

# 补全缺失的 embedding
gbrain embed --stale

坑 #3:Embedding 覆盖率骤降。 迁移完成后 embed_coverage 可能只有 30-40%,因为部分 chunk 的向量数据在迁移过程中没有完整复制。当时我的情况是 33%——37 个页面成功迁移,但 27 个 chunk 缺了 embedding。跑一次 gbrain embed --stale 补上就行。

踩坑总结

除了上面提到的,还有几个值得注意的点:

MCP 进程重启追踪

迁移完成后需要重启 gbrain serve,但我当时不知道当前进程是谁启动的——是手动启动的,还是 cron job 拉起来的,还是 Hermes gateway 自动管理的?

排查方法通用:追踪 PID 链(cat /proc/$PID/status 看 PPid)找父进程。后来发现是 daily-diary cron job 每天凌晨 2:05 会自动 pkill 并重启 gbrain serve,迁移后这个重启实际上已经不需要了(PostgreSQL 多连接不存在文件锁问题),算是遗留操作。

迁移命令的断点续传

GBrain 的迁移命令用 migrate-manifest.json 记录进度,如果中途崩溃或中断,再次执行可以从断点继续。这个设计让大库迁移时不用从头再来。

什么时候该迁移

不是所有人都需要从 PGLite 切到 PostgreSQL。我的判断标准:

场景 建议
刚接触 GBrain,<50 页 PGLite 完全够用,零配置
自己用,偶尔切 MCP/CLI PGLite 够用,错开使用不影响
50-500 页,操作频繁 考虑迁移,PGLite 开始吃力
MCP + CLI 频繁同时用 必须迁移,锁冲突影响工作流
多设备远程访问 必须迁移,PGLite 只能本机
1000+ 页 必须迁移,性能瓶颈明显

我最初 14 页时选择了「后续有需要再切换」。等到知识库上量、MCP 和 CLI 并发使用成为日常后,花了一个小时迁移完成。

技术要点

迁移命令的底层逻辑

从源码上看(src/commands/migrate-engine.ts),迁移流程是按页逐条搬砖:逐页从源引擎读取(页面元数据、chunk+embedding、标签、时间线等)→ 写入目标引擎 → 所有页面迁完后复制链接关系 → 复制配置 → 更新 config.json → 后验证。

关键设计亮点是 manifest 断点续传和原引擎数据保留不动。迁移不是”剪切+粘贴”,而是”复制+切换指针”。

日常巡检命令

迁移之后:

# 健康检查
gbrain call get_health '{}'
# 关注 brain_score, embed_coverage, orphan_pages

# 统计数据
gbrain call get_stats '{}'
# 关注 page_count, chunk_count

# 补 embedding
gbrain embed --stale

总结

PGLite 对大多数 GBrain 用户够用,但当你需要 MCP + CLI 同时工作、需要远程访问、或者知识库上量时,PostgreSQL 迁移是绕不过去的。GBrain 的内置迁移命令做得比较完善——保留了原数据、支持断点续传、自动更新配置——但三个坑是文档没写的:

  1. 新数据库需要手动 CREATE EXTENSION vector;
  2. MCP 环境变量要显式传入 config.yaml,不能只靠 config.json
  3. 迁移后必须跑 gbrain embed --stale 补 embedding

花了大概一小时完成全部迁移和验证,之后 MCP 和 CLI 可以同时跑,远程也能查知识库了。