谁动了我的磁盘:Linux磁盘空间被未知资源耗尽
最近跑一稳定性测试,为防止日志过多塞满磁盘。特将程序日志指向空设备(/dev/null),不实际写磁盘。
结果一晚上过去了,磁盘还是快爆了,而且日志文件是空的!
使用df -hlT查看磁盘剩余空间,所剩无几:
[higkoo@TestServer ~]# df -hlT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext3 20G 6.6G 12G 36% /
/dev/sda2 xfs 115G 103G 13G 89% /data
tmpfs tmpfs 2.0G 0 2.0G 0% /dev/shm
而使用du -sh查看该分区磁盘占用量仅13G:
[higkoo@TestServer ~]# du -sh /data/
13G /data/
使用find也无法找到较大的文件,谁吃了我的磁盘空间呢?
想起昨晚的一个删除操作:先删除日志文件,然后将日志指向(ln -s logfile /dev/null)空设备而没有重启服务。顿时恍然大悟
立马停止服务(killall -15 nginx)再查看磁盘,空间成功释放。
产生这个问题的根本原因是:文件确实是从文件系统中删除了,但没有从磁盘上删除。
之所以误删除可以被找回来,也是同样的道理(注意: rm -rf / 和 rm -rf ./)。上文进程在写文件时,文件被删除。而进程还在继续向文件地址后擦写数据,导致仍然占用磁盘空间。由于进程正在操作磁盘,待进程退出后操作才能被更新。所以,在删除文件前先看一下有谁正在读写。
要重现这个现象非常容易,如下操作:
[higkoo@TestServer ~]# df -hlT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext3 20G 6.6G 12G 36% /
/dev/sda2 xfs 115G 13G 103G 11% /data
tmpfs tmpfs 2.0G 0 2.0G 0% /dev/shm
[higkoo@TestServer ~]#du -sh /data/
13G /data/
[higkoo@TestServer ~]# rm /data/filetest # 删除后约一分钟后执行下面的命令
[higkoo@TestServer ~]#du -sh /data/
13G /data/
[higkoo@TestServer ~]#df -hlT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext3 20G 6.6G 12G 36% /
/dev/sda2 xfs 115G 33G 83G 29% /data
tmpfs tmpfs 2.0G 0 2.0G 0% /dev/shm
如何跟踪这类问题呢?答案:
lsof -n | grep deletedCOMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
dd 31708 higkoo 1w REG 8,2 5523705856 429590 /data/filetest (deleted)
命令打lsof -n | grep deleted印出所有针对已删除文件的读写操作,这类操作是无效的,也正是磁盘空间莫名消失的根本原因!