The problem
ZFS datasets are a powerful way to organize your filesystems.
At first glance, datasets look a lot like filesystems,
so you may default to just one or at most a handful per pool. But
unlike with traditional filesystems where you have to decide how much
of your disk space each one gets when it's created, ZFS datasets
share the space available to the entire pool. Since datasets are the
granularity at which ZFS operations like snapshots and
zfs send
/recv
work, having more
datasets can give you better control over having different backup
policies for different subsets of your data, and ZFS
scales just fine to hundreds or thousands of
datasets, so you don't have to really worry about creating too many.
But if you're me (well, not just me) and you realize
this after you already have months of snapshots of a few terabytes of
data, how do you reorganize your ZFS pool into more datasets without
either losing the snapshot history or ending up wasting a lot of disk
space on redundant copies of data?
The solution
Before doing anything with real data, make backups and confirm you can
restore from them.
I do not have a one-size-fits-all solution here; instead I'll outline
the general process and recommend you continually review at each step to
make sure things look correct and be ready to
zfs rollback
and retry if you make a mistake
or notice a way you could have done something in a more space-efficient
manner.
- Create the new dataset hierarchy. I'll refer to the old dataset as
tank/old
and the new dataset root as tank/new
.
- Do an initial copy of the earliest snapshot you want to keep
from the
.zfs
directory.
If it's @first
, then the copy command will be
rsync -avhxPHS /tank/old/.zfs/snapshot/first/ /tank/new/
.
- Check your work and possibly delete or dedup files.
zfs snapshot -r tank/new@first
- Do an incremental copy of the next snapshot. If it's
@second
,
this may be as simple as
rsync -avhxPHS@-1 --delete /tank/old/.zfs/snapshot/second/ /tank/new/
,
but that will waste space if you have moved files or modified small
sections of large files.
- Check your work, and make any necessary changes.
zfs snapshot -r tank/new@second
- Repeat steps 5-7 for each snapshot you want to keep.
zfs rename tank/old tank/legacy && zfs rename tank/new tank/old
The details