-
docs(plan): 更正事故注释 —— 昨晚那条 OOM 日志是 6 天前的,叙事全错 · 3e62c5f0
09-05 用 journalctl -b -1 复盘,推翻了 09-04 当晚写进代码的三条事实: ① **当晚内核一条 OOM 都没打。** VNC 上那条 `Killed process 945388 (node) anon-rss:6321668kB` 是 **2026-08-29 07:26:17** 的 —— pid/anon-rss/pgtables 与内核日志逐字段相同,内核 cmdline 带 console=tty0, 它在 framebuffer 上留了 6 天没被刷掉。/var/log/messages 独立日志槽交叉验证同样只此 1 条。 ② **这台机没有 swap**(Swap: 0B / vm.swappiness=0 / /proc/swaps 空),「swap 抖死」不成立。 ③ **没有崩溃循环**:内核 `eth0: renamed from` 按天计数 Sep 03=0 / Sep 04=0, 当晚一次容器启动都没有;journalctl -u docker 事故时段无条目。 真正形态是**无 swap 下的 page-cache refault 活锁**:匿名页吃满后只能回收文件页, 程序正文被刷掉、下一条指令又缺页读回(监控上 286MB/s 满速读、写≈0、CPU~15%)。 因为始终有文件页可回收,out_of_memory() 从未被调用 —— 没人被杀,也就没有任何自愈, 一路挂到人工硬重启,共约 11.8 小时(不是原注释写的 2.5 小时)。 对照 08-29:同机同水位同样吃到 6GB,那次走 OOM kill、10 分钟量级自愈。 **失败形态比内存本身更决定后果。** 死点(生产库写入痕迹重建,应用日志已随部署 --force-recreate 丢失): 场景+预取 4,110s → 写入段仅 43s(550,011 行落库)→ 第 3 步 stale-close 最后一次提交 20:05:49(全库最后一次写)→ 收尾 backfillMissing 一行没写、阶段耗时从未打出。 代码行为不改(分批本身经测试机实测有效:45 批 heapUsed 单调下降 462→107MB、零累积; 属性测试证明结果与批大小无关)。改的是**它的定位**: 从「本次事故的直接对策」改成「降低峰值 → 降低再次触发活锁的概率」, 并明确写出**不治**的三项:hits 交接的双份拷贝(≈2.1GB,现存最大未处理项)、 第 3 步整池 findMany、以及真正的兜底缺口(容器 MemLimit=0 + 无 swap ⇒ cgroup OOM 与内核 OOM 两道兜底全被绕过)。 顺带删掉 treatment-initiation-recall.scenario.ts 里一句自 2026-08-30 起就失真的注释: 「场景查询是串行的,同一时刻只有一条在跑,峰值可控」—— 那天起生产设了 conc=4, RDS 上同时有 4 个 SET LOCAL work_mem='256MB' 的事务,DB 侧峰值不再可控。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
luoqi committed
| Name |
Last commit
|
Last update |
|---|---|---|
| .. | ||
| scenarios | Loading commit data... | |
| chain-composer.service.ts | Loading commit data... | |
| plan-engine.service.ts | Loading commit data... | |
| priority-scorer.ts | Loading commit data... | |
| reason-refresh.ts | Loading commit data... | |
| scenario.interface.ts | Loading commit data... |