数据库零停机迁移:用 Expand and Contract 控制兼容窗口

将 schema 变更拆成扩展、回填、切换与收缩阶段,保证新旧应用版本可并行运行和安全回退。

文章目录 · 4 节

将新增列、数据回填和删除旧列放在一次发布中,会让应用回滚几乎不可能。Expand and Contract 通过兼容阶段拆开风险。

四阶段迁移

  1. Expand:添加可空列、索引或新表,不改变旧代码行为。
  2. Migrate:小批量回填历史数据,记录进度并可重入。
  3. Switch:新版本双写或改读新结构,持续校验一致性。
  4. Contract:确认所有旧版本退出后再删除旧结构。
ALTER TABLE orders ADD COLUMN region_code varchar(16) NULL;
CREATE INDEX CONCURRENTLY idx_orders_region ON orders(region_code);

不同数据库对在线 DDL 的支持不同,必须验证锁类型、表重写、复制延迟和磁盘空间。

控制回填压力

按主键范围小批提交,限制 QPS,并在复制延迟或业务延迟升高时暂停。不要用一个超大事务回填整表。

发布约束

  • 新旧应用同时运行时都能读写
  • 双写失败有告警和补偿队列
  • 切读前比较新旧结果的差异率
  • 删除字段前搜索所有消费者和离线任务

收尾清单

为每阶段定义进入条件、验证指标和回退方法。迁移完成后删除双写、兼容代码和临时指标,避免永久复杂度。