极狐GitLab在线发布(数据库)方法论
前言
其他公司——邮件
“这周五凌晨6点公司产品发布,请相关的产品、设计、测试、运维、DBA、后端、前端、客服准时就位,6点开始我们准时挂维护页面。“
产品公告栏
“各位客户,我们产品定于xxxx(本周五)版本发布,维护xx小时,由此带来的不便请谅解,特此通告!“
极狐GitLab
SRE:昨天发布了。
产品/设计/测试/后端/前端/研发/客服:“啊?“”昨天发布了啊?”“哦....”.
背景
我们现在大部分公司的产品发布很多时候都会需要维护,以及相关人员到场,进行相关发布适宜;而在我们的极狐GitLab,好像“不存在”发布,有些小伙伴入职咱们公司可能入职一年都不知道原来我们的产品在“源源不断”地进行着发布。这一方面大大降低了小伙伴们的工作量,另一方面,自动化来做,出错的概率会比人工操作降低很多。
其他产品发布中,如果是遇到数据库表,特别是大表需要结构变更之类的,我想很多都逃不过产品维护的命运。因为一般来说我们的数据库在面对咱们的大表结构变更的时候,通常需要比较久的时间才能够完成。
那么在极狐GitLab的在线发布中,在面对变更大表的结构的时候,极狐GitLab怎么来做的呢?下面我们就说一下极狐GitLab在线发布数据库的方法论。
参考文档
Migration
Migration:简单来说,就是我们在发布版本的时候对数据库的操作,也就是我们在一般发布中的sql文件包里面的东西。
在极狐GitLab中,将这个发布里面的需要执行的SQL文件分成了三个类别,分别是:Regular Migration、Post-deploy migration和Background migration。
Regular Migration这些是在部署新应用程序代码之前的sql,因为新代码可能会依赖这些执行的sql
Post-deploy migration 发布代码之后的对数据库的一些操作sql,比如添加索引啥的
Background migration 一般是放在后台执行的数据库操作,比如对大表的数据处理那些。
下面图是整个选择是哪个Migration的大致流程。
在线升级的实现
例:将一个主键从int改为bigint
- 建立一个新bigint字段 (release M)
首先,发布一个版本M,建立一个新字段类型为bigint,并且创建触发器同步两个字段的数据,使新列的数据同步旧列数据
- 交换两个列(release M+1)
再发布一个版本M+1,在bigint列创建索引、外键、并且重置触发器,然后删除旧列索引、删除旧外键 ,然后在代码层面在这个表所涉及的功能加上一个feature flag,并且会创建一个忽略旧列的规则,这个时候涉及的相关功能会暂时失效。 然后交换两个列
- 移除旧列和触发器 (release M+2)
发布另一个版本M+2,来删除旧列和触发器
- 移除规则(release M+3)
最后发布一个版本 M+3,移除对旧列的忽略规则。(这里的规则是第三步,因为在gitlab这个产品中如果没建立对旧列的忽略的话,会报错,也就是说,我这数据库里面的列如果有没有使用的列或者表,是会出现报错的。)
也就是在发布的过程中必须要锁表的时候我们是先让这所涉及的功能暂时“不可用”,然后执行相关操作,最后“可用”该部分功能来达到我们的目的。
流程图
总结
综上,极狐GitLab就是配合代码分解了一些对数据库的大操作SQL,并且如果无法避免的锁表操作,可以通过feature flag来控制我们实现部分功能暂时不可用,等待完成之后再来对我们的相关功能进行恢复,从而保证整个产品的不停服。整个在线升级的方法论听上去,可能一说大家都能比较好的理解,但是真的要实现这里面的逻辑,需要很多地方严密配合。
这也是极狐GitLab产品的一个非常好的特有属性,保证了我们产品的安全可靠,这也体现了企业追求卓越的品质。
关注【极狐GitLab】获取更多 DevOps 行业最佳实践。