[Critical] Go 内存模型:lock-free read 需要原子发布机制 #9
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.3 MemTable "并发策略"(~line 600)与 Section 3.2 步骤 ⑥⑧(~line 109-112)
问题描述
Section 3.3 声明 MemTable 使用 "Mutex 写 + 无锁读",Section 3.2 步骤 ⑥ 在 fsync 前将 entry 写入 MemTable(pending 状态),步骤 ⑧ 通过更新
publishedSequence使 entry 对无锁读可见。在 Go 内存模型中:
atomic.Pointer或等效发布机制确保节点对读者可见。publishedSequence更新:作为普通变量写入,无锁读者可能看到过时值或部分写入。必须是 atomic 操作。影响
在 ARM 架构(弱内存序)上可能出现读者看到
publishedSequence已更新但对应 skiplist 节点尚未可见的情况,导致读到不一致数据。建议修复
在 Section 3.2 或 3.3 中明确内存序要求:
atomic.Pointer或自定义 release 操作)发布,确保无锁读者看到完整的节点内容。publishedSequence必须是 atomic 变量(atomic.Uint64),且其Store必须在所有 batch entries 的 skiplist 节点都已原子发布之后执行。这保证读者先看到节点,再通过publishedSequence筛选可见 entry。atomic.LoadpublishedSequence,再遍历 skiplist。