Gitlab从删库到恢复:永久丢失6小时生产数据!
太平洋时间周二晚上,这家初创公司发布了一系列令人不安的推特消息,我们在下面列了出来。幕后原因是,一名疲惫不堪的系统管理员在荷兰工作到深夜,他在令人沮丧的数据库复制过程中不小心删除了一台不该删除的服务器上的目录。
这个人不会被解雇。Gitlab已重申,他将被迫看“10小时的彩虹猫”,以示惩罚!
可以点击这篇文章回顾:《GitLab.com崩溃,rm -rf删了300GB数据;要命的是,备份偏偏失效》
以下为GitLab对此次事件的全程记录,供各位参考:
昨天我们的其中一个数据库遭遇了严重事故。我们GitLab.com丢失了6个小时的数据库数据(包括问题列表、合并请求、用户、评论、代码片段等数据)。Git/维基代码库和自我托管的安装系统并没有受到影响。丢失生产数据是无法接受的;几天后,我们会发帖公布这起事件发生的原因以及我们将实施的一系列措施。
最新动态:18:14 UTC(协调世界时):GitLab.com已恢复正常。
截至本文截稿时,我们正从6小时前的数据库备份系统恢复数据。这意味着,在GitLab.com重新上线之前,17:20 UTC到23:25 UTC之间来自数据库的任何数据(项目、问题列表、合并请求、用户、评论和代码片段等)已丢失。
Git数据(代码库和维基)以及自我托管的GitLab实例并没有受到影响。
下面简述了事件的整个过程。同样欢迎大家查看我们的最新事后分析文档(https://docs.google.com/document/d/1GCK53YDcBWQveod9kfzW-VCxIABGiryG7_z_6jHdVik/pub)。
第一起事件
2017年1月31日18:00 UTC,我们发现了垃圾邮件发送者在创建代码片段,以此向数据库发动攻击,导致数据库不稳定。我们随后开始排查故障,搞清楚到底出了什么问题、如何对付。
2017年1月31日21:00 UTC,这个问题变得更严重了,导致了数据库上面出现写入锁死,这引起了数据库停运。
采取的行动
我们根据IP地址阻止了垃圾邮件发送者访问。
我们删除了一个用户,该用户使用代码库作为某种CDN,这导致47000个IP地址使用同一个帐户登录(因而引起过高的数据库负载)。
我们删除了(通过创建代码片段)发送垃圾邮件的那些用户。
第二起事件
2017年1月31日22:00 UTC,我们接到了通知,原因是数据库复制(DB Replication)实在太滞后了,实际上停止运行。之所以出现这种情况,是由于写入操作数量猛增,辅助数据库没有及时处理这些写入操作。
采取的行动
我们试图修复db2,至此它已滞后了大约4GB的数据。
b2.cluster拒绝复制,/var/opt/gitlab/postgresql/data被擦除,确保干净的复制。
db2.cluster拒绝连接到db1,抱怨max_wal_senders值设得太低。这个设置用来限制WAL (= replication)客户机的数据。
Team-member-1(团队成员1)将max_wal_senders调整为db1上的32,重启PostgreSQL。
PostgreSQL抱怨太多的信号处于打开状态,拒绝启动。
Team-member-1将max_connections从8000调整为2000,PostgreSQL再次启动(尽管8000已经用了差不多一年)。
db2.cluster仍拒绝复制,不过它不再抱怨连接;相反,它就挂在那里,什么都不干。
这时,沮丧的心情开始随之而来。这天晚上早些时候,team-member-1明确提到时间太晚了(当地时间23:00左右),他准备下班收工,但是由于复制问题突然冒了出现,他没法下班。
第三起事件
2017年1月31日23:00左右,team-member-1认为,可能是由于PostgreSQL数据目录依然存在(尽管内容空空如也),pg_basebackup拒绝正常运行,于是决定删除该目录。片刻之后,他注意到自己是在db1.cluster.gitlab.com上而不是在db2.cluster.gitlab.com上运行删除操作。
2017年1月31日23:27,team-member-1终止终端,可惜为时太晚。大概300GB数据当中只剩下区区4.5GB数据。
我们不得不将GitLab.com下线,并在Twitter上发布这则信息:
我们正在执行紧急数据库维护,https://t.co/r11UmmDLDE将处于离线状态。
— GitLab.com状态(@gitlabstatus)2017年1月31日
遇到的问题
LVM快照在默认情况下每24小时才做一次。在故障发生前大概6小时,Team-member-1正好手动运行了一次,因为当时他正在为数据库搞负载均衡。
常规备份似乎也是每24小时才做一次,不过team-member-1未能查清楚它们存储在何处。据team-member-2声称,这些似乎并未奏效,只生成了几个字节大小的文件。
Team-member-3:pg_dump似乎失效了,原因是运行的是PostgreSQL 9.2二进制代码,而不是9.6二进制代码。之所以会出现这种情况,是由于如果data/PG_VERSION被设成9.6,omnibus只使用Pg 9.6,但是在worker节点上,该文件并不存在。因而,它在默认情况下运行9.2,悄然失效。因而没有SQL转储出现。Foggem可能清除掉了早些时候的备份。
已为NFS服务器启用了Azure中的磁盘快照,但是没有为数据库服务器启用Azure中的磁盘快照。
一旦将数据同步到试运行数据库(staging),同步过程就消除Web钩子(webhook)。除非我们可以在过去的24小时内从常规备份中获取这些数据,否则它们将丢失殆尽。
复制程序很不可靠,容易出错,依赖几个随机性的shell脚本,而且缺少完备的说明文档。
我们备份到S3的内容显然也没有奏效:存储桶(bucket)空空如也。
所以换句话说,在部署的5套备份/复制方法中,没有一套在可靠运行或当初设置正确。
pg_basebackup会悄悄等待主系统开始复制过程,据另一位生产工程师声称,这个过程最多耗时10分钟。这会导致用户误以为整个过程似乎卡住了。使用“strace”运行这个过程提供不了关于当前情况的任何有用信息。
恢复
眼下我们正在努力恢复,为此使用来自试运行数据库的数据库备份内容。
我们不小心删除了生产数据,可能不得不从备份系统来恢复。带活动说明(livenote)的Google Dochttps://t.co/EVRbHzYlk8
— GitLab.com状态(@gitlabstatus)2017年2月1日
2017年2月1日00:36:备份db1.staging.gitlab.com数据。
2017年2月1日00:55 :将db1.staging.gitlab.com挂载到db1.cluster.gitlab.com上。
将数据从试运行/var/opt/gitlab/postgresql/data/复制到生产/var/opt/gitlab/postgresql/data/。
2017年2月1日01:05: nfs-share01服务器被用来充当/var/opt/gitlab/db-meltdown中的临时存储区。
2017年2月1日01:18:复制剩余的生产数据,包括打包成20170131-db-meltodwn-backup.tar.gz的pg_xlog。
下面这个图显示了删除和随后复制数据的时间。
云头条编译|未经授权谢绝转载
相关阅读: