知识卡片
两阶段迁移保证滚动升级兼容
内容
生产环境的应用通常是多实例部署,升级采用滚动升级——一次只替换一两个实例,新旧版本会有一段时间同时在线,直到全部替换完成。这意味着数据库结构变更不能”一步到位”:给表加一个业务上必填的新字段,如果直接设成 NOT NULL,滚动升级过程中还在跑的旧版本代码(不知道这个新字段)写数据时会直接失败。正确做法分两步走——第一次迁移先把字段加成可选的,让新旧版本代码都能正常写入(旧版本不填这个字段,新版本按需填);等所有实例都升级到能填这个字段的新版本后,再来一次迁移把字段收紧成必填,并用数据迁移脚本给历史空值补上默认值。发散:这条两阶段套路的本质是”数据库结构变更的兼容窗口要盖住整个滚动升级过程”——数据库不是应用的附属品,一旦有多个版本的应用实例同时读写同一个 schema,数据库结构就必须同时对新旧两代代码保持兼容,这是分布式部署给传统”改个字段很简单”的直觉挖的一个坑。
参考来源
《Cloud Native Spring in Action》第5章《Persisting and managing data in the cloud》