4.1 KiB
PostgreSQL 聊天记录月度归档
数据范围与月份
页面月份来自业务数据库 threads_meta.created_at,按北京时间的会话创建月份归档。一次归档会搬迁该月会话的全部 LangGraph checkpoints、checkpoint blobs 和 pending writes;跨月继续的会话仍完整放在创建月份的 SQLite 文件中。系统线程和当前状态为运行中的会话会跳过。
聊天列表元数据仍留在原业务数据库(MySQL 配置不变)。LangGraph Store 中的用户记忆、智能体数据和其他应用表不属于聊天 checkpoint,不会被清理。
固定目录与现有 SQLite 配置
默认目录:$DEER_FLOW_HOME/data/chat-archives/;未设置 DEER_FLOW_HOME 时为项目目录下 .deer-flow/data/chat-archives/。可用 DEER_FLOW_CHAT_ARCHIVE_DIR 指定其他绝对路径。目录内容:
chat-YYYY-MM.db:每个归档月份一个 LangGraph SQLite checkpoint 数据库。catalog.db:月份任务、会话到月份的映射、复制/删除/回滚状态。.locks/:Worker 与主服务共享的会话级跨进程读写锁。
归档 SQLite 是叠加的历史层,不会修改 checkpointer.connection_string、sqlite_connection_string 或旧的 dual_read_sqlite_paths。PG 仍是写入目标;查询某个 thread 时先读 PG,缺少 checkpoint 才按 catalog.db 找到相应月份 SQLite。历史会话页面和 LangGraph history/state 接口使用同一套回退逻辑。首次管理员启动归档任务后才创建索引;此前聊天写入不创建锁文件、不额外写归档数据。仅打开页面只查 threads_meta 月份汇总,不扫描 PG 检查点表,也不创建归档目录或索引。
如果启用 Worker 池,归档目录必须位于主服务和 Worker 共同挂载的可写持久卷。默认目录落在 $DEER_FLOW_HOME/data 下,标准 Docker 部署的 data volume 会共享该路径;自定义路径需要放入相同的共享卷。PostgreSQL Worker 检查会在卷未共享时拒绝启动,避免只在主容器可见的归档导致历史查询丢失。
操作流程
归档、清理、回滚通过 SQLite 原子任务认领,保证全局同一时间只运行一个月份任务,避免多个管理请求同时压满 PostgreSQL 和磁盘 I/O。
- 管理员打开「设置 → 聊天记录归档」。页面按月聚合轻量会话元数据,不会打开页面就扫描 PostgreSQL 的 80GB checkpoint 表,也不会创建归档状态文件;同时显示归档卷可用空间。
- 选择已经结束的月份执行「归档到 SQLite」。任务后台逐会话复制并核对 checkpoint id;进度写在固定目录,关页或服务重启后可重新发起继续处理。
- 确认状态为「归档已校验」后,才可点击「删除已归档 PG 数据」。删除任务会在每个会话上取得共享卷锁,等待正在进行的 checkpoint 写入结束,再次复制并验证 SQLite,最后删除 PostgreSQL 中该 thread 的 checkpoints、blobs 和 writes。
- 页面「回滚到 PostgreSQL」会把该月 SQLite checkpoint 重新写回 PostgreSQL 并校验;SQLite 副本会保留,历史读取可继续回退。
归档、清理、回滚均按会话运行,并限制并发到单个月任务。目标卷会保留至少 2 GiB 空间;低于阈值时任务暂停,复制校验失败时会保留该会话的 PostgreSQL 数据。清理后 PostgreSQL 可以复用空闲页,但普通 DELETE 不保证操作系统看到的数据库文件立即变小;系统不会自动执行可能带来明显 I/O 和锁表风险的 VACUUM FULL。
部署与验证
更新后台 app/、packages/、tests/ 和前端 dist 后重启主服务。数据库不需要新增 PostgreSQL migration;首次任务会创建本地 SQLite 月库和归档目录。部署前确保该卷有足够空间容纳选中月份的副本,并将 DEER_FLOW_HOME/data 纳入备份。
回归测试覆盖归档复制、checkpoint 校验、PG 删除后的透明 SQLite 回退、回滚,以及 Worker 共享归档卷校验。线上执行前先在单个月份做归档和历史读取验收;归档按钮本身不会删 PG,删除操作须管理员单独点击。