跳到主要内容
分离式内存事务系统全景调研

第7章:持久化、故障与恢复 —— DM 上的 durability 模型

拆解 DM 系统持久化的核心矛盾(MN 不主动 flush)、PMEM / RDMA log 的工程设计、故障模型分类、恢复协议。从 FaRM 到 Plor 系统梳理

DM 事务 持久化 PMEM 故障恢复 epoch lease 调研

事务系统四大基本属性 ACID 中的 D(Durability)和故障下的恢复 是被讨论得最少的——大多数 DM 论文focus在性能,对 durability 一笔带过。但生产 OLTP 必须能”宕机不丢数据”,DM 系统的 durability 模型远比单机复杂:MN 不主动 flush、PMEM 协议复杂、跨副本一致性、CN 故障 vs MN 故障的语义差异。本章把 DM 的持久化、故障、恢复系统梳理一遍——从 FaRM 的 epoch + lease 经典模型,到 Clover / Plor 的 PMEM 加速,再到 LOTUS / AURA 的 CN-side 状态恢复。读完你应该能回答”DM 系统挂了一个节点,会丢什么、能恢复到什么程度”。

📑 目录


1. 单机 vs DM:durability 模型的根本差异

1.1 单机数据库的 durability

   单机持久化路径
   ────────────────
   1. 事务在内存修改
   2. 写 WAL(Write-Ahead Log)→ append to log file
   3. fsync()  ← 强制刷到磁盘
   4. 返回 commit OK 给客户端
   5. 后台异步把 WAL 应用到主数据
   ──────────────────────
   crash 后:从 WAL recover

关键单一进程 + OS 提供的 fsync 语义——简单可靠。

1.2 DM 的持久化路径

   DM 持久化路径
   ────────────────
   1. CN 在本地修改
   2. CN RDMA WRITE 数据到 MN
   3. ??? MN 主机内存不是 PMEM 怎么 flush
   4. ??? CN 怎么知道数据真的落到持久存储
   5. 返回 OK 给客户端
   ──────────────────────
   crash 后:??? 谁来 recover MN 状态

🌟 核心矛盾DM 的 MN 不主动做任何事——MN 既不能主动 flush,也不能主动 recover。所有持久化协议必须由 CN 主导

1.3 三种 durability 假设

DM 系统的 durability 模型按”假设强度”分三档:

模型假设适合
In-memory only节点不 crash,依赖副本实验室 baseline
PMEM-backedMN 主机有 PMEM真正持久化
NVMe + RDMA数据写到 NVMe via RDMA折中方案

🍎 直觉:DM 的”持久化”不像单机的 fsync 那么简单——它是一组协议级约定,要 CN 和 MN 配合才能保证。


2. 三种持久化媒介

2.1 DRAM-only(无持久化)

   配置
   ──────
   - MN 只有普通 DRAM
   - 数据在 DRAM
   - 节点 crash → 数据丢
   
   适合
   ──────
   - 实验室测性能
   - 副本足够多(多 MN)→ 容忍单 MN 丢失

🌟 现状大多数 DM 论文实验是 DRAM-only——FORD / Motor / CREST 的 main result 都是 DRAM。

2.2 PMEM(Intel Optane)

   配置
   ──────
   - MN 主机有 Intel Optane DC PMM
   - byte-addressable + persistent
   - 容量大(768GB/CPU),但比 DRAM 慢 3-5×
特性DRAMPMEM
字节寻址
持久
延迟 (read)~50ns~150-300ns
延迟 (write)~50ns~150-300ns
容量单机 ~1TB单机 6-12TB

⚠️ 现状:Intel 2022 年宣布停产 Optane——PMEM 路线的未来不确定。后续可能被 CXL 持久化设备替代。

2.3 NVMe via RDMA

   配置
   ──────
   - MN 后端是 NVMe SSD
   - CN RDMA WRITE → MN buffer → 异步刷 NVMe
   - 持久化但更慢(~10µs vs PMEM 0.3µs)

优势:容量极大、便宜 劣势:延迟高、协议复杂

🌟 结论目前主流 DM 论文实验仍以 DRAM 为主,PMEM 是少数(Clover / Plor)。CXL 上的持久化是开放方向。


3. PMEM 持久化协议

