当事人复盘 GitLab 史上最严重的数据库故障
故事来源于当事人最近发表的回忆录 https://yorickpeterse.com/articles/what-it-was-like-working-for-gitlab/,相关节选。
GitLab 官网上还有当年这次事故的纪录。https://about.gitlab.com/blog/2017/02/01/gitlab-dot-com-database-incident/,事件发生在 2018 年 2 月 1 日。
误删库原因
GitLab 官方提到有好几道防线,所以最后还是恢复了过来。不过就像一开始当事人回忆里提到的,差一点点就完蛋了。事实上 GitLab 设置的所有防线其实都被击穿了:
每天的自动备份不奏效,因为备份所用的 pg_dump 版本和 GitLab 的 PG 版本不一致,所以每次备份只产生了几个 bytes 的数据。
在 Azure 上的磁盘备份没有在数据库服务器上启用。
到 S3 的备份也是坏的,目录为空。
备份恢复需要定期演练。不演练还不如不要备份。这点其实也从侧面体现了云数据库服务商的优势。因为他们能够保障备份的有效性,也提供了 Point-in-time-recovery (PITR) 这样的闪回能力。GitLab 是自己在云主机上搭了数据库服务,手搓一套备份/恢复的方案,结果完全不可用。
不要在疲劳时操作数据库。当事人本来已经因为时间很晚,准备休息了。但因为突然出现的同步问题,继续熬夜。
尽可能通过工具而不是人肉操作。GitLab 的这个故障应该是当事人直接登上服务器,进行命令行操作的。这里至少有 2 个卡点可以引入工具,一个是登陆服务器,一个是登陆后在服务器上执行命令。如果通过工具操作的话,工具界面会提示正在操作生产库,并且进一步可以设置审批流程。
危险操作事前先备份。这个故障可以挽回在于当事人还是一个老手,所以做了事前手工备份,否则后果不堪设想。
前段时间 Linear 误用 TRUNCATE 也造成了其史上最大故障。对生产环境,尤其是数据库上的操作永远要心怀敬畏。操作时应该尽量通过工具自动化。万不得已需要手动挡,始终也要确保有可用备份兜底。