OceanBase 什么是分布式事务?两阶段提交(2PC)在 OB 中的执行流程是什么?什么场景下会触发分布式事务?
2 个赞
什么是分布式事务
在 OceanBase 中,分布式事务是指一个事务的操作涉及两个及以上 Tablet(数据分片),这些 Tablet 可能分布在不同的节点上。为了保证事务的 ACID 特性(原子性、一致性、隔离性、持久性),OceanBase 需要协调多个节点上的数据变更,使其要么全部成功提交,要么全部回滚。
OceanBase 通过以下核心技术栈实现分布式事务的强一致性保证:
- 全局时间戳服务(GTS):为每个事务分配全局唯一的事务 ID 与快照时间戳,解决分布式环境下的时钟同步问题。
- 优化的两阶段提交(2PC):保证跨分区操作的原子性。
- MVCC(多版本并发控制):实现读写互不阻塞,支持多种隔离级别(默认读已提交)。
- Paxos 协议:确保事务日志在多数派副本上持久化,提供故障恢复能力。
两阶段提交(2PC)在 OceanBase 中的执行流程
OceanBase 的 2PC 与传统 2PC 有显著区别,其核心特点是协调者无状态(不写日志),事务状态全部由参与者通过 Paxos 日志持久化来保证。
Prepare 阶段
- 确定协调者:事务的发起分区自动成为协调者(Coordinator),无需独立的中心化事务管理器。
- 发送 Prepare 请求:协调者向所有参与事务的分区(参与者,Participant)发送 Prepare 请求。
- 参与者执行预提交:每个参与者收到请求后:
- 在本地执行事务操作(写数据、加锁)
- 将 Redo 日志和 Prepare 状态日志写入基于 Paxos 协议复制的日志流(Log Stream)
- 只有当该日志被多数派副本(如三副本中的两个)持久化成功后,才视为 Prepare 成功
- 返回响应:参与者向协调者返回 Prepare OK(或失败/Abort)。
Commit 阶段
- 判断提交/回滚:
- 若所有参与者均返回 Prepare OK → 协调者向所有参与者发送 Commit 请求
- 若任一参与者失败 → 协调者发起全局回滚(Abort)
- 参与者提交:参与者收到 Commit 请求后,释放锁资源,持久化 Commit 日志,清理事务上下文,并返回 Commit OK。
- 清理阶段:协调者收集所有 Commit OK 后,向参与者发送 Clear 请求,参与者持久化 Clear 日志后退出。
关键优化点(与传统 2PC 对比)
| 对比维度 | 传统 2PC | OceanBase 2PC |
|---|---|---|
| 协调者角色 | 独立的中心化节点,易成单点瓶颈 | 事务发起分区自动担任,去中心化 |
| 日志机制 | 协调者需额外写决策日志 | 协调者不写日志,参与者通过 Paxos 日志保证状态 |
| 响应时机 | 客户端需等待完整两阶段结束 | Prepare 成功后即可提前响应客户端,Commit 异步进行 |
| 故障恢复 | 协调者宕机可能导致事务"悬挂" | 借助 Paxos 日志自动恢复,新 Leader 可查询日志确定事务状态 |
| 单机优化 | 不区分 | 单分区事务直接降级为一阶段提交,完全跳过 2PC |
触发分布式事务的场景
在 OceanBase 中,判断是否为分布式事务的核心标准是:事务的修改是否涉及两个及以上 Tablet(数据分片)。 以下场景会自动触发分布式事务:
同一张表、跨分区修改
表按分区键(如 user_id)做了 HASH/RANGE 分区,当事务中的多条 DML 命中的是不同分区时,即触发分布式事务。
BEGIN;
-- user_id=1001 和 user_id=2002 可能落在不同分区/不同节点
UPDATE tb_order SET amount = 100 WHERE user_id = 1001;
UPDATE tb_order SET amount = 200 WHERE user_id = 2002;
COMMIT;
多张表、跨分区/跨节点同时修改
事务中涉及多张分区表,且这些表的分区分布在不同节点上。典型场景如转账业务:
BEGIN;
-- 扣减账户余额(分区A)
UPDATE tb_account SET balance = balance - 100 WHERE user_id = 1001;
-- 插入订单记录(分区B)
INSERT INTO tb_order (user_id, amount) VALUES (1001, 100);
COMMIT;
涉及全局索引的 DML
当对分区表执行 DML 操作时,如果表上存在全局索引(Global Index),维护全局索引的更新可能涉及其他分区,也会触发分布式事务。
跨租户、跨库操作
在同一集群内对多个租户或数据库对象进行操作时,同样会进入分布式事务流程。