3.1 PMEM 持久化的硬件协议

   单机 PMEM 持久化(Intel ISA)
   ────────────────────────────
   1. store (write) 到 cache line
   2. clflush / clwb 显式刷 cache → memory controller
   3. memory controller 进入 PMEM controller
   4. PMEM controller 确认写入 ADR domain(电力丢失保护域)
   ──────────────────────────────
   只有第 4 步完成才算"真正持久化"

3.2 RDMA + PMEM 的协议复杂性

   DM 上的 PMEM 持久化
   ────────────────────
   1. CN RDMA WRITE → MN
   2. 数据到 MN 主机内存 cache
   3. ??? cache 何时 flush 到 PMEM
   4. ??? CN 何时知道 PMEM 落下

几个工程做法

做法描述
MN 主动 flush需要 MN CPU(违反 DM 哲学)
特殊 RDMA opDDIO / FLUSH(NIC 直接 flush)
CN 触发CN 写一个 “flush flag” → MN 触发

3.3 RDMA Persist 扩展(实验性)

Mellanox 在新 NIC 中加入了 RDMA Persist:

// 实验性 verb
ibv_post_send(qp, IBV_WR_RDMA_WRITE_WITH_PERSIST, ...);

语义:NIC 保证数据已落 PMEM 才返回 CQE。省去 CN 协议层逻辑

⚠️ 现状:仅在 ConnectX-7+ 实验性支持,主流 DM 论文还没普遍用。

3.4 client-side flush 协议(Clover / Plor)

   主流做法(Clover, Plor)
   ──────────────────────
   1. CN RDMA WRITE 数据 → MN
   2. CN RDMA WRITE 到一个 "flush trigger" 地址 → MN
   3. MN 主机有一个轻量 worker 监听 trigger → 触发 clwb
   4. CN RDMA READ "flush_done" 标志 → 确认完成
   ──────────────────────
   ↑ 仍然需要 MN 一点 CPU,但只是周期性查询

🌟 结论完全 zero-CPU MN 的 PMEM 协议还没有成熟方案——这是开放方向。


4. RDMA log 设计

4.1 为什么需要 RDMA log

事务的 redo / undo log 必须持久化才能 recover。在 DM 上:

   传统 WAL: 写本地磁盘
   DM WAL:   写 MN PMEM via RDMA

4.2 RDMA log 的工程挑战

挑战解释
顺序保证log 必须按事务 commit 顺序 append
持久化保证必须确认落 PMEM 才能 commit
并发 append多 CN 同时写 log 怎么不冲突
GC老 log 何时可以删

4.3 Plor 的核心设计(ATC’23)

核心 insight:把”顺序 append”做成 atomic FAA + WRITE 组合。

   Plor log append 协议
   ────────────────────
   1. log_offset = rdma_faa(global_log_tail, increment=record_size)
      ↑ atomic 拿到唯一 offset
   2. rdma_write(log_addr + log_offset, log_record)
      ↑ 写到对应位置
   3. wait for flush trigger / read flush flag
   ──────────────────────
   ↑ 多 CN 并发 append 不冲突(FAA 保证)

4.4 Plor 性能数字

WorkloadFaRM-style logPlor
Log append latency~15µs~5µs
Log throughput~200K~600K

🌟 结论:Plor 是 DM PMEM log 的当前 SOTA

4.5 Log GC

老 log 何时删?

   GC 决策
   ──────────
   1. 找到所有 CN 的最早 active tx_id
   2. log_record.tx_id < min_active_tx_id → 可删
   3. 后台 worker 周期性 truncate

⚠️ 限制:长事务会 hold log 很久——log 累积压力。


5. 故障模型分类

5.1 故障类型

   DM 系统的故障分类
   ──────────────────
   ┌─────────────────────────────────────┐
   │ 节点故障                             │
   ├─────────────────────────────────────┤
   │ - CN crash                          │ ← 简单
   │ - MN crash                          │ ← 复杂
   │ - 部分故障(CPU OK,NIC 挂)          │ ← 难处理
   ├─────────────────────────────────────┤
   │ 网络故障                             │
   ├─────────────────────────────────────┤
   │ - 丢包(RDMA 自动重传)              │ ← OK
   │ - 网络分区(partition)              │ ← 复杂
   │ - 高延迟(RDMA timeout)             │ ← 中等 |
   ├─────────────────────────────────────┤
   │ 持久化故障                           │
   ├─────────────────────────────────────┤
   │ - PMEM 损坏                         │ ← 副本兜底 |
   │ - SSD 损坏                          │ ← 同上 |
   └─────────────────────────────────────┘

5.2 故障模型四档

