下厨房6月26日数据丢失事故总结 MYSQL主分区被rm 命令误删除

下厨房6月26日数据丢失事故总结 MYSQL主分区被rm 命令误删除

http://tech.xiachufang.com/?p=18

在6月26日凌晨12点左右,我们在做线上数据库的备库时,误将线上数据库分区上的所有文件删除。丢失的数据时间段为4月23日至6月25日两个月,在经过7天的努力后,恢复了99%以上的数据。(具体见下面的统计)。

下面把整个事故过程记录下来,令关心本次技术事故的人们知晓。

 

一. 事故隐患

现在回顾,事故隐患在4月23日之后就已经存在。

我们线上数据库使用的是MySQL,在4月23日之前,我们对线上数据库主节点有三类备份。一是有一个独立的数据库从节点来备份,与线上服务器保持数据的实时同步,需要时可切换作线上使用。二是会定期把整个数据库dump成sql文件来备份,一天保存一次,备份的来源是数据库从节点。三是主节点开启有binlog 拷binlog,默认是保存十天的binlog,十天内有任何事故可以从日志里完整恢复全部数据。这三个备份分别存放在两台不同的物理机,三个不同的分区上,是当时想到的最安全的方式。

4月23日,我们把数据库主节点迁移到一台新的物理机上,并把版本升级到5.5。由于版本和配置的问题,原来的从节点并不能直接使用。而一天一次的备份来源是从节点(备份主节点会令网站和手机app有1小时左右的卡顿),这个备份方式也就停止了更新。只有最后一个binlog还在运行。数据库迁移之后应用服务器存在一些性能问题需要投入时间,包括修复MySQL5.5版本和原代码的兼容,以及把应用服务器从gunicorn换成uwsgi Python的web代理,之后又陆续有一些开发任务,以致重新启用备份节点的工作一再拖延。

我们对数据库迁移工作的管理存在失误,是造成事故的根本原因。没有完成数据库备份节点,迁移工作就并没有结束。我们技术团队的所有人对这个事故都负有责任,这个隐患在两个月里都可能被发现,每个人都有可能提出这个工作的高优先级。也都可能提出相应的弥补工作来保证数据安全,比如在启用从节点前延长二进制日志的保存时间等。是我们的工作失误使数据库成为系统最脆弱的环节,经受不住偶然事故的冲击。

 

二. 事故发生过程

6月26日凌晨12点左右,我们开始重新建立备份节点的工作,需要把原来的从节点删除,重新安装,所以先使用了rm -f方式删除备份节点分区上的所有文件。

5分钟后,发现刚才删除的是数据库主节点的分区,为防止硬盘继续写入,就马上把mysql进程停止了。所有技术人员开始应急处理。一是把整个分区dd成镜像,准备做将来硬盘恢复的备份。二是把memcache里的数据dump出来,以备可能的恢复。三是重新启用原来的从数据库,由于数据时间只到4月23日,需要调整近两月表结构变更,让最新的代码可以跑起来。

当天的应急工作至凌晨4点,服务器都恢复访问,但数据停留在4月23日。

在整个应急过程中,部分是紧张,部分是沟通上存在误解,还是出现了失误。当配置从数据库的技术人员完成之后,重启了服务器和memcache,恢复了正常访问。但是做memcache导出工作的技术人员还没有完成,所以最终能从memcache里得到的那部分数据只有一半左右。

事后从沃趣科技的数据库工程师那里得知,我们第一时间停止MySQL防止硬盘继续写入这个应急措施是错误的,即使分区完全没有文件,mysql的进程继续运行,只要保留这个现场,可以从内存中获取更多的数据库结构信息,对恢复数据非常有帮助

 

三. 事故后恢复工作

事故后恢复工作从数据来源分为4条线索进行: 1. 硬盘上数据的恢复(主线) 2. 从memcache导出的数据恢复 3. 从binlog里恢复 4. 从搜索引擎的快照里恢复页面

