Apache Doris 事务保障实战教程:从三阶段提交到 Flink 精确一次写入

Apache Doris 打破"OLAP 无需事务"认知。本教程用 7 步实操事务机制:三阶段提交流程、Label 幂等导入、显式多表 ELT、StreamLoad 2PC 对接 Flink,实现金融级数据一致性。

关键词:Apache Doris · 事务保障 · 三阶段提交 · Label · StreamLoad 2PC · Flink · 实战教程


前置准备

  • Apache Doris 2.1+ 集群
  • 基础 SQL + curl 知识

Step 1:验证 READ COMMITTED 隔离级别

sql 复制代码
-- Doris 默认 READ COMMITTED
-- 语句只能看到该语句开始前已提交的数据
​
-- Session 1:开启事务但未提交
BEGIN;
INSERT INTO test_table VALUES (1, 'pending');
​
-- Session 2:查询看不到未提交数据
SELECT * FROM test_table WHERE id = 1;  -- 查不到
​
-- Session 1:提交
COMMIT;
​
-- Session 2:再查询
SELECT * FROM test_table WHERE id = 1;  -- 可见

Step 2:Label 幂等导入

bash 复制代码
# Stream Load 指定 Label
curl -X PUT \
 -H "label:order_batch_20260728_001" \
 -H "column_separator:," \
 -T data.csv \
http://fe_host/api/db/orders/_stream_load
​
# 查询 Label 状态
mysql -h fe_host -P 9030 -uroot -e \
 "SHOW LOAD WHERE label = 'order_batch_20260728_001';"
​
# 重复导入相同 Label → 不会产生重复数据
curl -X PUT \
 -H "label:order_batch_20260728_001" \
 -H "column_separator:," \
 -T data.csv \
http://fe_host/api/db/orders/_stream_load
# 返回:Label already exists

Step 3:三阶段提交验证

sql 复制代码
-- 查看 Doris 集群模式(存算一体 or 存算分离)
SHOW FRONTENDS;
SHOW BACKENDS;
​
-- 存算一体:三阶段 PREPARE → COMMITTED → VISIBLE
-- 导入数据时观察事务状态
SET enable_profile = true;
​
-- 执行导入
INSERT INTO orders SELECT * FROM staging_orders;
​
-- 查看事务状态变化
SHOW TRANSACTION WHERE label LIKE 'insert%';
-- 观察 status: PREPARE → COMMITTED → VISIBLE

Step 4:显式多表 ELT 事务

sql 复制代码
-- 复杂 ELT:多表原子操作
BEGIN;
​
-- 从 staging 表抽取数据
INSERT INTO orders SELECT * FROM staging_orders WHERE dt = '2026-07-28';
​
-- 更新订单状态
UPDATE order_status SET status = 'processed' WHERE batch_id = 'batch_001';
​
-- 清理 staging
DELETE FROM staging_orders WHERE dt = '2026-07-28';
​
-- 全部成功才提交,任一失败自动回滚
COMMIT;
kotlin 复制代码
# 第一阶段:准备提交(数据写入但不可见)
curl -X PUT \
 -H "two_phase_commit:true" \
 -H "label:flink_batch_001" \
 -H "column_separator:," \
 -T data.csv \
http://fe_host/api/db/orders/_stream_load
# 返回: {"TxnId": 18036, "status": "PREPARED"}
​
# 第二阶段:确认提交
curl -X PUT \
 -H "txn_operation:commit" \
 -H "txn_id:18036" \
http://fe_host/api/db/orders/_stream_load_2pc
# 返回: {"status": "Success"}
​
# 如需回滚
curl -X PUT \
 -H "txn_operation:abort" \
 -H "txn_id:18036" \
http://fe_host/api/db/orders/_stream_load_2pc

Step 6:Group Commit 高频导入

sql 复制代码
-- 开启 Group Commit 提升高频导入吞吐
SET enable_group_commit = true;
​
-- 高频小批量导入
-- 多个导入请求会被合并为一个事务
INSERT INTO realtime_metrics VALUES (1, 'cpu', 85.5);
INSERT INTO realtime_metrics VALUES (2, 'memory', 72.3);
INSERT INTO realtime_metrics VALUES (3, 'disk', 91.2);

Step 7:可见性超时配置

ini 复制代码
-- INSERT 操作可见性超时
SET insert_visible_timeout_ms = 30000;  -- 30 秒
​
-- StreamLoad 操作(be.conf)
-- txn_commit_rpc_timeout_ms = 10000
-- 可见性超时 = txn_commit_rpc_timeout_ms / 2 = 5 秒
​
-- 大数据量导入时适当调大
SET insert_visible_timeout_ms = 120000;  -- 2 分钟

事务配置 Checklist

序号 能力 配置 场景
1 READ COMMITTED 默认 所有查询
2 Label 幂等 stream load header 精确一次
3 显式事务 BEGIN/COMMIT 多表 ELT
4 StreamLoad 2PC two_phase_commit:true Flink 对接
5 Group Commit enable_group_commit=true 高频导入
6 可见性超时 insert_visible_timeout_ms 大数据量
7 存算分离 FDB cloud-native 部署 云原生事务

常见问题

Q1:导入后数据什么时候可见? A:三阶段提交中 COMMITTED 后进入 VISIBLE 即可见。通常秒级。可通过 insert_visible_timeout_ms 调整超时。

Q2:Label 重复导入会怎样? A:相同 Label 的导入只会成功一次,第二次返回 "Label already exists",不会产生重复数据。

Q3:StreamLoad 2PC 和普通导入有什么区别? A:普通导入一步完成(写入+可见)。2PC 分两步:先 PREPARED(写入不可见),再 commit(可见)。适合需要事务确认的场景。

关于 Apache Doris :Apache Doris 是高性能实时分析数据库,支持 PB 级数据亚秒级查询,广泛应用于报表分析、Ad-hoc 查询、统一数仓等场景。SelectDB 是 Apache Doris 的商业化公司,提供企业级支持和云服务。欢迎加入 Doris 社区 交流更多实践。

相关推荐
SelectDB1 小时前
Apache Doris 向量化执行实战教程:从 CPU 指令到性能验证的完整实践
后端
神奇小汤圆1 小时前
别再乱排查了!Kafka 消息积压、重复、丢失,根源基本都是 Rebalance!
后端
神奇小汤圆2 小时前
字节二面:10亿数据毫秒级查手机尾号后4位,答不出“异构索引”直接挂?
后端
IT_Octopus2 小时前
Spring Boot 线程池关闭:destroyMethod 的作用与最佳实践
java·spring boot·后端
Leslie1652 小时前
用 Reactor 和 Linux 命名管道实现一个本地事件总线
后端
一只叫煤球的猫2 小时前
ThreadForge 源码解读三:从任务执行到并发编排,ScopeJoiner 是怎么工作的?
后端·性能优化·开源
无限压榨切图仔3 小时前
从 Claude Code 切到 Codex:我用 Agent、Skills、MCP 做完了一个内容运营工具
前端·后端
董员外3 小时前
RAG 系统进化论(一):纵览 RAG 的发展历程
前端·人工智能·后端
Yao8063 小时前
MyBatis-Plus LambdaQueryWrapper实战:告别手写SQL
后端