模型假设复杂度
Crash-stop节点 crash 后永不返回
Crash-recover节点 crash 后能恢复
Network partition网络分区,节点活但不通
Byzantine节点可能恶意(不在 DM 范围)-

主流 DM 系统假设 Crash-stop + 持久化时考虑 Crash-recover

5.3 故障检测

   主流做法
   ──────────
   - 心跳协议(heartbeat)
   - RDMA timeout 触发
   - epoch + lease(FaRM)
   - Paxos/Raft 维护 membership

6. CN 故障 vs MN 故障

6.1 CN 故障(相对简单)

   CN 故障的影响
   ──────────────
   1. 该 CN 上正在跑的事务全部失败
   2. 客户端重试到其他 CN
   3. CN 上的本地缓存丢失(无所谓,可以从 MN 重读)
   ──────────────
   ↑ 通常不影响数据一致性

但有例外:

系统CN 故障的特殊问题
LOTUSCN-side 锁丢 → 该 CN 拥有的 cohort 不可用
AURA同上,但 fallback 到 MN 兜底
MotorCN 上 active tx 的 ts 丢失,可能阻塞 GC

6.2 MN 故障(复杂)

   MN 故障的影响
   ──────────────
   1. MN 上的数据全部不可访问
   2. 单 MN 配置:整个系统宕
   3. 多 MN 副本:另一个副本顶上

主流做法

  • 每份数据存在多个 MN(FaRM 默认 3 副本)
  • 用 Paxos 协议维护副本一致

🌟 关键事实单 MN 故障是 DM 系统的高严重事件——必须有多副本兜底。

6.3 部分故障

最难处理:节点活着但部分组件挂(如 NIC 挂)。

   症状
   ──────────
   - CN 心跳还在(CPU OK)
   - 但 RDMA op timeout(NIC 挂)
   - membership 协议判它"半死"
   
   处理
   ──────────
   - 把它从 OwnerMap 中移除(AURA)
   - 等 CN 自己 reset NIC 后重新加入

⚠️ 挑战:判断”NIC 慢” vs “NIC 挂”的边界——容易误判。


7. FaRM-style epoch + lease 经典模型

7.1 FaRM 故障恢复的核心思想

Epoch + Lease

   Epoch 协议
   ────────────
   - 全局递增 epoch number(由 config service 管理)
   - 每个 CN/MN 持有一个 lease(时间窗口)
   - lease 过期 → 必须刷新 epoch
   - epoch 推进 → 旧 lease 失效
   ────────────
   ↑ 让"故障检测"和"故障恢复"基于时间窗口,不需要复杂分布式协议

7.2 FaRM 协议详细

   正常时
   ──────
   t=0   epoch=42, lease=10ms
   t=5ms heartbeat OK → lease 续期
   t=10ms heartbeat OK → lease 续期
   ...
   
   节点 X crash
   ──────────────
   t=20ms X 不再发 heartbeat
   t=30ms 其他节点检测到 X 失败
   t=30ms config service 推 epoch → 43
   t=30ms 所有节点开始 recovery(X 上的事务全 abort)
   t=40ms 系统恢复正常

7.3 FaRM 协议的性质

性质价值
不需要 Byzantine 检测简单
time-bound 恢复知道最差恢复时间
epoch 全局有序不会有”两个 leader”问题
基于 Paxos 的 config service可靠

🌟 结论FaRM-style 是 DM 故障恢复的”标准做法”——后续 FORD / Motor / Plor 都用类似的协议。

7.4 FaRM 的局限

⚠️ 限制

  • lease 期间无法快速检测故障(恢复延迟 = lease 时间)
  • 全局 epoch 推进受 Paxos 限制
  • 跨 DC 时 lease 时间过短不可行

8. Plor:PMEM log 加速

8.1 Plor 的双重贡献

第 4 节已经讲了 Plor 的 log append——这里讲它的 recovery

   Plor recovery 协议
   ──────────────────
   1. 系统启动 → 找到所有 PMEM log 的最新 tail
   2. 从 last checkpoint 开始 redo all log records
   3. apply 到主数据
   4. 标记完成 → 系统进入 normal 模式

8.2 加速点

Plor 的 recovery 用 RDMA 并行读 log——多 CN 同时拉取 log records:

   Recovery throughput
   ──────────────────
   单 reader: ~50 MB/s
   多 reader(4 个并行): ~200 MB/s
   ↑ 重启时间从分钟级压到秒级

