Files
ARTEX/traffic
Autumn-27 3227f2e54c fix(traffic): 删除流量后把索引空间真正还给操作系统
删除流量只让数据不可见,磁盘占用从不下降。两处原因叠加:

1. SQLite 删行仅把页挂到 freelist,而索引库建库时未启用 auto_vacuum,
   文件永不收缩。256KB 以下的正文全部内联在这个库里,所以体积主体就在
   这里,且只增不减。
2. ex_fts 是 contentless_delete 全文索引,DELETE 只写 tombstone、不回收
   原 postings,从来没有合并过——删流量反而让索引变大(实测 exchanges
   清零后 ex_fts_data 仍占 3.3MB / 840 行)。

trigram 索引约为正文体积的 2 倍,加上内联正文,抓包量大的实例会为早已
删掉的流量长期占用数倍磁盘:实测抓 6MB 文本正文 → 索引 16.2MB,删光后
仍是 16.2MB。

修复:
- 新建索引库在建表前启用 auto_vacuum=incremental。该 pragma 只在库中尚
  无表时可设,且只有紧随的 VACUUM 才把它写入文件头,两步都必须落在同一
  条连接上,故新增 initIndex 固定一条 *sql.Conn 串起 pragma 与建表。
- 新增 reclaim/reclaimChunk:删除提交后在后台分块执行全文索引增量合并、
  incremental_vacuum 与 wal_checkpoint(TRUNCATE)(不做 TRUNCATE 则空间
  留在 WAL 里、文件大小不变,PASSIVE 也清不掉)。接入 DeleteHost、
  HostDeleteStage.Commit 与 RecoverHostDeleteStages 三条路径。
- 回收分块进行并在块间释放写锁:record() 由 go-mitmproxy 在把响应写回
  客户端之前同步调用,一次性回收数 GB 会连带卡住被测请求。Close 先发停止
  信号,剩余预算留给下次删除,不拖住进程退出。
- 终止条件按「是否有进展」判定:incremental_vacuum 只能释放挪得到文件
  末尾的页,残留少量空闲页是正常结果;另加步数上限兜底。fts5 无法查询
  索引是否已合并完(其特殊 INSERT 自身即计一次 changes),故改为固定合并
  预算,未做完的留给后续删除。
- busy_timeout 改由 DSN 提供:它是每连接设置,原先的 db.Exec 只配到池中
  碰巧被选中的那一条,其余连接在有写者时会立即失败而非等待。驱动按第一个
  '?' 切分 DSN,故数据目录路径含 '?' 时退回裸路径 DSN。

已有实例的索引库仍是旧模式(auto_vacuum 无法事后开启),incremental_vacuum
在其上为空操作,启动时打印提示;此类库的 tombstone 增长已止住,已占体积
待后续「存储压缩」入口一次性回收。

测试:新增 reclaim_test.go(空间回收回归、tombstone 合并、新库模式、旧库
不卡死)与 upgrade_test.go(旧装机升级后同库同数据、全文与正文可用、
legacy path 行不受影响;以及降级回旧二进制仍可读写)。
2026-09-30 01:44:44 -04:00
..
2026-08-28 12:56:29 +08:00
2026-08-28 12:56:29 +08:00
2026-07-26 04:27:45 -04:00