为什么有些历史数据禁止重做?
区分可重做与禁止重做的变更类型:表结构破坏、业务语义变化、输入契约变化与新老系统重大重构;理解为什么「SQL 能运行」不构成兼容性证据。
为什么有些历史数据禁止重做?
历史重做统一使用最新加工程序,而不是历史版本。但如果程序、表结构或业务语义已经发生破坏性变化,最新程序无法可靠处理历史输入,所谓「重做」就不再安全——这时平台必须直接禁止,转专项修复。
SQL 能跑通,就说明历史数据可以重做吗?
版本边界(Version Boundary)
最新加工程序能够安全处理历史输入的条件边界。越过边界(例如表结构破坏性变更或业务语义变化)时,历史重做不再是恢复动作,而需要先设计数据迁移与回填的专项方案。
平行 Job 用最新程序,不用历史版本
历史重做的目标是让历史结果与当前口径一致,因此平行 Job 统一使用最新加工程序。如果改用历史版本,重做出来的结果仍然停留在旧口径,既不能修正错误,也会与当前下游的期望不一致。
但「用最新程序处理历史输入」有一个前提:最新程序必须能够解释历史输入。程序结构与输入契约在业务演进中发生变化时,这个前提就可能不成立。
- 平行 Job 的 program version 始终是最新版本。
- 使用最新程序是为了让历史结果对齐当前口径。
- 前提是最新程序能可靠处理历史输入,否则进入版本边界。
为什么「SQL 能跑」不等于兼容
SQL 能执行只说明语法正确、依赖可解析、执行计划可生成。它不能证明字段含义没有变化,也不能证明历史数据满足新表的约束,更不能证明新口径与历史口径表达的是同一件业务事实。
常见的越界情形有四类:表结构破坏性变更(字段删除、类型改变、约束变化)、业务语义变化(口径或含义变化)、输入契约变化(历史输入不再满足新程序期望)、新老系统重大重构。任何一类成立时,直接历史重做都可能产出「能跑但错误」的结果。
- SQL 执行成功 ≠ 输入契约兼容 ≠ 结果正确。
- 表结构、业务语义、输入契约与重大重构是四类典型版本边界。
- 越界时必须禁止直接重做,不能凭试跑放行。
切换变更类型,看判定如何变化
选择不同的变更类型:无变更与 SQL 逻辑调整可以生成平行 Job / Plan;表结构破坏、业务语义变化、输入契约变化与新老系统重大重构会直接禁止历史重做,并给出转专项修复的动作。还可以模拟「仅凭 SQL 试跑通过」,观察判定不会因此改变。
被禁止之后怎么办:转专项修复
禁止直接历史重做不等于放弃历史数据,而是换一条更安全的路径:先设计数据迁移 / 历史回填的专项方案,明确新旧字段映射、口径差异、分区与目标表、验证证据和下游消费处理,再按方案执行。
这条路径的成本更高,因此更要在流程上明确:不能因为「重做更快」就把不兼容场景伪装成兼容,绕过版本边界。
- 禁止直接重做 → 专项修复方案(映射 / 口径 / 迁移 / 验证)。
- 专项方案完成并验证后,才谈历史数据恢复。
- 版本边界判定必须由变更类型证据支持,不能凭试跑结论。
可重做与禁止重做的边界
同样的平行 Job / Plan 机制,在不同的变更类型下结果完全不同。
输入契约仍然兼容
- 无变更:程序与契约保持一致。
- SQL 逻辑调整:加工逻辑变化,输入含义不变。
- 使用最新程序生成平行 Job / Plan。
- 重做结果可以对历史下游做重新装数。
历史输入已不兼容
- 表结构破坏性变更:历史数据不满足新约束。
- 业务语义 / 输入契约变化:口径或字段含义已变。
- 新老系统重大重构:历史输入无法被最新程序解释。
- 动作:转专项修复,不以试跑结论放行。