Skip to content
Berktug Berke Ates
Berktug Berke Ates

软件工程师

博客

实践中的零停机数据库迁移

· 6 分钟阅读

用扩展再收缩的交付方式,在真实流量下安全变更 schema。

部署会重叠

Schema 迁移很少孤立运行。新旧应用实例可能同时服务流量,worker 可能处理延迟任务,移动客户端可能数月仍活跃。安全迁移假定这种重叠,并保持每个中间状态兼容。

扩展再收缩模式把有风险的替换拆成可逆阶段。先扩展 schema 或接口,再迁移行为与数据,观察结果,之后才移除旧路径。额外步骤在关键时刻买来控制。

扩展而不改变含义

以现有代码可忽略的方式添加新的可空列、表、索引或端点。避免在不理解数据库行为时,用默认值或约束在锁下重写大表。在引擎支持时并发构建大索引,并监控复制滞后与锁持有时间。

部署可写入两种表示或为新创建数据填充新模型的代码。双写引入一致性风险,因此保持过渡有界,对分歧做埋点,并在两条记录共享同一数据库时优先单事务。

  • 先衡量表大小与锁行为
  • 让迁移命令可重启
  • 在生产负载下节流回填
  • 用稳定检查点记录进度

把回填当作一项操作

生产回填是工作负载,而非一次性脚本。处理确定性批次,持久化检查点,限制并发,并暴露进度与失败。任务应可安全停止与恢复,且不重复效应。

持续验证新表示。比较计数、校验和、不变量与抽样记录,而非等到结束。若迁移改变含义,把预期映射编码为领域所有者审阅过的可执行检查。

有意移动读取

一旦新写入与历史数据就绪,在功能开关或受控发布后切换读取。影子读可比较新旧结果而不改变用户响应。按路径分段错误与延迟,使推进决策基于证据。

此阶段的回滚通常意味着切回读取,而非反转 schema。破坏性回滚脚本可能让可恢复部署变得糟得多。在信心足够高之前保留扩展状态。

仅在证据之后收缩

停止写入旧表示,等待重叠应用版本与排队工作清空,然后移除未用代码。通过遥测确认旧字段或表不再被读取后,再在单独部署中删除它。

零停机不是没有风险。它是一种使风险可观测、限制爆炸半径,并在每个阶段保留安全决策的交付形态。


由 Berktug Berke Ates 于 2024年6月5日 发布。