du df

记一次文件删除bug查询

Posted by Tango on March 19, 2019

背景

线上服务接连多次磁盘空间不足报警,通过du和df命令查询磁盘使用空间,发现其显示结果明显不一致。

Du和Df区别

Du(Disk Usage)原理

du命令会对待统计文件逐个调用fstat这个系统调用,获取文件大小。

它的数据是基于文件获取的,所以有很大的灵活性,不一定非要针对一个分区,可以跨越多个分区操作。

如果针对的目录中文件很多,du速度就会很慢了。

Df(Disk Free)原理

df命令使用的是statfs这个系统调用,直接读取分区的超级块信息获取分区使用情况。

它的数据是基于分区元数据的,所以只能针对整个分区。

由于df直接读取超级块,所以运行速度不受文件多少影响。

Du和Df不一致原因

当一个文件被删除后,在文件系统 目录中已经不可见了,所以du就不会再统计它了。

然而如果此时还有运行的进程持有这个已经被删除了的文件的句柄,那么这个文件就不会真正从磁盘中被删除,分区超级块中的信息也就不会更改。

这样df仍旧会统计这个被删除了的文件。

如何定位

lsof命令

lsof abc.txt 显示开启文件abc.txt的进程

lsof -c abc 显示abc进程现在打开的文件

lsof -c -p 1234 列出进程号为1234的进程所打开的文件

lsof -g gid 显示归属gid的进程情况

lsof +d /usr/local/ 显示目录下被进程开启的文件

lsof +D /usr/local/ 同上,但是会搜索目录下的目录,时间较长

lsof -d 4 显示使用fd为4的进程

lsof -i 用以显示符合条件的进程情况

lsof -i [46] [protocol][@hostname hostaddr][:service port] 46 –> IPv4 or IPv6 protocol –> TCP or UDP hostname –> Internet host name hostaddr –> IPv4地址 service –> /etc/service中的 service name (可以不止一个) port –> 端口号 (可以不止一个)

定位步骤

1、lsof | grep deleted > deleted_file查看有哪些未被释放的文件

2、排序看最大的未被释放的文件大小,命令:sort -nr -k 7 deleted_file>sort_deleted_file

3、more sort_deleted_file 查看前面那些文件,将占用空间大的程序kill掉 kill 进程号