简短的摘要:
在创建仅包含一个容量为 1TB (= 931GiB) 的磁盘的单个 zfs 磁盘池时,文件系统仅显示 899 GiB 可用空间(df -h
或zfs list
;zpool list
实际上显示分区大小 (931 GiB) 减去一些开销(导致 928 GiB空间)。
更长的版本:
我试图设置一个 zfs 磁盘池,其中仅包含一个容量为 1TB(= 931,53 GiB)的磁盘:
# fdisk -l /dev/sdb
Disk /dev/sdb: 931.53 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: xxxx
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: xxx
Device Start End Sectors Size Type
/dev/sdb1 2048 1953516976 1953514929 931.5G Linux filesystem
设置 zfs 池时
# zpool create -f -o ashift=12 tank /dev/sdb1;
缺少 32,5 GiB:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
tank 360K 899G 96K /tank
是什么导致单个磁盘设置的 32.5 GiB 开销?
zpool list
正在报告:
# zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 928G 444K 928G - - 0% 0% 1.00x ONLINE -
但这不是实际可用的空间,因为也在df -h
报告:
# df -h
Filesystem Size Used Avail Use% Mounted on
tank 899G 128K 899G 1% /tank
没有配额或预留集:
# zfs get quota
NAME PROPERTY VALUE SOURCE
tank quota none default
# zfs get reservation
NAME PROPERTY VALUE SOURCE
tank reservation none default
# zfs get refquota
NAME PROPERTY VALUE SOURCE
tank refquota none default
# zfs get refreservation
NAME PROPERTY VALUE SOURCE
tank refreservation none default
# zfs get usedbyrefreservation
NAME PROPERTY VALUE SOURCE
tank usedbyrefreservation 0B -
创建 zpoolashift=9
没有任何区别。
我可以忍受 3,5 GiB 的实际开销(= 分区大小与 zpool 报告的大小),但不能承受 32,5 GiB 或 29 GiB 的开销(= zfs 报告的大小 - zpool 报告的大小)磁盘。
尝试使用 btrfs 进行相同操作时,我获得了更多可用空间:
# btrfs filesystem show
Label: 'tank' uuid: xxx
Total devices 1 FS bytes used 128.00KiB
devid 1 size 931.51GiB used 2.02GiB path /dev/sdb1
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 932G 3.8M 930G 1% /mnt
更多细节
# zfs --version
zfs-0.8.3-1ubuntu12.5
zfs-kmod-0.8.3-1ubuntu12.5
# uname -a
Linux xxx 5.4.0-58-generic #64-Ubuntu SMP Wed Dec 9 08:16:25 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/os-release | grep VERSION
VERSION="20.04.1 LTS (Focal Fossa)"
VERSION_ID="20.04"
VERSION_CODENAME=focal
# zfs list -o space
NAME AVAIL USED USEDSNAP USEDDS USEDREFRESERV USEDCHILD
tank 899G 88.5K 0B 24K 0B 64.5K
更新:使用命令重新创建zpool create -oashift=12 tank /dev/sdb1
。
没有不同:
# zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 928G 432K 928G - - 0% 0% 1.00x ONLINE -
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
tank 336K 899G 96K /tank
输出zdb tank | grep metaslab | tail -n 3
:
# zdb tank | grep metaslab | tail -n 3
loading concrete vdev 0, metaslab 115 of 116 ...
metaslab 114 offset e400000000 spacemap 0 free 8G
metaslab 115 offset e600000000 spacemap 0 free 8G
vdev 0 metaslabs 116 fragmentation 0%
输出zdb | grep metaslab_shift
:
# zdb | grep metaslab_shift
metaslab_shift: 33
我无法重现您的问题。
在上面的示例中,我从一个 931GiB(大致为 1TB)块设备开始,并使用 4KiB 扇区在其上创建一个池。可用容量为 928GiB,正如您考虑 metaslab 剩余部分时所预期的那样。
我的 931GiB “磁盘”被分成 116 个 8GiB 元数据块;这留下了 0.44125 的 metaslab 剩余物。
...鲍勃是你的叔叔。为什么你会看到大约十倍的开销,我不知道;我也在 Focal 上,与您报告的 ZFS 版本相同。
从头开始通过命令查看池本身的实际创建和/或该
zdb | grep metaslab_shift
池的输出可能会有所帮助。正如用户 grenkins 在 subreddit /r/zfs 中指出的那样(https://www.reddit.com/r/zfs/comments/kp2nnk/zfs_single_disk_setup_1tb_9315_gib_325_gib/ - 所有功劳归他所有)zfs 保留 3.2% 的空间默认。此预留由系统上的内核模块完成,与 quota/reservation/refquota/refreservation/usedbyrefreservation zpool 设置无关。见https://openzfs.github.io/openzfs-docs/Performance%20and%20Tuning/Module%20Parameters.html#spa-slop-shift
保留由 zfs 内核模块的 spa_slop_shift 设置完成。
概括:
我通过创建以下文件将 spa_slop_shift 设置增加到 15:
重启后有 928 GiB 可用:
这实际上
zpool list
是报告的可用空间(931,5 分区大小 - 一些小的开销)。所以这对我来说是固定的。