FreeBSD で ZFS を利用する – ファイルシステムを管理する

ZFS

前回はプールの機能説明で終わってしまいましたので,今回からはファイルシステムの管理 (作成や削除,スナップショットなどなど) について触れていきたいと思います.

現状,このような ZFS ストレージがあります.(前回作成した RAIDZ の環境です)

ストレージプール且つファイルシステムと記載していますが,OS 上見るとこのようにマウントされ,読み書きも可能な状態であるためにこの表現となっています.

# df -H
Filesystem    Size    Used   Avail Capacity  Mounted on
/dev/da0p2     20G    3.2G     15G    18%    /
devfs         1.0k    1.0k      0B   100%    /dev
pool0         413G     32k    413G     0%    /pool0

この状態を前提に,以下色々とやってみようと思います.

追加のファイルシステムを作成する

pool0 がプールであり /pool0 としてマウントされています.pool0 のプールから別のファイルシステムを作成することが可能です.
こんな感じでファイルシステムを切り出してみたいと思います.

ファイルシステムの作成は zfs create コマンドを利用します.pool 名に / を付けて作成したいファイルシステムを記載します.結果はこのようになります.

# zfs create pool0/data
# zfs create pool0/share

# df -H
Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/da0p2      20G    3.2G     15G    18%    /
devfs          1.0k    1.0k      0B   100%    /dev
pool0          413G     31k    413G     0%    /pool0
pool0/data     413G     31k    413G     0%    /pool0/data
pool0/share    413G     31k    413G     0%    /pool0/share

プールも含めて全てからっぽの状態ですのでサイズ,使用量,空き容量は pool と同一です.

色々と遊んでみる

マウントする先を変更する

ただファイルシステムを作成した場合はプール名の配下に作成されます.これでは使い勝手が悪いケースも多いかと思います.
作成後に別の所にマウントするようにしたい場合は zfs set コマンドで実施することが可能です.
ここでは /pool0/data を /data に変更してみます.

# zfs set mountpoint=/data pool0/data

# df -H
Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/da0p2      20G    3.2G     15G    18%    /
devfs          1.0k    1.0k      0B   100%    /dev
pool0          413G     31k    413G     0%    /pool0
pool0/share    413G     31k    413G     0%    /pool0/share
pool0/data     413G     31k    413G     0%    /data

このように,何らか変更したい場合は zfs set コマンドを用いるんだ.という点を押さえてください.

ファイルシステムの上限(クォータ)を設定する

プールから切り出されたファイルシステムはプールの領域を必要に応じて消費していきます.
従って,予定外の所で使用しつくされた結果,プールが枯渇することが生じる場合があります.
そのような事態を防ぐために容量制限を設けたい.ということがありますのでこれをやってみます.pool0/data に対して 10GB の上限を設定してみます.

# zfs set quota=10G pool0/data

# df -H
Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/da0p2      20G    3.2G     15G    18%    /
devfs          1.0k    1.0k      0B   100%    /dev
pool0          413G     31k    413G     0%    /pool0
pool0/share    413G     31k    413G     0%    /pool0/share
pool0/data      11G     32k     11G     0%    /data

結果としてはこのようになり,Size の所を見て頂くとわかるとおり pool0/data が pool0 と変わっています.10G で指定したのに 11G なのは GiB と GB の違いになります.

ファイルシステムの下限(リザーブ)を設定する

プロジェクトあたり,やユーザーあたり最低容量を保証.というような使い方をするケースはあると思います.
ZFS では予約を行いプールや他のファイルシステムがどれだけ使っても予約分は維持されるようにできます.

pool0/share に対して 10GB の予約を設定してみます.予約も zfs set で設定します.

# zfs set reservation=10G pool0/share

# df -H
Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/da0p2      20G    3.2G     15G    18%    /
devfs          1.0k    1.0k      0B   100%    /dev
pool0          402G     31k    402G     0%    /pool0
pool0/share    413G     31k    413G     0%    /pool0/share
pool0/data      11G     35k     11G     0%    /data

先のクォータの時の df の結果と見比べて頂きたいのですが,pool0 の Size に変化が生じており,予約された分が減算されています.pool0/share は見た目上変化はありません.

スナップショットを作成する

pool0/data に対してスナップショットを作成して現状状態 (カレント状態) とスナップショットの中の状態の比較を行いたいと思います.

まずは幾つかファイルを作成してみます.

# echo "before-snapshot" > /data/data1.txt
# echo "before-snapshot" > /data/data2.txt
root@bsd13-1:~ # ls /data
data1.txt       data2.txt

