实际上,这是可以做到的。因为如果空间允许,可以从池中移除顶级vdev。所以关键在于:
1. add a temp disk/file vdev to the pool with smaller size, but is enough to hold all existing data (including snapshots etc)
2. remove the old vdev
3. possibly re-partition old vdev to smaller size, or replace with a smaller disk
4. add it back
5. remove the temp disk.
所有文件应保持完整。
为了说明步骤:
1. 分配文件。
# fallocate -l 3G 3G_1.img
# fallocate -l 3G 3G_2.img
# fallocate -l 2G 2G_1.img
# fallocate -l 2G 2G_2.img
使用镜像创建具有两个3G文件的ZFS(我的目录是/var/snap/lxd/common/lxd/disks)。
# zpool create test3g mirror /var/snap/lxd/common/lxd/disks/3G_1.img /var/snap/lxd/common/lxd/disks/3G_2.img
# zpool status test3g
pool: test3g
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
test3g ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/var/snap/lxd/common/lxd/disks/3G_1.img ONLINE 0 0 0
/var/snap/lxd/common/lxd/disks/3G_2.img ONLINE 0 0 0
errors: No known data errors
# zpool list test3g
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
test3g 2.75G 111K 2.75G - - 0% 0% 1.00x ONLINE -
你可以清楚地看到test3g池可用空间为2.75G,它是镜像的。
2. 让我们尝试在里面创建虚拟文件,以模拟您现有的数据。
这样您就可以在练习后验证您的数据是否完好无损。
# echo test > /test3g/test.txt
# cat /test3g/test.txt
test
#
现在附上另一面尺寸较小的镜子(例如2G)。
# zpool add test3g mirror /var/snap/lxd/common/lxd/disks/2G_1.img /var/snap/lxd/common/lxd/disks/2G_2.img
# zpool status test3g
pool: test3g
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
test3g ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/var/snap/lxd/common/lxd/disks/3G_1.img ONLINE 0 0 0
/var/snap/lxd/common/lxd/disks/3G_2.img ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
/var/snap/lxd/common/lxd/disks/2G_1.img ONLINE 0 0 0
/var/snap/lxd/common/lxd/disks/2G_2.img ONLINE 0 0 0
errors: No known data errors
# zpool list test3g
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
test3g 4.62G 156K 4.62G - - 0% 0% 1.00x ONLINE -
现在我们有一个可用容量为4.62GB的条纹镜像。
4. 让我们移除之前的3G部分。
# zpool remove test3g mirror-0
# zpool status
pool: default
state: ONLINE
scan: scrub repaired 0B in 0 days 00:06:45 with 0 errors on Fri May 21 15:20:30 2021
config:
NAME STATE READ WRITE CKSUM
default ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/opt/lxc_image/default.img ONLINE 0 0 0
/var/snap/lxd/common/lxd/disks/default.img ONLINE 0 0 0
errors: No known data errors
pool: tank
state: ONLINE
scan: scrub repaired 0B in 0 days 00:00:10 with 0 errors on Tue May 18 19:42:56 2021
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/var/snap/lxd/common/lxd/disks/tank.img ONLINE 0 0 0
/nfs-dual/zfs-images/tank.img ONLINE 0 0 0
errors: No known data errors
pool: test3g
state: ONLINE
scan: none requested
remove: Removal of vdev 0 copied 102K in 0h0m, completed on Fri May 21 15:33:19 2021
72 memory used for removed device mappings
config:
NAME STATE READ WRITE CKSUM
test3g ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
/var/snap/lxd/common/lxd/disks/2G_1.img ONLINE 0 0 0
/var/snap/lxd/common/lxd/disks/2G_2.img ONLINE 0 0 0
errors: No known data errors
# zpool list test3g
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
test3g 1.88G 142K 1.87G - - 0% 0% 1.00x ONLINE -
空间剩余1.87G。
注意,根据您的数据大小,可能需要很长时间,但会成功完成。
请查看上方的消息。
Removal of vdev 0 copied 102K in 0h0m, completed on Fri May 21 15:33:19 2021
你在技术上将zpool的大小从3G减小到2G,没有停机时间,也没有丢失数据。
5. 让我们验证数据是否仍然存在。
# cat /test3g/test.txt
test
#
当然可以。
请注意,只有最新版本的zfs支持此功能。具体效果可能因人而异。
谢谢
最好的祝福
Shilin
zpool add
而不是zpool attach
。据我所知,zpool add
将新的磁盘添加为RAID-0(或者说是一堆磁盘,总容量相加),而zpool attach
将新的磁盘作为RAID-1(镜像,总容量不变)进行连接。然后,通过zpool remove
删除RAID-0的一部分,强制数据流向剩余部分。因此,实现了调整大小的目的。值得一提的是,如果数据大小大于zpool中剩余磁盘的容量,会提示“无法删除...:空间不足”错误。你根本无法使用zpool remove
来删除它。感谢ZFS的设计,它非常安全可靠。 - midnitezpool remove
之后,如何摆脱indirect-0?https://serverfault.com/q/1102923/237756 - midnite#zfs
IRC频道上听到的,一旦你在周围“添加”或“删除”vdevs,ZFS会向池中添加一个功能标志,使其与“grub”不兼容。这个问题可能已经在后来的grub版本中修复了,但在进行移动之前,至少要先检查一下,或者在开发阶段进行测试。 - anarcatzfs-2.1.5-1ubuntu6~22.04.1
上遇到了unrecognized command 'status'
和unrecognized command 'add'
的问题,我原以为这是比较新的版本。这是否意味着我需要更新?@Wu-Shilin,你使用的是哪个版本? - Cadoiz