我有一个非常高密度的容器虚拟化环境,所以我试图让每个容器变得非常小。 “非常小”意味着 87 MB乌班图14.04(Trusty Tahr)不会破坏包管理器的兼容性。
所以我用左心室容量作为我的容器的后备存储,最近我发现了非常奇怪的数字。他们来了。
让我们创建一个 100 MiB(是的,2 的幂)逻辑卷。
sudo lvcreate -L100M -n test1 /dev/purgatory
我想检查尺寸,所以我发出sudo lvs --units k
test1 purgatory -wi-a---- 102400.00k
天啊,这真的是 100 MiB。
现在让我们做一个外部4文件系统。当然,我们记住-m 0
参数,这可以防止空间浪费。
sudo mkfs.ext4 -m 0 /dev/purgatory/test1
mke2fs 1.42.9 (4-Feb-2014)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
25688 inodes, 102400 blocks
0 blocks (0.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67371008
13 block groups
8192 blocks per group, 8192 fragments per group
1976 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729
Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
甜美又干净。注意块大小 - 我们的逻辑卷很小,因此 mkfs.ext4 决定制作 1 KiB 大小的块,而不是通常的 4 KiB。
现在我们将安装它。
sudo mount /dev/purgatory/test1 /mnt/test1
让我们df
不带参数调用(我们希望看到 1 KiB 块)
/dev/mapper/purgatory-test1 95054 1550 91456 2% /mnt/test1
等等哦希~
我们总共有 95054 个区块。但设备本身有 102400 个 1 KiB 的块。我们只有 92.8% 的存储空间。我的街区在哪里,伙计?
让我们在真实的块设备上看一下。 A 有一个 16 GiB 的虚拟磁盘,16777216 个 1K 块,但 df 输出中只有 15396784 个块。 91.7%,这是什么?
现将调查情况通报如下(剧透:没有结果)
文件系统不能从设备的开头开始。这很奇怪,但却是可能的。幸运的是,ext4 有魔法字节,让我们检查一下它们的存在。
sudo hexdump -C /dev/purgatory/test1 | sudo hexdump -C /dev/purgatory/test1 | grep "53 ef"
这显示了超级块:
00000430 a9 10 e7 54 01 00 ff ff 53 ef 01 00 01 00 00 00 |...T....S.......|
十六进制 430 = 十二月 1072,所以在第一个千字节之后的某个地方。看起来很合理,ext4 会跳过前 1024 个字节来处理 VBR 等奇怪现象。
- 这是日记!
不它不是。日志占用可用 if df 输出的空间。
- 哦,我们有 dump2fs,可以检查那里的大小!
...很多 grep ...
sudo dumpe2fs /dev/purgatory/test1 | grep "Free blocks"
哎哟。
Free blocks: 93504
Free blocks: 3510-8192
Free blocks: 8451-16384
Free blocks: 16385-24576
Free blocks: 24835-32768
Free blocks: 32769-40960
Free blocks: 41219-49152
Free blocks: 53249-57344
Free blocks: 57603-65536
Free blocks: 65537-73728
Free blocks: 73987-81920
Free blocks: 81921-90112
Free blocks: 90113-98304
Free blocks: 98305-102399
我们还有另一个号码。 93504 个空闲块。
问题是:这是怎么回事?
- 块设备:102400k(lvs说)
- 文件系统大小:95054k(df 说)
- 空闲块:93504k(dumpe2fs 说)
- 可用大小:91456k(df说)
答案1
尝试这个:mkfs.ext4 -N 104 -m0 -O ^has_journal,^resize_inode /dev/purgatory/test1
我认为这确实让你明白“发生了什么事”。
-N 104
(设置文件系统应具有的 iNode 数量)
- 每个 iNode “成本”可用的空间(128字节)
-m 0
(无保留块)
-O ^has_journal,^resize_inode
(停用功能has_journal
并resize_inode
resize_inode
“成本”自由的空间(您在df
- 12K 中看到的 1550 个 1K-Blocks/2% 中的大部分用于“lost+found”文件夹)has_journal
“成本”可用的空间(在您的情况下为 4096 1K 块)
我们102348
离开了102400
,另外 52 个块不可用(如果我们删除了“lost+found”文件夹)。因此我们深入研究dumpe2fs
:
Group 0: (Blocks 1-8192) [ITABLE_ZEROED]
Checksum 0x5ee2, unused inodes 65533
Primary superblock at 1, Group descriptors at 2-2
Block bitmap at 3 (+2), Inode bitmap at 19 (+18)
Inode table at 35-35 (+34)
8150 free blocks, 0 free inodes, 1 directories, 65533 unused inodes
Free blocks: 17-18, 32-34, 48-8192
Free inodes:
Group 1: (Blocks 8193-16384) [BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0x56cf, unused inodes 5
Backup superblock at 8193, Group descriptors at 8194-8194
Block bitmap at 4 (+4294959107), Inode bitmap at 20 (+4294959123)
Inode table at 36-36 (+4294959139)
8190 free blocks, 6 free inodes, 0 directories, 5 unused inodes
Free blocks: 8193-16384
Free inodes: 11-16
Group 2: (Blocks 16385-24576) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0x51eb, unused inodes 8
Block bitmap at 5 (+4294950916), Inode bitmap at 21 (+4294950932)
Inode table at 37-37 (+4294950948)
8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
Free blocks: 16385-24576
Free inodes: 17-24
Group 3: (Blocks 24577-32768) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0x3de1, unused inodes 8
Backup superblock at 24577, Group descriptors at 24578-24578
Block bitmap at 6 (+4294942725), Inode bitmap at 22 (+4294942741)
Inode table at 38-38 (+4294942757)
8190 free blocks, 8 free inodes, 0 directories, 8 unused inodes
Free blocks: 24577-32768
Free inodes: 25-32
Group 4: (Blocks 32769-40960) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0x79b9, unused inodes 8
Block bitmap at 7 (+4294934534), Inode bitmap at 23 (+4294934550)
Inode table at 39-39 (+4294934566)
8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
Free blocks: 32769-40960
Free inodes: 33-40
Group 5: (Blocks 40961-49152) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0x0059, unused inodes 8
Backup superblock at 40961, Group descriptors at 40962-40962
Block bitmap at 8 (+4294926343), Inode bitmap at 24 (+4294926359)
Inode table at 40-40 (+4294926375)
8190 free blocks, 8 free inodes, 0 directories, 8 unused inodes
Free blocks: 40961-49152
Free inodes: 41-48
Group 6: (Blocks 49153-57344) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0x3000, unused inodes 8
Block bitmap at 9 (+4294918152), Inode bitmap at 25 (+4294918168)
Inode table at 41-41 (+4294918184)
8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
Free blocks: 49153-57344
Free inodes: 49-56
Group 7: (Blocks 57345-65536) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0x5c0a, unused inodes 8
Backup superblock at 57345, Group descriptors at 57346-57346
Block bitmap at 10 (+4294909961), Inode bitmap at 26 (+4294909977)
Inode table at 42-42 (+4294909993)
8190 free blocks, 8 free inodes, 0 directories, 8 unused inodes
Free blocks: 57345-65536
Free inodes: 57-64
Group 8: (Blocks 65537-73728) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0xf050, unused inodes 8
Block bitmap at 11 (+4294901770), Inode bitmap at 27 (+4294901786)
Inode table at 43-43 (+4294901802)
8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
Free blocks: 65537-73728
Free inodes: 65-72
Group 9: (Blocks 73729-81920) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0x50fd, unused inodes 8
Backup superblock at 73729, Group descriptors at 73730-73730
Block bitmap at 12 (+4294893579), Inode bitmap at 28 (+4294893595)
Inode table at 44-44 (+4294893611)
8190 free blocks, 8 free inodes, 0 directories, 8 unused inodes
Free blocks: 73729-81920
Free inodes: 73-80
Group 10: (Blocks 81921-90112) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0x60a4, unused inodes 8
Block bitmap at 13 (+4294885388), Inode bitmap at 29 (+4294885404)
Inode table at 45-45 (+4294885420)
8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
Free blocks: 81921-90112
Free inodes: 81-88
Group 11: (Blocks 90113-98304) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0x28de, unused inodes 8
Block bitmap at 14 (+4294877197), Inode bitmap at 30 (+4294877213)
Inode table at 46-46 (+4294877229)
8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
Free blocks: 90113-98304
Free inodes: 89-96
Group 12: (Blocks 98305-102399) [INODE_UNINIT, ITABLE_ZEROED]
Checksum 0x9223, unused inodes 8
Block bitmap at 15 (+4294869006), Inode bitmap at 31 (+4294869022)
Inode table at 47-47 (+4294869038)
4095 free blocks, 8 free inodes, 0 directories, 8 unused inodes
Free blocks: 98305-102399
Free inodes: 97-104
并计算已使用的块(对于备份超级块、组描述符、块位图、索引节点位图和索引节点表)或者我们grep
并计数:
LANG=C dumpe2fs /dev/mapper/vg_vms-test1 | grep ' at ' | grep -v ',' | wc -l
这给了我们有一个块的行数(在我们的例子中)和
LANG=C dumpe2fs /dev/mapper/vg_vms-test1 | grep ' at ' | grep ',' | wc -l
这给了我们有两个块的行数(在我们的例子中)。
因此,(在我们的示例中)我们有13
每行包含一个块的行和19
每行包含两个块的行。
13+19*2
它为我们提供了51
ext4 本身正在使用的块。最后只剩下一块了。块 0,是1024
引导扇区等开头跳过的字节。
答案2
简短的回答:
并非块设备上的所有空间都会成为数据的可用空间:文件系统内部和幕后簿记需要一些原始空间。
该簿记包括超级块、块组描述符、块和索引节点位图以及索引节点表。此外,在多个位置创建用于备份/恢复目的的超级块的副本。有关 EXT4 文件系统内部结构的长篇文章可以在ext4.wiki.kernel.org。
由于 EXT4 是一个日志文件系统,也会占用一些空间。
此外,还保留了一些空间用于文件系统未来的扩展。
长答案:
我在我的一个测试系统上重新创建了您的场景:
lvcreate -L 100M -n test MyVG
mkfs.ext4 -b 1024 /dev/MyVG/test
然后在挂载文件系统之前dumpe2fs
显示:
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 25688
Block count: 102400
Reserved block count: 5120
Free blocks: 93504
Free inodes: 25677
First block: 1
Block size: 1024
Fragment size: 1024
Reserved GDT blocks: 256
Blocks per group: 8192
Fragments per group: 8192
Inodes per group: 1976
Inode blocks per group: 247
Flex block group size: 16
Filesystem created: Fri Feb 20 13:20:54 2015
Last mount time: n/a
Last write time: Fri Feb 20 13:20:55 2015
...
Journal size: 4096k
...
安装后:
df /tmp/test/
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/MyVG-test 99150 5646 88384 7% /tmp/test
那么df
向我们展示了什么?在原始存储设备容量的 102400 个块中,有 99150 个 1K 块对文件系统可见,这意味着 3250 个 1K 字节的原始存储空间块已无法用于实际数据存储。
那些块去哪儿了?在输出中向下滚动dumpe2fs
可准确显示位置:
Group 0: (Blocks 1-8192) [ITABLE_ZEROED]
Checksum 0x0d67, unused inodes 1965
Primary superblock at 1, Group descriptors at 2-2
Reserved GDT blocks at 3-258
Block bitmap at 259 (+258), Inode bitmap at 275 (+274)
Inode table at 291-537 (+290)
4683 free blocks, 1965 free inodes, 2 directories, 1965 unused inodes
Free blocks: 3510-8192
Free inodes: 12-1976
1 block
(块 #0)前 1024 个字节被跳过,以允许安装 x86 引导扇区和其他奇怪的东西。
1 block
被Primary超级块占用。
1 block
包含组描述符。
256 blocks
是为组描述符表保留以允许将来调整文件系统的大小。
16 blocks
被分配给块位图。
16 blocks
被分配给 inode 位图。
246 blocks
被分配给 inode 表。
这已经占了 3250 个缺失区块中的 537 个。 ext4 文件系统被分为一系列块组,向下滚动进一步显示原始存储容量到其他块组中文件系统内部的类似分配:
Group 1: (Blocks 8193-16384) [INODE_UNINIT, ITABLE_ZEROED]
Checksum 0x0618, unused inodes 1976
Backup superblock at 8193, Group descriptors at 8194-8194
Reserved GDT blocks at 8195-8450
Block bitmap at 260 (+4294959363), Inode bitmap at 276 (+4294959379)
Inode table at 538-784 (+4294959641)
7934 free blocks, 1976 free inodes, 0 directories, 1976 unused inodes
Free blocks: 8451-16384
Free inodes: 1977-3952
Group 2: (Blocks 16385-24576) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Checksum 0xcfd3, unused inodes 1976
Block bitmap at 261 (+4294951172), Inode bitmap at 277 (+4294951188)
Inode table at 785-1031 (+4294951696)
8192 free blocks, 1976 free inodes, 0 directories, 1976 unused inodes
Free blocks: 16385-24576
Free inodes: 3953-5928
Group ....
现在回到输出df
:
df /tmp/test/
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/MyVG-test 99150 5646 88384 7% /tmp/test
在该新文件系统上,已有 7% 的容量被标记为正在使用的原因是:
99150(文件系统的大小)减 5120(保留块计数)减 5646(已使用的块,其中 4096 个来自日志(也是 dumpe2fs` 输出的一部分))
= 88384
dumpe2fs 中的空闲块计数是文件系统的可用大小减去实际使用量(并且不考虑保留块),因此 99150 - 5646 = 93504。
答案3
这不是问题的答案,但我很好奇,所以我想其他人也会这么做。因为我已经启动了 liveCD,并且有一个可以随意使用的硬盘,而不必担心打字错误会损坏任何东西,所以我继续进行测试。
我使用 Ubuntu 14.10 为其提供 mkfs 的所有 FS 在 100MiB 分区上创建了分区。 (除了 minix,它只支持 64MiB,还有 bfs,这是我从未听说过的 SCO 东西。)
首先,我查看了df -k
可用空间(使用默认的 mkfs 设置),然后我dd
编辑了/dev/zero
每个 FS 上的一个文件,以确保它们可以一直填满。 (即检查所声明的内容available space
是否确实可用。)
for i in /media/ubuntu/small-*;do sudo dd if=/dev/zero of="$i/fill" bs=16k;done
* FS: empty `df -k` : non-zero `df -k` when full (false bottom)
* jfs: 101020k
* fat32:100808k : 4
* ntfs: 99896k
* btrfs: 98276k : 4428
* ext2: 92480k
* xfs: 90652k : 20
* ext4: 86336k
* ext3: 88367k
* reiserfs(v3): 69552k
为什么btrfs有这么多未使用的空间?也许是为了元数据?好吧,不:
$ for i in /media/ubuntu/small-*;do sudo touch "$i/touched";done
touch: cannot touch ‘/media/ubuntu/small-btrfs/touched’: No space left on device
touch: cannot touch ‘/media/ubuntu/small-reiser/touched’: No space left on device
两种基于树的文件系统都无法将空文件打包到任何位置,但其他所有系统都可以。
或者看看您可以创建多大的文件:
$ ls -SdlG --block-size=1k /media/ubuntu/small-*/*
-rw-r--r-- 1 root 101020 Feb 21 11:55 /media/ubuntu/small-jfs/fill
-rw-r--r-- 1 ubuntu 100804 Feb 21 11:55 /media/ubuntu/small-fat/fill
-rw------- 1 ubuntu 99848 Feb 21 11:55 /media/ubuntu/small-ntfs/fill
-rw-r--r-- 1 root 97216 Feb 21 11:55 /media/ubuntu/small-ext2/fill
-rw-r--r-- 1 root 93705 Feb 21 11:27 /media/ubuntu/small-btrfs/foo
-rw-r--r-- 1 root 93120 Feb 21 11:55 /media/ubuntu/small-ext3/fill
-rw-r--r-- 1 root 91440 Feb 21 11:55 /media/ubuntu/small-ext/fill
-rw-r--r-- 1 root 90632 Feb 21 11:55 /media/ubuntu/small-xfs/fill
-rw-r--r-- 1 root 69480 Feb 21 11:55 /media/ubuntu/small-reiser/fill
drwx------ 2 root 12 Feb 21 11:33 /media/ubuntu/small-ext2/lost+found
drwx------ 2 root 12 Feb 21 11:43 /media/ubuntu/small-ext3/lost+found
drwx------ 2 root 12 Feb 21 11:29 /media/ubuntu/small-ext/lost+found
(我将我的 ext4 分区称为“small-ext”,因为我不打算疯狂地创建每个文件系统。所以这里 ext=ext4。不是原来的 pre-ext2 ext。)
df -k
再次删除后输出:
/dev/sdd6 95980 5328 90652 6% /media/ubuntu/small-xfs
/dev/sdd7 95054 1550 86336 2% /media/ubuntu/small-ext
/dev/sdd5 102400 93880 101020 96% /media/ubuntu/small-btrfs
/dev/sdd8 101168 101168 0 100% /media/ubuntu/small-jfs
/dev/sdd9 99150 1550 92480 2% /media/ubuntu/small-ext2
/dev/sdd10 102392 32840 69552 33% /media/ubuntu/small-reiser
/dev/sdd11 100808 1 100808 1% /media/ubuntu/small-fat
/dev/sdd12 102396 2548 99848 3% /media/ubuntu/small-ntfs
/dev/sdd13 95054 1567 88367 2% /media/ubuntu/small-ext3
(在我删除“touched”之后,jfs 的使用率也回到了 1%。要么存在时间延迟,要么需要另一次写入才能获取可用大小来更新。)
无论如何,我认为这就是出于我的好奇心。