一直在研究 btrfs,考虑从 ext4 转移到那个。
然而,当想要比较读写速度时,我似乎遇到了一个(至少对我来说)btrfs 磁盘上的异常行为du
,它显然没有以与我的 ext4 上的文件相同的方式报告文件大小。
(抱歉,此处使用的是挪威语。不过大多数人可能对英语输出足够熟悉,知道发生了什么)
制作测试文件
我在
dd
挂载的文件系统磁盘 :$ sudo dd if=/dev/urandom of=5G_dd_test_file.tmp bs=1 count=0 seek=5G 0+0 oppføringer inn 0+0 oppføringer ut 0 byte kopiert, 0,00393248 s, 0,0 kB/s
以类似的方式,我在相同位置创建一个测试文件
fallocate
:$ sudo fallocate -l 5G 5G_fallocate_test_file.tmp
ls
确认他们都在那里:$ ls 5G_dd_test_file.tmp 5G_fallocate_test_file.tmp
du
行為怪异..(?)
输出的尺寸du <file>
:
$ sudo du 5G_dd_test_file.tmp
0 5G_dd_test_file.tmp
$ sudo du 5G_fallocate_test_file.tmp
5242880 5G_fallocate_test_file.tmp
注意 dd 生成的文件的大小为 0
相比之下,ls
在stat
同一个文件上:
$ ls -l *.tmp
-rw-r--r-- 1 root root 5368709120 mars 24 18:07 5G_dd_test_file.tmp
-rw-r--r-- 1 root root 5368709120 mars 24 18:12 5G_fallocate_test_file.tmp
$ stat *.tmp
Fil: 5G_dd_test_file.tmp
Størrelse: 5368709120[tab]Blokker: 0 IO Blokk: 4096 vanlig fil
Device: 0,40 Inode: 258 Links: 1
Tilgang: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Tilgang: 2022-03-24 18:07:34.646755042 +0100
Omgjøring: 2022-03-24 18:07:34.646755042 +0100
Endring: 2022-03-24 18:07:34.646755042 +0100
Fødsel: 2022-03-24 18:07:34.646755042 +0100
Fil: 5G_fallocate_test_file.tmp
Størrelse: 5368709120[tab]Blokker: 10485760 IO Blokk: 4096 vanlig fil
Device: 0,40 Inode: 259 Links: 1
Tilgang: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Tilgang: 2022-03-24 18:12:11.768422242 +0100
Omgjøring: 2022-03-24 18:12:11.768422242 +0100
Endring: 2022-03-24 18:12:11.768422242 +0100
Fødsel: 2022-03-24 18:12:11.768422242 +0100
但是如果我将-b
参数添加到du
(通常不需要)当执行相同的操作时,dd
生成的文件显示0尺寸。然后du
看起来一切如常。
$ sudo du -b 5G_dd_test_file.tmp
5368709120 5G_dd_test_file.tmp
另一件奇怪的事情来自du
(?)
因此,出于好奇,我决定简单地gzip
从以下位置获取文件dd
:
$ sudo gzip 5G_dd_test_file.tmp
$ sudo du 5G_dd_test_file.tmp.gz
5092 5G_dd_test_file.tmp.gz
现在它显示的尺寸非零。
$ sudo ls -l 5G_dd_test_file.tmp.gz
-rw-r--r-- 1 root root 5210230 mars 24 18:07 5G_dd_test_file.tmp.gz
sudo stat 5G_dd_test_file.tmp.gz
Fil: 5G_dd_test_file.tmp.gz
Størrelse: 5210230 [tab]Blokker: 10184 IO Blokk: 4096 vanlig fil
Device: 0,40 Inode: 260 Links: 1
Tilgang: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Tilgang: 2022-03-24 18:07:34.646755042 +0100
Omgjøring: 2022-03-24 18:07:34.646755042 +0100
Endring: 2022-03-24 18:43:41.061926016 +0100
Fødsel: 2022-03-24 18:42:27.554141544 +0100
问题是
- 这是正常行为吗?而且确实是可以预料到的吗?
- 如果不是,这是否可能破坏依赖于
du
回报的脚本或程序?
答案1
这是正常行为吗?而且确实是可以预料到的吗?
基本上是的。
创建文件时使用dd seek=…
是一种创建疏文件. 使用dd seek=…
和写入任何内容(count=0
)是创建完全稀疏文件的一种方法。
[…] 稀疏文件是一种计算机文件,当文件本身部分为空时,它会尝试更有效地利用文件系统空间。这是通过将代表空块的简要信息(元数据)写入数据存储介质而不是构成块的实际“空”空间来实现的,从而消耗更少的存储空间。仅当块包含“真实”(非空)数据时,才会将完整块大小作为实际大小写入介质。
我更喜欢的方式是truncate
。另一方面, 的主要目的fallocate
是实际上分配块。fallocate
为您创建了一个非稀疏文件。
du
报告磁盘使用情况。完全稀疏文件使用零块来存储数据。它只是一个分配了零块的目录条目。
您gzip
创建了一个非稀疏文件。没有完全稀疏的文件可以成为有效的 gzip 存档,因为完全稀疏的文件在读取时会返回空字节,但 gzip 标头本身包含非空字节。此外,我不希望任何 gzip 存档是(能够)部分稀疏的,因为零块(即假设的稀疏部分)几乎不费吹灰之力就可以高度压缩,而它们的存在意味着gzip
它的工作失败了。
这是否可能会破坏依赖于
du
回报的脚本或程序?
不,除非脚本du
在应该使用du -b
或时使用了wc -c
;但那是一个错误在脚本中。
du
按照设计用途使用。以下是一些见解:为什么有这么多不同的方法来测量磁盘使用情况?
Ext4 也支持稀疏文件。使用你的dd
命令,我在 ext4 文件系统和 btrfs 文件系统中分别创建了一个完全稀疏的文件。整个“问题”绝对是不是关于 ext4 与 btrfs。