Unable to zfs send | zfs receive datasets in same zpool
Solution 1
A kernel update recently occurred on the server (via CPanel) and the server hasn't been restarted. After reviewing log files I noticed that ZFS has been updated as well. I believe the commands in this question are malfunctioning due to version conflict between kernel module and CLI tools.
I arrived at this conclusion after successfully executing the following on a different server.
# zfs send -R tank1@--refresh-- | zfs recv -Fu tank2
# zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
tank1@turtle 9K - 34K -
tank1@tiger 9K - 47.5K -
tank1@squirrel 10K - 58.5K -
tank1@rabbit 10K - 70K -
tank1@owl 11K - 80.5K -
tank1@deer 11K - 90.5K -
tank1@bear 0 - 106K -
tank1@--refresh-- 0 - 106K -
tank2@turtle 9K - 34K -
tank2@tiger 9K - 47.5K -
tank2@squirrel 10K - 58.5K -
tank2@rabbit 10K - 70K -
tank2@owl 11K - 80.5K -
tank2@deer 11K - 90.5K -
tank2@bear 1K - 106K -
tank2@--refresh-- 0 - 106K -
I then returned to the original server and switch ZFS module from DKMS to kABI module system for the kernel and restarted server. The commands executed correctly. See https://github.com/zfsonlinux/zfs/wiki/RHEL-%26-CentOS
Solution 2
Several things are important here. Your errors stem from combinations of them:
- Normally you send a specific snapshot or several snapshots instead of a whole file system. This means you do not need to unmount the datasets and disrupt your users, and you can incrementally
send/recv
later on. - If you do not specify a snapshot on the source, you will get the automatically generated snapshot
@--head--
, which is the state of your source at the moment of sending (if you would have sent an existing snapshot, that snapshot would take the place of@--head--
on the destination side). -
The
send -R | recv -F
combination means full replication (recursive and including properties on source, destroy old stuff on destination), so you need to decide how to expand the file system hierarchy: you can use either-e
,-d
, or no flag on receiving (no flag means merging the contents under the new dataset without preserving the name of the parent dataset on the source side):The -d and -e options cause the file system name of the target snapshot to be determined by appending a portion of the sent snapshot's name to the specified target filesystem. If the -d option is specified, all but the first element of the sent snapshot's file system path (usually the pool name) is used and any required intermediate file systems within the specified one are created. If the -e option is specified, then only the last element of the sent snapshot's file system name (i.e. the name of the source file system itself) is used as the target file system name.
- Your last idea (single send, full receive) should work (I tested it in a simple environment and it did work), but it would not be what you wanted anyway.
So, to sum it up and apply to your specific situation:
-
First recursively create a current snapshot or choose an older one that contains all the older stuff you want to replicate):
zfs snapshot -r zfs/staging.assets@now
Destroy any old snapshots on the destination side which are on the source side (show all snapshots with
zfs list -Hr -o name -t snap zfs/choang.assets
or take the hints from the error message). Alternatively destroy the destination dataset and recreate it if it does not contain anything of importance.-
Send recursively and fully receive, destroying all old datasets on the second dataset, merging the sub-datasets into the destination so that they mirror the source:
zfs send -R zfs/staging.assets@now | zfs recv -Fu zfs/choang.assets
Solution 3
Using Send / Receive on ZFS you are able to use it only with snapshots and it is not necessary to unmount the datasets. You will be not able to send / receive a volume.
The zfs send command creates a stream representation of a snapshot that is written to standard output. By default, a full stream is generated. You can redirect the output to a file or to a different system. The zfs receive command creates a snapshot whose contents are specified in the stream that is provided on standard input. If a full stream is received, a new file system is created as well. You can send ZFS snapshot data and receive ZFS snapshot data and file systems with these commands.
The proper commands are:
zfs send tank/data@snap1 | zfs recv spool/ds01
The better way to send / receive a zfs snapshot is using mbuffer to minimize the risk of I/O latency and to fill up the network buffer.
On the sending machine:
zfs send pool/image@test | mbuffer -s 128k -m 1G -O 127.0.0.1:9090
On the receiving machine:
mbuffer -s 128k -m 1G -I 9090 | zfs receive -F pool/image1
As you can use 127.0.0.1 for the same machine or xx.xx.xx.xx for remote machine.
Source: https://docs.oracle.com/cd/E18752_01/html/819-5461/gbchx.html
Related videos on Youtube
Michael Niño
I am a "full stack" software engineer with a great passion for software and technology!!! Beach Billiards Cooking Fitness Motorcycles Movies
Updated on September 18, 2022Comments
-
Michael Niño over 1 year
I have two environments Staging (staging) and Development (choang). I am unable to replicate (including snapshots) from dataset
zfs/staging.assets
to another datasetzfs/choang.assets
within the same zpoolzfs
.NOTE: I am assuming I need to unmount both origin and destination datasets.
zfs unmount zfs/staging.assets zfs unmount zfs/choang.assets zfs send -R zfs/staging.assets | zfs receive -F zfs/choang.assets
When executed, the above commands generate the following error:
Error: Unsupported flag with filesystem or bookmark. cannot receive: failed to read from stream
When I remove the -R option and execute the commands, it succeeds:
zfs send zfs/staging.assets | zfs receive -F zfs/choang.assets
However, no snapshots are received and a single snapshot
zfs/choang.assets@--head--
is created.Finally, I attempted to send a snapshot-- thinking maybe I might send a snapshot at a time:
zfs send zfs/staging.assets@sha512_hash | zfs receive -Fduv zfs/choang.assets
This didn't work either and generated the following error:
internal error: Invalid argument cannot receive: failed to read from stream
How can I replicate all snapshots?
-
Michael Niño over 6 yearsThank you for the example using mbuffer. That was on my list of tools to implement
-
Michael Niño over 6 yearsI attempted the step-by-step however I am still receiving the following error message:
zfs send -R zfs/staging.assets@refresh | zfs recv -Fu zfs/choang.assets internal error: Invalid argument cannot receive: failed to read from stream
-
Michael Niño over 6 yearsIn addition, please note that each of the several snapshots for
zfs/staging.assets
as well as thezfs/staging.assets@refresh
(read:@now
in your example) were taken with-r
. Could it be because I am sending replicating to and from datasets within the same zpool? Or do you think it is something else?