🌟 意义:DM 系统重启不需要”长时间不可用”——这对生产场景重要。


9. AURA 的 CN-side 状态恢复

9.1 AURA 多了一类故障:owner CN 的状态丢失

   传统 DM(FaRM/FORD):CN 故障无大碍
   AURA:owner CN 故障 = cohort 上的"权威"丢失

9.2 AURA 的应对:fallback to MN

   owner CN 故障检测
   ──────────────────
   1. 心跳超时(500ms)→ 判定 owner 故障
   2. OwnershipPlanner 把 cohort 改为 FALLBACK 状态
   3. publish 新 OwnerMap epoch
   4. 该 cohort 上的事务自动走 MN atomic 路径(与 FORD 相同)
   ──────────────────
   ↑ 不会卡住整个 cohort

9.3 fallback 的语义保证

   AURA 不变式 I4:commit 路径不依赖 owner 位置
   ──────────────────────────────────────────────
   ↑ 即使 owner 在 commit 中途挂,事务可以:
     - abort(自动 retry)
     - 或者继续走 MN atomic(fallback)
   ↑ 数据一致性不损失

🌟 结论AURA 的 fallback 是它”故障安全”的核心——详见模块十五第 6 章。


10. 跨副本一致性

10.1 多 MN 副本的需求

单 MN 系统是 SPOF(single point of failure)。生产 DM 系统必须有多 MN 副本。

10.2 副本协议

   主流副本协议
   ──────────────
   1. Primary-backup(FaRM)
      - 1 个主 + N-1 个备
      - 写到主,主 RDMA WRITE 给所有备 → 等 quorum ack
   
   2. Chain replication
      - 写到 head,head → next → ... → tail
      - tail ack → commit
   
   3. Paxos/Raft
      - quorum-based
      - 通常用于 metadata(不用于数据)

10.3 副本一致性的代价

副本数写延迟容忍故障
1(无副本)~10µs0
2~12µs1
3~15µs1
5~20µs2

🌟 主流选择3 副本——容忍 1 节点故障,延迟可接受。

10.4 跨 DC 副本(开放问题)

   跨 DC 挑战
   ──────────────
   - RTT 从 1µs(同 DC)→ 1ms(跨 DC)
   - 等 quorum ack 延迟爆炸
   - 主流 DM 系统不支持 cross-DC 副本

⚠️ 限制:DM 系统目前都是单 DC——cross-DC 是开放方向(详见第 9 章)。


✅ 自我检验清单

  • DM vs 单机 durability:能解释为什么 MN 不能主动 flush
  • 三种持久化媒介:能列出 DRAM/PMEM/NVMe + 各自延迟
  • PMEM 协议:能解释 cache flush + ADR domain
  • client-side flush:能描述 Clover 的协议
  • RDMA Persist:能说明它的实验性现状
  • Plor log append:能写 FAA + WRITE 协议伪代码
  • 故障模型四档:能列出 crash-stop / crash-recover / partition / Byzantine
  • CN 故障 vs MN 故障:能列出复杂度差异
  • 部分故障难点:能描述 NIC 慢 vs NIC 挂的边界问题
  • FaRM epoch + lease:能描述 lease 续期与 epoch 推进
  • Plor recovery 加速:能说明并行 log 读如何减少重启时间
  • AURA fallback:能解释 owner crash 后 cohort 如何兜底
  • 副本协议三种:能列出 primary-backup / chain / Paxos
  • 3 副本是主流:能说明数字理由

📚 参考资料

关键论文

  • FaRM (Dragojević et al., NSDI’14) —— epoch + lease 经典
  • Clover (Tsai et al., ATC’20) —— PMEM + RDMA 持久化
  • Plor (Lee et al., ATC’23) —— PMEM log 加速
  • Hyder (Bernstein et al., CIDR’11) —— single-leader log 早期参考

PMEM 资料

  • Intel ISA Persistence Programming Model —— 官方 PMEM 编程指南
  • Persistent Memory Programming (Scargall, 2020) —— 教科书

故障与恢复

  • Concurrency Control and Recovery (Bernstein et al., 1987) —— 经典教材
  • Distributed Snapshots (Chandy & Lamport, 1985) —— 分布式快照鼻祖
  • Raft Consensus —— 简化 Paxos

行业讨论

  • Intel Optane DC PMM 停产公告(2022) —— PMEM 路线讨论
  • CXL 2.0 持久化扩展讨论 —— 未来方向