Linux du 和 df统计目录大小为何不一样?

简介: Linux du 和 df统计目录大小为何不一样?

1、问题


使用du 和df 分别对/etc 统计其大小,发现统计结果差距很大?何因?

[root@P1QW01 ~]# df -h /etc/
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/rootvg-rootlv
                      4.8G  249M  4.4G   6% /
[root@P1QW01 ~]# 
[root@P1QW01 ~]# du -sh /etc/
31M    /etc/
[root@P1QW01 ~]# 

--------------------update 2020年7月30日15:10:13------------------------------------------


最近发现目录空间不足的报警,查看一番发现df 统计的结果和du差距很大。

 home]# du -sh *
220K  ansibleDemo
28K cp.log
172M  gpadmin
4.0K  host.sh
36K ktabrm
36K ktahis
40K ktappt
36K ktauas
16K lost+found
1.4M  oracle
637M  scripts
home]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/root_vg-rootlv
                      9.8G  2.9G  6.4G  31% /
tmpfs                 127G  216K  127G   1% /dev/shm
/dev/sda2             477M   36M  416M   8% /boot
/dev/sda1             500M  272K  500M   1% /boot/efi
/dev/mapper/root_vg-homelv
                       20G   16G  2.8G  86% /home

2、结论


原因是:


df 统计的时候是从文件系统考虑的,不仅包含文件系统大小,还要统计被命令或者程序占用的空间,


例如 文件已经被删除,但是被某个进程持有。其原理是读取每个分区的superblock来获取空闲数据块、已使用数据块,从而计算出空闲空间和已使用空间,因此df统计的速度极快(superblock才占用1024字节)。所以非常快。

q1:为什么文件被删除了df -h 还可以统计的到?


要回答这个问题需要很多基础知识,以后有空再写两篇,这里简单说一下,只要bmap中不将这个文件的data block标记为未使用,就会算到实际使用的空间中。bmap是元数据区的一个位标记,其中记录的是数据区的block是否被使用。


du 是面向文件的,只计算文件或者目录占用空间,其具体做法就是stat 文件,然后统计其所占的实际物理空间,因此可以跨分区统计某些你想统计的文件大小总和。因为它们都能被stat找到并统计。

codis]# find / -type f -name "*.conf" -print0 | xargs -0 du -csh
8.0K  /datap11/gpseg0/pg_hba.conf
4.0K  /datap12/gpseg2/pg_hba.conf
12K total

如果文件被删除了,这种肯定是统计不到的。因此看到的du 统计的使用更少,而df 统计的结果更多,可能是因为文件被程序持有。

3、如何找出“丢失的空间”?


既然文件已经被删除了为何还不释放呢? 文件已经被删除,但是被某个进程持有。这种情况就不会释放。


如何查找出这些僵尸文件呢?

 regExp]# lsof |grep deleted

找到的结果就是一些文件已经被删除,但是空间还没有释放的。可以很久实际情况将持有的改文件的PID kill掉来释放空间。


可以使用如下命令批量删除。 生产环境谨慎操作。

for i in `lsof |grep deleted |awk '{ print $2 }'` ; do kill -15 $i ;done

至此,可以解决大多数问题,在网上找了很多都没有提到如果还是解决不了应该怎么办?


有的说是要重启服务器,这就.............


经过一番查询。发现 du -sh* 并不包括隐藏文件和目录。


果然  .ansible占了16GB,至此凶手找到了,ansible 的tmp文件删除就可以了。

.ansible]# du -sh *
16G tmp

再仔细看一下gp一个segment的录下的文件数量我惊呆了。40W+ 的文件目录数量,总共30GB,直接报错了。

ansible]# ls tmp/|wc -l
406278
.ansible]# time rm -rf ./tmp/*
-bash: /bin/rm: Argument list too long
real  0m7.728s
user  0m4.686s
sys 0m0.408s

如何解决呢?通过传参的方式解决

.ansible]# time find /home/.ansible/ -name  "a*"  | xargs rm -rf "a*"
real  33m10.841s
user  0m7.251s
sys 0m53.530s

有没有更快的办法呢?


经过查询可以使用rsync ,使用--delete-before, -d 后跟两个目录,前一个目录为一个空目录,后一个目录为需要删除的目录。


经过测试,时间大约节省了一半的时间。


rsync 的原理大致是: 接收端的rsync会先删除目标目录下已经存在,但源端目录不存在的文件。也就是"多则删之,少则补之"。


如果是"--delete-before",则在目标端rsync刚启动时,会比较源端和目标端,对本利来说,经过比较发现目标端的文件夹是空的,那就是说源端的那个目录/home/.ansible/tmp/需要全部删除,于是就开始删除了。

30G /home/.ansible/tmp
 tmp]# ll |wc -l
410049
 tmp]# time rsync --delete-before -d /home/.ansible/tmp_1/ /home/.ansible/tmp/
