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;
Step 5:StreamLoad 2PC 对接 Flink
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 社区 交流更多实践。