删库不要跑,我站起来还可以删

谙忆 2019-09-06

服务器 mysql 日志 数据库 主机 测试 Server binlog 磁盘 删库

原文地址:
https://copyfuture.com/blogs-details/201909061555306597xvo4pefwz7sy68

删库不要跑,学学下面的操作,每天执行一次rm -rf /*不是梦
上午删完,下午恢复,一天就过去了,还不用加班

前些日子在菜鸟架构上看到一篇服务器误删文件的恢复过程文章,感觉挺有意思的,在这里进行分享一波。

事故背景

大佬:"这里有个在生产服务器上安装Oracle的任务,部门的哪个妹子接一下"
然后有个妹子接受了大佬的安装Oracle的任务,妹子未注意到shell的语法,当变量未被赋值的时候,会是个空值。注意了,圈起来要考的。

妹子执行命令如下:

rm -rf $ORACLE_BASE/*

看到这条命令,你就知道有多危险了,更何况妹子用的是root账号??what?

“很幸运”,ORACLE_BASE不存在或者未赋值,上面命令变成大家熟悉的:

rm -rf /*

root用户?执行后,可以跑路了...
(插个小技巧:使用${var:=初始值},可以让未定义的变量或者空值进行赋初值)

当然,妹子没跑路,那个大佬也没跑路,稳稳的背下了恢复数据的大锅。

整个盘的文件都被删了,咋办~ ~

大佬的原文是:

mysql数据库不是在运行吗?linux能删除正在执行的文件?反正是彻底删除了,最后还剩一个tomcat的log文件,估计是文件过大,一时没有删除成功

看着妹子自责的眼神,又是因为这事是我安排她做的,也没有跟她讲清厉害关系,没有任何培训,责任只能一个人背了,况且怎么能让美女背负这个责任呢? 打电话到机房,将盘挂到另一台服务器上,ssh上去查看文件全部被清,这台服务器运行的可是一个客户的生产系统啊,已经运行大半年了,得尽快恢复啊。于是找来脱机备份的数据库,发现备份文件只有1kb,里面只有几行熟悉的mysqldump注释(难道是crontab执行的备份脚本有问题),最接近的备份也是2013年12月份的了,真是屋漏偏逢连夜雨啊。想起来一位领导说过的案例:当一个生产系统挂掉以后,发现所有备份都有问题,刻录的光盘也有划痕,磁带机也坏了(一个业界前辈,估计以前还用光盘做备份了),没想到今天真的应验到我的身上了,怎么办??

部门领导知道情况后,已经做了最坏的B计划:领导亲自带队和产品AA周日赶到客户所在的地市,星期一去领导层沟通;BB和CC去客户管理员那边想办法说服客户。。。


大佬接下来试了两种方法恢复数据:
ext3grep和extundelete,都是只能恢复一部分数据(原因:事故发生后,没有及时发现,造成部分数据写入磁盘,造成不可恢复问题。)

两个工具的下载地址(寄希望于工具?送四个字:听天由命):
ext3grep:https://code.google.com/p/ext3grep/
extundelete:http://extundelete.sourceforge.net/

庆幸的是:
binlog文件还在。没看到大佬说的是恢复的binlog文件还是说该文件存在另外的盘,反正就是binlog文件找到了。

那不用说,数据是没问题了。普及下binlog文件的认识。

binlog 基本认识

MySQL的二进制日志可以说是MySQL最重要的日志了,它记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的。

一般来说开启二进制日志大概会有1%的性能损耗,这点消耗完全是可以接受的,为了数据的安全。

从binlog日志恢复数据

恢复语法格式:
mysqlbinlog mysql-bin.0000xx | mysql -u用户名 -p密码 数据库名

常用选项:
  --start-position=953                   起始pos点
  --stop-position=1437                   结束pos点
  --start-datetime="2013-11-29 13:18:54" 起始时间点
  --stop-datetime="2013-11-29 13:21:53"  结束时间点
  --database=zyyshop                     指定只恢复zyyshop数据库(一台主机上往往有多个数据库,只限本地log日志)
    
不常用选项:    
  -u --user=name              Connect to the remote server as username.连接到远程主机的用户名
  -p --password[=name]        Password to connect to remote server.连接到远程主机的密码
  -h --host=name              Get the binlog from server.从远程主机上获取binlog日志
  --read-from-remote-server   Read binary logs from a MySQL server.从某个MySQL服务器上读取binlog日志

小结:实际是将读出的binlog日志内容,通过管道符传递给mysql命令。这些命令、文件尽量写成绝对路径;

总结一波

说实话,错误挺低级的。应该比我以前写的一篇,redis key*的那种错误更加低级。

先看看大佬的总结:


  • 本次安排MM进行服务器维护时没有提前对她进行说明厉害情况,自己也未重视,管理混乱,流程混乱。一个在线的生产系统,任何一个改动一定要先谋而后动。
  • 自动备份出现问题,没有任何人检查。脱机备份人员每次从服务器上下载1k的文件却从未重视。需要明确大家在工作岗位上的责任。
  • 事故发生后,没有及时发现,造成部分数据写入磁盘,造成不可恢复问题。需要编写应用监控程序,服务一旦有异常,短信告警相关责任人。
  • 不能使用root用户来操作。应该在服务器上开设不同权限级别的用户。

我也简单的总结一下:
猜想,这个妹子应该是运维的小姐姐,不是开发人员(运维吗?过分了呀,那我也要转运维)

  • root用户,一定是不能随便用来用的,而且还是生成环境,按照需要来分配不同权限的账号使用
  • shell语法熟知过少?还是疏忽了,我猜应该是没重视
  • 不过直接用变量来rm -rf来调用,其实也是有问题的,需要把变量输出一下瞅瞅是啥值。建议是,如果是变量的路径需要rm -rf的,先把变量输出,再拷贝变量的值路径,进行删除
  • 了解下binlog是必要的
  • shell命令可以再熟悉熟悉

另外,出了这么大的事故,部门领导的做法不错

原文:

通过本次事故,几位跟这个项目和事故没有任何关系的同事,主动前来帮忙,查资料,帮测试,有一位同事还帮忙到晚上1点多钟进行数据恢复测试。同时产品经理在想到面向客户的巨大压力的情况下,没有慌乱而责怪开发人员和具体操作人,而让大家能静下心来想解决方案。部门领导也积极主动的帮忙想办法,陪我们加班测试,实时跟踪事情进程


真不知道我在线上环境来个rm -rf /*会背多大的锅,可能会n+1吧、
不过毕竟没有权限~ ~(跃跃欲试的表情此刻变成了弯眉)

建议在执行 rm -rf /* 类似的命令的时候,自己检查3遍,请小伙伴看看,有未知变量的,把变量输出一遍,就不会出现这种情况了。

吾非大神,与汝俱进

最后插播广告时间:公众号未关注的贝贝们可以来一波关注

感谢关注

登录 后评论
下一篇
云攻略小攻
1894人浏览
2019-10-11
相关推荐
MySQL误删数据救命指南
6292人浏览
2018-01-02 13:30:50
如何防止 SQL 注入?
855人浏览
2018-10-26 10:44:03
Redis和编程语言的纠缠
531人浏览
2018-11-11 21:32:00
oracle 手工删库
456人浏览
2017-11-13 13:56:00
0
0
0
627