经过两天的不懈努力,终于恢复了被误删的生产服务器数据。把这次事故的过程和解决办法记录在这里,以警醒自己,也提醒别人不要犯这样的错误。也希望遇到问题的朋友能找到一点解决问题的灵感。01事故背景安排一个妹子在生产服务器上安装Oracle。妹子一边研究一边安装Oracle。她觉得是安装不对,打算卸载重装。从网上找到卸载方法,需要执行一行命令删除Oracle安装目录,命令如下:`rm-rf$ORACLE_BASE/*`如果ORACLE\_BASE变量没有赋值,然后命令变为:`rm-rf/*`等等,女孩正在使用Root帐户。这样一来,整个磁盘上的所有文件都被删除了,包括应用Tomcat,MySQL数据库等等……MySQL数据库不是在运行吗?Linux可以删除正在执行的文件吗?反正就是彻底删除了,最后还剩下一个TomcatLog文件。估计是文件太大了,一会删除也没有成功。看女孩自责的眼神,是我安排她这么做的,我没有和她说明清楚和她的关系。没有任何培训,责任只能由一个人承担。再说了,这责任怎么让美女来承担??打电话到机房,将磁盘挂载到另一台服务器上,查看是否所有文件都被ssh清除了。该服务器正在运行客户的生产系统。已经运行半年多了,需要尽快恢复。于是找到离线备份的数据库,发现备份文件只有1KB,里面只有几行熟悉的mysqldump注释(会不会是crontab执行的备份脚本有问题),最接近的备份也是2013年12月,真是漏了正好下了一夜雨。想起一个领导说的一个案例:当一个生产系统挂了,发现所有备份都有问题,刻录的光盘也有划痕,磁带机也坏了(业内资深人士,我猜他以前都是用光盘备份的。),没想到今天真的实现了,怎么办?部门领导知道情况后,已经做好了最坏的B计划:周日领导亲自带团队和产品AA到客户所在城市,周一与领导沟通;BB和CC去找客户管理员找解决方案说服客户...02救命稻草:Ext3grep赶紧上网查资料恢复误删数据。果然找到了一个ext3grep,可以恢复rm-rf删除的文件。我们的盘也是ext3格式的,网上也有很多成功的案例。于是燃起了一线希望,赶紧umount磁盘,防止重写补充文件扇区。下载ext3grep并安装它(更不用说艰难的编译和安装过程)。先执行扫描文件名的命令:ext3grep/dev/vgdata/LogVol00--dump-names打印出所有被删除的文件和路径,欣喜若狂,不用执行B计划,文件都在了。本软件无法按目录恢复文件,只能执行命令全部恢复:ext3grep/dev/vgdata/LogVol00--restore-all结果当前磁盘空间不足,无法恢复文件。试了好几个文件,有些成功了Partialfailure:ext3grep/dev/vgdata/LogVol00--restore-filevar/lib/mysql/aqsh/tb\\\_b\\\_attench.MYD不禁感慨冷,是因为我删除了写在磁盘上的文件吗?恢复的几率很小,数一数能恢复多少,可能重要的数据文件就在能恢复的MYD文件里。所以先把所有文件名重定向到一个文件:ext3grep/dev/vgdata/LogVol00--dump-names>/usr/allnames.txt过滤掉MySQL数据库的所有文件名,保存为mysqltbname.txt。编写恢复文件的脚本:读取LINE时执行echo"begintorestorefile"$LINEext3grep/dev/vgdata/LogVol00--restore-file$LINEif\\\[$?!=0\\\]ethenechores"torfailed,exit"fidone<./mysqltbname.txt执行,大概用了20分钟,恢复了40多个文件,还不够,我们有近100张表,每个table有frm,myd,myi三个文件,怎么说有300多个呢!将检索到的文件附加到现有数据库中,设置文件权限为777后,重启MySQL,也算是恢复了部分数据,但是客户的重要考勤签到数据和手机端上报的数据(据说客户把这些数据压在了员工绩效方面)还没有找到。该怎么办?中间尝试了另外一个工具,extundelete,语法和ext3grep基本一样,原理应该是一样的,不过据说可以按目录恢复。好吧,试一试:extundelete/dev/vgdata/LogVol00--restore-directoryvar/lib/mysql/aqsh果不其然,无法恢复!!!!!!!!这些文件已损坏。向领导汇报,实施B计划……下班灰溜溜回家。(周末了,回去休息一下,想办法)03一次头脑风暴:Binlog第二天一大早起床(脑子里的东西),装上电脑,去公司(这个周末算是要报销的,不批的话,举报,罚款,开除也不错,有什么周末)。还是跑ext3grep,extundelete,就几个小技巧,把系统放到测试服务器上,看看能不能补充数据。在测试服务器上执行mysqldump,恢复文件,覆盖恢复的文件,给文件添加权限,重启MySQL。等等等等,不是有Binlog吗?我们的服务都需要开启Binlog。或许我们可以通过Binlog恢复数据?于是从Dump的文件名中找到Binlog文件,一共有三个:mysql-binlog0001mysql-bin。mysql-bin.000001居然失败了。。。看另外两个文件,mysql-bin.000010也就几百MB吧,应该比较靠谱,执行restore命令,成功了!赶紧SCP到测试服务器。执行Binlog恢复:mysqlbinlog/usr/mysql-bin.000010|mysql-uroot-p输入密码,卡住(goodsign),等了好久,终于结束了。打开app,哦,感谢CCTV,MTV,数据回来了!04后记我也希望把这次事故牢记在心,以后不要再犯同样的错误。事故反思如下:这次在安排MM维护服务器的时候,没有提前跟她说明情况严重,我也没注意。管理混乱,流程混乱。在在线生产系统中,必须首先计划任何更改。自动备份出了点问题,没有人检查。离线备份小哥每次都从服务器下载1K??的文件,从来不理会。有必要明确每个人在工作场所的职责。事故发生后没有及时发现,导致部分数据被写入磁盘,造成无法恢复的问题。需要写一个应用监控程序。一旦服务出现异常,将通过短信提醒相关负责人。根据评论的提示,再补充一句:不能用root用户操作。应在服务器上设置不同权限级别的用户。通过这次意外,分享本文使用的工具链接:https://code.google.com/p/ext...http://extundelete.sourceforg...功能类似ext3grep,原理应该相似。编译安装依赖很多,具体安装方法可以上网搜索。最后希望各位同行业的朋友们能够牢记这篇文章的大事,愉快地敲代码,千万不要出错~PS:如果觉得我的分享不错,欢迎点赞观看.