pool0/data のスナップショットを作成してみます.スナップショットの作成は zfs snapshot コマンドを利用します.

# zfs snapshot pool0/data@snap-1

# df -H
Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/da0p2      20G    3.2G     15G    18%    /
devfs          1.0k    1.0k      0B   100%    /dev
pool0          402G     31k    402G     0%    /pool0
pool0/share    413G     31k    413G     0%    /pool0/share
pool0/data      11G     35k     11G     0%    /data

スナップショットを作成してもファイルシステム上には表示されていないことが確認できます.
確認するには zfs list コマンドを利用します.オプションの有無でファイルシステムを表示するのかスナップショットを表示するのかが変わります.

# zfs list pool0/data
NAME         USED  AVAIL     REFER  MOUNTPOINT
pool0/data  32.0K  10.0G     32.0K  /data

# zfs list -t snapshot pool0/data
NAME                USED  AVAIL     REFER  MOUNTPOINT
pool0/data@snap-1     0B      -     32.0K  -

では,データを追加・編集していきます.data2.txt の内容を変更,data3.txt を追加しました.

# echo "after-snapshot" > /data/data3.txt
root@bsd13-1:~ # echo "modify-data" > /data/data2.txt
root@bsd13-1:~ # ls /data
data1.txt       data2.txt       data3.txt

スナップショットにアクセスし,スナップショットとファイルシステムのデータと比較をしてみます.

# ls /data
data1.txt       data2.txt       data3.txt

# ls /data/.zfs/snapshot/snap-1
data1.txt       data2.txt

# cat /data/data2.txt
modify-data
# cat /data/.zfs/snapshot/snap-1/data2.txt
before-snapshot

このように,正しくスナップショットが働いている事が確認できます.
説明が前後してしまいましたが,スナップショットへのアクセスは .zfs/snapshot/[スナップショット名] としてディレクトリーが作成されていますので OS から直接アクセスすることが可能です.

スナップショットは複数作成することが可能です.数の制限はほぼ無い状態ですので1時間毎などの取得も可能です.
ここでは snap-1 を作成していますので,9個作成して10個のスナップショットを持つ状態としてみたいと思います.
(上以降データの変更は発生していませんが…)

# zfs snapshot pool0/data@snap-2
# zfs snapshot pool0/data@snap-3
# zfs snapshot pool0/data@snap-4
# zfs snapshot pool0/data@snap-5
# zfs snapshot pool0/data@snap-6
# zfs snapshot pool0/data@snap-7
# zfs snapshot pool0/data@snap-8
# zfs snapshot pool0/data@snap-9
# zfs snapshot pool0/data@snap-10

スナップショットの一覧および .zfs 経由で見た場合このようになります.

# zfs list -t snapshot pool0/data
NAME                 USED  AVAIL     REFER  MOUNTPOINT
pool0/data@snap-1   19.3K      -     32.0K  -
pool0/data@snap-2      0B      -     34.0K  -
pool0/data@snap-3      0B      -     34.0K  -
pool0/data@snap-4      0B      -     34.0K  -
pool0/data@snap-5      0B      -     34.0K  -
pool0/data@snap-6      0B      -     34.0K  -
pool0/data@snap-7      0B      -     34.0K  -
pool0/data@snap-8      0B      -     34.0K  -
pool0/data@snap-9      0B      -     34.0K  -
pool0/data@snap-10     0B      -     34.0K  -

# ls /data/.zfs/snapshot/
snap-1  snap-10 snap-2  snap-3  snap-4  snap-5  snap-6  snap-7  snap-8  snap-9

スナップショットを削除する

名前を付け間違った場合や,用途を終えた (保持期間を過ぎた) などでスナップショットを削除したい場合は発生します.
スナップショットの削除は zfs destroy コマンドで行います.このコマンドはファイルシステムの削除でも用いられるコマンドですので取り扱いには注意しましょう.
最新の snap-10 を削除してみます.

# zfs destroy pool0/data@snap-10

# zfs list -t snapshot pool0/data
NAME                USED  AVAIL     REFER  MOUNTPOINT
pool0/data@snap-1  19.3K      -     32.0K  -
pool0/data@snap-2     0B      -     34.0K  -
pool0/data@snap-3     0B      -     34.0K  -
pool0/data@snap-4     0B      -     34.0K  -
pool0/data@snap-5     0B      -     34.0K  -
pool0/data@snap-6     0B      -     34.0K  -
pool0/data@snap-7     0B      -     34.0K  -
pool0/data@snap-8     0B      -     34.0K  -
pool0/data@snap-9     0B      -     34.0K  -

