分布式事务原理

最近更新时间:2025-12-24 12:03:44

我的收藏

分布式事务模型:读写阶段

分布式事务设计旨在同时保证正确性与高效性。随着业务规模不断扩大,对数据库系统负载能力提出更高要求。为应对此类高并发场景,必须对事务的读写和提交链路进行全面优化。

参与者管理机制:以复制组(Replication Group)为基本单位管理事务参与者。当事务需要访问特定复制组数据时,自动创建对应的参与者上下文。SQLEngine 的一个事务单元,访问 TDStore 集群上的多个参与者,每个参与者管理一个 Replication Group 的数据。
事务模型特性
事务在执行第一条语句的时候,会从 MC 获取时间戳,作为读快照。事务执行读写请求的时候,会去访问数据对应的 Replication Group 的 Leader 副本,并在该副本上创建一个参与者上下文。参与者上下文位于内存中,会缓存事务在该 Replication Group 上写入的数据,以及持有的悲观锁。事务提交时,会选择其中某一个参与者担任协调者,并向该协调者发送提交请求,请求中带有该事务访问过的所有 Replication Group 的 ID。协调者收到后,会按照 2PC 流程,保证所有参与者数据提交的原子性。在 2PC 的 commit 阶段开始前,协调者会从 MC 再次获取一个时间戳,作为 commit_ts,这个 commit_ts 会随着 2PC 的 commit 请求下发到各个参与者,并作为数据写入 RocksDB 的 sequence number。在后续做可见性判断的时候,会将读操作的读时间戳和各个版本的 sequence number 做比较,对于 sequence number 小于读时间戳的所有版本,选取 sequence number 最大的版本读取。
数据缓存机制
事务数据在提交前完全缓存在内存中。
SQLEngine 层不缓存事务数据,由 TDStore 实现分散缓存。
仅在事务提交阶段进行数据持久化操作。
内存管理机制
事务在内存中的数据(包括未提交的数据和悲观锁信息等)大小被严格限制
正在推进大事务数据提前落盘功能,减缓内存使用压力,从根本解决问题

分布式事务模型:提交阶段

2PC 下沉

2PC 的实现被完全下沉到 TDStore 层,SQLEngine 不感知事务提交流程。
1. SQLEngine 提交分布式事务时,从参与者中选取一个节点作为协调者。
2. 向选定的参与者节点发送提交请求,请求中包含事务涉及的所有参与者列表。
3. 接收请求的节点在其复制组内创建协调者上下文。
4. 由协调者负责向其他参与者发送读写请求,推进完整的 2PC 流程。

数据持久化

TDStore 直接使用 Raft log 作为 WAL 日志,数据写入 LSM-Tree 不需要额外写 WAL 日志。具体做法:
1. 节点重启时从上一记录点回放 Raft Log。
2. 数据刷新到磁盘后推进日志点,减少宕机时需回放的日志量。
3. 通过单一 Log 实现备机数据同步和故障恢复双重功能。相当于减少了额外写入 WAL 的步骤,也达到了减少写数据量的目的。


分布式事务提交原理

传统 2PC 的瓶颈:在传统的两阶段提交实现中,协调者和参与者都需要同步日志,导致整个流程需要5次日志同步操作,这在性能上存在明显瓶颈。
TDSQL Boundless 核心优化实现了分布式事务下沉,使用协商式 2PC 避免协调者同步日志带来的开销,保证了跨 Replication Group 的事务的原子性。


日志式
协商式
RPC 轮数
2轮 RPC:prepare、commit
3轮 RPC:prepare、commit、clear(异步)
日志同步次数
参与者2次 + 协调者3次 = 5次日志
参与者同步3次日志(包含1次异步日志)
故障处理
宕机重启,参与者/协调者回放本地日志即可确定状态
宕机重启,参与者回放本地日志即可确定状态,协调者需要通过参与者发送的消息确定状态
参与者必须定时向协调者发消息告知状态