ZFS snapshotting and mirroring
Although ZFS seamlessly will support synchronous mirrors over multiple backend storage arrays, there are some advantages in keeping the mirror process asynchronous.
This is a pretty trivial process to script up. Here are the basics:
To set up the initial mirror of the source/root ZFS to the dest/root ZFS:
# zfs snapshot -r source/root@0001
# zfs send source/root@0001 |
zfs receive -d dest
This’ll create a dest/root and a dest/root@0001 snapshot.
To update the mirror:
# zfs snapshot -r source/root@0002
# zfs send -i 0001 source/root@0002 |
zfs receive -Fd dest
This sends an incremental set of changes and applies them to the dest/root snapshot. The -F first rolls back dest/root to the latest snapshot - resetting any local changes (including atimes). The result of this is dest/root with two snapshots - the latest, 0002, and the first, 0001.
We can remove the earlier snapshots once the mirror is complete:
# zfs destroy -r dest/root@0001
# zfs destroy -r source/root@0001
This leaves just the latest mirror snapshot available at both ends, permitting the next incremental to run using the same pattern.
Note: there is no recursive option for zfs send; where there are multiple dependent filesystems under source/root, we need to send them one after the other. Assuming the initial filesystem transfer has been done, that looks like this:
# zfs snapshot -r source/root@0003
# zfs send -i 0002 source/root@0003 |
zfs receive -Fd dest
# zfs send -i 0002 source/root/x@0003 |
zfs receive -Fd dest
# zfs send -i 0002 source/root/y@0003 |
zfs receive -Fd dest
The recursive flag on zfs destroy takes care of all the dependent snapshots in one go.