后端服务在有数据库变更的情况下,如何不停服务发版

2023-05-11 15:37:17 +08:00
 NoKey
请教大家一个问题
比如我们后端服务器有 5 台,数据库是同一个
新版本要发布了,有数据库变更,比如我们把某个字段去掉了,或者改了名等
那么在发版前,需要先执行变更 sql ,这个 sql 一执行,就会影响所有服务
那么所有服务必须跟着都发版才行
否则部分功能会因为 sql 变更了执行失败
无法做到部分先升级验证,验证 ok 再升级剩下的
请假一下,有啥比较完善的方式处理这个问题呢,谢谢~
3772 次点击
所在节点    程序员
29 条回复
garylikira
2023-05-11 15:41:19 +08:00
mysql 的话有个 gh-ost , 有 online ddl 模式。具体原理没了解过。好像本质就是先建立幽灵表,然后 copy 原始数据到幽灵表,然后 rename 原始表名字到幽灵表
EmiliatanTenshi
2023-05-11 15:49:33 +08:00
类似的问题都可以抽成两种变更:
1. 新增字段
2. 删除字段。
EmiliatanTenshi
2023-05-11 15:52:12 +08:00
@EmiliatanTenshi 快捷键直接提交回复了。
1.新增字段。这种变更先变更 db ,再升级服务,保证字段可空就不会有问题
2. 删除字段。这种变更先把在线服务对待删除字段的依赖去除,再操作 db 变更,也可以保证兼容性。
至于修改字段这种,在我经历过的几家公司都是禁止的,原因就是在线无法保证兼容性。但也不是完全无解,可以新增一个新字段,把历史数据及增量数据都写到新字段上,再把老字段下线,相当于拆解成了一个删除字段和一个新增字段的操作。不过问题就是涉及历史数据比较麻烦
brader
2023-05-11 15:52:29 +08:00
你应该在代码开发上就要考虑兼容了。如果无法平滑过渡的,你就在新开发的接口里面,加一些版本判断的代码
sujin190
2023-05-11 15:56:03 +08:00
如果你要平滑升级,那么数据结构就要支持平滑升级啊,比如这种修改字段的需要升级两个版本才能完成,第一版添加心字段并且修改业务逻辑同时兼容新老字段使用,第二版删除老字段同时业务逻辑删除对老字段的使用和支持,一劳永逸的方法肯定是没有的,否则大家废了吧劲的搞设计模式搞业务抽象搞微服务干嘛呢
Anivial
2023-05-11 16:02:09 +08:00
你这种情况属于多个服务都能更改同一数据库同一表的数据,最好是每个服务的数据都分离,公用的数据上再建立一个服务对外提供接口
LeegoYih
2023-05-11 16:10:04 +08:00
兼容处理平滑过渡
半夜人少的时候发布

删字段 /表,改字段名 /表名是什么逆天操作,保留着又不影响你干活
我以前维护一个老项目,一堆 typo 和弃用字段,凑合用就完事了,实在不行就跳槽
zsc8917zsc
2023-05-11 16:11:48 +08:00
为啥要删字段。。统一都是新增字段
koloonps
2023-05-11 16:12:31 +08:00
“改了名” 用数据库视图
opengps
2023-05-11 16:22:07 +08:00
按照开闭原则去做,改字段原则上是不允许的。如果确实必要,可以用“现在加字段+后期减字段”模式
Masoud2023
2023-05-11 16:30:58 +08:00
你这个问题就不应该出现,生产环境为什么要删字段或者改字段名?
seers
2023-05-11 16:31:59 +08:00
你们验证就不能去测试环境吗
killva4624
2023-05-11 16:34:36 +08:00
字段去掉或者改名也太逆天了...
1 、 在服务里做兼容,先升级服务,再 sql 变更;记得做好数据库备份,万一不兼容可以回滚。
2 、如果可以禁写操作的话,就弄一套完全一样的服务+数据库,把流量先切过去,原库+原服务变更好了再一点点切回来。
brust
2023-05-11 16:41:17 +08:00
你做减量 sql 发版不怕回退版本吗?
h82258652
2023-05-11 16:45:09 +08:00
绝大部分项目都可以深夜停机吧。反正我以前就是停服务,更新数据库,更新服务,启动服务,写好脚本,一套下来也就几十秒。
brust
2023-05-11 16:46:51 +08:00
有 sql 版本控制的
比如 java 可以用 flyway
crazyweeds
2023-05-11 16:52:19 +08:00
肯定可以,就是成本有点高。从数据库层面而言,你创建一个新表,把旧表数据实时同步过去,新服务用新表即可。这就实现了新老服务互不干涉。
cyningxu
2023-05-11 17:54:58 +08:00
“比如我们把某个字段去掉了”:先把 5 台机器都上线后,再删除字段。
“或者改了名”:假定 A 改名为 B ,先新增 B ,代码中取值时要新增找不到 B 字段则使用 A 字段兜底的逻辑,写值时要新增 A 字段存在时 AB 双写,A 不存在则仅写 B 的逻辑,待 5 台机器都上线后,删除 A 字段即可。下次升级版本再去掉 A 字段的冗余逻辑。
Dogtler
2023-05-11 18:30:33 +08:00
要不复制新表出来再用切换表的方式发布版本?大概是起个 tmp 的作用。
yazinnnn
2023-05-11 18:38:38 +08:00
改名确实有点逆天

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/939227

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX