适用范围与批次契约
本文面向 StarRocks 3.3 及以后版本的普通 Stream Load 与 Primary Key 表,讨论写入结果、重放和乱序更新。shared-data 与 shared-nothing 的部分更新和索引能力存在版本差异,应按实际补丁确认。Merge Commit 和 Stream Load 事务接口具有单独的确认语义,本篇不把它们当作普通同步请求。内容待实测,验证等级为 PENDING。
导入前应有源端范围、输入摘要、列映射、业务主键、版本字段与 label 的对应关系。排障只读取既有请求和结果,不向真实表发送数据。能够重复发送一份文件,并不意味着能够安全重复执行这个业务批次。
Primary Key 保存当前状态
Primary Key 表用主键索引定位行,并通过删除标记等结构维护新旧行的有效性,适合订单状态与 CDC 更新。主键唯一性和查询排序是不同需求;主键列须包含分区与分桶列,因此可变日期或租户字段必须谨慎纳入键设计。机制和约束见 Primary Key 表。
SHOW CREATE TABLE analytics.orders_current;
DESC analytics.orders_current;从实际 DDL 确认 PRIMARY KEY,不要把 UNIQUE KEY 名称相似的旧模型直接等同于它。检查 source_version 的类型、是否允许空值以及来源。若把普通属性全部放进复合主键,属性改变会成为新键,不能获得预期的订单状态替换。
Stream Load 的接入与响应
普通 Stream Load 使用 HTTP PUT,向 FE 提交后可能重定向到作为协调者的 BE 或 CN。因此客户端只通 FE 端口而无法访问重定向目的地,也会出现“数据库能连、导入失败”。网络诊断应依据实际重定向目标,不把认证信息发给未经确认的地址,流程见 从本地文件系统导入。
保存 JSON 正文而不仅是 HTTP 返回码。Success 表示数据已加载且可查询;Publish Timeout 表示已成功提交但尚未可查,无需重新导入;Label Already Exists 表明原 label 已使用,可能仍在加载或已经成功。NumberLoadedRows 仅在 Status=Success 时有明确有效性,字段以 STREAM LOAD 参考 为准。
用正确视图追踪导入
普通 Stream Load 不能通过 SHOW LOAD 查询结果,应首先查看保存的响应。在现场版本提供并保留相应记录时,可精确查询 information_schema.stream_loads:
SELECT LABEL, TXN_ID, DB_NAME, TABLE_NAME, STATE,
ERROR_MSG, NUM_ROWS_NORMAL, NUM_ROWS_AB_NORMAL
FROM information_schema.stream_loads
WHERE DB_NAME = 'analytics'
AND TABLE_NAME = 'orders_current'
AND LABEL = 'orders_20260901_batch0042'
LIMIT 5;这是对已知批次的检查,STATE 是该视图中的任务状态,不应直接套用 Doris 的事务状态名称。字段、保留和可见权限需按环境核验;查不到可能是版本、记录范围或保留问题,不是安全重放的证明。字段见 stream_loads 视图。
去重与乱序更新分别验证
Primary Key 保证同一键的有效记录唯一,但不会自动理解上游事件的业务先后。条件更新可通过导入参数 merge_condition 指定版本列。官方示例按传入版本大于或等于当前版本时更新,因此版本相等但载荷不同仍可能产生覆盖,需要上游保证相同版本内容一致,见 通过导入变更数据。
用订单 90001 解释验收:当前版本 20 已支付,迟到版本 19 待支付应被挡住;版本 21 已退款应生效;同为版本 21 却金额不同属于源端冲突。DELETE 不支持同样的条件更新保护,删除事件乱序必须单独设计,不应直接以一次 UPSERT 试验推断删除也安全。
部分更新需要明确缺失列语义
普通完整 UPSERT 与部分更新不能混用。先检查请求是否开启 partial_update、使用 row 还是 column 模式、明确列映射,并确认当前部署形态支持该组合。缺失列、显式 NULL、空字符串和默认值有不同含义,尤其会影响非空约束和新键行为。
将样本拆成“既有键只变状态”“新键只提供部分字段”“显式清空字段”三类,各自写出期望结果。两个并发写入者更新不同列,也要核实版本与合并策略,不能认为开启部分更新就自动解决所有写冲突。本文不提供可直接提交的写入命令,以免把缺失的表定义与数据契约藏在示例中。
label 与 Merge Commit 的边界
普通 Stream Load 的 label 应稳定标识同一份业务输入。记录保留有期限,因此它不是永久去重账本;同一批数据换一个 label 后,仍需要靠业务模型和来源约束避免错误重放。质量过滤与 WHERE 条件过滤也要分开核对,不能用总行数抵消业务键丢失。
从 3.4 起,Merge Commit 可合并并发小请求,但服务端会生成 label、忽略客户端指定 label。异步模式仅确认接收,不保证此时已持久化或可见,也不保证同客户端请求的顺序。使用该模式需独立保存事务结果并验证,不能沿用普通同步模式的“收到成功立即推进位点”规则,见 Merge Commit 说明。
核查有效状态与资源代价
事务结果明确后,按已知主键和分区验证:
SELECT tenant_id, order_id, status, source_version, amount
FROM analytics.orders_current
WHERE order_date = '2026-09-01'
AND tenant_id = 42
AND order_id IN (90001, 90002, 90003)
LIMIT 10;执行前先确认分区裁剪,LIMIT 不是读取成本保证。比较的不只是唯一行数,还包括最高业务版本、状态与金额。新增行数少可能完全正常,因为批次大部分是已有主键更新。
主键索引、删除标记和合并都占用资源。持续小批更新变慢时,观察热分区、索引内存、版本增长与 Compaction,而不是直接提高并发。持久化索引把部分成本转移到存储,不能笼统写成“不占内存”。相关权衡见 Primary Key 表最佳实践。
验收、停止与回退
完成验收需要批次响应或后续终态、输入摘要与 label 对应关系、过滤原因、版本样本和源端位点证据。测试应涵盖重复批次、乱序版本、相等版本冲突、部分更新新键和删除;任何未知语义都不能以“无重复行”结案。
若旧版本覆盖新状态、删除重放产生歧义、记录缺失而源端准备推进,停止自动重试并保留事件。已提交更新不能靠停止加载恢复旧值;回退需要可信旧版本或源端事件重建。关联阅读 StarRocks 两种存储架构 与 查询 Profile 调优。