feat(documents): 引用计数 + 文档/侧车 GC(主人 2.2 裁决;S7)
- 引用计数真实维护(documents 表唯一写入面):增减点只有四处 —— history 的 insert / UpdateMessageDocument / DeleteMessage / DeleteSession,且**全在同一事务**内(计数写失败 ⇒ 消息写入整体回滚,有钉住用例);UpdateMessageDocument 按新旧名字**集合差**增减(三阶段回写是常态,重算会重复计数 ⇒ 文件永远回收不掉)。 - GC:候选 = ref_count = 0;判据 = last_referenced_at(NULL 回落 created_at)早于 now − 保留期;动作 = 删 sidecar + 原件 + 元数据行(删行带 AND ref_count = 0 原子再确认);路径双检;汇总日志(含实占字节);单件失败 WARN 并继续;删除顺序 = 先文件后行(失败则行留着下轮重试,不留孤儿)。 - 组合根:启动期清扫一次(不阻塞启动)+ ticker 常驻(可停,close 顺序在关库之前);env DOCUMENT_GC_INTERVAL 默认 1h / DOCUMENT_RETENTION 默认 168h,**任一 ≤0 = 关闭 GC**(RETENTION=0 不解释成立即回收,关闭时记 WARN);.env.example 已同步(AGENTS §10)。 - 主会话独立验收:隔离 worktree(S7 的 18 文件,排除 F2 在途的 mcp/vision)build/vet 绿、全树 59 包 0 FAIL、GC/引用用例 20 PASS、双平台交叉编译绿;**变异亲自复现**(候选查询去掉 ref_count = 0 ⇒ TestGCDoesNotDeleteReferencedDocument 红:candidates = 1, want 0)。 - 未做(任务书允许的「只做后端」):面板手动「清理未引用附件」入口 —— 后端能力已就绪(documents.NewGC + GC.Sweep),接成端点属小切片(含 admin 路由 + 审计 document.gc + 契约登记)。 - 已知窄窗口(已在 gc.go 文件头登记):一轮 GC 与一次落库几乎同时发生时可能删掉刚被引用的文件(行不删、记 WARN);坏 document 列只记 WARN 不阻塞消息写入 ⇒ 计数可能偏低(只会让文件**晚**回收,绝不早删)。
This commit is contained in:
1 parent
79b1ec36aa
commit
3ba31b58ff
18 files changed
+1951
-29
No files matched your search
@@ -38,6 +38,19 @@ CHAT_IMAGE_MAX_BYTES=5242880
|
||||
# ≤0(写 0 或负数)= 用默认值 20 MiB,不是「禁用上限」。
|
||||
CHAT_DOCUMENT_MAX_BYTES=20971520
|
||||
|
||||
# ---- 文档回收(GC:引用计数 + 保留期,design/24 §3.2(配额与清理);切片 S7) ----
|
||||
# 判据:**未被任何消息引用**(ref_count = 0)且最后一次被引用(从未被引用则看上传时间)
|
||||
# 早于「现在 − 保留期」。动作:原件(<DATA_DIR>/uploads/documents/<存储名>)+ 抽取正文
|
||||
# sidecar(<DATA_DIR>/extracted/<存储名>.txt)+ documents 表里的元数据行**三样一起删**。
|
||||
# 引用计数由消息落库/编辑/删除时维护(都在同一个事务里),因此**仍被引用的文件绝不删**。
|
||||
# 启动时清扫一次 + 此后按间隔定时清扫;每轮只记一条汇总(删了几件/释放多少字节,不含正文)。
|
||||
# DOCUMENT_GC_INTERVAL:定时清扫间隔(Go duration,如 30m / 1h / 6h),默认 1h。
|
||||
# DOCUMENT_RETENTION:保留期(Go duration),默认 168h(7 天)。
|
||||
# ⚠️ 任一键写 0 或负数 = **关闭 GC**(同时关闭启动期那一次清扫,日志会写明原因)。
|
||||
# `DOCUMENT_RETENTION=0` 不是「立即回收」——那种解释会让一次笔误清空未引用的附件。
|
||||
DOCUMENT_GC_INTERVAL=1h
|
||||
DOCUMENT_RETENTION=168h
|
||||
|
||||
# ---- 认证 / 管理员 ----
|
||||
# JWT_SECRET 必填,长度 >= 32;缺失或过短会在启动时 panic。
|
||||
JWT_SECRET=change-me-to-a-random-string-at-least-32-characters
|
||||
|
||||
Reference in new issue
Block a user