下厨房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日数据丢失事故总结”
Pingback: 626技术故障的致歉信
-
Lenwood July 3, 2013 at 10:44 am
低级失误,rm 命令太不安全。
Reply ↓-
zer4tul July 11, 2013 at 6:50 pm
nod,就算是rm -i也不安全,那提示根本没人去看。
建议: 要删除文件的时候,先mv到固定路径,观察一段时间(个人建议一天左右),如果没有问题再rm掉。其实就是类似回收站的机制。
另外,关于立即停机的事情。个人觉得当时应该立即停止对外服务(公网入口),因为我们不清楚能恢复到什么程度,所以应该直接拒绝用户写入更多的数据,这比提示“提交成功”但是转眼就找不到自己提交的东西要好多了。但是MySQL实例不能停止,在文件打开的情况下,不会真正删除这个文件。直到所有句柄都关闭后这个文件才彻底消失。
Reply ↓
-
zer4tul July 11, 2013 at 6:50 pm
-
程序员老A July 3, 2013 at 11:42 am
意识问题,另外还缺少一个成熟的dba,如果有成熟的dba在,即使删除了,也可以恢复更多的数据。
Reply ↓ -
lutaf July 3, 2013 at 12:18 pm
我们之前发生过把网站用户注册数据全部删除的*,7000万用户,用drop table,从库也执行了这条命令,没有sql静态文件备份,悲剧很多
马上停机是正确的,防止文件被覆盖。 停机后取下硬盘并用dd复制一份数据,所有操作在新硬盘上执行
如果你的分区是ext3,用ext3grep, +脚本批量处理一下,99.9%的数据可以抢救回来
Reply ↓-
依云 July 4, 2013 at 2:11 pm
马上停机在任何情况下都是错误的。停机的决定应当在明白你在干什么时再做决定,只有直接导致问题的操作应当立即中止。误删除什么的,意识到之后的第一反应应当是:哪些进程依旧打开了这个文件,如果有,立即从其文件描述符备份。
Reply ↓-
Zoom.Quiet July 6, 2013 at 7:44 pm
理论上是可行的,问题是: - 文件太多,无法简单的快速恢复 - 不是所有涉及文件有进程在打开
Reply ↓-
li July 9, 2013 at 12:26 pm
从内存copy文件很快的
Reply ↓
-
li July 9, 2013 at 12:26 pm
-
Zoom.Quiet July 6, 2013 at 7:44 pm
-
li July 9, 2013 at 12:25 pm
马上停机是完全错误的,proc文件系统中有可恢复的数据,只要文件描述符没被关闭。
Reply ↓
-
依云 July 4, 2013 at 2:11 pm
-
popwin8 July 3, 2013 at 12:43 pm
很客观的看待问题,而不是把所有的责任都抛给了那个输错rm的员工。这种错误也经常出现,备份才是王道
Reply ↓ -
laichendong July 3, 2013 at 1:37 pm
虽然事故发生了。但我看到的一个高效,合作,高执行力的团队。全力解决问题,利用各种手段,寻求外界帮助等等。很赞! 不犯错是不可能的,如何对待已经犯下的错误更重要。
Reply ↓ -
Byron July 3, 2013 at 2:15 pm
万幸。
Reply ↓ -
Simon July 3, 2013 at 2:18 pm
> 4月23日,我们把数据库主节点迁移到一台新的物理机上,并把版本升级到5.5。由于版本和配置的问题,原来的从节点并不能直接使用。
4.23 的数据库版本升级就应该主、备库一起升级,这应该是根本性的错误。 另外,在执行 rm -f 之前,哪怕是从节点,也最好做好备份操作。
Reply ↓ Pingback: 数据丢失的进展
-
anbb July 3, 2013 at 4:21 pm
整个过程曲折啊,不过能恢复99%已经非常不错了。 在看的过程中想,如果是我遇到这样的问题,我会这么办?貌似一点办法都没有。 因为上面提到很多术语不知道。。。
Reply ↓ -
chris July 3, 2013 at 4:24 pm
错误大家都会犯,关键还是做好保护措施。
Reply ↓ -
magicxiao July 3, 2013 at 9:01 pm
只能说,备份很关键,删除数据库分区,不管是用rm还是drop table 都有认为误操作的可能性,再一个,重大更新时,需要两个人协调确认
Reply ↓ -
jiangyou July 3, 2013 at 9:54 pm
应付数据丢失的方式就是多存几个备份。。
Reply ↓ -
chenggang July 3, 2013 at 11:02 pm
很奇怪,线上不是主从的架构么?只是删除主库分区,任何一台从库数据都应该是ok的啊。
Reply ↓ -
logzgh July 3, 2013 at 11:07 pm
自己运维总是难免会因为缺乏专业的各方法的人才而出现各种问题。 对创业者来讲云计算是一个很好的选择。
Reply ↓ -
TonyLiu July 4, 2013 at 1:56 am
测试环境,在系统或者重大升级之前把所有的系统和软件的升级做一遍,并在测试环境中做好一切的工作,可以顺利升级生产环境,减少错误和对生产环境的影响。
Reply ↓ -
Charles July 4, 2013 at 8:45 am
没想到,数据丢失的后果这么可怕,可以想见当时兄弟们在怎样的心理压力下工作,对技术团队的士气打击估计也很严重。以后要引以为戒,不能再对数据安全不以为然了。另外我比较好奇,这次事故总共造成了多少经济损失?那些数据恢复公司,不可能是免费的吧。还有就是总共造成了多少间接损失?比如用户流失之类的。有没有相关数据披露?
Reply ↓ -
alfa July 4, 2013 at 12:15 pm
看完整篇文章给我的感觉就是:我们非常牛B,虽然没有备份,但仍然恢复了99.9%的数据
整篇文章完全没有总结出问题所在,下次肯定还会犯错误
delete数据的那个人的责任只有5%,运维的责任有10%,管理的责任是85%
从4月23号就停止了备份,中间各种原因没有去备份,管理人员干毛去了?你们不知道备份的重要性?还有什么事情比备份重要?本来这下你们知道备份的重要了吧?结果只是增加一个云备份,,下次你再有这种情况,你还是仅有2个月前的备份,还照样扯蛋
增加云备份也好,增加多台服务器备份也好,这些只是细节, 最重要的是提高备份的优先级,象这种数据库升级完成之后,备份没做好这事儿就不算完,禁止使用,禁止上线,这才是根源,否则下次还会被其它事情拖后,还会出问题
你们应该很庆幸,感谢那个delete的人,才2个月就出了事,绝对应该给那个人发奖金,否则按当前的态度下去,你一直不会有时间来做备份,一年之后再挂,哈哈哈哈,我就不信你还出说能恢复到90%?
Reply ↓-
Zoom.Quiet July 6, 2013 at 7:42 pm
#是也乎#无法同意更多…
Reply ↓
-
Zoom.Quiet July 6, 2013 at 7:42 pm
Pingback: “下厨房”技术团队分析、总结6.26数据丢失事故 | r6
-
李君南 July 4, 2013 at 3:27 pm
还好找回99%,吃一亏长一智。。。
Reply ↓ -
qiuqiu July 4, 2013 at 4:57 pm
我大约在6月份入侵了你们的系统获取到了mysql的权限 并且做了一次dump
这部分数据我不知是否是有用的,可以通过网盘分享给你
Reply ↓-
Rwing July 5, 2013 at 3:23 pm
这个才是最nb的啊。。。。。。
Reply ↓
-
Rwing July 5, 2013 at 3:23 pm
-
互联网新资讯技术组 July 4, 2013 at 7:09 pm
我们也曾遇到过数据丢失的情况,也是因为备份机制不完善。往往到数据丢失时才后悔莫及,多么痛的领悟:( 从搜索引擎的快照里恢复页面,我们当时也这么干过。备份,备份,还是备份!
Reply ↓ -
dohkoos July 4, 2013 at 7:35 pm
“6月26日凌晨12点左右,我们开始重新建立备份节点的工作,需要把原来的从节点删除,重新安装,所以先使用了rm -f方式删除备份节点分区上的所有文件。”
晕倒,涉及数据库的操作前竟然不先做个备份,运维做的也太没有章法了吧!
升级前备份,升级后备份,备份要保留n天。
Reply ↓ -
空杯岳 July 5, 2013 at 3:18 pm
值得警惕。
Reply ↓ -
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 ↓-
zhuwowuyuing July 8, 2013 at 9:39 pm
试验过,这个方法真不错。
Reply ↓
-
zhuwowuyuing July 8, 2013 at 9:39 pm
-
jerry July 6, 2013 at 8:08 pm
执行操作的哥们意识到上错机器后肯定脊梁骨都凉了啊!
Reply ↓ -
hpfplane July 7, 2013 at 10:43 am
只能说,运维水平太低。 前面有不少说了的,我就不重复了。
首先,作业现场,作业实施者,有没有再三确认自己的作业内容?确认自己所在机器? 这个不是靠个人自觉或者个人技术水平,而是要明确写在“作业计划”“实施步骤”里面。
第二,作业的时候,有没有另外一个人在旁边看着?帮忙确认? 如果没有,也是不允许的。这种线上生产环境的作业,一定至少要求双人作业。
Reply ↓ -
孔德远 July 9, 2013 at 1:42 pm
备份最重要。就算是这个操作人员不会出错,能保证其他的人员不会操作出错。
Reply ↓ -
chunzhi July 10, 2013 at 4:18 pm
搞个集群用mysql cluster吧,开3 replica
Reply ↓ -
weipengfei July 11, 2013 at 4:09 pm
你们什么都不缺,就缺一个专业DBA,鉴定完毕
Reply ↓ -
ani di July 11, 2013 at 6:08 pm
数据库操作简单,保证安全困难。像硬盘这些都是有寿命的。以后谨记天天备份,数据无价啊
Reply ↓ -
yyydd July 15, 2013 at 1:02 pm
1.hostname 2.backup
Reply ↓ -
太单纯了 July 18, 2013 at 3:09 pm
有MYSQL slave 节点 ,应该先升级salve 然后再master. 剩下的就是犯了低级错误了。
Reply ↓ -
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~