Nexenta (OpenSolaris) で ZFS を (2)

Nexenta (OpenSolaris) で ZFS を (1) - daily dayflower の続きです。

zpool を作る

zpool(ZFS storage pool)とは LVM でいう VG のようなもの*1です。

c0d0s3 に領域を確保したので,ここを datapool という名前の zpool にしてみましょう。

dayflower@myhost:~$ sudo zpool create datapool c0d0s3
invalid vdev specification
use '-f' to override the following errors:
/dev/dsk/c0d0s3 overlaps with /dev/dsk/c0d0s2

おっと,怒られてしまいました。

昨日のべたように,Partition#2 はディスク全体を示すスライスであるという慣例があります。このスライスと今回使用するスライスが重なっている(あたりまえ)ので怒られたのです。

ディスク全体や単一ファイルを zpool とする場合は怒られないのですが,ディスクのスライスを zpool にするとこのように怒られてしまいます。重複先が s2 であれば問題ないので,指示されたように -f オプションをつけて前に進みます。

dayflower@myhost:~$ sudo zpool create -f datapool c0d0s3

dayflower@myhost:~$ zpool list

NAME       SIZE   USED  AVAIL    CAP  HEALTH  ALTROOT
datapool  1016M   139K  1016M     0%  ONLINE  -
syspool   3.97G   806M  3.18G    19%  ONLINE  -

無事作成できました。syspool というのは,あとで出てきますが,インストール時に作成した Root fs 用の zpool です。

作成はできましたが,zpool create コマンドは,デフォルトでは同じ名称のディレクトリに自動的にマウントされてしまいます。確認してみます。

dayflower@myhost:~$ df -h
Filesystem             size   used  avail capacity  Mounted on
syspool/rootfs-nmu-000
                       3.9G   796M   3.1G    20%    /
/devices                 0K     0K     0K     0%    /devices

...... snip snip snip ......

datapool               984M    18K   984M     1%    /datapool

このように,/datapool というディレクトリにマウントされています。

全体を使うのならこのままでも構わないのですが,あくまで Storage pool として使いたいのでマウントされるのはちょっと気持ち悪い気もします。一度削除して,オプションを指定してやり直します。

dayflower@myhost:~$ sudo zpool destroy datapool

dayflower@myhost:~$ sudo zpool create -m none -f datapool c0d0s3

-m でマウントポイントを指定できますが,ここに none を指定するとマウントされません。先ほどもそうでしたが,ZFS 関連のコマンドは,成功するとなにもメッセージを表示しません。

zpool status コマンドで,各 zpool の詳細を見ることができます。

dayflower@myhost:~$ zpool status
  pool: datapool
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        datapool    ONLINE       0     0     0
          c0d0s3    ONLINE       0     0     0

errors: No known data errors

  pool: syspool
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        syspool     ONLINE       0     0     0
          c0d0s0    ONLINE       0     0     0

errors: No known data errors

datapool として /dev/dsk/c0d0s3アサインされていること,syspool として /dev/dsk/c0d0s0アサインされていること,両者ともに ONLINE 状態であることがわかります。

zpool から zfs を切り出す

zpool から新しい zfs を切り出して使用しようと思います。ターゲット先は /data とします。

dayflower@myhost:~$ sudo zfs create -o mountpoint=/data datapool/main

dayflower@myhost:~$ ls /
bin    data     etc     initrd  media  opt       root  system  var
boot   dev      export  kernel  mnt    platform  sbin  tmp
cdrom  devices  home    lib     net    proc      srv   usr

mountpoint プロパティとして /data を指定して zfs create を行いました。あらかじめ /data というディレクトリを切っておかなかったことに注目!ZFS では zpool や zfs を作った場合,自動的にマウントポイントを作成してくれます((Physical に作成するわけではない(……と,思う)ので zfs destroy 等した場合,/data ディレクトリは消失します))。楽ですね。

