ZFS send/receive

A few weeks back I needed to migrate an entire ZFS pool from one machine to another. I used raw send to keep the stream compressed, and I used mbuffer to smooth out the send/receive (see the reference link at the bottom)

First, prepare the receiving end by creating the pool. If this is not a bootable pool, just create it the simple way:

poolname=rpool
disk=/dev/sda
zpool create ${poolname:?} ${disk:?}

Now start up mbuffer to receive the initial send stream ("-s" is for resumable receive in case the receive gets interrupted part way through)
I'm using a block size of 128k, a buffer size of 1G and listening on port 9090:

mbuffer -s 128k -m 1G -I 9090 | zfs receive -Fs ${poolname:?}

Now switch over to the sending machine. Here we will take a snapshot, and then send it over mbuffer to the receving machine. We'll do a raw and resumable send.

poolname=rpool
snapname=migration-snap1
receiver=receiver.example.com
zfs snapshot -r ${poolname:?}@${snapname:?}
zfs send -Rvw ${poolname:?}@${snapname:?} | mbuffer -s 128k -m 1G -O ${receiver:?}:9090

If the sending side has changed since the first snapshot completed sending, do an incremental send/receive to sync up the last changes (repeat as needed)

On receving machine, rerun the receiving command:

mbuffer -s 128k -m 1G -I 9090 | zfs receive -Fs ${poolname:?}

On the sending machine, take another snapshot and send over the incremental stream:

snap2=migration-snap2
zfs snapshot -r ${poolname:?}@${snap2:?}
zfs send -Rvw ${poolname:?}@${snapname:?} ${poolname:?}@${snap2:?} | mbuffer -s 128k -m 1G -O ${receiver:?}:9090

References: