thzxx
edd9f1dcd9
fix(B-6): KVStore 损坏尾部不再清空整库 + 后台 checkpoint 失败语义(两处 P0)
PLAN-v0.7.5.md §4 B-6 的 KVStore 三处止血中最严重的两处,均为**P0 数据丢失**。
① open() 遇损坏日志尾部会清空整个日志
修复前 `open()` 检测到 corruptOffsets 后调用 `truncateLog()` —— 那是"写空文件",
用于 checkpoint 之后(此时快照已覆盖全部数据)。用在崩溃恢复路径上,
等价于把"尾部损坏"放大成"整库丢失"。实测(本提交的新用例锁定):
写 a/b/c 三条 → 第 4 条撕裂(只落 20 字节)→ 重开:a/b/c 可见
→ **再重开一次:全部为空**
修法:新增 `truncateLogTo(keepBytes)`,恢复路径截断到
`findValidLogLength(log)`(与 repair() 同一口径),只丢弃损坏尾部。
两个方法的语义差异写进注释:checkpoint 后可清空(快照是数据来源),
恢复时只能截断(日志前缀才是唯一数据来源)。
② 自动 checkpoint 失败会让已确认写入报错
修复前 `appendRecord` 末尾的自动 checkpoint 没有 try/catch:快照/meta 写失败
会把异常冒泡到 `put()`,但那条写入**已经在 WAL 里**(WAL 是权威来源,崩溃后
一定能重放)。用户看到"写入失败"、数据却在盘上 —— 报错与事实相反,
调用方据此重试会写两次、据此丢弃业务状态会丢数据。
修法:抽出 `autoCheckpoint()`,失败记录为 `lastBackgroundError` 而不抛出;
由**下一次显式 `checkpoint()`** 报告(`KV_BACKGROUND_ERROR`)——
那是用户主动要求压实数据的时机,此时失败才是真实问题。
WAL 追加本身失败仍然照旧抛 `KV_LOG_ERROR` 且不回滚内存索引(原子性保持)。
验证方式:tests/v080-kvstore-commit-point.test.ts —— 11 项,使用
`FaultyBackend` 做**真实字节级**故障注入(撕裂写 / bit-flip / 掉电丢弃 /
写失败),而非"重开测试"。并做了**变异验证**:把两处修复分别回退到修复前的
行为,对应用例立即失败(①2 项失败、②3 项失败),恢复后全绿 ——
确认这些断言真的能拦住回归,不是假绿。
全量 85 套件 / 1657 测试通过;typecheck(src+tests) 与 lint 零错误。
2026-09-15 00:21:32 +08:00
..
2026-09-14 21:03:06 +08:00
2026-09-15 00:00:08 +08:00
2026-09-14 21:03:06 +08:00
2026-09-14 21:43:21 +08:00
2026-08-14 22:53:46 +08:00
2026-07-26 15:00:01 +08:00
2026-09-15 00:15:41 +08:00
2026-09-14 23:22:26 +08:00
2026-09-14 21:03:06 +08:00
2026-07-26 15:00:01 +08:00
2026-09-14 21:03:06 +08:00
2026-07-26 16:40:11 +08:00
2026-09-14 22:29:51 +08:00
2026-08-10 13:56:04 +08:00
2026-09-15 00:15:41 +08:00
2026-09-14 21:03:06 +08:00
2026-09-14 21:03:06 +08:00
2026-09-14 21:03:06 +08:00
2026-07-26 15:00:01 +08:00
2026-09-14 21:03:06 +08:00
2026-08-14 22:53:46 +08:00
2026-08-13 15:31:16 +08:00
2026-08-10 13:56:04 +08:00
2026-09-14 21:03:06 +08:00
2026-09-14 22:29:51 +08:00
2026-09-14 21:03:06 +08:00
2026-07-26 16:40:11 +08:00
2026-08-10 14:11:44 +08:00
2026-09-14 21:03:06 +08:00
2026-09-14 21:08:20 +08:00
2026-09-14 21:03:06 +08:00
2026-09-14 21:03:06 +08:00
2026-09-14 22:03:56 +08:00
2026-09-14 21:03:06 +08:00
2026-09-14 21:03:06 +08:00
2026-09-14 21:03:06 +08:00
2026-09-14 23:22:26 +08:00
2026-08-13 10:30:39 +08:00
2026-08-13 10:57:26 +08:00
2026-08-13 11:14:42 +08:00
2026-08-13 15:31:16 +08:00
2026-09-14 23:38:58 +08:00
2026-09-14 21:03:06 +08:00
2026-09-14 22:02:30 +08:00
2026-09-14 22:29:51 +08:00
2026-09-15 00:21:32 +08:00
2026-09-15 00:00:08 +08:00
2026-09-14 21:53:46 +08:00
2026-09-15 00:15:41 +08:00
2026-09-14 23:22:26 +08:00
2026-09-14 22:29:51 +08:00
2026-09-15 00:00:08 +08:00
2026-09-14 21:03:06 +08:00