Tag Archives: zfs

[zfs][zpool] zfsの別ディスクへの移行

Pocket

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で済んでる。

これで引っ越し完了。

以上

[FreeBSD] システムアップグレード時にはzpool(ZFS)のアップグレードも忘れずにNE!

Pocket

10.1-RELEASEにアップグレードしたけどzpool(ZFS)のアップグレードを忘れてたのでメモ。
アップグレードでfeaturesがいくつか追加されるから、まあやっておくのがおすすめ。
9.x系列からのアップグレードの場合は、以下を参照のこと。
[メモ]zpoolのupgrade
[メモ]zpoolのVersionについて(Versionナンバはもう使われない)

10.1-RELEASEで追加されるfeaturesは以下の通り。
詳細はman zpool-featuresせよ(手抜き)。
この中ではbookmarksがすごいと思うよ。

アップグレードが必要かどうかは、zpool statusで分かる。

前も書いたと思うけど、ZFSは「何をすべきか」まで教えてくれるのがとても助かる。
ファイルシステムなんてそんな頻繁にいじらないし、久しぶりだとコマンド忘れてしまうからね。
この場合はzpool upgradeせよと。

まず一般権限でzpool upgrade。

追加されるfeaturesを確認したらスーパーユーザでもう一度zpool upgrade。
すぐ終わる。
お約束だが、フルバックアップは取っておこうな!

zfs snapshotの差分send/recvについて

Pocket

 

zfs snapshotの差分send/recvについて

zfsのバックアップは、snapshotを撮っておいて、自ホストの別zpool、あるいは他ホストの別zpoolに移すことで行われる。
バックアップは定期的に行われるものであるが、ではそのsnapshotを移す際、毎回毎回まるまる送っていたんでは帯域も時間もディスク寿命も無駄である。
zfsはそこも考慮していて、差分だけを送ればいいようにincrementalオプションがきちんと用意されている。

書式は以下の通りsendに-iオプションを与えるだけ。
(recv側にはsnapshotAがすでに転送済みの前提)

 

よろしい。では次回からは…?

ふむ。
では二回目以降はどうするのだろう?
上記の書式例でsnapshotCが出来たらどうするのだろう?
まさかsnapshotA, B, Cを全部並べるのか?と思ったけどそれは間違いで、snapshotB, Cだけでよい。

recv側にはsnapshotAがすでにあるとき。
zfs send -i snapshotA snapshotBでAとBの差分のみが送られる。
つぎにzfs send -i snapshotB snapshotCでBとCの差分のみが送られる、というわけ。

では早速試してみる。が。

「転送先が更新されているため差分を転送できません」

こんなエラーがでる。

まあ文字通りなんですが。
バックアップ用の転送先が更新されるのはなぜか分からないが(atimeだろうか?)。

こういう場合には、recv側で-Fオプションを与えればよい。
-Fオプションによりrecv側は最新snapshotに強制rollbackして、それからsnapshotを受け取る。

下記の例だと、recv側は@20131226にいったんrollbackしてから受け取る。

 

atimeのoff

recv側がなぜ更新されてるのか、atimeが怪しいのでoffにしておく。
recv側のzpoolに対してzfs set atime=offするだけ。
(zpoolから切り出されたzfsすべてに適用される)

 

[メモ]zpoolのVersionについて(Versionナンバはもう使われない)

Pocket

 

過日、zpool v28のアップグレードをして、いくつかのfeature flagsを有効にした。
したのだが、よく分からないことがいくつかあった。

すなわち、最新のはずのv28なのにアップグレードを促されたこと、アップグレードしたら zpool get allの結果からバージョンが消えてしまったこと、である。

WikipediaのZFSやOpenZFSを眺めてみて分かったのは、zpool((Open)ZFS)はv28以降、バージョンナンバの使用を止めてしまったせいとの由。
http://en.wikipedia.org/wiki/OpenZFS
http://en.wikipedia.org/wiki/ZFS#RELEASEHISTORY

以下に調べた結果を示す。
なお、ご覧の通り情報の出所はwikipediaである。
問題ないとは思うが、各位においてはご留意されたい。

ZFSの歴史

もともと、zpoolやZFS filesytemに機能が追加されるたび、バージョンナンバがインクリメントされてきた。
しかし2010年、OpenSoralisの開発が停止され、ZFSはオープンソースではなくなった。
本家(Oracle)のZFSはプロプライエタリとなって、2013/12/24現在、ZFS filesystemはv6, ZFS Poolはv34まで進んでいる。

それはそれとして、illumos(OpenSolaris後継)やBSD/Linux/OSX関連の方々は、オープンであったzfs v5, zpool v28をベースに本家とは別の開発が進める。
これが2013年にOpenZFSとなる。

バージョンナンバとフィーチャーフラグ

