zfsプール全​​体を別のzfsプールに一方向でミラーリングする方法


15

複数のzvolとデータセットが含まれているzfsプールがありますが、それらの一部もネストされています。すべてのデータセットとzvolは、zfs-auto-snapshotによって定期的にスナップショットされます。すべてのデータセットとzvolには、手動で作成されたスナップショットもあります。

時間の不足により、zfs send -Rを介したローカル高速ネットワークを介した初期コピーが完了しなかったリモートプールをセットアップしました(一部のデータセットが欠落しているか、一部のデータセットに古いスナップショットがあります)。

現在、プールは低速接続で物理的にリモートになっているため、リモートプールをローカルプールと定期的に同期する必要があります。つまり、ローカルプールにあるデータをリモートプールにコピーし、ローカルプールから削除されたデータをリモートプールから削除する必要があります。 「zvols」、「datasets」または「snapshots」を意味するデータによって、リモートプールに存在するがローカルプールには存在しないデータをリモートプールから削除する必要があります。

rsyncを使用して2つの通常のファイルシステム間でこれを行った場合、「-axPHAX --delete」になります(一部のシステムを実際にバックアップするためです)。

リモートプールのzvolとデータセット(スナップショットを含む)がローカルのzvol、データセット、スナップショットと同期できるように、同期タスクを設定するにはどうすればよいですか?

sshのスループットパフォーマンスが低いため、sshを介した転送は避けたいと思います。代わりにmbufferまたはiscsiを好むでしょう。


どうやってイニシャルをやりましたzfs send -R ...か?を介して出力をパイプした場合ssh、エスケープ文字を無効にしましたzfs send -R ... | ssh -e none ...か?
アンドリューヘンレ

また、低速な接続に十分な帯域幅を確保して、リモートコピーを最新の状態に保つ必要があります。リモートシステムに送信できるよりも多くの変更をローカルシステムに適用している場合、リモートコピーを最新の状態に保つことはできません。増分zfsレプリケーションストリームを取得し、ファイルに保存します。ファイルが、スナップショット間の時間内にリモートサイトに送信できるデータ量よりも大きい場合、追いつくことはできません。 zfs send -R -i pool@snap1 pool@snap2 | gzip --fast > /output/file.gz
アンドリューヘンレ

あなたはまた、自動にそれを行うには、このスクリプトを使用するように試みることができる:github.com/psy0rz/zfs_autobackup/blob/master/README.md
エドウィンはeefting

回答:


10

免責事項:zvolを使用したことがないので、zvolsが通常のファイルシステムまたはスナップショットとレプリケーションで異なるかどうかは言えません。私は彼らがそうであると思いますが、それについて私の言葉を受け入れません。


あなたの質問は実際には複数の質問です、私はそれらに別々に答えようとします:

プール全体をリモートロケーションに複製/ミラーリングする方法

タスクを2つの部分に分割する必要があります。最初に、レプリケーションスナップショットを台無しにしない限り、最初のレプリケーションを完了し、その後増分レプリケーションを実行する必要があります。増分レプリケーションを有効にするには、最後のレプリケーションスナップショットを保存する必要があります。それ以前のすべてを削除できます。以前のスナップショットを削除すると、zfs recv文句を言い、複製を中止します。この場合、最初からやり直す必要があるため、これを行わないようにしてください。

正しいオプションが必要な場合は、次のとおりです。

  • zfs send
    • -R:指定されたプールまたはデータセットの下にすべてを送信します(常に必要な再帰的レプリケーションを含む-p)。また、受信すると、削除されたすべてのソーススナップショットが宛先で削除されます。
    • -I:最後のレプリケーションスナップショットと現在のレプリケーションスナップショットの間のすべての中間スナップショットを含める(インクリメンタル送信でのみ必要)
  • zfs recv
    • -F:ソースで削除された既存のデータセットの削除を含む、ターゲットプールの展開
    • -d:ソースプールの名前を破棄し、宛先プール名に置き換えます(ファイルシステムパスの残りは保持され、必要に応じて作成されます)
    • -u:宛先にファイルシステムをマウントしません

