如果源库 DDL 变更,Datastream 会如何响应?

解读

在国内金融、电商、SaaS 等真实场景中,源端往往是自建的 MySQL 或 PostgreSQL,业务版本迭代频繁,加字段、改索引、拆表等 DDL 操作几乎每周都有。面试官问“Datastream 如何响应”,核心是想确认两点:

  1. 你是否理解 Datastream 的 CDC 本质——它只解析 binlog/WAL 里的逻辑事件,不持有表结构快照;
  2. 你是否具备 “事前评估 + 事中监控 + 事后兜底” 的完整闭环思路,而不是简单回答“自动同步”或“不支持”。
    答得太浅会被追问“如果字段顺序变了会不会丢数”,答得太深把 Datastream 源码搬出来又显得不接地气。要给出 国内可落地的运维方案,才能体现资深 DBA 或数据架构师的段位。

知识点

  1. Datastream 架构:无代理,通过 IP allowlist/VPC peering 连源库,只读 binlog/WAL,不执行 DDL。
  2. DDL 事件类型:MySQL 的 QueryEvent(DDL SQL 文本)、PostgreSQL 的 RelationMessage(逻辑解码元数据)。
  3. 同步模式
    • 自动同步模式(默认):Datastream 把 DDL 文本原样带到目标 Cloud SQL,成功则继续,失败即暂停作业。
    • 手动模式:DDL 被捕获但不下发,需在 Google Cloud Console 或 Terraform 里点“应用”或“忽略”。
  4. 国内常见坑
    • 源库使用 gh-ost、pt-online-schema-change 产生的临时表会被同步,需加 exclude 正则。
    • MySQL 8.0 instant add column 在 binlog 里仍写全表 rebuild 事件,目标端若磁盘不足会失败。
    • PostgreSQL 逻辑复制槽 在 DDL 后重新发布表,需手动刷新 publication,否则新列不会捕获。
  5. 监控指标
    • ddl_count:每下发一条 DDL 自动 +1,可用于告警。
    • lag_bytes/lag_seconds:DDL 失败时 lag 瞬间冲高,比看日志更快。
  6. 回滚方案:Cloud SQL 开启 point-in-time recovery,DDL 失败先回滚源库,再在 Datastream 控制台“跳过事件”继续同步,避免全量重抽。

答案

“源库 DDL 变更时,Datastream 会先把事件原样捕获,然后根据作业配置决定是 自动下发 还是 暂停等待人工确认
如果目标 Cloud SQL 兼容该 DDL(如加列、加索引),作业继续,毫秒级延迟;若 DDL 在目标端失败(如字段类型不兼容、磁盘满、外键冲突),Datastream 会 立即暂停作业并抛出 FAILED 状态,同时把具体错误日志打到 Cloud Logging。
此时在国内运维流程里,我们会:

  1. 先用 Cloud SQL 的 PITR 把目标库回滚到 DDL 前;
  2. 在 Datastream 控制台选择 ‘跳过该事件’‘修改 DDL 后重试’
  3. 同步恢复后,用 Datastream 的 backfill 机制 只重抽受影响的分区,而不是全表,把对在线业务的影响压到最低。
    此外,上线前我们会在测试环境用 ‘影子表+canary 任务’ 预跑一遍 DDL,确保 Datastream 能正常解析,再把变更窗口放到凌晨低峰期,基本可以做到业务零感知。”

拓展思考

  1. 如果源库是 PolarDB MySQL 8.0 只读实例,binlog 格式为 ROW + 压缩,Datastream 解析会出现 “Event too large” 错误,需要先在源端关闭 binlog 压缩,或把 Datastream 版本升到 1.7.3 以上。
  2. 国内合规要求 “数据不出境”,Datastream 通过 VPC Service Controls 把数据流限制在 上海/北京 region 的 perimeter 内,DDL 日志同样受控,审计员可在 Cloud Audit Logs 里查看谁下发了哪条 DDL,满足等保 2.0 对运维审计的条款。
  3. 未来若业务想 “双向同步”(Cloud SQL ↔ 源库),DDL 必须走 GitOps 流水线,由 Terraform 统一执行,禁止人工直连数据库,否则两边 DDL 顺序不一致会导致 Datastream 进入不可恢复的冲突状态。