real  14m7.573s
user  0m6.763s
sys 1m6.309s
也可以使用另外一个参数差别不大。
ll |wc -l
410515
 tmp]# df -h /home/.ansible/;echo;du -sh /home/.ansible/
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/rootvg-homelv
                      201G   42G  149G  22% /home
30G /home/.ansible/
You have new mail in /var/spool/mail/root
 tmp]# ll |wc -l
410597
 tmp]# time rsync -a --delete  /home/.ansible/tmp_1/ /home/.ansible/tmp/
real  13m42.883s
user  0m6.075s
sys 1m4.439s

在这里想说的是,如果都是文件的话,删除速度更快一些。看如下几个例子。

 redis]# for i in $(seq 1 410000);do echo text >>$i.txt;done
 redis]# time rsync -a --delete /redis/tmp/ /redis/
real  0m46.074s
user  0m0.336s
sys 0m44.341s
使用python删除
import os
import timeit
def main():
    for pathname,dirnames,filenames in os.walk('/redis/tmp/'):
        for filename in filenames:
            file=os.path.join(pathname,filename)
            os.remove(file)
if __name__=='__main__':
 t=timeit.Timer('main()','from __main__ import main')
print t.timeit(1)
 tmp]# time python /home/scripts/delansbieltmp.py 
13.6427898407
real  0m13.663s
user  0m1.733s
sys 0m10.006s

结论: 如果删除大量小文件,速度还是很快,使用rsync 就可以解决,如果有多级目录,删除起来会比较慢。

4、du和df的原理


du -s命令通过将指定文件系统中所有的目录、符号链接和文件使用的块数累加得到该文件系统使用的总块数,因为是stat所以所有类型的 ”文件” 都可以统计的到;而df命令通过查看文件系统磁盘块分配图得出总块数与剩余块数。文件系统分配其中的一些磁盘块用来记录它自身的一些数据,如i节点,磁盘分布图,间接块,超级块等。这些数据对大多数用户级的程序来说是不可见的,通常称为Meta Data

du命令是用户级的程序,它不考虑Meta Data,而df命令则查看文件系统的磁盘分配图并考虑Meta Data。df命令获得真正的文件系统数据,而du命令只查看文件系统的部分情况。


相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
目录
相关文章
|
9天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
37 3
|
14天前
|
存储 Linux Windows
linux常用目录
/sbin s就是super User的意思,这里存放的是系统管理员使用的系统管理程序。 /home 存放普通用户的主目录,在Linux中每个用户都有一个自己的目录,一版该目录名是以用户的账号命名的。 /root 该目录为系统管理员,也称为超级权限者的用户主目录。 /lib 系统开机所需要最基本的动态连接共享库,其作用类似于windows里的DLL文件。几乎所有的应用程序都需要用到这些共享库。 /etc 所有的系统管理所需要的配置文件和子目录。 /usr 这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于windows下的program fies目录。 /bo
31 2
|
13天前
|
Linux Python
Linux 中某个目录中的文件数如何查看?这篇教程分分钟教会你!
在 Linux 系统中,了解目录下的文件数量是常见的需求。本文介绍了多种方法,包括使用 `ls` 和 `wc` 命令组合、`find` 命令、`tree` 命令以及编程方式(如 Python)。无论你是新手还是有经验的用户,都能找到适合自己的方法。掌握这些技巧将提高你在 Linux 系统中的操作效率。
25 4
|
19天前
|
网络协议 Linux
linux系统重要文件目录
本文介绍了Linux系统中的重要目录及其历史背景,包括根目录、/usr、/etc、/var/log和/proc等目录的结构和功能。其中,/etc目录下包含了许多关键配置文件,如网卡配置、DNS解析、主机名设置等。文章还详细解释了各目录和文件的作用,帮助读者更好地理解和管理Linux系统。
42 2
|
28天前
|
Linux 开发工具 Perl
Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
【10月更文挑战第20天】Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
38 4
|
IDE Linux 开发工具
Linux 常用统计指令
CentOS常用到的查看系统命令 uname -a 查看内核/操作系统/CPU信息 head -n 1 /etc/issue # 查看操作系统版本 cat /proc/cpuinfo # 查看CPU信息 hostname ...
962 0
|
8天前
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
73 6
|
9天前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
30 2
|
17天前
|
缓存 监控 Linux
|
4天前
|
运维 监控 网络协议
运维工程师日常工作中最常用的20个Linux命令,涵盖文件操作、目录管理、权限设置、系统监控等方面
本文介绍了运维工程师日常工作中最常用的20个Linux命令,涵盖文件操作、目录管理、权限设置、系统监控等方面,旨在帮助读者提高工作效率。从基本的文件查看与编辑,到高级的网络配置与安全管理,这些命令是运维工作中的必备工具。
22 3