分布式快照、MVCC 与混合逻辑时钟
本文基于模型知识整理(生成时未联网核对),关键结论建议对照经典文献复核。
一句话定义
分布式系统需要"某个全局时刻的完整一致视图"来做备份、一致性读与事务排序:Chandy-Lamport 快照协议在不停止系统的情况下抓取一致性切面,MVCC 用多版本让读者不阻塞写者,混合逻辑时钟(HLC)则给"无专用时钟硬件"的系统提供接近物理时间的因果时间戳。
为什么重要
"备份时数据在变怎么办""隔离级别底层怎么实现""跨地域数据库的时间戳从哪来"——三个高频工程问题的答案都指向本条。它是连接一致性模型(kp-013)与存储引擎实现(kp-032)的桥梁层。
前置知识
核心概念
- 一致性快照(consistent snapshot):快照内部满足"如果记录了某消息的接收,也必记录其发送"——即不出现"凭空出现的消息"。
- Chandy-Lamport 协议: initiator 发带标记(marker)的记录消息;节点收到首个 marker 时记录自身状态并把自己的出边全部打标;marker 在信道上的语义是"此前收到的都算入快照"。系统不停机,快照异步完成。
- MVCC(多版本并发控制):每次写产生新版本(带版本号/时间戳),读按快照版本取可见版本——读写互不阻塞,是快照隔离与一致性读的引擎。
- HLC(Hybrid Logical Clock):时间戳 = (物理毫秒, 逻辑计数),物理部分跟随本地墙钟并与所见消息取最大,逻辑部分在物理部分不变时递增——既接近真实时间(便于 TTL/调试/分页),又保持因果单调(物理时钟回拨也能保证递增)。
原理与机制
为什么快照协议能保证一致性:marker 划定了每条信道的"分界线"——分界前收到的消息,其发送必然发生在发送方记录状态之前(消息先行于 marker)。归纳起来快照里不存在"接收在快照内、发送在快照外"的幻影消息,于是快照是系统的一个可达状态(可作恢复点)。注意它记录的是切面状态而非"某一物理瞬间"——异步系统本没有全局瞬间。
MVCC 与隔离级别的映射:只读最新已提交版本 = 读已提交;读"事务开始时"的版本 = 快照隔离;可见性判定再叠加提交时间戳排序 = 可串行化的基础(SSI 在其上加冲突检测)。存储层实现通常是 per-key 版本链 + GC(老版本回收,回收水位依赖活跃事务最小快照点——长事务会顶住 GC 水位,是 MVCC 系统的经典运维坑)。
HLC 解决什么:纯逻辑时钟(kp-004)与真实时间脱节(TTL、按时间查询困难);纯物理时钟不单调(kp-003)。HLC 以物理时间为主轴、逻辑计数兜底因果,让单库时间戳可直接跨库比较(CockroachDB 用它做全局事务时间戳,无需 TrueTime 硬件)。
图示
Chandy-Lamport:
P1 ──[marker]──► P2: P2 收到 marker → 记录自己状态 → 对 P2 的出边打标
信道语义: marker 之前收到的消息已入快照, 其发送方必已记录 → 无幻影消息
MVCC:
key=balance: v5=100(ts=41) ← v6=80(ts=47) ← v7=95(ts=52)
事务(快照ts=47)读 balance → 取 ts≤47 的最新版本 v6=80
实例或案例
- 数据库在线备份:基于 MVCC 快照的一致性备份(如 TiDB BR、PG pg_backup_start 时代的备份)无需停写。
- Kafka Streams / Flink 的 checkpoint:分布式快照思想(barrier 对齐)实现 Exactly-once 状态。
- CockroachDB:HLC 时间戳 + MVCC 版本链,跨地域无硬件获得可串行化事务。
- TiDB:中心化 TSO(单一时间戳服务)发号 + Percolator 风格 MVCC,另一种时间戳来源路线。
常见误区
- 误区一:"快照 = 某一物理时刻的冻结"。异步系统无全局瞬间;快照是一致性切面(因果自洽的状态),两组件的记录时刻可以不同。
- 误区二:"MVCC 无锁所以没有代价"。写写冲突仍需检测/等待;长事务阻止版本 GC,历史版本膨胀会拖垮读性能与磁盘。
- 误区三:"HLC 让墙钟变准了"。HLC 不修正物理时钟(kp-003 的结论不变),只是把"物理部分"包进单调因果框架,物理部分本身仍不可信。
与其他知识点的关系
- kp-003/004:HLC 是物理与逻辑时钟的合流点。
- kp-013:MVCC 是一致性读的实现载体。
- kp-023/032:跨节点提交的时间戳排序(Spanner commit wait、TiDB TSO、CRDB HLC 三条路线对比)。
自测题
- Chandy-Lamport 快照如何排除"幻影消息"?
答:marker 划定信道分界,marker 前收到的消息其发送必在发送方快照记录之前(消息先于 marker 传播),故快照中消息的收发两端闭合。
- 为什么长事务会拖垮 MVCC 系统?
答:GC 水位取决于最老活跃事务的快照点,长事务使其后所有旧版本无法回收,版本链膨胀拖慢读与占用存储。
- HLC 相比纯 Lamport 时钟多了什么能力?
答:时间戳携带真实物理时间信息,支持 TTL、按时间范围查询与跨系统调试,同时保留因果单调性。
延伸阅读
- K. Mani Chandy & Leslie Lamport, "Distributed Snapshots: Determining Global States of Distributed Systems"(TOCS 1985)。
- CockroachDB 文档:HLC 设计(hybrid logical clock RFC)。
- Kleppmann《DDIA》第 7 章(快照隔离与可串行化)。