Gitlab删库事件回顾,备份手段还停留在“原始社会”?
作者简介:孙朝阳 沃趣科技高级产品经理。
Gitlab简介
Gitlab是大家很熟悉的开源Git代码托管工具,国内公司大多使用社区版自行搭建私有化的内部代码托管平台。Gitlab.com本身也提供在线代码托管和持续集成的云服务,类似Github+Travis CI的结合体。2016年Gitlab完成的B轮融资金额达2000万美元。
Gitlab 的数据库采用PosgreSQL集群,db1.cluster和db2.cluster。另外还有db1.staging 和 db2.staging两台staging数据库 。
故障原因及损失
2017/01/31 18:00 UTC Gitlab遭受攻击,运维工程师采取一系列措施抵御。
2017/01/31 22:00 UTC 运维工程师发现db2.cluster复制延迟滞后,尝试清空了data目录后,依然拒绝复制。
2017/01/31 23:00 UTC 运维工程师在试过多种方法后,认为删除db2.cluster的data目录(已经是空目录)可能有用,但操作的时候,却误删除了db1.cluster的data目录。待工程师反应过来的时候,原本300GB的数据仅剩下4.5GB。
2017/02/01 18:14 UTC 经过了17个小时的奋战,以及YouTube全程直播并求助,Gitlab 数据库终于恢复成功。
恢复过程
Gitlab具备多重数据库备份,但恢复的时候,竟然差点找不到一个可用的。
- 日常备份24小时执行一次。找到的备份文件仅有几个字节大小,明显早已失效。pg_dump本应使用9.6的,但实际运行的却是9.2的版本,所以没有结果。
- Azure上的硬盘快照,仅对NFS启用了,对数据库的完全没开启。
- 备份到S3也没成功,都是空的。
- 同步到staging的脚本虽然是成功的,但是同步过程中会删除webhook数据。实际上staging根本就不应该承担备份的角色。
- LVM快照24小时执行一次,幸好6个小时前工程师偶然做过一次手动快照,否则丢失的数据会更多!
恢复的详细过程不再赘述,可以参考官方的说明: https://docs.google.com/document/d/1GCK53YDcBWQveod9kfzW-VCxIABGiryG7_z_6jHdVik/pub
最后工程师们使用db1.staging上的那份6小时前的快照恢复数据库成功(没有webhook数据,后来从另一份拷贝恢复了部分),但丢失了6小时的数据。
Gitlab表示不会开除该工程师,也没有简单的总结成我们要加强备份,我们要优化流程之流,而是展现了真正的工程师文化。尤其是恢复工作日志(专业化程度可见一斑,远高于业界平均水平)
详细的损失如下,主要是工程、fork等需要存在数据库里的信息丢失,代码和wiki没有受到影响。
±6 hours of data loss
4613 regular projects, 74 forks, and 350 imports are lost (roughly); 5037 projects in total. Since Git repositories are NOT lost, we can recreate all of the projects whose user/group existed before the data loss, but we cannot restore any of these projects’ issues, etc.
±4979 (so ±5000) comments lost
707 users lost potentially, hard to tell for certain from the Kibana logs
Webhooks created before Jan 31st 17:20 were restored, those created after this time are lost
考虑到Gitlab曾计划推出自己的私有云服务,此次事件对其声誉也是个沉重的打击。
经验教训
相信从本次的Gitlab事件,所有人都可以很明显的看出该公司在备份环节存在的问题:
全部的备份都没有验证过!!!
全部的备份都没有验证过!!!
全部的备份都没有验证过!!!
重要的事情说三遍。也许是上帝仁慈,幸好运维工程师手工做过一次lvm快照,否则就只能恢复到24小时前了!
其实,在备份领域,备份文件的验证一直是个难题,要保证备份100%可用,最稳妥的方法自然是使用该备份恢复出完整的数据库。
但是!
随着数据库的不断增大,恢复的时间/空间成本会越来越高(想象一下完整恢复几十TB的数据库需要多长时间!)
那么该如何避免Gitlab此次遇到的问题呢?
由沃趣科技自主研发的QBackup数据库备份云一体机,可极大缩短恢复时间,实现秒级数据库验证,同时具备多项极具吸引力的特性。
- 秒级验证。QBackup 由备份恢复至完整的可访问数据库,仅需要几十秒,验证过程耗费时间极短,成本极低。
- 持续备份。Gitlab的定时备份始终存在时间窗口,一定存在数据丢失,区别仅仅是多与少的问题。QBackup采用CDP技术,数据库的每一个变动后都会实时备份,真正的实现了数据零丢失。
- 秒级时间点恢复。QBackup实现了Point-in-time recovery ,可以秒级恢复数据库到指定的时间点。
- 配套完善。Gitlab官方自己检讨称,诸多备份流程失效不仅没有任何人发现,竟然连一条告警都没有。QBackup具备完善的配套措施,在添加需要保护的数据库后,自动配套监控及报警,第一时间发现异常。
由Gitlab此次的恢复过程所遇到的问题来看,QBackup的核心功能,几乎都是针对数据库备份中最重点的部分研发,极大的降低了企业备份环节的成本,从根本上提高了数据库的安全性。
- Android面试系列之AsyncTask
- Kali-Linux扩充弹药:Kali Linux metapackages
- 使用HackRF解调TDD-LTE信号
- 一个优秀的Android应用从建项目开始
- Ruby OpenSSL 私钥伪造脚本
- 基于 k8s 的 Jenkins 构建集群实践
- Visual C#.Net网络程序开发-Tcp篇(1) 祥细内容:
- 无服务器化的微服务持续交付
- Visual C#.Net网络程序开发-Tcp篇(2) 祥细内容:
- 看你是否够老 – ipman的vxd程序介绍的翻译
- Visual C#.Net网络程序开发-Tcp篇(3) 祥细内容:
- 安全科普:流量劫持能有多大危害?
- OpenSSL心脏出血漏洞全回顾
- Nmap扫描对比工具–libnmap实践
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Spring 中的依赖注入(DI),你都知道多少?
- Docker配置1台Nginx+3台Tomcat做负载均衡
- Centos7.x+Docker部署RabbitMQ
- LeetCode(1)-找出数组中重复的数字
- LeetCode(面试题:二维数组中的查找)
- 面试题05-替换空格(LeeCode)
- 解决Mybatis当实体类中的属性名和表中的字段名不一致的问题
- 图书管理系统(一)项目框架结构搭建
- Mybatis中模糊查询like语句的使用方法
- win10暴力查看wifi密码
- 再也不怕面试官问java中的goto关键字了?
- 死磕Java之分析short类型
- 死磕Java之Java数据类型的来龙去脉
- 请不要再使用判断进行参数校验了
- 检测假新闻:比较不同的分类方法的准确率