← 中文资源

简体中文版本

扩展-收缩数据库迁移

把 schema 变更拆成向后兼容的阶段,使新旧应用版本可以在滚动发布期间同时运行,避免协调停机。

阅读英文原文

为什么一步式迁移会破坏发布

滚动发布会同时运行新旧代码。如果迁移删除了旧版本仍在读取的列,重叠期间请求就会失败。扩展-收缩让每个阶段都兼容两个版本。

-- 扩展:可空、向后兼容
ALTER TABLE accounts ADD COLUMN display_name text;

-- 分批回填
UPDATE accounts
SET display_name = name
WHERE display_name IS NULL
  AND id IN (SELECT id FROM accounts WHERE display_name IS NULL LIMIT 1000);

步骤

  1. 扩展 schema:添加可空列、新表或新索引,不删除或重命名现有结构;在支持时使用并发建索引。
  2. 部署双写或兼容读逻辑,先写新旧字段并以回退方式读取,逐步发布。
  3. 在有界批次中回填历史数据,监控复制延迟与锁等待,校验行数与约束。
  4. 回填验证并观察后,把读取切换到新结构,移除回退逻辑。
  5. 在后续版本中收缩:确认没有实例使用旧结构后,删除旧列/表与兼容代码。

验证

  • 新旧应用版本都能通过针对迁移后 schema 的集成测试。
  • 行数与约束符合预期。
  • 回填期间锁等待与查询延迟在预算内。
  • 生产级副本上的备份恢复成功。

回滚

收缩阶段之前,回滚只是代码变更,旧 schema 仍在。收缩之后,回滚需要从备份恢复被删除的结构或执行可逆迁移,因此应等新版本验证充分后再执行破坏性步骤。

决策点

活跃表优先使用在线扩展-收缩;只有确实无法在线执行时才使用维护窗口。回填使用有界批次并监控延迟与锁;单个大事务会增加锁时间与回滚成本。