Files
dsh_shenxian/dsh-server-docs/04-调整方案/28-用户数据清理策略.md
T
admin 5ad755116e chore(docs): 文档库并入代码仓(R4 选 a)+ 索引/台账跟进
1) dsh-server-docs/ 从工作区(原 E:\...\aliyun-dsh-server\dsh-server-docs)**整体并入本仓**,
   保留目录名 ⇒ 仓库内 dsh-server-docs/... 的相对引用天然继续有效;旧目录(含其 .git)已归档到
   工作区 _中间产物_待清理/,未随本提交带入。
2) .gitattributes:新增 `dsh-server-docs/** -text` —— 原文档库是 `* -text` + autocrlf=false,
   必须保持纯 LF,否则会被本仓的 CRLF 规则翻掉。
3) 活引用里的绝对路径已全部改到新位置(docs 的 INDEX / README / scripts / skills + 用户级 skills
   + ~/.workbuddy/settings.json 的 hooks);历史档案(04-调整方案/、archive/)按「只增不改」未动。
   ⚠️ hooks 路径改动需「完全重启会话」才生效(配置是会话启动快照)。
4) 交接单/T08:新增 §16「生产整体切换执行记录」(形态 / 落地动作 / **4 个只有真上线才暴露的真 bug** /
   验收证据 / 回滚命令 / 残留项);台账 T08 行 → 已完成并归档;03-路线图 §二 登记 T08 收尾项。
5) 统一称谓:**「本机」只指跑 WorkBuddy 的开发机**,47 / 106 一律写「远程服务器」。
2026-09-15 18:47:13 +08:00

6.7 KiB
Raw Blame History

28 · 用户数据清理策略(工作区 / 会话 / 回收站)

  • 日期:2026-09-11
  • 背景:用户提出「AI 生成的代码和脚本等才是需要定期清理的重点」,并明确「这些脚本基本都是根据某个对话任务产生,没有复用价值」;同时要求「会话记录达到某个大小阈值后,可清除 90 天前的记录」。
  • 结论一句话:已落地三件套(ws-cleanup 工作区清理 / session-gc 会话回收 / purge-trash 回收站清空)+ 修掉一个平台自身 bug(pnpm store/cache 污染用户工作区);全部走"先 mv 到回收站、30 天后才真删"。

一、先说结论:谁在吃盘

用户 清理前 ws 其中"平台产物" 真正用户内容 sessions
admin 18 MB / 2045 文件 17.6 MB(pnpm store 16.1M + cache 1.5M + 6 个 tgz + poc/.poc-backup) 92 KB 708 KB
guest 2.5 MB / 30 文件 2.0 MB(cache 1.8M + store 180K + 3 个 tgz) 504 KB 1.1 MB

发现(平台 bug):安装脚本原用 HOME=<用户 ws> pnpm add … → pnpm 把 store($HOME/.local/share/pnpm/store)与 cache($HOME/.cache/pnpm)写进了用户工作区,再加我们复制进去的 *.tgz、poc/。这不是 AI 产物,是平台自己制造的污染,且掩盖了真正要治理的对象。 已修:安装改为 --store-dir <home>/.pnpm-store --cache-dir <home>/.pnpm-cache + 直接用 /opt/dsh/artifacts/ 的 tgz(不再复制进 ws)。 已清:存量污染 mv 到 <userRoot>/trash/2026-09-11-ws-pollution/;效果 admin 18M/2045 文件 → 12K/0 文件、guest 2.5M/30 → 480K/8;并实测清理后真实 dsh 仍正常启动、插件正常加载。

二、清理策略:三档分类(判定依据只有"路径/文件名模式 + 年龄")

前提说明:无法按"是不是 AI 生成的"判定(没有可靠标记),所以规则只认模式 + 年龄,并强制分档:

档 对象 规则 动作
T1 平台产物/明确垃圾 ws/{.local,.cache,.poc-backup,poc,__pycache__,.pytest_cache,node_modules,.ipynb_checkpoints}、*.tgz/.tmp/.log/.bak/.part/.crdownload 白名单精确匹配 达阈值即清(mv 到回收站)
T2 一次性临时脚本 ws 顶层的 *.py/.js/.mjs/.cjs/.sh/.ps1/.bat/.ts/.ipynb/.sql 且 mtime 超过 90 天(用户口径:无复用价值) 达阈值即清
T3 其它一切 目录、文档、表格、图片、视频、数据、报告… — 永不自动删,只统计与告警

