在排查软件应用卡顿时,通常会检查服务器的磁盘使用情况。然而有些时候,使用 df
和du
查到的情况不一致。
例如,分别使用 df -h /
和 du -h /
查看 /
的磁盘大小。结果可能差异如下:
df -h /
查看结果为197G
root@xzbd:~# df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 217G 197G 8.3G 97% /
du -h / --max-depth=1
查看结果为 34G
root@ceph03:~# du -h / --max-depth=1
4.0K /lib64
791M /home
...
4.0K /srv
17M /etc
32K /mnt
34G /
通过案列,发现两者差距甚大。
分析
导致两者数据不一致,通常有两种情况。
一种是,两次查询之间有数据写入或清除操作。这种情况下一般数据变化比较小。很显然,此处并不是。
另一种情况是df
和 du
统计原理不一致,导致数据有偏差。
df
和 du
命令的差异如下:
特点 | du命令 | df 命令 |
---|---|---|
功能 | 估算文件和目录的磁盘空间使用情况 | 显示文件系统的磁盘空间使用情况 |
范围 | 递归计算指定目录下所有文件和子目录的磁盘空间使用情况 | 显示已挂载文件系统的磁盘空间使用情况 |
输出信息 | 文件和目录的磁盘空间使用量 | 文件系统的磁盘空间使用情况,包括总容量、已使用、可用和挂载点等信息 |
查找大文件 | 是 | 否 |
用途 | 定位存储占用问题,查找占用空间较大的文件或目录 | 查看整个文件系统的使用情况和可用空间 |
高级选项 | 提供一些高级选项,如--exclude 用于排除指定的文件或目录,--max-depth 用于限制递归深度等 | 提供一些高级选项,如-i 用于显示inode的使用情况,-T 用于显示文件系统类型等 |
导致这两个命令查看磁盘容量不一致的原因,很大程度是因为用户删除了大量的文件,而这些文件被进程或应用程序占用而仍然处于打开状态。在Linux系统中,当一个文件被打开并被进程使用时,即使你删除了该文件,它在磁盘上的存储空间并不会立即释放,直到所有引用该文件的进程关闭该文件时才会真正释放空间。
df
命令通过读取文件系统的元数据信息来获取磁盘使用情况,而不是实时计算文件的占用空间。因此,即使你删除了文件,df
命令仍然显示文件系统占用的空间没有发生变化,直到相应的进程关闭了文件并释放了相关的存储空间。
当使用du
命令查看文件和目录的磁盘空间使用情况时,它会遍历指定的文件和目录,并累加它们的大小来计算总的磁盘空间使用量。du
命令在计算磁盘空间时不依赖于文件的打开状态或文件系统的元数据,而是通过读取文件的内容来确定其大小。
总结起来,du命令之所以能够准确地查出文件和目录的磁盘空间使用情况,是因为它直接读取文件的内容并计算大小,不受文件打开状态或文件系统元数据的影响。这使得du命令成为了一个可靠的工具,用于查看特定文件或目录的磁盘空间使用情况。
解决
对于已删除,但未释放空间的文件,可以使用 lsof
查找。具体命令如下:
sudo lsof | grep deleted
根据 lsof
列出的pid
直接kill
相应进程或重启相应的服务即可。
验证
root@xzbd:~# df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 217G 197G 8.2G 97% /
root@xzbd:~# lsof | grep deleted
none 4639 root txt REG 0,1 8632 163554 / (deleted)
rsyslogd 19953 syslog 7w REG 8,3 180902886402 2621453 /var/log/syslog (deleted)
in:imuxso 19953 19966 syslog 7w REG 8,3 180902879272 2621453 /var/log/syslog (deleted)
in:imklog 19953 19967 syslog 7w REG 8,3 180902880842 2621453 /var/log/syslog (deleted)
rs:main 19953 19968 syslog 7w REG 8,3 180902882830 2621453 /var/log/syslog (deleted)
root@xybd:~# kill -9 19966 19967 19968
root@xzbd:~#
root@xybd:~# df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 217G 31G 175G 16% /
总结
查询结果不一致的原因,通常是因为这些文件被进程或应用程序占用而仍然处于打开状态。在Linux系统中,当一个文件被打开并被进程使用时,即使你删除了该文件,它在磁盘上的存储空间并不会立即释放,直到所有引用该文件的进程关闭该文件时才会真正释放空间。
df命令通过读取文件系统的元数据信息来获取磁盘使用情况,而不是实时计算文件的占用空间。因此,即使你删除了文件,df命令仍然显示文件系统占用的空间没有发生变化,直到相应的进程关闭了文件并释放了相关的存储空间。
du命令查看文件和目录的磁盘空间使用情况时,会遍历指定的文件和目录,并累加它们的大小来计算总的磁盘空间使用量。du命令在计算磁盘空间时不依赖于文件的打开状态或文件系统的元数据,而是通过读取文件的内容来确定其大小。du命令的实时性使得它可以准确地反映文件和目录的当前磁盘空间使用情况。
需要注意的是,du命令只报告指定文件或目录的磁盘空间使用量,并不包括整个文件系统的使用情况。如果想要查看整个文件系统的使用情况,可以使用df命令。