Linux

無法 zfs 發送 |zfs 在同一個 zpool 中接收數據集

  • October 1, 2017

我有兩個環境 Staging ( staging ) 和 Development ( choang )。我無法從數據集複製(包括快照)到同一個 zpool 中的另一個zfs/staging.assets數據集。zfs/choang.assets 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

如何複製所有快照?

伺服器上最近發生了核心更新(通過 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

這裡有幾件事很重要。您的錯誤源於它們的組合:

  • 通常你發送一個特定的快照或幾個快照而不是整個文件系統。這意味著您不需要解除安裝數據集併中斷您的使用者,您可以send/recv在以後逐步增加。
  • 如果您沒有在源上指定快照,您將獲得自動生成的快照,這是您的源在發送時的狀態(如果您要發送現有的快照,則該@--head--快照將代替@--head--目的地側)。
  • send -R | recv -F組合意味著完全複製(遞歸併包括源上的屬性,銷毀目標上的舊東西),因此您需要決定如何擴展文件系統層次結構:您可以在接收時使用-e,-d或不使用標誌(沒有標誌意味著合併新數據集下的內容,而不保留源端父數據集的名稱):
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
  1. 銷毀源端目標端的任何舊快照(顯示所有快照zfs list -Hr -o name -t snap zfs/choang.assets或從錯誤消息中獲取提示)。或者,如果目標數據集不包含任何重要內容,則銷毀並重新創建它。
  2. 遞歸發送和完全接收,銷毀第二個數據集上的所有舊數據集,將子數據集合併到目標,以便它們鏡像源:
zfs send -R zfs/staging.assets@now | zfs recv -Fu zfs/choang.assets

引用自:https://unix.stackexchange.com/questions/394620