首页/数据/数据工程与 ETL 速查/CDC 与源端 DDL 变更处理
CDC 与同步53 条

CDC 与源端 DDL 变更处理

源端 DDL 是 CDC 链路的高频事故源:加列通常影响小,删列/改类型/改主键会让下游解析或写入失败;RENAME 与 TRUNCATE 在 binlog 中表现为 QUERY 事件而非行事件。落地要有“先下游兼容、再执行变更”的发布流程,工具侧只能缓解、不能替代流程。

源端 DDL 为什么危险

源端 DDL 是 CDC 链路高频的事故源:加列通常影响小,删列、改类型、改主键会让下游解析或写入直接失败;RENAME 与 TRUNCATE 在 binlog 里表现为 QUERY 事件而不是行事件,所以只依赖行事件的下游根本收不到「表已被清空」这个信息。落地要有「先让下游兼容、再执行变更」的发布流程,工具侧只能缓解,替代不了流程。

基本信息

低风险变更新增可空列,下游按列名取值时通常无感
高风险变更删列、改类型、改主键,可能导致解析或写入失败
特殊事件TRUNCATE 与 RENAME 在 binlog 中是 QUERY 事件,无逐行删除
应对原则下游先兼容再执行 DDL,避开结算与大促窗口

典型使用场景

  • 新增字段:先确认下游按列名还是按列位置解析
  • 字段下线:先双写观察,再清理旧列
  • 表重命名:同步调整主题映射与下游消费逻辑
  • 清表操作:TRUNCATE 后手工同步目标端清空,避免行数长期不一致
  • 发布流程:把 DDL 纳入变更审批,提前通知数据下游

变更前后的核对动作

变更前后的核对动作
-- 变更前:确认当前结构与目标基线
SHOW CREATE TABLE app.orders\G
SELECT COUNT(*) FROM dw.orders;

-- 变更后:核对目标端是否出现解析或写入错误、行数是否出现偏差
-- 常规做法:先加可空列 → 双写观察一段时间 → 再清理旧列

变更类型与风险

变更类型binlog 表现下游风险
ADD COLUMNQUERY 事件,后续行事件带新列按固定列数组解析的下游报错或丢列
DROP 或 RENAME COLUMNQUERY 事件按旧结构解析然后错位
改数据类型QUERY 事件类型不兼容导致写入失败
TRUNCATEQUERY 事件,无逐行删除目标端未同步清空,行数长期对不上
RENAME TABLEQUERY 事件主题与表的映射失效
常规做法是先加可空列、双写观察一段时间、再清理旧列;大促或结算窗口内避免执行 DDL,一次解析失败可能要回滚整条链路。
不同 CDC 工具对 DDL 的支持程度差别很大:有的记录结构历史并自动适配,有的只保证不崩;接入前先用工具文档确认支持边界,不要靠试。

易错点

  • 以为 TRUNCATE 会生成逐行删除事件,目标端保留了一整份已被清空的数据
  • 在结算窗口执行 DDL,CDC 作业重放到该点时直接解析失败
  • 下游按列位置而非列名解析,加列后字段整体错位
  • 重命名表后未同步主题映射,链路静默停止同步,直到对账才发现

数据来源与参考

  • Debezium 官方文档(DDL 与 schema 历史)
  • MySQL 8.0 官方文档(Replication / Binary Log)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