一、事务模型概览
分布式事务设计旨在同时保证正确性与高效性。TDSQL Boundless 对事务的读写和提交链路进行了全面优化。
二、参与者管理机制
·复制组为单位:以 Replication Group 为基本单位管理事务参与者
·自动创建上下文:当事务访问特定复制组数据时,自动创建对应的参与者上下文
·分散缓存:SQLEngine 层不缓存事务数据,由 TDStore 实现分散缓存
三、事务执行流程
1. 获取读时间戳:事务执行第一条语句时,从 MC 获取时间戳作为读快照
2. 读写操作:访问数据对应的 Replication Group 的 Leader 副本,在该副本上创建参与者上下文
3. 事务提交:选择其中一个参与者担任协调者,向协调者发送提交请求
四、数据缓存机制
| 特性 | 说明 |
| 提交前缓存 | 事务数据在提交前完全缓存在内存中 |
| SQLEngine 不缓存 | SQLEngine 层不缓存事务数据 |
| 分散缓存 | 由 TDStore 实现分散缓存 |
| 提交时持久化 | 仅在事务提交阶段进行数据持久化操作 |
五、2PC 下沉
TDSQL Boundless 将 2PC 的实现完全下沉到 TDStore 层,SQLEngine 不感知事务提交流程。
提交流程:
1. SQLEngine 提交分布式事务,从参与者中选取一个节点作为协调者
2. 向选定的参与者节点发送提交请求,请求中包含事务涉及的所有参与者列表
3. 接收请求的节点在其复制组内创建协调者上下文
4. 协调者负责向其他参与者发送读写请求,推进完整的 2PC 流程
六、数据持久化
TDStore 直接使用 Raft log 作为 WAL 日志,数据写入 LSM-Tree 不需要额外写 WAL 日志:
1. 节点重启时从上一记录点回放 Raft Log
2. 数据刷新到磁盘后推进日志点,减少宕机时需回放的日志量
3. 通过单一 Log 实现备机数据同步和故障恢复双重功能
七、日志式 vs 协商式 2PC
TDSQL Boundless 采用协商式 2PC,相比传统日志式 2PC 具有显著优势:
| 对比项 | 日志式 2PC | 协商式 2PC (TDSQL Boundless) |
| RPC 轮数 | 2轮 (prepare、commit) | 3轮 (prepare、commit、clear 异步) |
| 日志同步次数 | 参与者2次 + 协调者3次 = 5次 | 参与者同步3次(含1次异步) |
| 故障处理 | 宕机重启,参与者/协调者回放本地日志即可确定状态 | 宕机重启,参与者回放本地日志即可确定状态;协调者需要通过参与者发送的消息确定状态 |
核心优势:
·使用协商式 2PC 避免协调者同步日志带来的开销
·保证跨 Replication Group 事务的原子性
·日志同步次数从5次降低到3次
八、亲和性定义
数据亲和性:数据之间存在相关性,例如:
·表内部的主键和二级索引
·不同表之间的连接键
将相关的数据调度到同一个复制组,可以进行事务优化。
九、典型案例:表内亲和
场景:用户创建包含 ID、姓名、年龄的表,并在年龄列创建二级索引。
传统方案的问题:
·主键索引和二级索引 key 范围相距较远
·必须通过 2PC 完成分布式事务
·事务执行效率显著低于单机事务
TDSQL Boundless 优化方案:
·将关联数据(主键与二级索引)置于同一复制组
·查询读写只需向目标复制组发送请求
·事务提交只需与单个复制组交互
·通过 1PC 协议极大提升事务处理效率
十、基于数据感知的调度
典型案例分析:
1. 用户创建包含 ID、姓名、年龄的表(表 ID 为100)
2. 在年龄列创建二级索引(索引表 ID 为200)
3. 主键索引 key 前缀为00000064,二级索引 key 前缀000000C8,两者 key 范围相距较远
十一、典型案例:跨表亲和
场景:小数据量商户余额账户表与大数据量商户流水账户表共存。
数据增长处理流程:
1. 初始状态:两表共存于同一节点
2. 数据增长:表开始自动分裂 Region(速度不同)
3. 确保相关性:对 Table 2 的 Region 进行自动分裂,将复制组也做分裂
4. 数据范围对齐:RG1管理数据范围0-5,RG2管理数据范围5-9
5. 负载增加时:RG2迁移至其它节点,实现数据拆分同时保证亲和性
十二、亲和性收益总结
| 收益 | 说明 |
| 数据本地化 | 经常被共同操作的数据存放在同一节点 |
| 减少 RPC | 读写涉及更少的数据移动和 RPC 调用 |
| 避免分布式事务 | 单复制组内操作无需 2PC |
| 大幅提升性能 | 显著降低延迟和网络开销 |