文件消失之谜——记一起linux文件被异常删除
国庆节之前,生产服务器上面的一些文件被异常删除,费了九牛二虎之力才找到删除原因,今天终于抽空在这里总结记录下事情的前因后果。
文件异常删除
9月27日突然接到 leader 的反馈,说业务团队没有收到当天的业务收据,让我检查对应的服务程序是不是异常。
于是开始登录对应服务器,开始检查每日数据发送的脚本。结果一查看,服务器下面的/mnt下面的文件全部被删了,难怪说收不到当前的数据了。好在有备份的脚本,首先将备份拷贝过来,先运行起来。
删除原因排查
于是下面开始各种排查,三下五除二,一通分析排查。
(1)首先 history 查看是否有 rm 删除的操作,检查下来完全没有删除的动作;
(2)其次 crontab -l 查看定时任务
结果定时任务正常
(3)然后 ps -elf 查看有无异常的运行程序,一通查下来并无异常程序;
(4)最后查看各种日志,排查是否有异常日志,结果也查不出任何异常;
...
因为使用云计算资源,有时候就是会出现一些奇葩的问题,比如网络突然会出现超时,然后自己就好了,也查不出到底啥问题。于是最后即将要放弃排查。
问题原因查明
初现端倪
到了第二天,偶然执行了一下 ls -l /
问题至此初现端倪:
发现 /mnt 和 /tmp 目录访问时间和大小等信息完全一致,于是猜想难道 /mnt实际指向的就是 /tmp,如果确实如此,那么文件被删除就是有可能的了,因为大家都知道 /tmp 是系统临时文件存放的目录,系统会自动定期做删除。
问题验证
执行stat进一步验证
发现两个目录的文件块、设备数、inode、连接数、访问时间、文件修改时间、文件属性修改时间等所有信息出奇的一致,进一步证实了/mnt 和 /tmp 实际就是一个目录。
真相大白
正常情况下,不同的目录stat查看到的信息不可能是完全一样的,至少inode不可能是一样,除非两个目录挂载到了一个磁盘设备下面。
从上图结合 lsblk 和 df 的结果来看,/mnt 和 /tmp 同时挂载到了 磁盘 vdc 下面,因为系统定期删除 /tmp 目录从而导致了 /mnt 下面的文件被删除。至此真相大白。
删除策略
既然指导是因为/tmp 被定时清理导致的,那么系统清理/tmp 的策略到底是怎样的呢?
经过查询资料,Centos7下面的systemd-tmpfiles-clean.service控制台系统的定期策略,服务器启动文件:/usr/lib/systemd/system/systemd-tmpfiles-clean.service,配置文件:/usr/lib/tmpfiles.d/tmp.conf
查看配置文件,系统会删除10天之前 /tmp 下面的文件。
之后跟组内同事确认,确实有人执行过 将vdc挂载到 /tmp 下的命令,差不多就是 10天之前执行的,当时 vdc 原本是 挂载到 /mnt 下面的,并且df 查看挂载点仍然在 /mnt下面,以为挂载失败了。
问题验证
为了彻底复现这个删除场景,于是在测试环境写了个删除检测脚本。
[root@api-server ~]# echo bbb > /mnt/bbb.txt;echo `date` 第一次创建文件bbb.txt >> check_file.log
[root@api-server ~]# nohup ./check.sh &
将首次创建文件的时间记录到日志里面,然后后台运行文件删除检测脚本,检测并记录文件被删除的时间。
国庆节后查看删除日志
果然10天后 /mnt 下面的文件会被删除。
事故总结
(1)生产环境数据必须要做到有备份;
(2)linux支持将一个磁盘文件挂载到不同的目录下面,df 只能查看到首次挂载的目录,二次甚至三次挂载的目录查看不到;
(3)操作有风险,生产环境需要注意切勿做一些危险操作。