增量空洞检测

增量同步的空洞检测用主键集合做差集:昨日存在、今日消失的主键(排除正常删除),以及状态回退的记录;CDC 断链重放或任务漏跑都会在主键集合上留下痕迹,按日快照主键集合是发现空洞的直接方法。

增量空洞是什么

增量同步按主键做 upsert,一旦 CDC 断链或任务漏跑,某些主键的更新就不会落库——总行数可能没变,数据却已经错了。主键集合做差集是最直接的发现方式:昨日存在、今日消失的主键(排除正常删除),以及状态字段由后向前回退的记录。只看总行数不看主键集合,丢失与补录等量发生时完全检测不出来。

基本信息

适用对象CDC 同步表、按日全量快照表
检查方法相邻两日主键集合差集、状态字段回退检测
必须排除正常删除(CDC delete 事件、is_deleted 标记)
前置条件源端有软删标记,或 CDC 保留 delete 事件
告警口径差集条数占当日增量的比例超过阈值

典型使用场景

  • CDC 断链恢复后:确认断链窗口内的变更是否已补回
  • 例行增量巡检:每日比对相邻两日主键集合,发现静默丢失
  • 补数任务验收:手工重跑后确认丢失的主键已回填
  • 状态机链路核查:检查订单状态是否出现由后向前的回退
  • 对账前排查:金额总量对不上时,先看是否为主键大面积丢失

昨日有今日无的主键

昨日有今日无的主键
-- a 为昨日快照主键,b 为今日快照主键,b 中查不到即为“昨日有今日无”
SELECT a.order_id
FROM (SELECT DISTINCT order_id FROM dwd_orders_df WHERE dt = '2026-10-10') a
LEFT JOIN (SELECT DISTINCT order_id FROM dwd_orders_df WHERE dt = '2026-10-11') b
  ON a.order_id = b.order_id
WHERE b.order_id IS NULL;   -- 记得先排除正常删除再统计结果

状态回退检测

状态回退检测
-- 状态回退:状态序号由大变小,通常是漏跑或乱序到达
SELECT cur.order_id,
       prev.status AS old_status,
       cur.status  AS new_status
FROM dwd_orders_df cur
JOIN dwd_orders_df prev
  ON cur.order_id = prev.order_id
WHERE cur.dt = '2026-10-11' AND prev.dt = '2026-10-10'
  AND cur.status < prev.status;

差集结果的三种来源

结果含义下一步
主键消失且无删除标记同步漏跑或 CDC 断链查任务实例,按时间窗补数
主键消失但源端已删除正常业务删除确认软删标记正常透传即可
主键存在但状态回退乱序到达或上游订正数据核对事件时间戳,判断是否需要去重
有删除业务的表要结合 delete 事件或 is_deleted 标记过滤,否则差集被正常删除淹没。
主键集合比对的前提是有一份可靠的主键快照;没有全量快照时,可退而比对源端与目标端的行数及主键哈希抽样。

易错点

  • 差集里混入大量正常删除,噪音大到无人查看:先过滤 delete 事件或 is_deleted 再统计
  • 只看总行数不看主键集合,丢失与补录等量发生时检测不出
  • 用 DISTINCT 做全量比对在大表上开销很大:先按主键哈希分桶抽样,或只比当日变更窗口
  • 把状态回退一律当成故障:上游订正数据也会造成回退,要结合事件时间判断

数据来源与参考

  • 行业 CDC 与增量同步实践
  • Debezium 官方文档(delete 事件结构)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