阈值(per-user,达到才动手):ws ≥ 2048 MB;sessions ≥ 1024 MB。 保留期:ws(T1/T2)90 天;sessions 365 天(用户 2026-09-11 定:对话记忆要留长些);回收站 30 天。

豁免机制:在 ws/ 顶层放一个 .keep 文件 → 该用户跳过 T2(一次性脚本不清理),T1 仍清。

三、落地组件

组件 作用
scripts/ws-cleanup.cjs 工作区画像(ws/T1/T2/资产 占比)+ 按阈值清理(--apply;默认 dry-run)
scripts/session-gc.cjs 会话保留期回收:sessions/<slug>/<session-id>/session.jsonl.zstd 超 N 天且该用户 sessions 达阈值 → mv(含 dry-run)
scripts/clean-ws-pollution.cjs 一次性:清平台自身污染(白名单同 T1 的前 4 项 + tgz)
scripts/storage-report.cjs 每小时生成用量快照 /var/run/dsh-storage-report.json(每用户 ws/sessions/trash/总计 + 可清理候选 + 阈值状态)
scripts/purge-trash.sh 清空 <userRoot>/trash/ 下超 30 天的回收目录(只有它会真删)
门户 「存储用量」面板 admin.html 新增一区块(表:工作区/会话/回收站/可清理项数),数据来自 GET /api/admin/storage(requireAdmin,直接读快照,不做实时 du)
/etc/cron.d/dsh-maintenance 每小时 05 分 storage-report;每天 04:10 ws-cleanup(2048MB/90d)/ 04:20 session-gc(1024MB/365d)/ 04:40 purge-trash;日志 /var/log/dsh-*.log

安全设计:所有清理动作都是 mv 到 <userRoot>/trash/<日期>-<任务>/(同盘秒级、可整目录移回恢复),30 天后才由 purge-trash.sh 真正删除。

四、为什么不"按 AI 产物"直接清

  1. 不可判定:AI 与用户都可能写脚本/文件,平台拿不到"这是 AI 生成的"标记;
  2. 误删代价高:ws 里同时有用户资产(guest 的 MCN短视频创作/ 对标数据、报告);
  3. 折中:只清"模式明确 + 超龄"的东西(T1/T2),其余一律保留并只做用量告警 —— 宁可少清,不可误删。

五、风险与回滚

风险 缓解
误清 T2(用户其实想留的脚本) 30 天回收期可整目录移回;且只清"ws 顶层 + 超 90 天"
回收站膨胀 purge-trash.sh 每日清 30 天以上
阈值调错 三个脚本都支持 --threshold/--days;cron 里可见当前值
会话删除影响 dsh 结构已实测:sessions/ 无索引文件、按工作区分桶;只在超阈值时动,且走回收站;并同步回收 session_projcache/sessions/<session-id>.json(按 id 精确匹配,不会误删他人会话)
误伤运行中实例 脚本只动 ws/ 与超龄 sessions/,不动 profile/node_modules

六、硬配额:评估结论 = 不做(2026-09-11 定)

  • 本机根文件系统实测为 ext4(/dev/vda3,/ : ext4 rw,relatime),未启用 prjquota → 无法直接使用 XFS project quota;
  • 若强行上配额,需要"重挂载/重建文件系统或改用 loopback+XFS 镜像",停机与数据风险都不可接受;
  • 当前用量仅 24%(8.6G/40G)、单用户最大 33MB → 无压力;
  • ⇒ 用"软阈值 + 每小时用量快照 + 门户可视 + 每日自动清理"替代硬配额;真到压力再评估(可选方案:loop 镜像挂到 ws/,成本中等)。

七、已完成(本轮"一次性优化到位")

  1. ✅ 会话保留期加长:90 → 365 天(阈值 500 → 1024 MB);
  2. ✅ .keep 豁免:ws/.keep 存在则跳过 T2;
  3. ✅ projcache 同步回收:删会话时按 session-id 精确回收投影缓存;
  4. ✅ 用量可见:storage-report.cjs(每小时)+ 门户 admin.html「存储用量」面板(GET /api/admin/storage,实测未登录 401 即受 requireAdmin 保护);
  5. ✅ 硬配额评估:结论"不做"(ext4 无 prjquota,风险不对称)。

剩余可选(非必要):T2 更细的豁免(项目目录内 scripts/)、按用户差异化阈值、用量面板加"趋势/告警"。