同步任务按 UTC 日切,每天 00:00 跑前一天分区。北京时间 00:00 到 08:00 的数据连续两天都进了分区,报表多算了一倍。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
SELECT toStartOfHour(create_time) h, COUNT(*)
FROM ods_order WHERE dt IN ('2026-02-28','2026-03-01')
GROUP BY h ORDER BY h;
分区条件用 toDate(create_time),而 create_time 存的是本地时间,日切时刻却按 UTC 算。两个口径差 8 小时,边界那一段在两天里各被圈进去一次。分区写入又是追加模式,重复不会自动覆盖。这一点先确认清楚,后面就不用反复试。
碰到「跨时区日切重复」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。
改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。
具体做法是,全链路统一时区 要么都存 UTC 要么都存本地;分区条件按明确边界写 不要用 toDate 隐式转换;分区写入改成 insert overwrite 同一分区;补一次边界核对 按小时统计行数。
改完照着核一遍,每个小时只归属一个分区 两天分区行数相加等于源表总数。
