I recently had to migrate my data to a new ZFS pool. There was lots of great info in this serverfault post. I’m writing this to bring it all together in one place for the next time I need to remember how to do this.
First, create a snapshot on the source pool, and send it to the new pool. You can leave your source pool online while the snapshot is being sent.
sudo zfs snapshot -r sourcepool@moving1 # Maybe do this next bit a screen. It can take a while. sudo zfs send -R sourcepool@moving1 | mbuffer \ | sudo zfs receive -F destpool
Since that step probably took a while, there are probably difference between the snapshot and what’s on your new pool. Take a new snapshot and send it. You can do an incremental send which should be much faster than the first send.
sudo zfs snapshot -r sourcepool@moving2 sudo zfs send -Ri sourcepool@moving1 sourcepool@moving2 | mbuffer \ | sudo zfs receive -F destpool
Now, we’ll have some downtime. Stop everything that’s currently accessing the old pool. You can check what’s using your pool with:
sudo lsof | grep /my/mountpoint
Now that nothing is using the original pool we no longer have a moving target to copy over. Do one last snapshot and send.
sudo zfs snapshot -r sourcepool@moving3 sudo zfs send -Ri sourcepool@moving2 sourcepool@moving3 | mbuffer \ | sudo zfs receive -F destpool
At this point, both pools should have exactly the same data. All that’s left is to mount the new pool where the old one was.
Before changing how things are mounted, you can double check your current mountpoint with.
sudo zfs get mountpoint sourcepool
zfs set mountpoint=/backup/mountpoint sourcepool zfs set mountpoint=/original/mountpoint destpool
After you’re satisfied that everything worked, you can destroy the snapshots you used to migrate.
sudo zfs destroy destpool@moving1 sudo zfs destroy destpool@moving2 sudo zfs destroy destpool@moving3
Optionally, destroy the old pool.
sudo zfs destroy sourcepool