[Critical] Go 内存模型:lock-free read 需要原子发布机制 #9

Closed
opened 2026-06-09 13:08:05 +08:00 by dailz · 0 comments
Owner

来源

Oracle 审核 docs/design.md Section 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 内存模型中:

  1. Skiplist 节点发布:Mutex 保护下的写入对未持锁的并发读者不一定可见。需要 atomic.Pointer 或等效发布机制确保节点对读者可见。
  2. publishedSequence 更新:作为普通变量写入,无锁读者可能看到过时值或部分写入。必须是 atomic 操作。

影响

在 ARM 架构(弱内存序)上可能出现读者看到 publishedSequence 已更新但对应 skiplist 节点尚未可见的情况,导致读到不一致数据。

建议修复

在 Section 3.2 或 3.3 中明确内存序要求:

  1. MemTable skiplist 节点必须通过 atomic store(atomic.Pointer 或自定义 release 操作)发布,确保无锁读者看到完整的节点内容。
  2. publishedSequence 必须是 atomic 变量(atomic.Uint64),且其 Store 必须在所有 batch entries 的 skiplist 节点都已原子发布之后执行。这保证读者先看到节点,再通过 publishedSequence 筛选可见 entry。
  3. 读者必须先 atomic.Load publishedSequence,再遍历 skiplist。
## 来源 Oracle 审核 `docs/design.md` Section 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 内存模型中: 1. **Skiplist 节点发布**:Mutex 保护下的写入对未持锁的并发读者不一定可见。需要 `atomic.Pointer` 或等效发布机制确保节点对读者可见。 2. **`publishedSequence` 更新**:作为普通变量写入,无锁读者可能看到过时值或部分写入。必须是 atomic 操作。 ## 影响 在 ARM 架构(弱内存序)上可能出现读者看到 `publishedSequence` 已更新但对应 skiplist 节点尚未可见的情况,导致读到不一致数据。 ## 建议修复 在 Section 3.2 或 3.3 中明确内存序要求: 1. MemTable skiplist 节点必须通过 atomic store(`atomic.Pointer` 或自定义 release 操作)发布,确保无锁读者看到完整的节点内容。 2. `publishedSequence` 必须是 atomic 变量(`atomic.Uint64`),且其 `Store` 必须在所有 batch entries 的 skiplist 节点都已原子发布之后执行。这保证读者先看到节点,再通过 `publishedSequence` 筛选可见 entry。 3. 读者必须先 `atomic.Load` `publishedSequence`,再遍历 skiplist。
dailz closed this issue 2026-06-11 18:30:07 +08:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dailz/go-kv#9