環境
- 紅帽企業版Linux 5、6和7
問題
- 文件的ls和df之間的文件大小不一致。
-
該文件報告較大(128Gb),但文件系統甚至沒有那么大。這怎么可能?
決議
- 有問題的文件可能是稀疏文件。
- 稀疏文件是指其元數據報告一個大小的文件,但是文件的實際數據消耗的大小不同。
- 稀疏文件是有效使用磁盤空間的常用方法。
-
您可以使用
ls -lsh
命令查看稀疏文件。這提供了兩個大小列: -
第一列是實際使用的磁盤空間。該文件實際上消耗了12Gb的空間。
- 第二個大小列提供文件元數據的大小。該文件的元數據報告它是24Gb文件。
稀疏文件的使用
-
要復制稀疏文件,必須使用能夠識別稀疏文件的命令。
-
cp --sparse=always /source/filename /destination/filename dd if=/source/filename of=/destination/filename conv=sparse rsync -S /source/filename root@hostname:/destination/filename
-
使用
scp
實用程序復制文件將導致“非稀疏”文件擴展為完整大小。
根本原因
- 在稀疏文件中,與那些區域保存非零數據時相比,文件全為0x00的部分被壓縮以占用更少的空間。
診斷步驟
可以使用truncate
命令輕松創建稀疏文件:
# truncate --size=1G sparsefile.bin
我們可以使用ls -lsh
查看稀疏文件的大小:
# ls -lsh sparsefile.bin 0 -rw-r--r-- 1 root root 1.0G Nov 6 09:00 sparsefile.bin
該文件占用0字節的空間,但是其元數據報告文件大小為1Gb。
我們可以將1Mb寫入該文件:
# for i in {1..1048576}; do echo -n "a" >> sparsefile.bin; done
然后再次檢查其大小:
# ls -lsh sparsefile.bin
1.0M -rw-r--r-- 1 root root 1.1G Nov 6 09:01 sparsefile.bin
該文件現在消耗了1Mb的實際空間,但是元數據報告的使用量為1.1Gb。元數據的輕微增長是由於分配了文件系統塊來存儲文件的數據。
將此文件與相同大小的完全分配的文件進行比較:
# dd if=/dev/zero of=fullfile.bin bs=1M count=1024 conv=fsync # ls -lsh fullfile.bin 1.1G -rw-r--r-- 1 root root 1.0G Nov 6 09:05 fullfile.bin
該文件實際消耗了1Gb以上的空間,其元數據報告的文件大小也為1Gb。
我們可以使用stat
命令從這兩個文件中獲取更多信息:
在上方,我們看到稀疏文件比完整文件消耗更少的文件系統塊。
我們可以使用filefrag
命令收集文件系統分配信息:
# filefrag sparsefile.bin
sparsefile.bin: 1 extent found
# filefrag fullfile.bin
fullfile.bin: 29 extents found
上面我們可以看到,稀疏文件已在一個較小的范圍內分配,而完整文件已在多個范圍內分配。
可以使用以下基本示例在C中創造稀疏文件:
#include <stdio.h> int main() { FILE *fp; fp = fopen("hello.txt", "w+"); fseek(fp, 1048576, SEEK_CUR); fputs("Hello\n", fp); fclose(fp); return 0; }
這將創建一個1 MB的文件,放入“ Hello”寫入其中。在strace
系統調用跟蹤器下運行以上命令顯示:
我們可以看到我們的文件是稀疏創建的,它報告的大小為1Mb,但僅消耗一個4kb的文件系統塊: