Files
HomeAgent/internal/memory
JianFeeeee baf2ecd7c9 test(memory): 块 union 的并发压测(字节与块同表之后的并发热点)
块 union 化把「元数据」与「负载」合并进同一行(memory_blocks.data BLOB),
原本分属两个存储(media.db 元数据 + blobs 文件)的读写现在全压到同一张表、
同一把 g.mu。这条改动是否引入锁争用/丢更新/字节错位,只有并发实测能回答。

7 条压测(全部 -race 通过,约 26 万次并发读、0 撕裂 0 丢失):

  1. ConcurrentPutSameContent  —— 16 写者同内容:只留 1 行且字节完整
  2. LeanRewriteMustNotBlankData —— ★ 瘦块(blockColumns 不含 data)重写
     已回填块时,ON CONFLICT 不得把 data 覆盖成空。这正是生产踩过的坑,
     变异(把 `CASE WHEN ... THEN memory_blocks.data` 改成 `= excluded.data`)
     当场被这条判据抓住。
  3. ConcurrentReadWriteNoTear —— 8 读者 + 4 写者(改向量):16456 次读
     0 撕裂 0 丢失
  4. BackfillConcurrentWithRecall —— 回填(单事务)与读取并发:101033 次读
     0 错字节;终态候选清零
  5. DeleteConcurrentWithRead —— 用真实删除路径 DeleteEntity:143k 次读
     只能看到「完整内容」或「不存在」;终态块与负载一起消失(union 两半同生共灭)
  6. ConcurrentSetVector —— 12 写者并发写向量:仍是合法 JSON、维度正确、字节未动
  7. ManyBlocksLargePayloads —— 120 块 × 256KB = 30MB 反复读写逐字节校验

★ 为何删除压测不用媒体块:生产**没有**按块 ID 删媒体块的路径。删除发生在
实体级(DeleteEntity 按 text_content 匹配)与孤块清理(PurgeOrphans 只扫
text_content != ''),所以用 DeleteEntity 这个真实路径。
2026-10-12 17:37:08 +08:00
..