[Feature suggestion] Able to decrease the vdev capacity (shrink vdev size / shrink pool)
System information
| Type | Version/Name |
|---|---|
| Distribution Name | - |
| Distribution Version | - |
| Linux Kernel | - |
| Architecture | - |
| ZFS Version | - |
| SPL Version | - |
Describe the problem you're observing
A vdev is configured to use all block device capacity. I need to reclaim some of the block device space to use with something else than zfs.
I don't want to destroy and recreate the pool and restore from backup.
Even if I don't have any high hopes, it would be cute if I could issue a zpool command to shrink the vdev by cutting space from either beginning or end. I'm pretty sure many other people wish for this, so I'm filing this feature request issue which should belong to openzfs upstream repo.
Wondering if work on https://github.com/openzfs/openzfs/pull/251 could be used to build this feature.
Describe how to reproduce the problem
Include any warning/errors/backtraces from the system logs
@behlendorf is it technically possible for a shrink pool tool to work offline and reduce the capacity by not moving data around but instead only giving up the right unused part of a vdev?
say you have this data usage of a vdev:
xxxx-----xx-xxx-xx--xx---x-x-x--x-x-xxx-------x----------------
where
x = data
- = unused space
is it complicated to just throw away the unused space at the right after the last used block to the end of the block device?
For the exact scenario you're describing it should be technically possible to shrink the vdev. Internally, each of vdev is subdivided in to fixed sized regions called metaslabs which are used to track the allocated space. When a vdev is expanded new metaslabs are added to the end of the device, this is easy. But to shrink a vdev those metaslabs need to be removed and in order to do this safely they need to empty. This might be the case for a very recently created pool, but this is pretty unlikely if the pool has ever seen any real use.
So practically speaking this functionality probably wouldn't be very useful without the additional ability to relocate the contents of a metaslab. That's a much thornier problem. The device removal feature you referenced does add some infrastructure for this, but it operates at the granularity of entire vdevs and not individual metaslabs. It might be possible to extend it, but it would definitely take some work.
thank you!
do you think the issue could be brought into developers talk at one of the future openzfs dev conferences?
this feature (offline shrinking) could make some users happy.
When removing a vdev with zpool remove, ZFS creates an indirect-X device that is used to track old blocks and redirect reads to some other location (as far as I understand). Is there anything stopping us from using this to shrink vdevs? Everything I've found seems to point to pool/vdev shrinking needing block pointer rewrites.
So practically speaking this functionality probably wouldn't be very useful without the additional ability to relocate the contents of a metaslab. That's a much thornier problem. The device removal feature you referenced does add some infrastructure for this, but it operates at the granularity of entire vdevs and not individual metaslabs. It might be possible to extend it, but it would definitely take some work.
Likely it won't help very many people without that additional ability, but this doesn't mean it is useless without that ability. Perhaps this simpler/trivial case could be handled as a first step towards the goal?
I could actually use the simpler feature. I created a pool on smaller storage devices, but over time upgraded them. Alas, zpool online -e tank sdc1 consumes the entire device, there is no way to only partially consume a device. Yet since the last time I ran zpool import -e tank a smaller device was still present, reclaiming that space should be rather simpler.
In fact this suggests an approach to this step of the problem. Perhaps zpool online -e tank sdc1 should handle shrinking the vdev, if the pool is using less than the full vdev?
(removing the start of the vdev will almost certainly be harder)