背景
一台测试服务器,/data磁盘大小为300G,时不时就满了,通过df命令查看300G基本全用了,use 100%。但是进到/data目录中通过du 命令查看,也就用了20个G左右,怎么都对不上。如何清理都没有释放太多空间。查看如下所示:
df -lh
du -lh *
排查
出现以上问题,即df -lh 查看和du -lh 查看磁盘大小不同,排查思路:
- 检查是否挂载点出现问题,即没找到相应的挂载点或者是挂载点覆盖了原来的磁盘目录。
# mount 命令检查挂载点
mount |grep '/data'
没看出来啥问题,这个命令执行完后,和df -lh显示的目录对应的文件系统是一致的,好像也没啥错啊。
2. 是否是有些文件删除后,没有释放导致的呢?先检查一下哪些文件被标记为已删除的文件
lsof +L1|grep '/data'|grep -i deleted
上述命令中含义如下所示:
- lsof 是查找,
- +L1:列出所有连接计算小于1的文件(已被删除的文件)
- grep ‘/data’: 只显示/data 目录下的文件
- grep -i ‘deleted’:过滤出状态为deleted的文件
执行此命令后,输出会包含多列,其中我们需要关注的是“PID”列(进程ID)和“FD”列(文件描述符),显示如下所示:
还真有很多被标记了已删除的文件,到底有没有完全删除释放空间啊?不知道,如何撤底删除呢?(好比windows下我们删除了文件,进了回收站,实际还是会占用C盘资源一样,我们需要清空回收站)
“清空回收站”需要以下命令:
truncate -s 0 /proc/[PID]/fd/[FD_NUM] # 通过lsof获取FD_NUM
如何查找PID、FD_NUM呢,需要了解一下lsof那一步中显示结果各列的含义了。以下补充了表头信息,我们只需找到对应的PID 和FD_NUM即可.
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME STATUS
java 978732 appuser 1w REG 253,4 303252014991 0 269777363 /data/js/WARN_CENTER/warn_center.log (deleted)
java 978732 appuser 2w REG 253,4 303252014991 0 269777363 /data/js/WARN_CENTER/warn_center.log (deleted)
java 978732 appuser 4r REG 253,4 0 0 269664611 /data/js/WARN_CENTER/warn_center.jar (deleted)
java 978732 appuser 10r REG 253,4 0 0 269664611 /data/js/WARN_CENTER/warn_center.jar (deleted)
由此可见,PID为第二列对应的978732,FD_NUM对应的是第四列FD且只取数字即可:1W中的1;2W中的2即可,而其后面的字母代表文件模式,如w代表可写入;
下面我们执行"清空回收站"的命令吧:
truncate -s 0 /proc/978732/fd/1
truncate -s 0 /proc/978732/fd/2
操作完再次df -lh检查,磁盘已释放了,问题圆满解决
总结
df 磁盘占用100%,du占用很少时,两个命令对应不上大小时,可以试着清空“回收站”(已被删除的文件,未释放资源)
- 查看删除状态的文件有哪些,并找到相应的PID和FN_NUM
lsof +L1|grep '/data'|grep -i deleted
- 通过truncate命令清除掉所有删除文件占用的资源
#PID参考上述命令结果中的第二列;FUN_NUM参考第四列并只取数字truncate -s 0 /proc/[PID]/fd/[FUN_NUM]
以上就是解决问题的问键了,但是还有一个问题,为啥rm -rf删除文件后,没有释放资源呢,原因就是进程并没有重启,如果进程重启后也可以释放,如没重启,空间资源就未释放了,那我们是不是也可以通过程启进程的方法替换truncate呢,答案是肯定的。当然可以。
除此,一般清理磁工作,可以通过du命令查看当前文件夹以子文件夹占用空间最大的文件,并指定排序后取前N条,参考以下命令
#du -ah --max-depth=1 |sort -rh|head -n 20
du -ah |sort -rh|head -n 20
du 和df 都是Linux下磁盘空间管理的两个核心命令,有啥区别啊?
概述一下两命令使用场景:df查看整个磁盘或分区的使用情况,而du分析特定目录或文件的空间占用。df 看大盘,du 查细节
两个命令后面常用到的参数说明:
-a: (all): 显示所有的文件和目录占用空间(默认仅显示目录)
-h(human-readable) 不加 −h 时输出单位为字节,可读性差。加了h是用人类能看懂的方式整式,以 K/M/G/T 等易读单位自动转换字节值(例如 1.2G 代替 1234567890)
- 日常检查用 du−sh(只显示目录总和)
- 深度分析用 du−ah−−max−depth=N(控制递归深度)