OpenZFSはいろんな所でいろんな人々が開発を続けている。
こういった状態で、単一のバージョンナンバを付与することは不可能である。
そこでフィーチャーフラグ(feature flags)という考え方を導入する。
機能ごとに個別の名前を与える、というもの。

個別の名前は、feature@<org-name>:<feature-name>という書式で表される。
org-nameは当該機能を開発した組織名。一意の名前。もちろん、勝手につけることは許されない。
org-nameが明らかな場合には、feature@<feature-name>と短縮してもよい。
feature@async_destroyというように。

フィーチャーの状態

フィーチャーの状態には三つある。
disabled, enabled, activeである。

  • disabled: 無効。機能を使えない状態。
  • enabled: 機能を使える状態。有効にはなっていない。
  • active: 機能が有効。旧バージョンとの互換性がなくなっている。

フィーチャーの種類

  • features for write : 書き込みには必須の機能。読み込みのみであれば不要。
  • features for read : 読み込み、あるいはpoolを開くために必須の機能。

たとえばasync_destroyはデータ書き込みの時だけ必要な機能なのでfeatures for write。

バージョンについて

一つでもフィーチャーを有効にするとpoolのバージョンは1000になる。
1000とはめちゃくちゃな数に見えるかもしれないが、本家のバージョンと被らないようにするため。

おわりに

ここで改めてzpoolの出力を見てみると、poolのバージョンがハイフンになっていることや、フィーチャーの記載など、なるほどと理解できることがありますな。

 

[メモ] ディスクを追加してZFSを作り、他zpoolのsnapshotを送り込む

Pocket

 

HDDを増設してZFSを作ったのでメモ。
一本のHDDにpool、zfsを作成し、圧縮、重複排除機能の有効化まで。
環境は(残念ながら10.0-Rではなく)FreeBSD 9.2-RELEASE-p1。

lz4でzfsの圧縮機能を気軽に試せるように

ファイルシステムで圧縮機能を有効にすると、読み書きのいずれにもCPUパワーが必要で、要するに遅くなる。
非力なCPUを使っているとなかなか使いにくい機能なのだが、圧縮方法にlz4が選べるようになってハードルは下がったように思う。
lz4はここでも触れたが、めっぽう速い圧縮アルゴリズムである。
これはぜひとも使ってみなければ。

 

 

ディスクの確認とzfs機能の確認

物理ディスクを追加し、ブートしたらdmesgを確認する。

ada2とのこと。

作業前にzfs, zpoolのバージョンを確認しておいてもいいかも。
zfs, zpoolそれぞれにupgradeオプションを与えればよい。
upgradeという名前の通り、upgradeのためのコマンドだが、バージョン確認にも使える。

zfsはバージョン5、zpoolはバージョン28。
このバージョンであれば、lz4による圧縮機能(LZ4 Compression algorithm support)と、重複排除機能(Deduplication)を使える。

pool、zfsの作成

warehouseというzpoolを作り、そこからbackupというボリュームを切り出す。

まずzpoolを作る。
ほんと簡単で速くて助かる。

で確認。

ではzpoolからzfsの切り出し。
先ほど作成したwarehouseからbackupという名前で。

あとは/etc/fstabに書くだけ。
warehouse/backupを/backupにマウントするとして以下のように書いておき。

/warehouse/backupをいったんunmountしてそれからmount。

 

圧縮機能と重複排除機能を有効に

ではさっそく圧縮機能と重複排除機能を有効にする。
といっても、すっごく簡単なんだけどね。

確認。
zfs getで対象zfsの属性を確認できる。

タイプが面倒ならzfs get allですべての属性を表示させ、grepすればよい。

 

書き込んでみる

今回追加したHDDはもともとバックアップ用途のつもり。
ここにスナップショットを流しこんでみる。

以下のようにしてスナップショットを作成する。

スナップショットのサイズは以下のとおりである。

これらスナップショットをバックアップのHDDに流し込む。
zfs sendとzfs recvをパイプで繋ぐ必要がある。
sudoを使う場合にはsh -cで。

注意点がある。
以上のようにsnapshotを送ると、受け側では:
①warehouse/backup/chamber ができ、さらに;
②warehouse/backup/chamber@20131121 つまり;
実ディレクトリで言えばwarehouse/backup/chamber/.zfs/snapshot/20131121ができる。

漠然とvault/chamber@20131121の内容がwarehouse/backup/chamberに書き込まれる思っていたので驚いた。

 

また、ロードアベレージを監視するような仕組みは特に入れていなかったので、topの出力を見たところ5を超えてた。ちょっと怖い。

そしてたかだか913GBのsnapshotの転送にかかった時間であるが。

まる二日半て…。
これは圧縮か重複排除か、どちらか止めた方がいいかもわからんね。

差分snapshotの転送

オリジナルディスクで複数回snapshotを作成した場合、バックアップディスクにはその差分を送ることができる。
zfs sendに-iを与え、二つのsnapshotを指定すればよいだけ。

以上