完全な例が必要な場合は、小さなスクリプトを次に示します。

#!/bin/sh

# Setup/variables:

# Each snapshot name must be unique, timestamp is a good choice.
# You can also use Solaris date, but I don't know the correct syntax.
snapshot_string=DO_NOT_DELETE_remote_replication_
timestamp=$(/usr/gnu/bin/date '+%Y%m%d%H%M%S')
source_pool=tank
destination_pool=tank
new_snap="$source_pool"@"$snapshot_string""$timestamp"
destination_host=remotehostname

# Initial send:

# Create first recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Initial replication via SSH.
zfs send -R "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"

# Incremental sends:

# Get old snapshot name.
old_snap=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$source_pool"@"$snapshot_string" | tail --lines=1)
# Create new recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Incremental replication via SSH.
zfs send -R -I "$old_snap" "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"
# Delete older snaps on the local source (grep -v inverts the selection)
delete_from=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$snapshot_string" | grep -v "$timestamp")
for snap in $delete_from; do
    zfs destroy "$snap"
done

SSHよりも高速なものを使用する

IPSecまたはOpenVPNトンネルなど、十分に安全な接続があり、送信者と受信者の間にのみ存在する別個のVLANがある場合、ここ説明するようにSSHからmbufferなどの暗号化されていない代替手段に切り替えるか、暗号化なしでSSHを使用できます圧縮を無効にします詳細については、こちらをご覧ください。SSHの再コンパイルに関するWebサイトもありましたが、残念ながらURLは覚えていません-見つかったら後で編集します。

非常に大きなデータセットと遅い接続の場合、ハードディスクを介した最初の送信にも役立ちます(暗号化されたディスクを使用してzpoolを保存し、宅配便、郵便、または直接の封印されたパッケージで送信します)。送信/受信の方法は重要ではないため、すべてをディスクにパイプし、プールをエクスポートし、ディスクを宛先に送信し、プールをインポートしてから、すべての増分送信をSSH経由で送信できます。

乱れたスナップショットの問題

前述のように、レプリケーションスナップショットを削除/変更すると、エラーメッセージが表示されます

cannot send 'pool/fs@name': not an earlier snapshot from the same fs

これは、コマンドが間違っていたか、スナップショットを削除して最初からやり直す必要がある一貫性のない状態にあることを意味します。

これにはいくつかの負の意味があります。

  1. 新しいレプリケーションスナップショットが正常に転送されるまで、レプリケーションスナップショットを削除することはできません。これらのレプリケーションスナップショットには他のすべての(古い)スナップショットの状態が含まれるため、削除されたファイルとスナップショットの空き領域は、レプリケーションが終了した場合にのみ回収されます。これにより、プール上の一時的または永続的なスペースの問題が発生する可能性がありますが、これは完全なレプリケーション手順を再起動または完了することによってのみ修正できます。
  2. 追加のスナップショットが多数あるため、listコマンドの速度が低下します(これは修正されたOracle Solaris 11を除く)。
  3. スクリプト自体を除き、スナップショットを(偶発的な)削除から保護する必要がある場合があります。

これらの問題の可能な解決策が存在しますが、私は自分で試していません。zfs bookmarkこのタスク専用に作成されたOpenSolaris / illumosの新機能を使用できます。これにより、スナップショット管理が不要になります。唯一の欠点は、現時点では、再帰的にではなく、単一のデータセットに対してのみ機能することです。すべての古いデータセットと新しいデータセットのリストを保存してから、それらをループし、ブックマーク、送信、受信してからリスト(または必要に応じて小さなデータベース)を更新する必要があります。

ブックマークのルートを試してみたら、それがどのように機能するか聞いてみたいと思います!


この詳細な回答に感謝します。私はただ送信していzpoolます。
ジッター、

1
素敵なスクリプト。-d 1両方のzfs listコマンドに追加して、検索の深さを制限します(プール名の下で検索する必要はありません)。これにより、多くのスナップショットを持つプールでの長い遅延を回避できます(たとえば、「バックアップ」プールには320000のスナップショットがあり、zfs list -r -t snapshot backup実行に13分かかります。0.06 秒しかかかりません-d 1)。次にzfs destroy、forループのコマンドには-r、同じスナップ名を持つすべてのスナップショットを再帰的に削除するオプションが必要です。
cas