このように,引数としてはファイルシステム名にスナップショット名まで含めた形で実行します.
もしスナップショット名を付けずに実行した場合は…

# zfs destroy pool0/data
cannot destroy 'pool0/data': filesystem has children
use '-r' to destroy the following datasets:
pool0/data@snap-9
pool0/data@snap-3
pool0/data@snap-4
pool0/data@snap-7
pool0/data@snap-5
pool0/data@snap-2
pool0/data@snap-8
pool0/data@snap-6
pool0/data@snap-1

と,スナップショットがある場合はこのように怒られます.ない場合は削除されますので注意が必要です.
メッセージのとおり -r を付けて実行すると,ファイルシステムとスナップショットを一気に削除することが可能です.
これについてはおいおいやっていきます.

クローンを作る

ZFS はクローンも簡単に作成することが可能です.
スナップショットは読み取り専用です.テスト用の領域としてデータがある読み書きできる環境を用意したいというような場合に利用できます.

同一プール内にクローンを作成する

今ある pool0 にクローンを作成することが可能です.主な利用ケースとしては先に述べたようにテスト用途になると思います.
クローンを作るには,スナップショットを指定する必要があります (そうじゃないと,データの静止点が取れないですし)

最新のスナップショットを指定してクローンを作成してみます.

# zfs clone pool0/data@snap-9 pool0/data-clone

# zfs list
NAME               USED  AVAIL     REFER  MOUNTPOINT
pool0             10.0G   375G     32.0K  /pool0
pool0/data        53.3K  10.0G     34.0K  /data
pool0/data-clone     0B   375G     34.0K  /pool0/data-clone
pool0/share       30.6K   385G     30.6K  /pool0/share

マウントポイントは pool0 の設定を引き継いでいるため,pool0 以下に作成されました.これは上のとおりで変更可能です.
クローンされたファイルシステムの中身やスナップショットがどうなっているのか見てみましょう.

# ls /pool0/data-clone
data1.txt       data2.txt       data3.txt

# zfs list -t snapshot pool0/data-clone
no datasets available

ファイルは pool0/data と同じものが存在しています.スナップショットはありません.
クローンの際に指定したスナップショットの状態がクローンされることになります.

別プール内にクローンを作成する

クローンは同じプールである必要はありません.一つだけ未使用のディスクがありますので,これでプールを作成し,ここにクローンを用意してみましょう.

まずはプールを作成します.

# zpool create pool1 da7

# zpool list
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
pool0   596G   690K   596G        -         -     0%     0%  1.00x    ONLINE  -
pool1  99.5G   128K  99.5G        -         -     0%     0%  1.00x    ONLINE  -

次にクローンを作成します.

# zfs clone pool0/data@snap-9 pool1/data-clone
cannot create 'pool1/data-clone': source and target pools differ

このようにエラーで怒られます.zfs clone コマンドは同一プールでないと利用ができません.別プールに作成する場合は zfs send と zfs recv を利用します.

# zfs send pool0/data@snap-9 | zfs recv pool1/clone

# zfs list
NAME               USED  AVAIL     REFER  MOUNTPOINT
pool0             10.0G   375G     32.0K  /pool0
pool0/data        53.3K  10.0G     34.0K  /data
pool0/data-clone     0B   375G     34.0K  /pool0/data-clone
pool0/share       30.6K   385G     30.6K  /pool0/share
pool1              154K  96.4G       24K  /pool1
pool1/clone       26.5K  96.4G     26.5K  /pool1/clone

pool1 に clone というファイルシステムが無事作成されました.この中身を見てみましょう.

# ls /pool1/clone
data1.txt       data2.txt       data3.txt

# zfs list -t snapshot pool1/clone
NAME                 USED  AVAIL     REFER  MOUNTPOINT
pool1/clone@snap-9     0B      -     26.5K  -

このようにデータはクローンされています.スナップショットも指定した物がクローン先に残っています.
これは zfs clone と zfs send / recv での動きが違うためとなります.
スナップショットは不必要であれば削除してもらっても大丈夫です.

このような使い方はバックアップ用途としても用いられると思います.が,これだけだと色々とバックアップ用途としては物足りない状態です.スナップショットを全て維持したまま,定期的にクローンを行いたい.というケースになると思いますが,これは次回実施します.

いい長さになったので今回はこれで終わります.次回はクローン (zfs send と zfs recv) について掘っていきたいと思います.

コメント

タイトルとURLをコピーしました