FoundationDB 事务如何实现?从源码看 GRV、Resolver、TLog 与 Storage Server

FoundationDB 支持跨任意 key range 的 ACID 事务,并向应用提供严格可串行化语义。但它既没有让每个 Storage Server 参与经典的两阶段提交,也不是传统单机数据库中“共享缓冲池 + Undo/Redo”的事务实现。 它的核心方案可以概括为: 全局版本号 + MVCC 快照读 + 客户端暂存修改 + Resolver 乐观冲突检测 + 多副本 TLog 持久化。 本文结合 FoundationDB 官方源码,沿着一笔事务的完整路径,解释它如何从读取、提交、冲突检测,一直走到日志持久化和 Storage Server 应用。 本文分析的源码版本为: commit: eab21ffe07c20575d5bac9ab0745375b8f7f8357 date: 2026-08-12 源码中的具体行号会随版本变化,阅读时应以函数和类型名为主要定位依据。 一、整体架构 FoundationDB 的事务涉及以下核心角色: 角色 主要职责 Client 保存事务 mutations、读冲突范围和写冲突范围 GRV Proxy 分配 Read Version Commit Proxy 批量接收事务、分配 Commit Version、组织提交流水线 Resolver 检测乐观事务冲突 TLog 复制并持久化已提交 mutations Storage Server 提供版本化读取,异步应用 TLog mutations Sequencer 为事务系统提供版本推进基础 完整流程可以简化为: Client │ ├── 获取 Read Version │ ├── 从 Storage Server 读取该版本 │ ├── 在客户端积累 mutations 和 conflict ranges │ └── 提交 │ ▼ Commit Proxy │ ├── 组成 Commit Batch ├── 分配 Commit Version └── 按 key range 发给 Resolver │ ▼ Resolver │ ├── 检查 read conflict ranges ├── 登记 write conflict ranges └── 返回 committed / conflict / too old │ ▼ Commit Proxy │ ├── 丢弃冲突事务 ├── 为 mutation 添加 Storage Server tag └── 将成功事务写入 TLog │ ▼ TLog │ ├── 按冗余策略复制和持久化 └── 返回 durable │ ▼ Commit Proxy │ └── 向 Client 返回 Commit Version │ ▼ Storage Server ├── 异步读取自己的 tagged mutations ├── 应用到内存中的版本化数据 └── 后台持久化到 Storage Engine 最关键的解耦是: ...

2026年8月14日 · 9 分钟 · Hellokitty