ZFS send single snapshot including descendent file systems

1.9k Views Asked by At

Is there a way to send a single snapshot including descendant file systems? 'zfs send' only sends the the top level file system even if the snapshot was created using '-r'. 'zfs send -R' sends the descendant file systems but includes all the previous snapshots, which for disaster recovery purposes consumes unnecessary space if the previous snapshots are not needed in the disaster recovery pool.

cat /sys/module/zfs/version 0.8.3-1ubuntu12.5

2

There are 2 best solutions below

1
Tamas Jantvik On BEST ANSWER

I perfectly understand your use case. Although I for one am usually faced with the oppositie situation where I have a remote backup pool from which I want to restore the latest snapshot on a local system.

In any case, while you cannot achieve what you want in a direct way, you can reach the desired state. The idea is to prune your recovery set so that it only has the latest snapshot. You start by sending an initial snapshot:

host# zfs snapshot -r tank/data@initial_snapshot
host# zfs send -R tank/data@initial_snapshot | \
 ssh recovery-host zfs recv tank/data

This will send all descending file systems, and will send the initial_snapshot and all those created before it. If you thus had created any snapshots prior, you can delete them:

recovery-host# zfs list -H -o name -t snapshot tank/data | head -n -1 \
 | xargs -r -n 1 zfs destroy -r -v

Then you send incremental updates and prune,

host# zfs snapshot -r tank/data@${LATEST_LOCAL_SNAPSHOT}
host# zfs send -R -i tank/data@${LATEST_REMOTE_SNAPSHOT} \
 tank/data@${LATEST_LOCAL_SNAPSHOT} | ssh recovery-host zfs recv tank/data
recovery-host# zfs list -H -o name -t snapshot tank/data | head -n -1 \
 | xargs -r -n 1 zfs destroy -r -v

assuming that LATEST_LOCAL_SNAPSHOT and LATEST_REMOTE_SNAPSHOT are appropriately set.

Please mind that this is a minimal seatbelt-less example. You should care about whether your send-receives are successful. If accidently reach the state where your recovery pool does not have any snapshots that match your source, you can no longer send increments and will thus need to start anew.

6
Andrew Henle On

No.

If you want the entire filesystem for disaster recovery, you need the entire filesystem.

A ZFS snapshot is not a complete filesystem. It's effectively the difference between it and the previous snapshot, and that chain continues all the way back through all the snapshots to the "base" copy of the filesystem.

You can send incremental snapshots, which only send the differences. Per Oracle ZFS documentation:

...

If you are sending the snapshot stream to a different system, pipe the zfs send output through the ssh command. For example:

host1# zfs send tank/dana@snap1 | ssh host2 zfs recv newtank/dana

When you send a full stream, the destination file system must not exist.

You can send incremental data by using the zfs send -i option. For example:

host1# zfs send -i tank/dana@snap1 tank/dana@snap2 | ssh host2 zfs recv newtank/dana

Note that the first argument (snap1) is the earlier snapshot and the second argument (snap2) is the later snapshot. In this case, the newtank/dana file system must already exist for the incremental receive to be successful.

The first zfs command

host1# zfs send tank/dana@snap1 | ssh host2 zfs recv newtank/dana

Sends the entire filesystem.

This one just sends the differences:

host1# zfs send -i tank/dana@snap1 tank/dana@snap2 | ssh host2 zfs recv newtank/dana

Which can then be followed by

host1# zfs send -i tank/dana@snap2 tank/dana@snap3 | ssh host2 zfs recv newtank/dana