ここで datapool/main という名前を指定してますが,main の部分はなんでもよいです。既存の zfs に対してサブディレクトリ的に指定すると,それが独立した zfs として使用できるようになります。だから実は,さらに datapool/main/foo などのように指定すると,新しい zfs を切り出すこともできます。

さて zfs list コマンドで現在の zfs の状況を確認してみます。

dayflower@myhost:~$ zfs list

NAME                             USED  AVAIL  REFER  MOUNTPOINT
datapool                         133K   984M     1K  none
datapool/main                     18K   984M    18K  /data
syspool                          806M  3.12G    23K  none
syspool/rootfs-nmu-000           806M  3.12G   796M  legacy
syspool/rootfs-nmu-000@initial  9.89M      -   794M  -

zfs として 5 つのボリューム名が認識されていること,datapool/main という名の zfs/data にマウントされています。

先ほど述べたように,syspool の zpool のサブボリュームとして rootfs-nmu-000 が切り出されており,これは実は Root(/)にマウントされています。syspool/rootfs-nmu-000 の MOUNTPOINT が legacy となっているのは,ZFS 組み込みのマウントシステムではなく /etc/vfstab 経由でマウントされているから,だと思います。

@initial というのはサブボリューム,ではなくて,後述する snapshot を意味します。

snapshot を作成する

いよいよ snapshot を作成します。zfs snapshot コマンドで,ターゲットとなる zfs 名に @ と snapshot 名を指定します。

dayflower@myhost:~$ sudo zfs snapshot datapool/main@step1

dayflower@myhost:~$ zfs list

NAME                             USED  AVAIL  REFER  MOUNTPOINT
datapool                         133K   984M     1K  none
datapool/main                     18K   984M    18K  /data
datapool/main@step1                 0      -    18K  -
syspool                          806M  3.12G    23K  none
syspool/rootfs-nmu-000           806M  3.12G   796M  legacy
syspool/rootfs-nmu-000@initial  9.89M      -   794M  -

step1 という snapshot ができあがりました。

ファイルシステムをいじりながら snapshot を作成してみます。

dayflower@myhost:~$ sudo touch /data/a

dayflower@myhost:~$ ls /data
a

dayflower@myhost:~$ sudo zfs snapshot datapool/main@step2


dayflower@myhost:~$ sudo touch /data/b

dayflower@myhost:~$ sudo rm /data/a

dayflower@myhost:~$ ls /data
b

dayflower@myhost:~$ sudo zfs snapshot datapool/main@step3


dayflower@myhost:~$ zfs list

NAME                             USED  AVAIL  REFER  MOUNTPOINT
datapool                         194K   984M     1K  none
datapool/main                     50K   984M    18K  /data
datapool/main@step1               16K      -    18K  -
datapool/main@step2               16K      -    18K  -
datapool/main@step3                 0      -    18K  -
syspool                          806M  3.12G    23K  none
syspool/rootfs-nmu-000           806M  3.12G   796M  legacy
syspool/rootfs-nmu-000@initial  9.89M      -   794M  -

datapool/main に3つの snapshot ができました。

snapshot にアクセスする

本来 snapshot は,当該 snapshot のバックアップをとったり,rollback したりするためのものですが,snapshot 時点のファイル(システム)を除くことができます。

マウントされているディレクトリの .zfs/snapshot/ フォルダ以下にあるはずなのですが……

dayflower@myhost:~$ ls -a /data
.  ..  b

ありませんね。

マニュアルから引用します。

Snapshots

A snapshot is a read-only copy of a file system or volume. Snapshots can be created extremely quickly, and initially consume no additional space within the pool. As data within the active dataset changes, the snapshot consumes more data than would otherwise be shared with the active dataset.

Snapshots can have arbitrary names. Snapshots of volumes can be cloned or rolled back, but cannot be accessed independently.

File system snapshots can be accessed under the ".zfs/snapshot" directory in the root of the file system. Snapshots are automatically mounted on demand and may be unmounted at regular intervals. The visibility of the ".zfs" directory can be controlled by the "snapdir" property.