5

個人的には、リモートサーバー上のzvol、データセットなどのリストを作成します。 最新のスナップショット持たないそれらのスナップショットをで更新しzfs sendます。帯域幅の。

そうすればzfs send、それ以降も引き続き使用でき、独自の同期コードを作成して車輪を再発明する必要はありません。rsync古いファイルシステムにzfs sendは適していますが、zfsにははるかに優れています- 正確に知っていますいますスナップショットで変更されたブロックを送信するだけで、rsyncはローカルサーバーとリモートサーバー間で個々のファイルやタイムスタンプを比較する必要があります。同じことbtrfs sendがbtrfsプールにも当てはまります。

最新にする必要があるスナップショットの数が少ない場合は、手動で行うことができます。それ以外の場合、自動的に実行するには、最新のローカルスナップショットとリモートスナップショットのリスト、およびzfs sendrmeoteサーバー上の古いバージョンとローカルスナップショットを比較するスクリプトが必要です。

各データセットの最新のスナップショットのみに関心がある場合は、これで十分です。以前のスナップショットをすべて気にかけている場合、スクリプトでそれらを処理する必要があることは明らかです。...それはかなり複雑になります。場合によっては、リモートサーバーでロールバックして、中間/不足しているスナップショットを再送信できるようにする必要があります。

リモートサーバーへの安全な接続が必要な場合は、使用する以外に選択肢はほとんどありませんssh-または、openvpnまたはでトンネルを設定してを使用しますnetcat


Zrepの使用はどうですか?bolthole.com/solaris/zrep
Xdg

知らない、使ったことがない。誰かが少しの調査とテストを行い、それを書く場合、それは良い答えになると思われます(それはヒントです)。
cas

Ubuntu(Linux上のZFS)でテストしましたが、より深いデータセット(tank / something / someother)では動作しませんでした。このポートをシェルリンクに使用していました。再帰フラグexport ZREP_R=-Rがまったく機能していませんでした。:(
Xdg

1

FreeBSDの `zrepl 'を見てください。これはあなたの人生を、そして誰でもそれをはるかに簡単にしてくれるでしょう。数日前にオタワで開催されたBSDCan2018で発表されました。それは有望に見え、あなたの問題の解決策かもしれません



質問の質問は、「リモートプールのzvolとデータセット(スナップショットを含む)がローカルのzvol、データセット、スナップショットと同期できるように、同期タスクを設定するにはどうすればよいですか?」です。
ジェフシャラー

0

zrepは優れたオールインワンソリューションであり、単なるSSH転送よりも高速な転送を取得する方法に関するドキュメントとフックがあります

https://github.com/bolthole/zrep

クロスプラットフォームでもあります:Linux、freebsd、solaris / illumosでサポートされています



1
質問の質問は、「リモートプールのzvolとデータセット(スナップショットを含む)がローカルのzvol、データセット、スナップショットと同期できるように、同期タスクを設定するにはどうすればよいですか?」です。
ジェフシャラー

ジェフ、最高の「答え」は、単にzrepへの参照を与えるのではなく、zrepドキュメントから切り取って貼り付けることだと提案していますか?
フィリップブラウン

1
最善の答えが何であるかはわかりませんが、ソフトウェアへのリンクは解決策ではありません。実際、すでに言及されています。質問:「リモートプールのzvolとデータセット(スナップショットを含む)がローカルのzvols、datasets&snapshotsと同期できるように同期タスクを設定するにはどうすればよいですか?」
ジェフシャラー

はい、それは質問です。ただし、タスクをうまく実行するには、ここのWebページに少しだけ書くよりもはるかに多くが必要です。そのため、zrepは2000行のシェルスクリプトです。元の問題では必要なかったすべての部分を削除したとしても、それを行うには数百行のスクリプトが必要です。
フィリップブラウン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.