以下按时间详细叙述:

  • 6月26日8点,我们去机房把服务器硬盘取出来,送到了一家硬盘数据恢复公司。到下午5点左右恢复出ibdata1文件,文件可能破损。
  • 6月26日12点,为了预防新插入的内容和原内容的冲突,我们把所有表的id都加到一个大值,半天的内容随后做特殊处理。
  • 6月26日23点,导入完了所有memcache里的数据。
  • 6月27日上午,从硬盘里又恢复出部分.ibd文件,也包含部分数据信息。已确定包含数据的ibdata1和.ibd文件有破损,无法直接使用,只能尝试从破损文件中提取部分有效信息。
  • 6月27日下午,联系上杭州沃趣网络科技有限公司的陈栋、李春,开始对数据的提取工作。至凌晨1点,提取出.ibd文件的数据,恢复部分表。
  • 6月28日全天,沃趣科技开始对ibdata1文件的提取,至29日凌晨1点,他们已经提出大部分数据。
  • 6月28日下午,得到阿里巴巴集团的周振兴的友情支持,他开始帮忙做ibdata1文件的提取工作,至凌晨4点,他完成部分带二进制段的数据表的修复,提取到了相关内容。
  • 6月28日下午,我们联系上北亚数据恢复中心,开始再次尝试对硬盘文件的恢复。
  • 6月28日晚,我们把所有从binlog来的数据导入完,完整恢复了最后10天的数据。
  • 6月29日中午,从沃趣科技得到的优先级较高的数据表已经恢复完成,开始恢复次优先级的数据。
  • 6月30日中午,提取完所有能从6月27日获取的破损数据库文件里的所有内容。至此这一阶段提取到缺失总数据量的近70%。
  • 6月30日下午,开始从搜索引擎快照里抓取部分菜谱重要页面,修补缺失的内容。并联系上某搜索引擎的快照部门,希望获取我们网站的全部页面快照。
  • 7月1日上午,北亚数据恢复中心取得很大的进展,提取到几乎是完整的ibdata1文件,至下午6点,提取到除了收藏和赞的所有数据表,我们开始把数据导入,至凌晨4点,恢复完得到的所有数据。
  • 7月2日整天,由于导入的旧数据和新注册的用户存在部分数据不一致,我们尽力配合用户恢复。
  • 7月2日下午4点,北亚提取到ibdata1剩下的文件碎片,得到了完整的ibdata1文件,mysql无报错启动,我们得到了6月26日凌晨事故前的完整数据库。至凌晨2点,我们提取出剩下的收藏和赞,恢复到数据库里。至此损失的数据内容已经恢复到99%。

下一阶段:

  • 在丢失两个月数据的这一周时间里,用户新产生的数据和恢复的旧数据会有少量不兼容的情况,我们会全力帮助用户找回自己的全部数据,出现的错误敬请用户包涵,帮助我们走过这一过渡阶段。
  • 除了原先的三种备份方式外,我们会继续落实和第三方的云存储方案的合作,把数据备份到我们的服务器之外的地方。

 

四. 所缺失的近两月数据当前的恢复情况

至今,内容大多得到了99%左右的恢复。缺失部分并不是来自硬盘数据丢失,而是6月26日12点前id移位至大值前,半天创建的内容和原位置内容的冲突,我们还在尽力修补。

以下是当前主要内容的恢复情况:

      菜谱    收藏      赞    作品     关注     菜单       用户
恢复比例  99.0%    98.6%    99.2%    99.5%    99.5%    99.3%    99.1%

 

五. 致谢

特别感谢一下三个公司和个人在这7天的恢复工作中对我们的帮助。

杭州沃趣网络科技有限公司(@沃趣科技)是来自原阿里巴巴DBA/SA团队核心骨干组建的创业公司,提供数据库和系统相关的专业服务和产品,陈栋(@grassbell)、李春(@pickup112)对破损的数据库文件进行了灾难修复,提取出绝大部分数据表的内容。

周振兴(@orczhou)是淘宝MySQL数据库运维负责人,他对破损文件中部分带二进制段的数据表进行了修复,提取到了相关内容。

北亚数据恢复中心是来自前信息产业部职鉴中心,专门从事数据恢复服务的技术公司。张宇,刘子龙对硬盘文件进行了完整的恢复,使我们得到了数据库的全部数据。

 

This entry was posted in Uncategorized on July 3, 2013 by xiachufang.

Post navigation

[Android]如何实现一个边播放边下载的mp3播放器

