Doris数据库BE——Stream load流程中事务状态

文章详细描述了StreamLoad系统的事务管理过程,涉及FE的角色、Doris事务状态(如PREPARE到COMMITTED再到VISIBLE和ABORTED),以及TCC模型在分布式事务中的应用,强调了幂等控制、防悬挂控制和并发控制的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
Stream Load的事务管理由FE负责,Doris的事务状态包括:PREPARE、COMMITTED、VISIBLE和ABORTED。
在这里插入图片描述
数据导入开始之前,Coordinator BE节点会向FE发送Begin Transaction请求,FE会为当前label开启一个新的事务,并为事务分配Transaction Id,同时将事务状态设置为PREPARE,然后将Transaction Id以及Begin Transaction成功的信息返回给Coordinator BE。

当数据在所有Executor BE节点完成写入之后,Coordinator BE节点会向FE发送Commit Transaction请求,FE会判断每一个Tablet成功写入数据的副本数量是否超过了Tablet副本总数的一半,如果每一个Tablet成功写入数据的副本数量都超过Tablet副本总数的一半(多数成功),则Commit Transaction成功,并将事务状态设置为COMMITTED;否则,向Coordinator BE返回Commit Transaction失败的信息。COMMITTED状态表示数据已经成功写入,但是数据还不可见,需要继续执行Publish Version任务,此后,事务不可被回滚。

当从FE获取导入计划失败、执行数据导入失败或Commit Transaction失败时,Coordinator BE节点会向FE发送Rollback Transaction请求,执行事务回滚。FE收到事务回滚的请求之后,会将事务的状态设置为ABORTED,并通过Thrift RPC向Executor BE发送Clear Transaction的请求,Clear Transaction任务在BE节点异步执行,将数据导入生成的Rowset标记为不可用,这些Rowset在之后会从BE上被删除。状态为COMMITTED的事务(Commit Transaction成功但Publish Version超时的事务)不能被回滚。

FE会有一个单独的线程对Commit成功的Transaction执行Publish Version,FE执行Publish Version时会通过Thrift RPC向Transaction相关的所有Executor BE节点下发Publish Version请求,Publish Version任务在各个Executor BE节点异步执行,将数据导入生成的Rowset变为可见的数据版本。当Executor BE上所有的Publish Version任务执行成功,FE会将事务状态设置为VISIBLE,并向Coordinator BE返回Commit Transaction以及Publish Version成功的信息。如果存在某些Publish Version任务失败,FE会向Executor BE节点重复下发Publish Version请求直到之前失败的Publish Version任务成功。如果在一定超时时间之后,事务状态还没有被设置为VISIBLE,FE就会向Coordinator BE返回Commit Transaction成功但Publish Version超时的信息(注意,此时数据依然是写入成功的,只是还处于不可见状态,用户需要使用额外的命令查看并等待事务状态最终变为VISIBLE。)

TCC 指的是Try - Confirm - Cancel。Try 指的是预留,即资源的预留和锁定。Confirm 指的是确认操作,这一步其实就是真正的执行了。Cancel 指的是撤销操作,可以理解为把预留阶段的动作撤销了。一个分布式的全局事务,整体是两阶段提交的模型。TCC也是一样的,单相对应2PC和3PC来说,把事务管理从数据库层面,提取到了业务层面。
TCC第一阶段:try行为,试探性操作
TCC第二阶段:confirm或cancel操作,第一阶段成功就会调用confirm,失败就会cancel操作
TCC还需要一个全局事务管理者的角色,用来记录TCC全局事务状态并提交或回滚事务
在这里插入图片描述
由于TCC每一步操作都需要业务上的定义,对于一个操作都要写三个方法对应try、confirm、cancel。因此TCC对业务的侵入性比较大和业务是紧耦合的关系。但是因为TCC是业务上的实现,所以他的适用范围更广,可以跨数据库、跨不同的业务系统来实现事务。

事务控制代码都需要开发去写,所以需要做好异常控制:

空回滚允许-现象是try没有被执行,就调用了cancel。

出现原因:Try超时(丢包)、分布式事务回滚触发cancel、未收到try收到cancel

解决办法:让cancel能够识别出这是一个空回滚,可以记录事务执行状态,cancel中判断try是否执行了。

幂等控制

