TL;DR
| |
It works the same for incremental sends (-i / -I) and for raw sends of encrypted datasets (-w).
Why
Without -s, an interrupted zfs recv throws away everything it had received: hours of transfer gone because of a network blip or a reboot. With -s (OpenZFS since 2017; Linux 0.7+, FreeBSD 12+) the receiver keeps the received piece in a hidden dataset (backup/data/%recv) and exposes the receive_resume_token property.
The token is the complete description of what is missing: it identifies the source snapshot, the object and offset where it stopped, and the stream options (raw, compressed, large blocks…). That is why zfs send -t needs no other arguments, and why you do not have to remember which flags the original send carried: they are rebuilt from the token.
Step by step
Always receive with
-s. It costs nothing and it is the only thing to remember before the drop.After the interruption, on the receiver:
1zfs get -H -o value receive_resume_token backup/dataIf it returns
-, there is no partial state (the send finished or never started).On the sender,
zfs send -t <token>with the usual pipeline intozfs recv -s. You can cut and resume as many times as needed; the token changes each time.Check the end:
zfs get receive_resume_tokengoes back to-and the snapshot shows up inzfs list -t snapshot -r backup/data.
For progress, -v on the send (bytes sent) or pv in the middle; to buffer latency on slow links, mbuffer between send and ssh.
Aborting
| |
Deletes the %recv and frees the space. Needed when the token no longer works (below) or when you decide to resend from another snapshot.
With syncoid
syncoid uses recv -s and the tokens on its own: if a send drops, the next run resumes it by itself. --no-resume turns it off if it ever gets in the way. Sanoid + syncoid are the comfortable way to do this in production.
Traps
- Destroying the source snapshot invalidates the token. If your snapshot policy (or a manual
zfs destroy) takes@snap1away mid-send,send -tfails:zfs recv -Aand start from a snapshot that exists. Aholdon the snapshot you are sending prevents it. - Both ends must support it: modern OpenZFS on both. Old Solaris and Illumos do not understand
-s. -wis preserved in the token: a resumed raw send stays raw; do not try to mix asend -twith arecvinto a target different from the original.- While partial state exists,
zfs destroyof the target dataset complains:recv -Afirst. -Rstreams (packages with several snapshots) resume too, but it is simpler to send snapshot by snapshot with-i, which is what syncoid does.