43 thoughts on “下厨房6月26日数据丢失事故总结”

  1. Pingback: 626技术故障的致歉信

  2. Lenwood July 3, 2013 at 10:44 am

    低级失误,rm 命令太不安全。

    Reply ↓
    1. zer4tul July 11, 2013 at 6:50 pm

      nod,就算是rm -i也不安全,那提示根本没人去看。

      建议: 要删除文件的时候,先mv到固定路径,观察一段时间(个人建议一天左右),如果没有问题再rm掉。其实就是类似回收站的机制。

      另外,关于立即停机的事情。个人觉得当时应该立即停止对外服务(公网入口),因为我们不清楚能恢复到什么程度,所以应该直接拒绝用户写入更多的数据,这比提示“提交成功”但是转眼就找不到自己提交的东西要好多了。但是MySQL实例不能停止,在文件打开的情况下,不会真正删除这个文件。直到所有句柄都关闭后这个文件才彻底消失。

      Reply ↓
  3. 程序员老A July 3, 2013 at 11:42 am

    意识问题,另外还缺少一个成熟的dba,如果有成熟的dba在,即使删除了,也可以恢复更多的数据。

    Reply ↓
  4. lutaf July 3, 2013 at 12:18 pm

    我们之前发生过把网站用户注册数据全部删除的惨案,7000万用户,用drop table,从库也执行了这条命令,没有sql静态文件备份,悲剧很多

    马上停机是正确的,防止文件被覆盖。 停机后取下硬盘并用dd复制一份数据,所有操作在新硬盘上执行

    如果你的分区是ext3,用ext3grep, +脚本批量处理一下,99.9%的数据可以抢救回来

    Reply ↓
    1. 依云 July 4, 2013 at 2:11 pm

      马上停机在任何情况下都是错误的。停机的决定应当在明白你在干什么时再做决定,只有直接导致问题的操作应当立即中止。误删除什么的,意识到之后的第一反应应当是:哪些进程依旧打开了这个文件,如果有,立即从其文件描述符备份。

      Reply ↓
      1. Zoom.Quiet July 6, 2013 at 7:44 pm

        理论上是可行的,问题是: - 文件太多,无法简单的快速恢复 - 不是所有涉及文件有进程在打开

        Reply ↓
        1. li July 9, 2013 at 12:26 pm

          从内存copy文件很快的

          Reply ↓
    2. li July 9, 2013 at 12:25 pm

      马上停机是完全错误的,proc文件系统中有可恢复的数据,只要文件描述符没被关闭。

      Reply ↓
  5. popwin8 July 3, 2013 at 12:43 pm

    很客观的看待问题,而不是把所有的责任都抛给了那个输错rm的员工。这种错误也经常出现,备份才是王道

    Reply ↓
  6. laichendong July 3, 2013 at 1:37 pm

    虽然事故发生了。但我看到的一个高效,合作,高执行力的团队。全力解决问题,利用各种手段,寻求外界帮助等等。很赞! 不犯错是不可能的,如何对待已经犯下的错误更重要。

    Reply ↓
  7. Byron July 3, 2013 at 2:15 pm

    万幸。

    Reply ↓
  8. Simon July 3, 2013 at 2:18 pm

    > 4月23日,我们把数据库主节点迁移到一台新的物理机上,并把版本升级到5.5。由于版本和配置的问题,原来的从节点并不能直接使用。

    4.23 的数据库版本升级就应该主、备库一起升级,这应该是根本性的错误。 另外,在执行 rm -f 之前,哪怕是从节点,也最好做好备份操作。

    Reply ↓
  9. Pingback: 数据丢失的进展

  10. anbb July 3, 2013 at 4:21 pm

    整个过程曲折啊,不过能恢复99%已经非常不错了。 在看的过程中想,如果是我遇到这样的问题,我会这么办?貌似一点办法都没有。 因为上面提到很多术语不知道。。。

    Reply ↓
  11. chris July 3, 2013 at 4:24 pm

    错误大家都会犯,关键还是做好保护措施。

    Reply ↓
  12. magicxiao July 3, 2013 at 9:01 pm

    只能说,备份很关键,删除数据库分区,不管是用rm还是drop table 都有认为误操作的可能性,再一个,重大更新时,需要两个人协调确认

    Reply ↓
  13. jiangyou July 3, 2013 at 9:54 pm

    应付数据丢失的方式就是多存几个备份。。

    Reply ↓
  14. chenggang July 3, 2013 at 11:02 pm

    很奇怪,线上不是主从的架构么?只是删除主库分区,任何一台从库数据都应该是ok的啊。

    Reply ↓
  15. logzgh July 3, 2013 at 11:07 pm

    自己运维总是难免会因为缺乏专业的各方法的人才而出现各种问题。 对创业者来讲云计算是一个很好的选择。

    Reply ↓
  16. TonyLiu July 4, 2013 at 1:56 am

    测试环境,在系统或者重大升级之前把所有的系统和软件的升级做一遍,并在测试环境中做好一切的工作,可以顺利升级生产环境,减少错误和对生产环境的影响。

    Reply ↓
  17. Charles July 4, 2013 at 8:45 am

    没想到,数据丢失的后果这么可怕,可以想见当时兄弟们在怎样的心理压力下工作,对技术团队的士气打击估计也很严重。以后要引以为戒,不能再对数据安全不以为然了。另外我比较好奇,这次事故总共造成了多少经济损失?那些数据恢复公司,不可能是免费的吧。还有就是总共造成了多少间接损失?比如用户流失之类的。有没有相关数据披露?

    Reply ↓
  18. alfa July 4, 2013 at 12:15 pm

    看完整篇文章给我的感觉就是:我们非常牛B,虽然没有备份,但仍然恢复了99.9%的数据

    整篇文章完全没有总结出问题所在,下次肯定还会犯错误

    delete数据的那个人的责任只有5%,运维的责任有10%,管理的责任是85%

    从4月23号就停止了备份,中间各种原因没有去备份,管理人员干毛去了?你们不知道备份的重要性?还有什么事情比备份重要?本来这下你们知道备份的重要了吧?结果只是增加一个云备份,,下次你再有这种情况,你还是仅有2个月前的备份,还照样扯蛋

    增加云备份也好,增加多台服务器备份也好,这些只是细节, 最重要的是提高备份的优先级,象这种数据库升级完成之后,备份没做好这事儿就不算完,禁止使用,禁止上线,这才是根源,否则下次还会被其它事情拖后,还会出问题

    你们应该很庆幸,感谢那个delete的人,才2个月就出了事,绝对应该给那个人发奖金,否则按当前的态度下去,你一直不会有时间来做备份,一年之后再挂,哈哈哈哈,我就不信你还出说能恢复到90%?

    Reply ↓
    1. Zoom.Quiet July 6, 2013 at 7:42 pm

      #是也乎#无法同意更多…

      Reply ↓
  19. Pingback: “下厨房”技术团队分析、总结6.26数据丢失事故 | r6

  20. 李君南 July 4, 2013 at 3:27 pm

    还好找回99%,吃一亏长一智。。。

    Reply ↓
  21. qiuqiu July 4, 2013 at 4:57 pm

    我大约在6月份入侵了你们的系统获取到了mysql的权限 并且做了一次dump

    这部分数据我不知是否是有用的,可以通过网盘分享给你

    Reply ↓
    1. Rwing July 5, 2013 at 3:23 pm

      这个才是最nb的啊。。。。。。

      Reply ↓
  22. 互联网新资讯技术组 July 4, 2013 at 7:09 pm

    我们也曾遇到过数据丢失的情况,也是因为备份机制不完善。往往到数据丢失时才后悔莫及,多么痛的领悟:( 从搜索引擎的快照里恢复页面,我们当时也这么干过。备份,备份,还是备份!

    Reply ↓
  23. dohkoos July 4, 2013 at 7:35 pm

    “6月26日凌晨12点左右,我们开始重新建立备份节点的工作,需要把原来的从节点删除,重新安装,所以先使用了rm -f方式删除备份节点分区上的所有文件。”

    晕倒,涉及数据库的操作前竟然不先做个备份,运维做的也太没有章法了吧!

    升级前备份,升级后备份,备份要保留n天。

    Reply ↓
  24. 空杯岳 July 5, 2013 at 3:18 pm

    值得警惕。

    Reply ↓
  25. Zoom.Quiet July 6, 2013 at 7:41 pm

    [via] CPyUG 的缅怀…. Re: [CPyUG] [OT]python写的 下厨房 被黑了。 … 2013年7月6日下午7:10,金浩  写道: > 可以说说如果 rm -rf >  了一个文件,但是还有进程占有这个文件句柄的情况下,怎么恢复刚刚被删除的文件吗?有没有参考资料?我想在当时这种情况下,如果开发人员知道这个技巧,恢复肯定会比现在简单的多,所以希望分享出来,给其他开发人员万一以后碰到类似的问题做个参考,谢谢!!!

    刚才试了下。。。

    一个终端(记为A):

    # [07/06 19:16:15] xenon@ribosome ~ $ touch delete-me # [07/06 19:16:22] xenon@ribosome ~ $ vim delete-me 写进去一行字,作为内容。

    另一个终端(记为B)打开文件:

    # [07/06 19:16:05] xenon@ribosome ~ $ python Python 2.7.5 (default, Jun 10 2013, 12:07:26) [GCC 4.7.3] on linux2 Type “help”, “copyright”, “credits” or “license” for more information. >>> fp = open(‘delete-me’) >>>  fp

    >>>

    在A里删掉文件:

    # [07/06 19:16:34] xenon@ribosome ~ $ rm delete-me rm:是否删除普通文件 “delete-me”?y

    找到刚才的Python进程:

    # [07/06 19:16:50] xenon@ribosome ~ $ ps -Af | grep python xenon     3285  3114  0 17:53 ?        00:00:01 /usr/bin/python2.7 /usr/bin/terminator xenon     4844  3114  0 19:16 ?        00:00:00 /usr/bin/python2.7 /usr/bin/terminator xenon     4933  4866  0 19:16 pts/1    00:00:00 /usr/bin/python2.7 xenon     4934  3114  1 19:16 ?        00:00:00 /usr/bin/python2.7 /usr/bin/terminator xenon     5070  4956  0 19:16 pts/2    00:00:00 grep –color=auto python

    是4933,然后:

    # [07/06 19:17:03] xenon@ribosome /proc/4933/fd $ ll /proc/4933/fd 总用量 0 dr-x—— 2 xenon xenon  0  7月  6 19:16 ./ dr-xr-xr-x 8 xenon xenon  0  7月  6 19:16 ../ lrwx—— 1 xenon xenon 64  7月  6 19:17 0 -> /dev/pts/1 lrwx—— 1 xenon xenon 64  7月  6 19:17 1 -> /dev/pts/1 lrwx—— 1 xenon xenon 64  7月  6 19:16 2 -> /dev/pts/1 lr-x—— 1 xenon xenon 64  7月  6 19:17 3 -> /home/xenon/delete-me (deleted) # [07/06 19:17:04] xenon@ribosome /proc/4933/fd $ cat /proc/4933/fd/3 This is data to be recovered~

    嗯,啥都不需要

    Reply ↓
    1. zhuwowuyuing July 8, 2013 at 9:39 pm

      试验过,这个方法真不错。

      Reply ↓
  26. jerry July 6, 2013 at 8:08 pm

    执行操作的哥们意识到上错机器后肯定脊梁骨都凉了啊!

    Reply ↓
  27. hpfplane July 7, 2013 at 10:43 am

    只能说,运维水平太低。 前面有不少说了的,我就不重复了。

    首先,作业现场,作业实施者,有没有再三确认自己的作业内容?确认自己所在机器? 这个不是靠个人自觉或者个人技术水平,而是要明确写在“作业计划”“实施步骤”里面。

    第二,作业的时候,有没有另外一个人在旁边看着?帮忙确认? 如果没有,也是不允许的。这种线上生产环境的作业,一定至少要求双人作业。

    Reply ↓
  28. Pingback: 如何从MySQL/InnoDB数据文件中的恢复数据 - 一个故事@MySQL DBA

  29. 孔德远 July 9, 2013 at 1:42 pm

    备份最重要。就算是这个操作人员不会出错,能保证其他的人员不会操作出错。

    Reply ↓
  30. chunzhi July 10, 2013 at 4:18 pm

    搞个集群用mysql cluster吧,开3 replica

    Reply ↓
  31. weipengfei July 11, 2013 at 4:09 pm

    你们什么都不缺,就缺一个专业DBA,鉴定完毕

    Reply ↓
  32. ani di July 11, 2013 at 6:08 pm

    数据库操作简单,保证安全困难。像硬盘这些都是有寿命的。以后谨记天天备份,数据无价啊

    Reply ↓
  33. yyydd July 15, 2013 at 1:02 pm

    1.hostname 2.backup

    Reply ↓
  34. 太单纯了 July 18, 2013 at 3:09 pm

    有MYSQL slave 节点 ,应该先升级salve 然后再master.  剩下的就是犯了低级错误了。

    Reply ↓
  35. newptone October 16, 2013 at 2:32 pm

    出了这样事情的教训就是弄个云备份? 看来还没有意识到问题出在哪里


 

xenon@ribosome /proc/4933/fd

$ ll /proc/4933/fd
总用量 0
dr-x—— 2 xenon xenon  0  7月  6 19:16 ./
dr-xr-xr-x 8 xenon xenon  0  7月  6 19:16 ../
lrwx—— 1 xenon xenon 64  7月  6 19:17 0 -> /dev/pts/1
lrwx—— 1 xenon xenon 64  7月  6 19:17 1 -> /dev/pts/1
lrwx—— 1 xenon xenon 64  7月  6 19:16 2 -> /dev/pts/1
lr-x—— 1 xenon xenon 64  7月  6 19:17 3 -> /home/xenon/delete-me (deleted)

/proc/4933/fd

$ cat /proc/4933/fd/3 This is the data to be recovered~

你可能感兴趣的:(下厨房6月26日数据丢失事故总结 MYSQL主分区被rm 命令误删除)