镇楼图
三个角色
删库以及更宽泛的数据库变更场景中有三个角色,业务研发,DBA 以及使用的数据库变更工具:
- 业务研发通常指的是后端研发。国内最主流的技术栈还是 Java,此外 Go 也有一部分,另有全栈的则使用 Node。这些语言通常会配备对应的 ORM 和数据库打交道,Java 的 MyBatis,Go 的 GORM,Node 的 TypeORM 等。
- DBA 就是数据库管理员。有些公司即使没有全职 DBA,也会有看着数据库的那个人。
- 数据库变更工具。公司业务稍微上了规模,一般会选择在专门的数据库变更工具上执行操作,开源的产品里比较主流的有 Archery, Yearning, Bytebase。
生命周期
交代完出场角色,我们再来说一下,数据库变更的整个生命周期:
- 研发在数据库变更工具上提交了一个变更工单。
- 工具可能进行一些自动化检测,修改字段会提示锁表,删库,删表会警告破坏应用代码的兼容性。
- DBA 进行审核。
- 审核通过后,进行发布。
- 告警铺天盖地/客诉蜂拥而来,业务一排查,怀疑可能是之前的数据库变更引起的,拉上 DBA,实锤。于是再一起制定补救方案。
- 经过几天的奋战,最终修复了问题。
- 开始进行复盘。
上一期回顾的 Linear 删库故障就是这样一套流程。到了复盘阶段,国外普遍采用 blameless postmortem,对事不对人,但国内通常会给故障定主责和次责。安全生产的角度来说,定责任人的威慑力肯定更强。但对于数据库变更,往往一出就是大故障,承担主责往往意味着全年绩效最低档。所以每当业务研发和 DBA 还有他们的主管走进会议室,都会很认真地想着怎样一起复盘。
场景模拟
我们先来模拟一个场景:
业务研发想在 MySQL 8.0 上把一个 VARCHAR 列的长度从 20 改成 100:
ALTER TABLE person MODIFY name VARCHAR (100);
研发在数据库变更工具上提交了这个语句,因为 DBA 也读了 MySQL 8.0 官方文档,知道 MySQL 8.0 修改列不会锁表导致不可用,所以审批通过,然后 DBA 执行这条语句。业务居然挂了!原来 MySQL 8.0 里当把 VARCHAR 长度修改为超过 64 时,还是会锁表的!
切回复盘室里认真讨论的气氛。业务团队主张 DBA 主责,业务研发次责,因为:
- 工具没有自动检测出这个风险,进行提示。
- DBA 作为专业人员在审核阶段没有发现锁表问题。
- 最后是由 DBA 去执行了变更操作。
- 业务研发提交了导致问题的 SQL,但要求业务研发了解这个 MySQL 的执行细节有点强人所难。
DBA 团队主张业务团队主责,DBA 次责,因为:
- 业务研发应该为自己的业务负责,包括数据库在内。
- 问题 SQL 是由业务发起的。业务研发并没有提示业务风险,比如业务的重要性,业务的高峰期等。
- DBA 没有识别到这个问题,督查失职。
好了,到了这里两边其实都有各自的道理,小伙伴们可以停下来思考一下,更倾向于如何定责。下面说一下我的观点。
我认为这个情况应该是**「业务团队主责,DBA 次责」**。
针对业务团队的几个主张:
工具没有自动检测出这个风险,进行提示。
那好,既然 DBA 引入带自动检测的工具反而留下把柄,那大家还是提交在文档上吧,完全没有自动化检测。
DBA 作为专业人员在审核阶段没有发现锁表问题。
双方这点都有共识,但光这条属于失查,次责。
最后是由 DBA 去执行了变更操作。
是 DBA 执行还是研发执行,这是流程的设计。谁去点执行按钮都改变不了这次故障的发生。
业务研发提交了导致问题的 SQL,但要求业务研发了解这个 MySQL 的执行细节有点强人所难。
没有错,但我们来换一个角度。研发写代码调用了一个 API,让 API 的维护者审核一下。结果 API 维护者也没有审核出来一个 bug,上线后导致故障。研发确实可以说让他了解 API 的实现细节有点难,但是研发为了完成自己的任务,使用了一个自己不熟悉的 API,那是不是应该由自己承担风险?
但在实际 PK 中由 DBA 承担主责的情况时有发生,往往是因为第 3 点,最后是由 DBA 点了发布按钮。但就像上面说的,我认为这点是站不住脚的。流程设计让 DBA 点那下,是因为由 DBA 来点效率是更高的,但如果因为 DBA 点了而要背锅,那 DBA 就会拒绝这个流程,甩给研发自己去发布,这样流程只会更加低效。这里也要澄清一下,也不是 DBA 点就一定是更高效的流程,但只想表达定责应该和谁最后点发布那一下无关。
场景泛化
我们再进一步把这个场景泛化一下。在垂直业务团队和横向平台团队的协作中,因为业务开发造成的故障,通常应该都由业务团队承担主责,否则的话,就会造成权责不对等,把平台团队推向消极合作的情况。
这个就像老师带着小朋友和家长们集体活动,照看小朋友的第一责任人始终是家长,如果要让老师承担主责,大概率就不会组织活动了。当然这也有例外,比如假设老师罔顾家长的嘱托,携带小朋友参加不适合的活动,造成意外,那就是老师的责任了。
回到模拟的场景,业务研发应该做的,是给 DBA 更多的业务风险提示,比如说哪些高峰时段不能做变更。如果研发说了这些,但是 DBA 依然置若罔闻,发布造成事故,那 DBA 也自然难辞其咎。
故障定责是一个激烈的话题,关乎到大家的奖金,加薪,升职。本文尝试给出一个判定的原则,也欢迎大家留言探讨。回忆起那些年参加过的复盘会议,就像抄起刚一同肝完的啤酒瓶,朝对方劈头盖脸扔了过去。我心中不禁泛起丝丝寒意,想到了鲁迅的呐喊:
「 从来如此,便对么?」
💡 更多资讯,请关注 Bytebase 公号:Bytebase