デフォルトでは on demand mount されるみたいです。

なので,ないはずの /data/.zfs ディレクトリを覗いてみます。

dayflower@myhost:~$ ls -a /data/.zfs
.  ..  snapshot

おお,snapshot フォルダがみつかりました。

dayflower@myhost:~$ ls -a /data/.zfs/snapshot
.  ..  step1  step2  step3

各 snapshot 名に対応したディレクトリがあることがわかります。

実際に ls してみると

dayflower@myhost:~$ ls -a /data/.zfs/snapshot/step1
.  ..

dayflower@myhost:~$ ls -a /data/.zfs/snapshot/step2
.  ..  a

dayflower@myhost:~$ ls -a /data/.zfs/snapshot/step3
.  ..  b

各 snapshot 時点でのファイルツリーが見受けられます。

rollback する

過去の snapshot に rollback してみます。

dayflower@myhost:~$ sudo zfs rollback datapool/main@step1

cannot rollback to 'datapool/main@step1': more recent snapshots exist
use '-r' to force deletion of the following snapshots:
datapool/main@step2
datapool/main@step3

もっと新しい snapshot があるけどほんとに大丈夫なの?と聞かれました。

指定されているように -r オプションをつけて rollback します。

dayflower@myhost:~$ sudo zfs rollback -r datapool/main@step1

dayflower@myhost:~$ ls -a /data
.  ..

step1 時点の snapshot に戻りました。

注意する必要があるのは,rollback というのは snapshot 時点から現在までの変更を破棄してしまうので,一度 rollback すると未来には戻せないところです。つまり RDBMS の rollback と同じです。SCM の過去リビジョンと同じように考えていると痛い目にあいます。なので,現在の snapshot を確認してみると,

dayflower@myhost:~$ zfs list

NAME                             USED  AVAIL  REFER  MOUNTPOINT
datapool                         134K   984M     1K  none
datapool/main                     18K   984M    18K  /data
datapool/main@step1                 0      -    18K  -
syspool                          806M  3.12G    23K  none
syspool/rootfs-nmu-000           806M  3.12G   796M  legacy
syspool/rootfs-nmu-000@initial  9.89M      -   794M  -

step2, step3 の snapshot は消失しています(これは zfs rollback -r の際に警告されていましたけどね)。


ちなみに snapshot 自体を消すには zfs destroy を使います。

dayflower@myhost:~$ sudo zfs destroy datapool/main@step1

dayflower@myhost:~$ zfs list

NAME                             USED  AVAIL  REFER  MOUNTPOINT
datapool                         134K   984M     1K  none
datapool/main                     18K   984M    18K  /data
syspool                          806M  3.12G    23K  none
syspool/rootfs-nmu-000           806M  3.12G   796M  legacy
syspool/rootfs-nmu-000@initial  9.89M      -   794M  -

zfs destroy は snapshot だけでなく zfs 自体についても適用可能(かつ確認なし)なので操作するときは注意深く行ってください。

感想

現在わたしの環境では,SCM で管理していないプロジェクトについては pdumpfs(と pdumpfs-rsync)で履歴管理を行っています。このようなケースや AppleTime Machine のような機能をファイルシステムレベルで(安定して・高速に)実現できるのが ZFS のうまみかな,と思います。また,今回は触れませんでしたが,容量が足りなくなってきたら zpool に新しいディスクを追加したり,mirroring を指定したり,というのが online でできるのがとても便利そうです。(Open)SolarisiSCSI ターゲットになれますし zfsiSCSI 用ボリュームとすることもできるので*2,ネットワークストレージにはもってこいな技術です。

ただまぁ ZFS はまだ歴史が浅いのでちょっと不安。

参考資料

*1:歯切れが悪いですが,後述のように zpool 全体を zfs としてそのまま利用できるからです。自動的に LVM でいう LV としての機能も兼ね備えているんですね。

*2:一瞬でのバックアップを実現するSolaris ZFS (3/4):OpenSolarisで始めるブログサーバ構築(4) - @IT