ZFS send/recvとnetcatを使ってネットワーク越しにZFSのデータを移行する

今回のサーバ更新では、ZFSからZFSへデータ移行をする必要があった。一般的にはrsyncやtarを使うんだろうけど、せっかくなのでZFSの機能を使って移行してみたら、かなり高速で快適だったのでメモ。
ZFSには、複製を作成するためのsend/recvという機能が用意されている。標準入出力を使ってデータをやりとりできるので、netcatを使ってネットワーク越しにつなぐことで、データを移行する。
まずは新サーバでの操作。netcatでネットワークからの入力を待ち受けて、標準出力へリダイレクトし、zfs recvで受信する。ポート番号は適当に選択する。受信するpoolはあらかじめ作成しておくこと。

# nc -l -p ポート番号 -w 120 | zfs recv -v pool/export@snapshot

次は、旧サーバでの操作。zfs sendはスナップショットしか送信できないので、スナップショットを作ってsendする。

# zfs snapshot pool/export@snapshot
# zfs send pool/export@snapshot | nc 宛先IPアドレス ポート番号

あとは待つだけ。rsyncやtarに比べて、ファイルシステムを直に扱うためオーバーヘッドが少ない、何も考えなくてもファイル作成時刻などのメタデータがそのままコピーできる、旧サーバのsnapshotも移行しようと思えば移行できる、などいいことだらけなので、今後もサーバ更新の際はzfs send/recvを使うようにしよう。

追記

netcatは転送するデータを暗号化せず平文で流すので、家庭内LANなどの覗き見されないネットワーク環境で使うこと。
覗き見の可能性があるなら、素直にsshを使うのがお手軽。