建立linux回收站
一次删库跑路实例
前天中午,正在那啃鸡腿吃午饭,同事电话打过来告诉我服务没反应了。
作为一个尽职的运维人员,嘴里叼着鸡腿从食堂跑到工位开始排查问题。
三年老运维,排错就是快。一个 df
命令就看出来,是项目的数据库服务器磁盘满了。老毛病了。
(别问我为什么没有磁盘监控,问就是测试环境懒得加)
早就让领导申请添加磁盘了,但是申请还没批下来,有啥办法,手工删除吧。
1 2 3 4 5
| cd /data/mysql rm -fr mysqlbak/* #这里删除全部文件是因为这个mysqlbak里,放的都是自动备份的mysql文件,并且已经做好他机备份了,本机备份可有可无。所以为了快速恢复业务,直接来了一个rm -fr * #本来做到这里就完事了,重启下mysql就成了。 systemctl restart mysqld
|
然后,然后,就发现数据库起不来了,看日志发现mysql的安装路径丢了。这可吓得我连鸡腿都掉到了地上。
赶紧跑到路径下一看,我*,mysql目录果然空了。
history
一看,刚才啃鸡腿没注意,运行的是 rm -fr mysql/*
。
得,删库了,订机票跑路吧。
当然其实不至于跑路,有备库,有备份,测试环境,直接恢复就行了。但是不可避免的,被领导批了一顿。
好在是测试环境,不然我现在可能已经在看守所了。
建立回收站机制
众所周知,windows文件如果误删除了,可以通过在回收站中找到文件进行还原的。
但是作为服务器的linux系统(我们用的是rhel 7),在非桌面模式下是没有回收站的。一线运维经常要快速解决问题,有时候手快就忘了备份的事,忘了通配符不能乱用,忘了XXXXX。
所以一方面,要加强生产环境的安全操作意识,一方面也要加强环境的安全程度。
所以建立一个回收站就很重要。
之前也琢磨过类似的东西,无非就是建立一个回收目录,然后用 mv
命令替换 rm
命令。 但是网上找的脚本都不好用,而且服务器太多,每隔服务器登录上去修改又容易弄出其他问题。所以决定自己写一个脚本,通过ansible搞定。
脚本编写过程
说搞就搞。
其实本身脚本并没有特别复杂的地方。
- 进来就三板斧,注释写好,定义时间变量和回收目录变量。
1 2 3 4 5 6 7 8 9 10 11
| #!/bin/bash
trashDir=~/.tarsh/
|
- 然后就是定义删除操作,本质上就是一个带提示的
mv
操作
1 2 3 4 5 6 7 8
| deleteOperation () { ls -d ${@} | while read deleteFiles do done }
|
但是测试的时候,模拟用户习惯,一般删除文件都会下意思 rm -rf
或者 rm -ri
等添加参数,但是上述脚本在删除的时候就会报错,因为没有 -fr
之类的文件。
- 所以为了解决这个问题,就要在删除的时候把参数过滤掉。
1 2 3 4 5 6 7 8 9 10 11 12 13
| deleteOperation () { while [[ -n ${1} ]]; do case ${1} in -*) shift 1;; *) break; esac done ls -d ${@} | while read deleteFiles do done }
|
但是确实有些人就是习惯了 rm -ri
这种提醒,如果没有确认,可能有些人就是不习惯。所以还要让脚本认识自己支持的参数。
1 2 3 4 5 6 7 8 9
| # helpPrint () { echo 'Usage: rm13 [OPTION]... FILE...' echo 'remove (unlink) the FILE(s).' echo ' -f ignore nonexistent files and arguments, never prompt' echo ' -i prompt before removal' echo ' -h display this help and exit' exit 1 }
|
1 2 3 4 5 6 7 8
| # alertPrint () { echo 'Are you sure to delete?(y/n)' read inputContent if [[ ${inputContent} != y ]]; then exit 1 fi }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| # deleteOperation () { while [[ -n ${1} ]]; do case ${1} in -f|-r|-rf|-fr ) shift 1;; -i|-ir|-ir ) alertPrint; shift 1;; -*) helpPrint; shift 1;; *) break; esac done ls -d ${@} | while read deleteFiles do done }
|
这样基本上,删除的功能就完成了。
但是我们没有考虑还原的功能。
作为一个回收站,我们可能不要求直接一键还原,但是我们要记录下来一个文件是什么时候删除的,在哪里删除的。
本来最好的方式是直接通过文件名来定义删除路径,但是因为linux下,路径分隔符 /
写到文件名里很麻烦。
1 2 3 4 5 6 7
| recordFile=${trashDir}recordFile
# recordFile() { `pwd` >> ${recordFile} echo ${@} >> ${recordFile} }
|
这样就可以把删除情况写到日志里,如果以后有需要,可以回头查找。
这样脚本就大功告成了。
以下是脚本全貌。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| #!/bin/bash
# #auther: fushisanlang #version: v1 #mail: fushisanlang@yahoo.com #use for replace rm command #
# trashDir=~/.tarsh/ recordFile=${trashDir}recordFile # alertPrint () { echo 'Are you sure to delete?(y/n)' read inputContent if [[ ${inputContent} != y ]]; then exit 1 fi }
# helpPrint () { echo 'Usage: rm13 [OPTION]... FILE...' echo 'remove (unlink) the FILE(s).' echo ' -f ignore nonexistent files and arguments, never prompt' echo ' -i prompt before removal' echo ' -h display this help and exit' exit 1 }
# deleteOperation () { while [[ -n ${1} ]]; do case ${1} in -f|-r|-rf|-fr ) shift 1;; -i|-ir|-ir ) alertPrint; shift 1;; -*) helpPrint; shift 1;; *) break; esac done recordFile ${@} ls -d ${@} | while read deleteFiles do done }
# recordFile() { `pwd` >> ${recordFile} echo ${@} >> ${recordFile} }
deleteOperation ${@}
|
自动化部署
上一篇文章,我们已经定义好了一个通过mv替代rm命令的脚本。但是如果要给所有服务器手工配置,就很麻烦了。
要登录服务器,上传脚本,修改环境变量。
所以要想一个简单的方法。
首先是脚本获取,我想的是放到一个url上,通过wget的方式获取。
https://download.fushisanlang.cn/rm13.sh
我这里用的是nginx代理的方式做的,nginx配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| server { listen 80; server_name download.fushisanlang.cn; rewrite ^(.*) https://$server_name$1 redirect; }
server { listen 443; server_name download.fushisanlang.cn; ssl on; ssl_certificate /usr/local/nginx/ca/download.crt; ssl_certificate_key /usr/local/nginx/ca/download.key;
ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 ; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:DHERSA-AES128-SHA:RC4-SHA:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!DSS:!PKS; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m;
root /usr/local/nginx/html/download; index index.html;
}
|
其次是配置方法,如果挨个服务器执行命令,工作量很大,所以直接写成脚本通过curl调用。
url为 https://download.fushisanlang.cn/install-rm.sh
安装脚本
1 2 3 4 5
| #!/bin/bash wget 'https://download.fushisanlang.cn/rm13.sh' -O ~/.rm13 echo "alias rm='sh ~/.rm13'" >> ~/.bashrc source ~/.bashrc echo "enjoy your new rm command."
|
使用方法也很简单,直接
1
| curl https://download.fushisanlang.cn/install-rm.sh | bash
|
就可以了。
最后就是ansible通过shell模块,让所有服务器执行上述命令就可以了。
反思
其实浩浩荡荡做了这么一个事,最重要的还是运维人员的安全操作意识。
操作前先备份,操作时双人确认。
等等等等。
还是希望大家规范操作,不要真等到删库跑路了才知道后悔。