无法向 zfs 发送 | zfs 在同一 zpool 中接收数据集

无法向 zfs 发送 | zfs 在同一 zpool 中接收数据集

我有两个环境暂存(分期)和发展()。我无法复制(包括快照) 从数据集zfs/staging.assets到另一个数据集zfs/choang.assets 之内相同的 zpool zfs

注意:我假设我需要卸载源数据集和目标数据集。

zfs unmount zfs/staging.assets
zfs unmount zfs/choang.assets

zfs send -R zfs/staging.assets | zfs receive -F zfs/choang.assets

执行时,上述命令会生成以下错误:

Error: Unsupported flag with filesystem or bookmark.
cannot receive: failed to read from stream

当我删除 -R 选项并执行命令时,它成功了:

zfs send zfs/staging.assets | zfs receive -F  zfs/choang.assets

zfs/choang.assets@--head--但是,不会收到任何快照,并且会创建单个快照。

最后,我尝试发送一个快照——想也许我可以一次发送一个快照:

zfs send zfs/staging.assets@sha512_hash | zfs receive -Fduv zfs/choang.assets

这也不起作用并生成以下错误:

internal error: Invalid argument
cannot receive: failed to read from stream

如何复制所有快照?

答案1

这里有几件事很重要。您的错误源于它们的组合:

  • 通常您会发送一个特定的快照或多个快照,而不是整个文件系统。这意味着您不需要卸载数据集并扰乱您的用户,并且您可以send/recv稍后逐步进行。
  • 如果您没有在源上指定快照,您将获得自动生成的快照@--head--,这是发送时源的状态(如果您发送了现有快照,则该快照将取代@--head--源上的快照)目的地侧)。
  • send -R | recv -F组合意味着完全复制(递归并包括源上的属性,销毁目标上的旧内容),因此您需要决定如何扩展文件系统层次结构:您可以在接收时使用-e-d或 no 标志(无标志意味着合并新数据集下的内容,而不保留源端父数据集的名称):

    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.
    
  • 你的最后一个想法(单次发送,完整接收)应该有效(我在一个简单的环境中测试了它并且它确实有效),但无论如何它都不是你想要的。

因此,总结一下并适用于您的具体情况:

  1. 首先递归创建当前快照或选择包含您要复制的所有旧内容的旧快照):

    zfs snapshot -r zfs/staging.assets@now
    
  2. 销毁目标端上源端的所有旧快照(显示所有快照zfs list -Hr -o name -t snap zfs/choang.assets或从错误消息中获取提示)。或者,如果目标数据集不包含任何重要内容,则销毁目标数据集并重新创建它。

  3. 递归发送并完全接收,销毁第二个数据集上的所有旧数据集,将子数据集合并到目标中,以便它们镜像源:

    zfs send -R zfs/staging.assets@now | zfs recv -Fu zfs/choang.assets
    

答案2

服务器最近发生了内核更新(通过 CPanel)并且服务器尚未重新启动。查看日志文件后,我注意到 ZFS 也已更新。我相信这个问题中的命令由于内核模块和 CLI 工具之间的版本冲突而出现故障。

在另一台服务器上成功执行以下操作后,我得出了这个结论。

# 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  -

然后我返回到原始服务器并将 ZFS 模块从 DKMS 切换到内核的 kABI 模块系统并重新启动服务器。命令执行正确。看https://github.com/zfsonlinux/zfs/wiki/RHEL-%26-CentOS

答案3

在 ZFS 上使用发送/接收,您只能将其与快照一起使用,并且无需卸载数据集。您将无法发送/接收卷。

zfs send 命令创建写入标准输出的快照的流表示形式。默认情况下,会生成完整的流。您可以将输出重定向到文件或不同的系统。 zfs receive 命令创建一个快照,其内容在标准输入上提供的流中指定。如果接收到完整的流,也会创建一个新的文件系统。您可以使用这些命令发送 ZFS 快照数据并接收 ZFS 快照数据和文件系统。

正确的命令是:

zfs send tank/data@snap1 | zfs recv spool/ds01

发送/接收 zfs 快照的更好方法是使用缓冲区最大限度地降低 I/O 延迟的风险并填满网络缓冲区。

在发送机器上:

zfs send pool/image@test | mbuffer -s 128k -m 1G -O 127.0.0.1:9090

在接收机上:

mbuffer -s 128k -m 1G -I 9090 | zfs receive -F pool/image1

因为您可以在同一台计算机上使用 127.0.0.1,或在远程计算机上使用 xx.xx.xx.xx。

来源:https://docs.oracle.com/cd/E18752_01/html/819-5461/gbchx.html

相关内容