zpoolを容量の多い別HDDに移したのでメモ。
一度、同じようなことはやっているが、時間も経っているので。
最初に書いておくが移行元でまずscrubしておくこと。

流れとしては以下の通り。

  1. 移行元HDD
    1. scrubしておく
    2. snapshot
  2. 移行先HDD
    1. GPTでzfsのパーティションを作成
    2. zpool作成
  3. zfs send, recvで丸々コピー

以下、実作業に触れる前に補足。

方針についての補足

なぜmirrorにしないのか

上記の方法のほかには、追加のディスクをmirrorとしてzpoolに追加し、resilveringが終わったら旧ディスクを外してexpandという手がある。
が、その手は採らない。
実は、zpool statusをする都度、以下のメッセージが表示されていた。
旧ディスクは512Bセクタになっていると文句を言っているのである。
ディスクを交換するか、新Poolに移せ、と。

 pool: vault  
state: ONLINE  
status: One or more devices are configured to use a non-native block size.  
Expect reduced performance.  
action: Replace affected devices with devices that support the  
configured block size, or migrate data to a properly configured  
pool.  
scan: scrub repaired 0 in 8h3m with 0 errors on Sun Nov 4 04:16:39 2018  
config:

NAME STATE READ WRITE CKSUM  
vault ONLINE 0 0 0  
ada1 ONLINE 0 0 0 block size: 512B configured, 4096B native  

512Bセクタのpoolにmirrorを追加したら、やっぱり512Bになるんではと心配になったので、mirrorではなく新規ディスクの新規Poolに移す。

なぜディスクをまるっと使わずgptでパーティションを切るのか

zpoolは、わざわざgptパーティションにしなくても、ディスクをまるっと使ってzpoolに指定できる。
できるのだが、/dev/ada2なんて名前よりも、gptラベルでpoolを作成したいのである。
これの有利な点は、例えば当該ディスクの物理的な位置で名前を付けることができる点である。
具体的には、slot_1とか名前を付けておくと、ディスク交換の時に楽。
幸いにもFreeBSDにおいては、gptパーティションを切ってもディスクをそのまま使っても、いずれもパフォーマンスに違いはない。
それならgptにしましょう。

https://www.freebsd.org/doc/handbook/zfs-zpool.html
There is no performance penalty on FreeBSD when using a partition rather than a whole disk.
(2018/11/09)

ではさっそく作業を。

実作業(移行元ディスクの準備)

scrubをしておく。

zpool scrub で。
かなり時間がかかるので覚悟しておくように。
なおscrubは最低3か月に一回が推奨
https://www.freebsd.org/doc/handbook/zfs-term.html#zfs-term-scrub
recommended at least once every three months

作業直前にsnapshot。

pool内に複数のディレクトリがある場合、最上階層でsnapshot -r(recursive)すればよい。
たとえばvaultというpoolにchamber, itunesがある場合に;

vault  
vault/chamber  
vault/chamber@20170503  
vault/itunes  
vault/itunes@20170503

※zfs list -t allの出力を一部削除したもの

zfs snapshot vault@20181109とすれば;

vault  
vault@20181109  
vault/chamber  
vault/chamber@20180503  
vault/chamber@20181109  
vault/itunes  
vault/itunes@20180503  
vault/itunes@20181109

※zfs list -t allの出力を一部削除したもの

となる。いちいち各ディレクトリ配下でコマンドを叩かなくてよい。

移行先作業

GPTパーティションの作成

以下のようなディスク

ada3 at ahcich3 bus 0 scbus3 target 0 lun 0  
ada3: ACS-3 ATA SATA 3.x device  
ada3: Serial Number WD-WCC7K3PU64NE  
ada3: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)  
ada3: Command Queueing enabled  
ada3: 3815447MB (7814037168 512 byte sectors)

GPTスキームをcreateし、全領域をfreebsd-zfsに割り当てる。
このとき、-lオプションでラベルを付ける。
同じくgpart showに-lオプションを付ければ名前を確認できる。

# gpart create -s GPT ada3  
ada3 created  
# gpart add -l slot_4 -t freebsd-zfs /dev/ada3  
ada3p1 added  
$ gpart show ada3  
40 7814037088 ada3 GPT (3.6T)  
40 7814037088 1 freebsd-zfs (3.6T)

$ gpart show -l /dev/ada3  
40 7814037088 ada3 GPT (3.6T)  
40 7814037088 1 slot_4 (3.6T)

zpoolの作成

/dev/ada3ではなくGPTラベルで指定する。
GPTラベルで指定するときは、gpt/<GPTラベル>というように指定する。

# zpool create warehouse gpt/slot_4  
# zpool status warehouse  
pool: warehouse  
state: ONLINE  
scan: none requested  
config:  
NAME STATE READ WRITE CKSUM  
warehouse ONLINE 0 0 0  
gpt/slot_4 ONLINE 0 0 0

プロパティの変更

zfsを作成する前に。
圧縮モードをlz4にする。lz4はCPU負荷の割には非常に効率が良いので積極的に有効にしたい。
また、atime(アクセスタイムの記録)もoffに。これがonだと差分snapshotが失敗するから、というのが一つと、これをoffにするとパフォーマンスが上がる(can result in significant performance gains)から。
zfs get <プロパティ名> で現在の値を取得。
zfs set <プロパティ名>=<値> で値のセット。
圧縮モードのプロパティ名はcompression、atimeはatime。

$ zfs get compression warehouse  
NAME PROPERTY VALUE SOURCE  
warehouse compression off default  
$ zfs get atime warehouse  
NAME PROPERTY VALUE SOURCE  
warehouse atime on default

# zfs set compression=lz4 warehouse  
# zfs set atime=off warehouse  
$ zfs get compression warehouse  
NAME PROPERTY VALUE SOURCE  
warehouse compression lz4 local  
$ zfs get atime warehouse  
NAME PROPERTY VALUE SOURCE  
warehouse atime off local

ディレクトリの用意とsend/recv

# zfs create warehouse/itunes  
# zfs create warehouse/chamber  

このとき、勝手にマウントされないようにすべきだった。-uを付ければよかったかな。
いずれにせよzfs set mountpointで後から変えられる。

sendに-Rを付けると、子孫やスナップショットもまとめてsendされる。

# zfs send -R vault/chamber@20181109 | zfs receive warehouse/chamber  
# zfs send -R vault/itunes@20181109 | zfs receive warehouse/itunes  

かかった時間、容量は以下の通り。うーむ。ちょっとかかったかな。

 991GiB 3:09:00 [89.5MiB/s]  
1.10TiB 3:58:24 [80.3MiB/s]  

このとき適当にhtopを叩いた結果。CPU負荷はそんなんでもないので、ボトルネックは別のところにあるように思われる。

1 [||||||||||||||||||||| 47.6%] Tasks: 43, 0 thr; 2 running  
2 [||||||||||||||||| 37.7%] Load average: 0.91 1.77 1.86  
Mem[||||||||||||||||||||||||||||||||642M/1.84G] Uptime: 12:03:30  
Swp[||||||||| 176M/907M]  

なおCPUはAMDのTurionである。

compression=lz4の結果は.
プロパティused(HDD上の容量)とlogicalused(圧縮前容量)で調べられる。

warehouse used 2.00T -  
warehouse logicalused 2.02T -  

本来なら2.02Tのところ、2.00Tで済んでる。

これで引っ越し完了。

以上