这是一个非常典型的 数据可见性(Data Visibility) 和 事务隔离 问题,在基于MVCC(多版本并发控制)的OLAP系统中,尤其是在数据加载和后台任务并发执行时,需要仔细排查。
1. Compaction是否是原因?
结论:Compaction(数据合并)本身导致数据不一致的可能性极低。
原因: StarRocks使用MVCC机制。当一个查询(包括您的 INSERT OVERWRITE 语句)开始执行时,它会锁定一个特定的数据版本(Snapshot)。Compaction是一个后台任务,它合并数据文件,但不会改变数据的逻辑内容,也不会影响正在运行的查询所读取的快照。只有当Compaction完成后,新的查询才会看到新的、合并后的版本。
因此,如果数据不一致,通常不是Compaction导致的,而是 数据加载或事务提交的时序 导致的。
2. 最可能的原因:T-2数据加载的可见性问题
您描述的现象——“凌晨写入的结果”和“早上查询的结果”不一致,且涉及的数据是T-2的、未变动的数据——最可能的原因是:
当凌晨的 INSERT OVERWRITE 任务开始执行时,前一天(T-2)的数据加载任务尚未完全提交或对查询不可见。
详细解释:
-
T-2数据加载: 假设T-2的数据是在昨晚23:00开始加载到
dm.dm_08_loan_rcapi_d 表中。
-
凌晨统计开始: 您的
INSERT OVERWRITE 任务在00:00开始执行。
-
并发状态: 如果T-2的数据加载任务在00:00时尚未完成(即Load Job状态不是
FINISHED ),或者虽然数据已经写入但事务尚未完全提交,那么 INSERT OVERWRITE 任务读取到的数据可能是一个 不完整 的T-2快照。
-
早上查询: 到了早上,T-2的数据加载任务早已完成并提交。此时您手动执行
SELECT 语句,它读取的是一个 完整且最新 的快照。
结果: 凌晨的 INSERT OVERWRITE 遗漏了部分T-2的数据,导致统计结果偏低或不一致。
3. 排查思路和建议
针对上述最可能的原因,您可以按照以下步骤进行排查:
步骤一:检查T-2数据加载状态
这是最关键的一步。
-
确定T-2数据加载任务的结束时间: 找到将T-2数据写入
dm.dm_08_loan_rcapi_d 表的Load Job(无论是Broker Load, Routine Load, 或其他方式)。
-
检查Load Job状态: 使用
SHOW LOAD 命令(如果是异步加载)或查看相关日志,确认该Load Job的状态变为 FINISHED 的具体时间点 T_{load\_finish} 。
-
对比统计任务开始时间: 确认您的
INSERT OVERWRITE 任务的开始时间 T_{insert\_start} 。
-
判断: 如果
T_{insert\_start} 早于 T_{load\_finish} ,那么这就是导致数据不一致的直接原因。
解决方案: 确保您的统计任务( INSERT OVERWRITE )在所有前置数据加载任务 完全结束并提交 之后再开始执行。
步骤二:检查并发写入冲突
虽然可能性低于步骤一,但仍需检查。
-
检查并发写入: 在凌晨
INSERT OVERWRITE 任务执行期间,是否有其他任务正在对 dm.dm_08_loan_rcapi_d 表进行写入( INSERT INTO 或 UPDATE )。
-
隔离级别: StarRocks默认提供快照隔离(Snapshot Isolation),这通常能保证读取一致性。但如果存在大量高并发的写入操作,并且这些操作涉及您查询的T-2分区,可能会引入极小的风险。
步骤三:隔离并分析异常数据
-
定位异常数据: 找出在凌晨临时表 (
mid_08_loan_rcapi_d_temp8 ) 中和早上查询结果中不一致的 LOANACNO 列表。
-
查询原始表: 针对这些异常的
LOANACNO ,分别在早上和凌晨(如果能重现)查询原始表 dm.dm_08_loan_rcapi_d 的明细数据:
-- 假设不一致的LOANACNO是 '123456'
SELECT * FROM dm.dm_08_loan_rcapi_d A
WHERE A.LOANACNO = '123456' AND A.WORKDATE2 < '2025-10-22';
-
对比明细: 比较两次查询返回的行数和总和是否一致。如果行数不一致,则确认了凌晨的
INSERT OVERWRITE 确实没有读取到全部数据。
总结建议
最稳妥的做法是 在调度层面增加依赖检查 。确保负责加载 dm.dm_08_loan_rcapi_d 表T-2数据的任务成功完成后,再触发 mid.mid_08_loan_rcapi_d_temp8 的统计任务。
如果您的数据加载是通过 StarRocks 的 Load Job 完成的,请务必检查 SHOW LOAD 结果,确保状态为 FINISHED 。