SQL 血缘与调度依赖:如何圈定依赖链重做范围?
联合 SQL 血缘、调度依赖与业务日期分区圈定影响范围,去重生成重做清单,并区分「停止集合 / 重做集合 / 等待集合 / 通知集合」。
SQL 血缘与调度依赖:如何圈定依赖链重做范围?
确认 2026-10-16 的 ODS_TRANSACTION 分区需要修复之后,下一个问题是:哪些任务必须重做?只按调度 DAG 找下游会漏,只按 SQL 血缘找也会漏;正确做法是把 SQL 读写血缘、实际调度依赖和业务日期分区放在一起判断。
一个校验任务既不读写 ODS_TRANSACTION,为什么也在重做范围里?
影响范围(Impact Scope)
一次数据事故中,需要停止、重做、等待或通知的任务实例集合。它由 SQL 读写血缘、实际调度依赖和业务日期 / 分区联合确定,而不是只看某一条关系或某个报错节点。
先分清两种关系:SQL 血缘与调度依赖不是一回事
SQL 血缘回答「这张表的输入来自哪里」:DWD 明细读取 ODS_TRANSACTION,所以 ODS 分区被污染时 DWD 进入范围。调度依赖回答「Job / Plan 里谁必须等谁完成」:完整性校验任务并不读取交易明细,但它的调度依赖是接入任务,接入任务重做时它也必须重做。
只按其中一种关系圈范围都会漏:只按血缘会漏掉调度型下游;只按 DAG 可达性会把没有数据关系、只是碰巧串在一起的任务也算进来。两种关系必须分别计算、取并集,再回到实例级别判断分区。
- SQL 血缘:reads / writes 与 JOIN 方式决定数据是否被污染。
- 调度依赖:实际 Job / Plan 的 dependsOn 决定哪些下游必须重新调用。
- 两类关系取并集后去重,才是重做清单的候选集合。
再到实例级别:业务日期与分区决定「这一次」是谁
同一个任务每天都有一个实例。ODS_TRANSACTION 2026-10-16 分区出错,不代表 2026-10-15、2026-10-10 的实例也要重做。影响范围必须收敛到「任务 + 业务日期 / 分区」的实例级:同一任务的其他分区、其他日期的实例保持原状态。
这也是为什么血缘影响分析的通用方法要先讲清楚表、任务和实例三层关系;字段级血缘与调查方法见 7-1 / 7-2,影响分析的通用框架见 7-4。
- 图上的节点是任务,重做清单里的对象是任务实例。
- 分区不匹配的实例不进入范围,避免无关日期被误伤。
- 下游已经在运行的实例要先停止;尚未启动的进入等待。
点击源节点,看范围是怎样长出来的
点击任一任务节点(推荐 ODS_TRANSACTION 事故源):实验会联合 SQL 血缘、调度依赖与业务日期分区计算影响闭包,输出停止 / 重做 / 等待 / 通知四类集合、去重后的重做清单与逐条影响证据。
四类集合:停止、重做、等待、通知各管什么
圈定范围之后,不同状态的实例走不同处理:正在运行或就绪的实例先停止或阻断,确认副作用处置后进入等待;已经执行过的实例全部重做,包括成功、失败和已停止的实例;尚未首次执行的实例保持等待,等依赖满足后由调度自动调用;受影响的消费方单独进入通知集合,因为数仓重做完成不等于消费端恢复。
重做清单要去重:ADS 报表同时读商户支和渠道支,两条证据都会指向它,但它只能重做一次。去重按实例而不是按证据做,既要保留「为什么进入范围」的证据,也要保证执行清单中没有重复项。
- 停止集合:running / stopping / ready 的受影响实例。
- 重做集合:success / failed / stopped 的受影响实例。
- 等待集合:waiting / blocked / skipped 的受影响实例。
- 通知集合:受影响的消费方,需要重新装数与确认。
LEFT JOIN:结果没变化也要重做
DWS 商户汇总用 LEFT JOIN 读取商户资料。很容易产生一个想法:反正 LEFT JOIN 允许右侧缺失,连接结果看起来没有变化,是不是可以不复算这一支?答案是不行。
判断依据是血缘链是否被污染,而不是这次连接结果是否变化。该任务读取的被污染输入已经进入了它的加工链,输出就必须重新计算;「看起来没变」不能作为排除条件。同理,本次事故中商户支的实际结果是否变化,要在重做完成后用数据核对回答,而不是在圈范围时提前假设。
- LEFT JOIN 不等于「可以忽略右侧输入」。
- 已执行实例只要在血缘范围内就重做,不做结果预判。
- 是否变化由重做后的核对回答,而不是范围判断的输入。
两种范围判断方式
同一个事故,两种判断方式会得到完全不同的重做清单。
只重跑报错的任务
- 本次事故没有任何任务报错,无法确定起点。
- 即使定位到 ODS 成因,也会漏掉调度型下游与消费方。
- LEFT JOIN 支可能被「看起来没变」排除。
血缘 + 调度 + 分区联合圈定
- 两类关系取并集,已执行实例全部重做。
- 按实例去重,汇合节点只执行一次。
- 未执行进入等待,无关分区与链路保持原状。