From 7557c38e6c8fbbff36f48cac76f6b50a573ccd00 Mon Sep 17 00:00:00 2001 From: dailz Date: Thu, 11 Jun 2026 20:17:29 +0800 Subject: [PATCH] update WAL tail truncation recovery design Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- docs/design.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/design.md b/docs/design.md index 413c935..3e85941 100644 --- a/docs/design.md +++ b/docs/design.md @@ -606,6 +606,25 @@ lastCompleteBatchEnd = 当前 WAL offset 如果 Batch Header 或 Entry 解析错误发生在 WAL 尾部,可以丢弃该 incomplete batch;如果发生在 WAL 中间,默认报错。 +###### 尾部截断持久化 + +当 recovery 在最后一个需要恢复的 segment 发现可截断的 WAL 尾部损坏时,截断本身是 recovery repair 的一部分,必须在恢复完成并接受新写入前持久化。截断目标始终是最后一个完整 WAL Batch 的结束位置 `lastCompleteBatchEnd`;非最后恢复 segment 中的异常仍按 WAL 中间损坏处理,不得通过截断 repair 静默跳过。 + +尾部截断持久化步骤: + +```text +1. ftruncate 当前 active segment 到 lastCompleteBatchEnd +2. fsync 被截断的 segment +3. 删除 startSequence == expectedSequence 且不含任何 complete batch 的后续空 segment +4. fsync WAL directory +5. 更新 MANIFEST 或等价 recovery metadata,记录本次 recovery repair 后的恢复终点 +6. fsync metadata directory +``` + +以上步骤全部成功后,recovery 才能进入恢复完成状态并允许 WAL writer 接受新写入。若任一步失败,recovery 必须报错,DB 不得进入可写状态;否则再次崩溃后可能重新暴露未持久化的截断尾部,导致重复 repair 或 recovery 边界不一致。 + +这里的 MANIFEST 更新只记录 recovery repair 后的安全边界,不等同于普通 checkpoint 推进,也不意味着旧 WAL segment 已经可以删除。旧 WAL 文件生命周期仍由 MemTable flush、SSTable 与 checkpoint 元数据持久化后的规则决定。 + ###### 恢复完成状态 恢复完成后: