当前位置: 首页 > Linux

你知道吗?为什么du和df的统计结果不一样?

时间:2023-04-06 03:44:06 Linux

我们经常使用du和df来获取目录或文件系统的占用空间。但他们的统计结果并不一致。大多数时候,他们的结果不会相差很大,但有时他们的统计结果会相差很大。例如:DF的统计结果[root@xuexi~]#DF-HTFILESYSYSTEMTYPESIZEUSEDAvailUSE%MountedOn/DEV/SDA2EXT418G1.7G15G11%/TMPFSTMPFS0491M0%/DEV/SHM/DEV/sda1ext4239M68M159M30%/boot//192.168.0.124/wincifs381G243G138G64%/mntdu统计根目录[root@xuexi~]#du-fdd/null>24/dev/所用空间“/”是1.7G,而du的结果是244G。这里du的统计结果大于df。查看/boot分区的统计结果。[root@xuexi~]#df-hT/boot;echo;du-sh/bootFilesystemTypeSizeUsedAvailUse%Mountedon/dev/sda1ext4239M68M159M30%/boot66M/bootdu结果为66M,是68M,差别不大,但是df的结果比du大。文件存储和删除的底层流程这里简单介绍一下文件系统相关的底层机制。首先,它解释了文件是如何存储在文件系统中的。如果你想把a.txt存放在/tmp目录下。当a.txt文件要存储在/tmp下时:(1)。先从inode表中找出一个空闲的inode号赋值给a.txt,比如2222。然后在inodemap(imap)中把2222这个inode号标记为used。(2).在/tmp的数据块中添加一个.txt文件的记录。该记录包括指向索引节点号的指针,例如“0x2222”。(3).然后从块映射(bmap)中找到一个空闲的数据块,开始将a.txt中的数据写入到数据块中。每写入一段空间(ext4每次分配一段空间),就从bmap中找一个空闲的数据块,直到所有数据存入。(4).设置inode表中2222号记录的数据块指针,通过这个指针可以找到a.txt使用了哪些数据块。当要删除a.txt文件时:(1).删除inode表中指向a.txt的数据块指针。只要把这里删了,外界就查不到a.txt的数据了。但是文件仍然存在,它只是一个“损坏”的文件,因为没有指向数据块的指针。(2).在imap中将inode编号2222标记为未使用。然后这个inode号被释放,可以被后续的文件重用。(3).删除父目录/tmp的数据块中关于a.txt的记录。只要把这里删了,外界就看不到也找不到这个文件了。(4).在bmap中将a.txt占用的块标记为未使用。在此处标记为未使用后,这些数据块可以被后续文件覆盖和重用。考虑一种情况,当一个文件被删除了,但是此时还有进程在使用这个文件,此时是什么情况呢?外界看不到也找不到这个文件,所以删除过程到了第(3)步。但是进程还在使用这个文件的数据,也能查到这个文件的数据,因为进程在加载文件的时候就已经得到了这个文件占用了哪些数据块。虽然文件被删除了,但是bmap中的这些数据块仍然没有被标记为未使用。du统计du的原理是使用stat命令统计每个文件(包括子目录)占用的总空间。较慢,因为stat命令用于每个涉及的文件。1、如果statistics目录下挂载了其他文件系统,那么这个文件系统也会被统计。例如“du-sh/”会统计所有分区的文件,包括挂载的。就像本文开头统计的“/”,du的结果是244G,明显比df统计的结果大,因为挂载了一个分区到/mnt目录。##DF的统计结果[root@xuexi~]#DF-HTFilesystemTypeSizeUseUseAvailUse%MountedOn/DEV/SDA2EXT418G1.7G15G11%/TMPFSTMPFS491m0491M0%/SHM/DEV/DEV/sda1ext4239M68M159M30%/boot//192.168.0.124/wincifs381G243G138G64%/mnt##根目录du统计[root@xuexi~]#du-sh/dev/2>/null244G/2。如果文件被删除,即使被其他进程引用,du命令也不能指望它。因为stat命令找不到这个文件。3.可以跨分区统计一些要统计的文件的总大小。因为它们都可以通过stat找到并统计。例如:统计linux下所有img文件的大小。[root@xuexi~]#find/-typef-name"*.img"-print0|xargs-0du-csh19M/boot/initramfs-2.6.32-504.el6.x86_64.img13M/mnt/linuxtools/cirros-0.3.4-x86_64-disk.img31Mtotal这里统计的两个img文件是不同的分区。df统计df的原理是读取每个分区的superblock,获取freedatablock和useddatablock,从而计算出freespace和usedspace,所以dfstatistics的速度极快(superblock只占1024字节).1、当一个文件系统下挂载了其他分区时,df不会统计这个分区。这个很好理解,因为df读取的是每个分区的superblock,即使分区1挂载在分区0的目录下,df统计分区0的时候,也只能读取分区0的superblock。比如下面/mnt和/boot不计入“/”。[root@xuexi?~]#?df?-hTFilesystem??????????Type???Size??Used?Avail?Use%?Mounted?on/dev/sda2???????????ext4????18G??1.7G???15G??11%?/tmpfs???????????????tmpfs??491M?????0??491M???0%?/dev/shm/dev/sda1???????????ext4???239M???68M??159M30%/boot//192.168.0.124/wincifs381G243G138G64%/mnt2。由于df每次统计都会读取superblock,所以df统计文件系统中的一个文件时,会自动转换为统计这个文件系统的信息。[root@xuexi~]#df-hT/etc/fstabFilesystemTypeSizeUsedAvailUse%Mountedon/dev/sda2ext418G1.7G15G11%/3.df将统计已删除但仍被进程引用的文件.一般情况下,删除一个文件会立即释放相关指针,并将imap和bmap中的相关位图标记为未使用。只要更改bmap,文件系统就可以立即知道每个块组中哪些数据块是空闲的,哪些数据块正在使用中,这些信息会更新到分区的超级块中。所以df可以立即统计实时空间信息。但是当一个文件被删除后,如果还有进程在引用这个文件,根据前面的分析,bmap不会将这个文件的数据块标记为未使用,也不会将该数据块的使用情况更新到superblock中。由于df根据超级块中空闲和已用数据块的数量计算空闲空间和已用空间,因此df将“已删除”文件计入已用空间。比如新建一个较大的文件放在“/”目录下,用du和df统计根目录的已用空间。[root@xuexi~]#ddif=/dev/zeroof=/my.isobs=1Mcount=1000[root@xuexi~]#df-hT/FilesystemTypeSizeUsedAvailUse%Mountedon/dev/sda2ext418G2.7G14G17%/[root@xuexi~]#du-sh--exclude="/mnt"/2>/dev/null2.7G/GB级单位是相等的。现在用一个进程引用这个文件,然后删除这个文件,然后用du和df算。[root@xuexi~]#tail-f/my.iso&[root@xuexi~]#rm-rf/my.iso[root@xuexi~]#ls/my.isols:cannotaccess/my.iso:No这样的文件或目录[root@xuexi~]#du-sh--exclude="/mnt"/2>/dev/null1.8G/[root@xuexi~]#df-hT/FilesystemTypeSizeUsedAvailUse%Mountedon/dev/sda2ext418G2.7G14G17%/可以发现外界没有获取到my.iso文件,所以du无法统计到这个文件。但是df统计的是文件大小,因为my.iso占用的数据块还没有标记为未使用。然后关闭tail进程,然后df会重新统计空间,结果会像du一样显示为正常大小。[root@xuexi~]#jobs[1]+Runningtail-f/my.iso&[root@xuexi~]#kill%1[root@xuexi~]#df-hT/FilesystemTypeSizeUsedAvailUse%Mountedon/dev/sda2ext418G1.7G15G11%/如果不知道文件系统中有哪些文件被删除了,但仍被进程引用,可以使用lsof获取。它还可以获取文件的大小,以查看哪个文件“占用了厕所,占用了多少个厕所”。比如在关闭tail进程之前,使用lsof进行检查。可以看到tail进程占用了/my.iso,这个文件的大小为1048576000字节。[root@xuexi~]#LSOF|GREP已删除PHP-FPM12597ROOTTXTRegs8,24058416931143/usr/sbin/php-fpm(已删除)PHP-FPM12657NOBODYTXTREG8,24058416/us931143/us/PHP-FPM(已删除)PHP-FPM12707没人TXTR8,24058416931143/USR/Sbin/PHP-FPM(已删除)PHP-FPM12708没人TXTR8,24058416931143/USR/SBIN/PHPM/PHPM/PHPM/PHPM/PHPM/PHPM/PHPM/PHPM/PHPM/PHPM/PHPM/PHPM/PHPM/PHPM/PHPM/PHP-PHP-PHP-PHP-F。(deleted)tail14437root3rREG8,210485760007171/my.iso(deleted)经过以上分析,du和df的结果肯定没有疑问了。作者:马金龙来源:https://www.cnblogs.com/f-ck-...