使用Go安全执行DB migrations:新增表字段如何避免服务downtime
无 downtime 数据库字段新增迁移方案
核心原则
所有生产环境的查询逻辑禁止使用select *获取业务数据,必须显式指定需要查询的列名,从根源上避免表结构变更对存量查询逻辑的影响。
具体分阶段操作步骤
- 第一阶段:修改存量代码上线
- 将原有查询语句从
select * from posts修改为select id, title, body from posts,显式指定需要的3个列 - 该版本代码不需要修改结构体、不需要修改Scan逻辑,和原有的表结构完全兼容,直接上线即可,业务无任何影响
- 将原有查询语句从
- 第二阶段:执行表结构变更SQL
- 线上代码稳定运行后,执行DDL语句
ALTER TABLE posts ADD author varchar(62);完成字段新增 - 此时线上代码的查询语句只取3个固定列,新增的author列不会被查询返回,Scan逻辑的参数数量完全匹配,服务不会出现任何报错
- 线上代码稳定运行后,执行DDL语句
- 第三阶段:迭代新功能代码上线
- 更新Post结构体,新增
Author string字段 - 将查询语句修改为
select id, title, body, author from posts,同时更新Scan方法,新增&p.Author参数 - 该版本代码和已经完成字段新增的表结构完全兼容,上线后即可正常使用author字段的能力
- 更新Post结构体,新增
扩展场景:新增非空字段的兼容处理
如果需要新增的是NOT NULL非空字段,只需要在第二阶段增加两步操作即可:
- 先新增可空的author字段,回填所有存量数据的author字段值
- 再执行DDL将author字段修改为
NOT NULL约束,后续再执行第三阶段的代码上线
内容的提问来源于stack exchange,提问作者bkr879
相关产品推荐
相关产品推荐

