7

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

 1 year ago
source link: https://www.v2ex.com/t/939227
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  程序员

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

  NoKey · 10 小时 21 分钟前 · 1882 次点击
请教大家一个问题
比如我们后端服务器有 5 台,数据库是同一个
新版本要发布了,有数据库变更,比如我们把某个字段去掉了,或者改了名等
那么在发版前,需要先执行变更 sql ,这个 sql 一执行,就会影响所有服务
那么所有服务必须跟着都发版才行
否则部分功能会因为 sql 变更了执行失败
无法做到部分先升级验证,验证 ok 再升级剩下的
请假一下,有啥比较完善的方式处理这个问题呢,谢谢~
25 条回复    2023-05-11 19:38:11 +08:00
garylikira

garylikira      10 小时 17 分钟前

mysql 的话有个 gh-ost , 有 online ddl 模式。具体原理没了解过。好像本质就是先建立幽灵表,然后 copy 原始数据到幽灵表,然后 rename 原始表名字到幽灵表
EmiliatanTenshi

EmiliatanTenshi      10 小时 9 分钟前

类似的问题都可以抽成两种变更:
1. 新增字段
2. 删除字段。
EmiliatanTenshi

EmiliatanTenshi      10 小时 6 分钟前

@EmiliatanTenshi 快捷键直接提交回复了。
1.新增字段。这种变更先变更 db ,再升级服务,保证字段可空就不会有问题
2. 删除字段。这种变更先把在线服务对待删除字段的依赖去除,再操作 db 变更,也可以保证兼容性。
至于修改字段这种,在我经历过的几家公司都是禁止的,原因就是在线无法保证兼容性。但也不是完全无解,可以新增一个新字段,把历史数据及增量数据都写到新字段上,再把老字段下线,相当于拆解成了一个删除字段和一个新增字段的操作。不过问题就是涉及历史数据比较麻烦
brader

brader      10 小时 6 分钟前

你应该在代码开发上就要考虑兼容了。如果无法平滑过渡的,你就在新开发的接口里面,加一些版本判断的代码
sujin190

sujin190      10 小时 2 分钟前

如果你要平滑升级,那么数据结构就要支持平滑升级啊,比如这种修改字段的需要升级两个版本才能完成,第一版添加心字段并且修改业务逻辑同时兼容新老字段使用,第二版删除老字段同时业务逻辑删除对老字段的使用和支持,一劳永逸的方法肯定是没有的,否则大家废了吧劲的搞设计模式搞业务抽象搞微服务干嘛呢
Anivial

Anivial      9 小时 56 分钟前

你这种情况属于多个服务都能更改同一数据库同一表的数据,最好是每个服务的数据都分离,公用的数据上再建立一个服务对外提供接口
LeegoYih

LeegoYih      9 小时 48 分钟前

兼容处理平滑过渡
半夜人少的时候发布

删字段 /表,改字段名 /表名是什么逆天操作,保留着又不影响你干活
我以前维护一个老项目,一堆 typo 和弃用字段,凑合用就完事了,实在不行就跳槽
zsc8917zsc

zsc8917zsc      9 小时 46 分钟前

为啥要删字段。。统一都是新增字段
koloonps

koloonps      9 小时 46 分钟前

“改了名” 用数据库视图
opengps

opengps      9 小时 36 分钟前

按照开闭原则去做,改字段原则上是不允许的。如果确实必要,可以用“现在加字段+后期减字段”模式
Masoud2023

Masoud2023      9 小时 27 分钟前

你这个问题就不应该出现,生产环境为什么要删字段或者改字段名?
seers

seers      9 小时 26 分钟前 via Android

你们验证就不能去测试环境吗
killva4624

killva4624      9 小时 24 分钟前

字段去掉或者改名也太逆天了...
1 、 在服务里做兼容,先升级服务,再 sql 变更;记得做好数据库备份,万一不兼容可以回滚。
2 、如果可以禁写操作的话,就弄一套完全一样的服务+数据库,把流量先切过去,原库+原服务变更好了再一点点切回来。
brust

brust      9 小时 17 分钟前

你做减量 sql 发版不怕回退版本吗?
h82258652

h82258652      9 小时 13 分钟前

绝大部分项目都可以深夜停机吧。反正我以前就是停服务,更新数据库,更新服务,启动服务,写好脚本,一套下来也就几十秒。
brust

brust      9 小时 11 分钟前

有 sql 版本控制的
比如 java 可以用 flyway
crazyweeds

crazyweeds      9 小时 6 分钟前

肯定可以,就是成本有点高。从数据库层面而言,你创建一个新表,把旧表数据实时同步过去,新服务用新表即可。这就实现了新老服务互不干涉。
cyningxu

cyningxu      8 小时 3 分钟前

“比如我们把某个字段去掉了”:先把 5 台机器都上线后,再删除字段。
“或者改了名”:假定 A 改名为 B ,先新增 B ,代码中取值时要新增找不到 B 字段则使用 A 字段兜底的逻辑,写值时要新增 A 字段存在时 AB 双写,A 不存在则仅写 B 的逻辑,待 5 台机器都上线后,删除 A 字段即可。下次升级版本再去掉 A 字段的冗余逻辑。
Dogtler

Dogtler      7 小时 28 分钟前

要不复制新表出来再用切换表的方式发布版本?大概是起个 tmp 的作用。
yazinnnn

yazinnnn      7 小时 20 分钟前

改名确实有点逆天
fantathat

fantathat      7 小时 0 分钟前 via iPhone

厨房炸了锅,餐厅还能出来菜,神奇
xuelu520

xuelu520      6 小时 57 分钟前

第一次见已上线的服务改字段名的。
Pantheoon

Pantheoon      6 小时 53 分钟前

第一次见已上线的服务删字段的
sadfQED2

sadfQED2      6 小时 47 分钟前 via Android

第一次见已上线的服务发版不考虑兼容的
ytmsdy

ytmsdy      6 小时 20 分钟前

还是老老实实停服务吧!涉及到改字段,好像都没法完美处理。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK