[Critical] WAL write failure 语义过于简化:write() 失败后 bytes 可能已落盘 #5
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 "写入流程" 步骤 ⑤ 及后续错误处理段落(~line 117)
问题描述
当前设计将 WAL encode/write 失败统一当作 "definitely failed" 返回普通错误。但实际上存在两种不同情况:
write()失败(bytes 可能已进入 OS page cache 或部分写入文件):不是 definitely failed。Recovery 后可能发现该 batch CRC 合法并被重放,导致语义矛盾——调用方收到错误认为写入失败,但数据实际被恢复影响
调用方可能基于"写入失败"做非幂等业务决策(如放弃、走替代路径),但数据实际持久化了。
建议修复
拆分 WAL write failure 处理:
write()):普通错误 + write-stoppedwrite()失败(bytes 可能已交给 OS):ErrCommitUnknown+ write-stopped,除非实现能证明零 bytes 到达文件(例如write返回 0 且无副作用)