OceanBase|OBCE 每日一题

OceanBase 什么是分布式事务?两阶段提交(2PC)在 OB 中的执行流程是什么?什么场景下会触发分布式事务?

2 个赞

:pushpin: 什么是分布式事务

在 OceanBase 中,分布式事务是指一个事务的操作涉及两个及以上 Tablet(数据分片),这些 Tablet 可能分布在不同的节点上。为了保证事务的 ACID 特性(原子性、一致性、隔离性、持久性),OceanBase 需要协调多个节点上的数据变更,使其要么全部成功提交,要么全部回滚。

OceanBase 通过以下核心技术栈实现分布式事务的强一致性保证:

  • 全局时间戳服务(GTS):为每个事务分配全局唯一的事务 ID 与快照时间戳,解决分布式环境下的时钟同步问题。
  • 优化的两阶段提交(2PC):保证跨分区操作的原子性。
  • MVCC(多版本并发控制):实现读写互不阻塞,支持多种隔离级别(默认读已提交)。
  • Paxos 协议:确保事务日志在多数派副本上持久化,提供故障恢复能力。

:arrows_counterclockwise: 两阶段提交(2PC)在 OceanBase 中的执行流程

OceanBase 的 2PC 与传统 2PC 有显著区别,其核心特点是协调者无状态(不写日志),事务状态全部由参与者通过 Paxos 日志持久化来保证。

Prepare 阶段

  1. 确定协调者:事务的发起分区自动成为协调者(Coordinator),无需独立的中心化事务管理器。
  2. 发送 Prepare 请求:协调者向所有参与事务的分区(参与者,Participant)发送 Prepare 请求。
  3. 参与者执行预提交:每个参与者收到请求后:
  • 在本地执行事务操作(写数据、加锁)
  • 将 Redo 日志和 Prepare 状态日志写入基于 Paxos 协议复制的日志流(Log Stream)
  • 只有当该日志被多数派副本(如三副本中的两个)持久化成功后,才视为 Prepare 成功
  1. 返回响应:参与者向协调者返回 Prepare OK(或失败/Abort)。

Commit 阶段

  1. 判断提交/回滚
  • 若所有参与者均返回 Prepare OK → 协调者向所有参与者发送 Commit 请求
  • 若任一参与者失败 → 协调者发起全局回滚(Abort)
  1. 参与者提交:参与者收到 Commit 请求后,释放锁资源,持久化 Commit 日志,清理事务上下文,并返回 Commit OK。
  2. 清理阶段:协调者收集所有 Commit OK 后,向参与者发送 Clear 请求,参与者持久化 Clear 日志后退出。

关键优化点(与传统 2PC 对比)

对比维度 传统 2PC OceanBase 2PC
协调者角色 独立的中心化节点,易成单点瓶颈 事务发起分区自动担任,去中心化
日志机制 协调者需额外写决策日志 协调者不写日志,参与者通过 Paxos 日志保证状态
响应时机 客户端需等待完整两阶段结束 Prepare 成功后即可提前响应客户端,Commit 异步进行
故障恢复 协调者宕机可能导致事务"悬挂" 借助 Paxos 日志自动恢复,新 Leader 可查询日志确定事务状态
单机优化 不区分 单分区事务直接降级为一阶段提交,完全跳过 2PC

:dart: 触发分布式事务的场景

在 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),维护全局索引的更新可能涉及其他分区,也会触发分布式事务。

跨租户、跨库操作

在同一集群内对多个租户或数据库对象进行操作时,同样会进入分布式事务流程。