驱蚊器喵的翻译平台

Can you hear the gravity?

  1. 1. 第一次事件
    1. 1.1. 采取的行动
  2. 2. 第二次事件
    1. 2.1. 采取的行动
  3. 3. 第三次事件
  4. 4. 遇到的问题
  5. 5. 恢复

原文地址: https://about.gitlab.com/blog/2017/02/01/gitlab-dot-com-database-incident/
原文标题: GitLab.com database incident
原文作者: GitLab Team
原文写于: 2017/02/01

译者:驱蚊器喵#ΦωΦ

翻译水平有限,有不通顺的语句,请见谅。

阅读时间:大约 5 分钟


更新:请看我们对这一事件的事后总结

昨天我们的一个数据库发生了严重事故。我们丢失了 GitLab.com 六个小时的数据库数据(问题、合并请求、用户、评论、代码片段等)。Git/wiki 存储库,以及私有搭建的 GitLab 没有受到影响。丢失生产数据是不可接受的,几天后我们会发表一篇文章,说明为什么会发生这种情况,并列出我们将采取的措施,以防止事故再次发生。

UTC时间 下午 6:14 更新。GitLab.com 已恢复上线

截至发稿时,我们正在从六小时前的数据库备份恢复数据。这意味着,当 GitLab.com 恢复上线时,数据库中 5:20pm UTC 到 11:25pm UTC 之间的所有数据(项目、问题、合并请求、用户、评论、代码片段等)都会丢失。

Git 数据(存储库和 wiki)和 GitLab 的私有搭建实例不受影响。

请阅读下文,了解事件的简要概述。也欢迎你查看我们的事后总结文档(译者注:文件已经被删除)。

第一次事件

在 2017/01/31 下午6点(UTC时间),我们检测到垃圾邮件发送者通过创建片段来攻击数据库,导致数据库运行不稳定。然后我们开始排除故障,了解问题以及如何防御。

在 2017/01/31 晚上9点(UTC),这个问题升级了,导致数据库的写入被加锁,这造成了一段时间的宕机。

采取的行动

  • 我们封禁了垃圾邮件发送者的 IP 地址。
  • 我们删除了一个将代码库作为类似 CDN 使用的用户,这导致了用户账号有 47000 个 IP 登录(导致数据库高负荷)。
  • 我们删除了发送垃圾邮件的用户(通过代码片段)。

第二次事件

在 2017/01/31 10pm UTC,我们被叫起来了,因为 DB Replication 滞后太多,几乎要停止了。发生这种情况的原因是因为有一个写入的高峰,而且辅助数据库没有及时处理。

采取的行动

  • 试图修复 db2,此时已经滞后了大约 4GB。
  • db2.cluster 拒绝进行副本的复制,删除了 /var/opt/gitlab/postgresql/data 目录,以确保能够进行干净的复制。
  • db2.cluster 拒绝连接到 db1,报错显示 max_wal_senders 太低。这个设置是用来限制 WAL (= replication)客户端的数量
  • Team-member-1db1max_wal_senders 调整为 32,重新启动 PostgreSQL
  • PostgreSQL 报错显示,too many semaphores being open,拒绝启动
  • Team-member-1max_connections8000 调整到 2000 ,PostgreSQL 再次启动(尽管 8000 已经被使用了将近一年)。
  • db2.cluster 仍然拒绝复制,但是没有报错连接问题;然而,它只是挂在那里不做任何事情。
  • 这个时候,team-member-1 感到有些沮丧。今天晚上的早些时候,team-member-1 明确表示他要下班打卡了,因为当时已经很晚了(当地时间23:00左右),但由于复制问题突然出现而导致加班。

第三次事件

在 2017/01/31 11pm-ish UTC,team-member-1 认为,也许是因为存在 PostgreSQL 数据目录(尽管是空的)所以 pg_basebackup 拒绝工作,决定删除该目录。一两秒钟后,他才注意到他是在 db1.cluster.gitlab.com 上执行的删除操作,而不是在 db2.cluster.gitlab.com

在 2017/01/31 11:27pm UTC,team-member-1 - 终止了删除操作,但已经太晚了。大约 300GB 数据中只剩下了 4.5GB。

我们不得不将 GitLab.com 关闭,并在 Twitter 上分享这一信息。

我们正在进行紧急数据库维护,https://gitlab.com 将被关闭
- GitLab.com Status (@gitlabstatus) January 31, 2017

遇到的问题

  • LVM 快照默认是每24小时才运行一次。Team-member-1 碰巧在停电前六小时手动运行了一次,因为他正在为数据库做负载平衡工作。
  • 定期备份似乎也是每24小时才进行一次,尽管 team-member-1 还没能弄清楚它们被储存在哪里。根据 team-member-2 的说法,这些备份似乎没有用,产生的文件只有几个字节的大小。
  • team-member-3:看起来 pg_dump 可能失败了,因为现在运行的是 PostgreSQL 9.2 版本的二进制文件,而不是 9.6 版本的二进制文件。发生这种情况是因为 omnibus 只在 data/PG_VERSION 设置为 9.6 时才使用 Pg 9.6,但在 workers 上这个文件并不存在。因此,运行失败了,默认启动了 9.2 版本的程序。所以,没有产生 SQL 备份。Fog gem 可能已经清理了旧的备份。
  • Azure 中的磁盘快照对 NFS 服务器启用,但对没有对 DB 服务器启用。
  • 同步过程中,一旦将数据同步到 staging,就会删除 webhooks。除非我们能从过去24小时的常规备份中提取这些数据,否则它们就会丢失。
  • 复制过程是非常脆弱的,容易出错,依赖于一些随机的 shell 脚本,而且这些文档记录得很差。
  • 我们备份到 S3 的工作显然也没有成功:存储桶里的数据是空的
  • 因此,换句话说,在部署的五种备份/副本复制技术中,没有一种能可靠地工作,也没有第一时间设置好。我们最后恢复了一个六小时前的备份。
  • pg_basebackup 会默默地等待主站启动复制进度,据另一位生产工程师说,这可能需要10分钟。这可能导致人们认为这个过程在某种程度上被卡住了。使用 “strace” 来运行该进程,没有提供关于可能发生的事情的有用信息。

恢复

我们现在正在努力通过使用一个暂存数据库的数据库备份来恢复。

我们不小心删除了生产数据,不得不从备份中恢复。这是谷歌文档与现场笔记 https://t.co/EVRbHzYlk8
- GitLab.com 状态(@gitlabstatus) 2017年2月1日

  • 2017/02/01 00:36 - 备份 db1.staging.gitlab.com 数据
  • 2017/02/01 00:55 - 将 db1.staging.gitlab.com 挂载到 db1.cluster.gitlab.com
  • 将数据从临时环境的 /var/opt/gitlab/postgresql/data/ 复制到生产环境的 /var/opt/gitlab/postgresql/data/
  • 2017/02/01 01:05 - nfs-share01 服务器被征用,作为 /var/opt/gitlab/db-meltdown 的临时存储
  • 2017/02/01 01:18 - 剩余生产数据的拷贝,包括 pg_xlog,被压缩成20170131-db-melodwn-backup.tar.gz

下面一张图显示了删除的数据和随后复制进来的数据,以及对应的时间。

另外,我们要感谢大家通过 #hugops 在 Twitter 上和其他地方对我们的特别支持。

本文作者 : meow
This blog is under a CC BY-NC-SA 4.0 Unported License
本文链接 : https://translation.meow.page/post/gitlab-dot-com-database-incident/

本文最后更新于 天前,文中所描述的信息可能已发生改变