[Critical] 预创建 segment 可破坏尾部截断逻辑 #7
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
来源
Oracle 审核
docs/design.mdSection 3.2 WAL位置
Section 3.2 "WAL 元数据持久化协议"(~line 173)与 "Physical Record 解析规则"(~line 491)
问题描述
新 segment 创建协议(步骤 1-8)允许
segment-N+1.wal在文件系统上可见(已完成 rename + directory fsync),即使它尚未承载任何 batch。如果此时进程崩溃,segment-N.wal可能有 crash-torn tail。Recovery 扫描时,因为
segment-N+1.wal存在且 header 合法,segment-N不再被视为"最后一个需要恢复的 segment"。按照当前的尾部/中间损坏分类规则,segment-N的尾部损坏会被升级为"WAL 中间损坏"→ 报错而非截断。影响
一个本应可截断恢复的尾部 partial write 场景被错误升级为不可恢复的中间损坏,导致整个 DB 无法启动。
建议修复
方案 A(推荐):禁止预创建未来 segment,直到当前 segment 在完整 batch 边界 sealed:
方案 B:Recovery 能识别并忽略空 segment:
已在设计文档中修复:f6a2cd9
update WAL segment boundary design补充了 segment rotation 约束,明确新 segment 的 durable-ready 协议只能在当前 active segment 已结束于完整 WAL Batch 边界后启动,并禁止预创建未来 segment / 让 segment-N+1 在 segment-N 仍可能存在未完成 Batch 尾部时对 recovery 可见。对应位置:docs/design.md:213、docs/design.md:328-332。