事务协调着会重复调用,try、confirm、cancel三个方法都需要实现幂等控制

解决办法:记录事务执行状态,如果执行过了,就不再执行。

防悬挂控制-Cancel比Try先执行

出现原因:Try超时(拥堵)、分布式事务回滚触发cancel、拥堵try到达

解决办法:记录事务执行状态,try执行时判断cancel是否执行了。

并发控制

Doris的事务模型中的Coordinator BE就是TCC中的使用者,FE就是TCC中的事务管理者,Executor BE就是TCC中的服务A。

  1. 调用者向事务管理者发起事务相当于Coordinator BE节点向FE发送Begin Transaction请求(当然还有向FE获取导入计划的交互流程未体现);

  2. 调用者向服务调用try,相当于Coordinator BE向Executor BE分发数据;

  3. 服务向调用者返回结果相当于Executor BE向Coordinator BE返回数据写入成功与否;

  4. 调用者向事务管理者发送提交命令即是Coordinator BE节点向FE发送Commit Transaction请求;

  5. 事务管理者向服务调用confirm相当于FE对commit成功的Transaction执行Publish Version,也就是通过Thrift RPC向Executor BE节点下发Publish Version请求。 (当然还有当Executor BE上所有的Publish Version任务执行成功,FE会向Coordinator BE返回Commit Transaction以及Publish Version成功的信息。如果存在某些Publish Version任务失败,FE会向Executor BE节点重复下发Publish Version请求直到之前失败的Publish Version任务成功)

当然对于第四步,调用者向事务管理者发送回滚命令相当于当从FE获取导入计划失败、执行数据导入失败或Commit Transaction失败时,Coordinator BE节点会向FE发送Rollback Transaction请求,执行事务回滚。事务管理者在收到回滚命令后会向服务发送Cancel请求相当于FE收到事务回滚的请求之后,会通过Thrift RPC向Executor BE发送Clear Transaction的请求。

### Apache Doris 中的事务机制 #### 一、事务特性概述 在 Apache Doris 中,事务如同一位细心的管家,负责维护数据的一致性和安全性[^3]。每当执行一系列相关联的操作时,这些操作要么全部成功提交,要么完全回滚,确保不会留下任何不一致的状态。 #### 二、事务支持情况 Apache Doris 高度兼容 MySQL 生态环境,这意味着它能够很好地继承 MySQL 的诸多优秀特性,包括但不限于其事务管理能力[^2]。具体来说: - **原子性**:每一次事务都是不可分割的工作单元; - **一致性**:事务前后数据库保持一致状态; - **隔离性**:并发访问期间不同用户的事务互不影响; - **持久性**:一旦提交后的更改永久保存下来。 #### 三、使用教程 ##### 创建测试表结构 为了更好地说明如何利用事务功能,在此先定义一个简单的表格作为例子: ```sql CREATE TABLE IF NOT EXISTS transaction_example ( id BIGINT, amount DECIMAL(10, 2), description STRING ) UNIQUE KEY(id) DISTRIBUTED BY HASH(id) BUCKETS 8; ``` ##### 开启显式事务控制 默认情况下,每条语句都会被当作独立的小型事务来对待。如果希望手动管理多个SQL命令之间的关系,则可以通过`START TRANSACTION;`开启一个新的事务会话,并通过 `COMMIT;` 或者 `ROLLBACK;` 来结束当前正在进行中的工作流。 ```sql -- 启动新事物 START TRANSACTION; INSERT INTO transaction_example VALUES (1, 99.99, 'First Entry'); UPDATE transaction_example SET amount = 88.88 WHERE id = 1; -- 提交变更 COMMIT; ``` 当遇到错误或者其他意外状况想要撤销所有已做的修改时,只需调用 `ROLLBACK;` 即可恢复到最初状态。 #### 四、最佳实践建议 - 对于批量写入操作,推荐将多条记录打包成单次大容量插入而非频繁发起小规模更新请求,这样不仅能减少锁竞争还能提高整体性能效率。 - 尽量缩短持有锁定资源的时间长度,避免长时间占用造成其他进程等待超时等问题发生。 - 定期备份重要业务逻辑对应的元数据信息以及实际存储的数据文件副本,以便应对可能发生的硬件故障或其他灾难事件带来的损失风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值