2012年12月23日日曜日

mikutterユーザ会共用サーバ(VPS)について

OSC 2012 Tokyo/Fallにて、お名前.com様からVPS(KVM メモリ4GBプラン)を mikutterユーザ会用として無償提供していただきました。
ありがてぇありがてぇヽ('ω')ノ三ヽ('ω')ノ

そこで、私(@Phenomer)が管理を引き受け、皆で共有できるようにしようとし た...のですが #ておくれポイント

ておくれポイント

  • FreeBSD + jailで共用サーバをユーザ毎にjailで隔離して利用できる設計に
    -> FreeBSDとKVMの相性は相変わらずイマイチらしい…
  • VIMAGEでjail毎のネットワークを分けよう
    -> EXPERIMENTAL
  • FreeBSD9-STABLEに最近入ったらしいvirtioでどうにかしよう
    -> RELEASEではない
  • とりあえずpfで。OpenBSDやNetBSDでも使ってるし
    -> 恐ろしくパフォーマンスが出ない(100KB/s程度…)
  • ならipfilterで。
    -> これまた恐ろしくパフォーマンスが出ない
  • 仕方ないのでipfwで
    -> NAT有効にした瞬間TCPが突然死する
  • ならipfw + natdで
    -> pf, ipfilter並にパフォーマンスが出ない
  • NAT無効だが環境が出来た状態でベンチマークとっていた
    -> NATかませたらパフォーマンス最悪 + 不安定に
    -> 手元の実験環境では問題なくパフォーマンスが出ていた
    -> 問題の切り分けが早期に行えなかった
  • jail内の環境構築にハマる
    -> wikiとかDBとか
  • 優先順位の見極めができていない
    -> どうでもいいところでずっとハマって悩む
  • 追い打ちをかけるFreeBSD鍵流出問題
    -> 疑いが持たれる公式パッケージを利用していたので、 全て再インストールするのが最善という悲しい結果に

...orz

結果

  • FreeBSD9やめてDebian wheezy + LXCにしました
  • 全てのユーザ毎にコンテナを作成するのはとりあえずやめました
  • ベースは1週間ぐらいでできました

ヽ(´ー`)ノ

現状

既に共有できるように設定済みですので、アカウント名と公開鍵を@Phenomer までご連絡頂ければ設定して折り返し連絡致します。 また、Arch LinuxのLiveCDベースのmikutter LiveCDの配布も行なっています。

詳細はmikutterユーザ会のWebページで ヽ('ω'ヾ(@⌒ー⌒@)ノ'ω')ノ

2012年12月3日月曜日

カーネル/VM Advent Calendar 2012 3日目: DragonflyBSDのHAMMERを使ってみよう!

1 はじめに

例年こわい方々で一杯と評判のカーネル/VM Advent Calendar、3日目は今年恐 る恐る初参加の@Phenomerです。 今回は、日本語情報がいまいち多くないDragonflyBSD(3.2.1)のHAMMERファイルシステ ムの使い方のようなものを纏めてみました。(いまいち纏まってない気もしますが…)

長くなってしまったので pdf版も上げておきます。よかったらどうぞ。

2 HAMMERとは

HAMMERは、DragonflyBSDにおけるFFSの代替のファイルシステムである。ZFSや btrfsに似ている機能を多く持っている。

HAMMERの機能として以下が挙げられる。

  • 障害からの素早い復旧
  • 複数のボリュームにまたがる大規模なファイルシステム
  • ミラーリング
  • スナップショット
  • きめ細かな履歴の保存
  • データの整合性チェック
  • データの重複排除

HAMMERの管理に関連するコマンドは以下の通りである。

  • newfs_hammer(8)
  • mount_Hammer(8)
  • hammer(8)
  • undo(1)

3 とにかく使ってみる

使ってみないことには始まらないのでDragonflyBSDをインストールする。 HAMMERの動作には最低でも50GBの空き領域が必要らしい。もし既にインストー ルしてあるDragonfly上で新たにHAMMERファイルシステムを作る場合、以下の ようにnewfsしてmountしておく。

# newfs_hammer -L MIKU /dev/ad0s1d
# mount_hammer /dev/ad0s1d /miku

残念ながらバージョン3.2.1ではvirtioやXen DOMUにはまだ対応していないた め、パフォーマンスも試す場合は物理マシンに導入したほうがよい。

(virtioは2011年のGSoCで実装する動きがあったようだが、本体にマージはさ れていない模様)

3.1 ディレクトリ構造

HAMMERファイルシステムの状態はinfoサブコマンドで参照できる。

negix# hammer info /
Volume identification
        Label               ROOT
        No. Volumes         1
        FSID                5c95cbb8-302f-11e2-8c0e-b9ac6f12aafc
        HAMMER Version      6
Big block information
        Total           69038
        Used              590 (0.85%)
        Reserved           39 (0.06%)
        Free            68409 (99.09%)
Space information
        No. Inodes     110799
        Total size       539G (579132719104 bytes)
        Used             4.6G (0.85%)
        Reserved         312M (0.06%)
        Free             534G (99.09%)
PFS information
        PFS ID  Mode    Snaps  Mounted on
             0  MASTER      9  /
             1  MASTER      9  /var
             2  MASTER      0  /tmp
             3  MASTER      9  /usr
             4  MASTER      9  /home
             5  MASTER      0  /usr/obj
             6  MASTER      9  /var/crash
             7  MASTER      0  /var/tmp

HAMMERでよく利用されるディレクトリは、/pfsと/var/hammerである。

  • /pfs - 各PFSへのシンボリックリンクを置く
  • /var/hammer - 各PFSでcronにより自動生成されるスナップショットへのシ ンボリックリンクが置かれる

ls -loすると、/pfsは以下のようになっている。

negix# ls -lo /pfs
total 0
lrwxr-xr-x  1 root  wheel  - 10 Nov 17 05:55 home -> @@-1:00004
lrwxr-xr-x  1 root  wheel  - 10 Nov 17 05:55 tmp -> @@-1:00002
lrwxr-xr-x  1 root  wheel  - 10 Nov 17 05:55 usr -> @@-1:00003
lrwxr-xr-x  1 root  wheel  - 10 Nov 17 05:55 usr.obj -> @@-1:00005
lrwxr-xr-x  1 root  wheel  - 10 Nov 17 05:55 var -> @@-1:00001
lrwxr-xr-x  1 root  wheel  - 10 Nov 17 05:55 var.crash -> @@-1:00006
lrwxr-xr-x  1 root  wheel  - 10 Nov 17 05:55 var.tmp -> @@-1:00007

mountは以下のようになっている。

negix# mount
ROOT on / (hammer, local)
devfs on /dev (devfs, local)
/dev/mfid0s1a on /boot (ufs, local)
/pfs/@@-1:00001 on /var (null, local)
/pfs/@@-1:00002 on /tmp (null, local)
/pfs/@@-1:00003 on /usr (null, local)
/pfs/@@-1:00004 on /home (null, local)
/pfs/@@-1:00005 on /usr/obj (null, local)
/pfs/@@-1:00006 on /var/crash (null, local)
/pfs/@@-1:00007 on /var/tmp (null, local)
procfs on /proc (procfs, local)

また、/etc/fstabは以下のようになっている。

# Device                Mountpoint      FStype  Options         Dump    Pass#
/dev/mfid0s1a           /boot           ufs     rw              1       1
/dev/mfid0s1b           none            swap    sw              0       0
/dev/mfid0s1d           /               hammer  rw              1       1
/pfs/var                /var            null    rw              0       0
/pfs/tmp                /tmp            null    rw              0       0
/pfs/usr                /usr            null    rw              0       0
/pfs/home               /home           null    rw              0       0
/pfs/usr.obj    /usr/obj                null    rw              0       0
/pfs/var.crash  /var/crash              null    rw              0       0
/pfs/var.tmp    /var/tmp                null    rw              0       0
proc                    /proc           procfs  rw              0       0

/となるPFSのみHAMMERとしてmountされ、それ以外はPFSに対しシンボリックリ ンクを張り、そのシンボリックリンクをnull mountしていることが分かる。

/を/pfs/rootとして置きたければ、以下のようにすればよい。

negix# ln -s @@-1:00000 /pfs/root
negix# ls /pfs/root
COPYRIGHT       compat          home            pfs             root            tmp
bin             dev             miku            proc            sbin            usr
boot            etc             mnt             rin             sys             var
negix# ls /
COPYRIGHT       compat          home            pfs             root            tmp
bin             dev             miku            proc            sbin            usr
boot            etc             mnt             rin             sys             var

3.2 マスタPFSの作成と削除

マスタPFSを作成しマウントする。そしてアンマウントして削除する。

negix# hammer pfs-master /pfs/miku
Creating PFS #8 succeeded!
/pfs/miku
    sync-beg-tid=0x0000000000000001
    sync-end-tid=0x0000000106e33fa0
    shared-uuid=d9c9419e-3489-11e2-ad25-b9ac6f12aafc
    unique-uuid=d9c941b0-3489-11e2-ad25-b9ac6f12aafc
    label=""
    prune-min=00:00:00
    operating as a MASTER
    snapshots directory defaults to /var/hammer/<pfs>
negix# mkdir /miku
negix# mount_null /pfs/miku /miku
negix# mount
ROOT on / (hammer, local)
devfs on /dev (devfs, local)
/dev/mfid0s1a on /boot (ufs, local)
/pfs/@@-1:00001 on /var (null, local)
/pfs/@@-1:00002 on /tmp (null, local)
/pfs/@@-1:00003 on /usr (null, local)
/pfs/@@-1:00004 on /home (null, local)
/pfs/@@-1:00005 on /usr/obj (null, local)
/pfs/@@-1:00006 on /var/crash (null, local)
/pfs/@@-1:00007 on /var/tmp (null, local)
procfs on /proc (procfs, local)
/pfs/@@-1:00008 on /miku (null, local)
negix# umount /miku
negix# hammer pfs-destroy /pfs/miku
You have requested that PFS#8 () be destroyed
This will irrevocably destroy all data on this PFS!!!!!
Do you really want to do this? y
This PFS is currently setup as a MASTER!
Are you absolutely sure you want to destroy it? y
Destroying PFS #8 () in  5 4 3 2 1.. starting destruction pass
pfs-destroy of PFS#8 succeeded!

4 複数ボリュームの利用

HAMMERでは、複数ボリュームによるスパニングがサポートされている。 スパニングを行いたい場合は、newfs時に複数ボリュームを指定すればよい。

negix# newfs_hammer -L TEST -f /dev/ad2s0 /dev/ad3s0
Volume 0 DEVICE /dev/ad2s0      size   1.95GB
Volume 1 DEVICE /dev/ad3s0      size   1.95GB
initialize freemap volume 0
initializing the undo map (504 MB)
initialize freemap volume 1
---------------------------------------------
2 volumes total size   3.91GB version 6
boot-area-size:        4.00MB
memory-log-size:       4.00MB
undo-buffer-size:    504.00MB
total-pre-allocated:   0.51GB
fsid:                5fe2448b-3c62-11e2-835a-535400123456
...
negix# mount_hammer /dev/ad2s0:/dev/ad3s0 /mnt
negix# df -h /mnt
Filesystem   Size   Used  Avail Capacity  Mounted on
TEST         3.4G   187M   3.2G     5%    /mnt
negix# hammer volume-list /mnt
/dev/ad2s0
/dev/ad3s0

/etc/fstabに書く際は、以下のようにコロンで区切り指定する。

/dev/ad2s0:/dev/ad3s0 /mnt hammer rw 1 2

デフォルトの場合は/dev/serno以下のノードを利用しているようなので、そち らを用いたほうがいいのかも知れない。

/dev/serno/QM00002.s0:/dev/serno/QM00004.s0 /mnt hammer rw 1 2

複数ボリュームを利用したHAMMERファイルシステムのマウント時は、全てのボ リュームを指定しないとエラーになる。

negix# mount_hammer /dev/ad2s0 /mnt
mount_hammer: mount  on /mnt: Invalid argument
negix# mount_hammer /dev/ad2s0:/dev/ad3s0 /mnt

4.1 ボリュームの取り外し

ボリュームの取り外しは、volume-delサブコマンドを用いて行う。

negix# hammer volume-del /dev/ad3s0 /mnt
negix# hammer volume-del /dev/ad2s0 /mnt
hammer volume-del ioctl: Invalid argument
negix# hammer volume-list /mnt
/dev/ad2s0

取り外した後は、再マウントしないとファイルシステムサイズには反映されな いようだ。(ディスクが無くなった分はUsedが大きくなっている)

negix# df -h /mnt
Filesystem   Size   Used  Avail Capacity  Mounted on
TEST         3.4G   2.1G   1.2G    63%    /mnt
negix# umount /mnt
negix# mount_hammer /dev/ad3s0 /mnt
negix# df -h /mnt
Filesystem   Size   Used  Avail Capacity  Mounted on
TEST         1.4G   179M   1.2G    12%    /mnt

4.2 ボリュームの追加

ボリュームの追加は、volume-addサブコマンドを用いる。 何故か複数ボリュームを指定してnewfsした時よりSizeが大幅に減ってしまう ようだ。(ディスクサイズが小さ過ぎるのが原因?)

negix# dd if=/dev/zero of=/dev/ad3s0 bs=1m count=128
128+0 records in
128+0 records out
134217728 bytes transferred in 2.548319 secs (52669121 bytes/sec)
negix# hammer volume-add /dev/ad3s0 /mnt
negix# hammer volume-list /mnt
/dev/ad2s0
/dev/ad3s0
negix# df -h /mnt
Filesystem   Size   Used  Avail Capacity  Mounted on
TEST         1.4G  -677M   2.1G   -47%    /mnt
negix# umount /mnt
negix# mount /dev/ad2s0:/dev/ad3s0 /mnt
negix# df -h /mnt
Filesystem   Size   Used  Avail Capacity  Mounted on
TEST         2.3G   227M   2.1G    10%    /mnt

ボリュームの追加前は、一旦dd等を用いて元あったHAMMERファイルシステムを 上書きしておかないとエラーになることがある。

negix# hammer volume-add /dev/ad3s0 /mnt
hammer volume-add ioctl: Inappropriate file type or format

5 ミラーリング

5.1 スレーブPFSの作成とマスタからのコピー

スレーブPFSはリードオンリーのPFSであり、マスタPFSのミラー先として用い られる。ミラーリング操作には主にmirror-copy、mirror-streamサブコマンド を用いる。この他にも、mirror-read、mirror-read-stream、mirror-write、 mirror-dumpサブコマンドがある。stream系サブコマンドは、PFSの状態に変更 があった際に自動的に送受信する用途で用いられる。

以下の例は、単純にマスタPFSからスレーブPFSへのコピーを行なうものである。

negix# hammer pfs-master /pfs/miku
Creating PFS #8 succeeded!
/pfs/miku
    sync-beg-tid=0x0000000000000001
    sync-end-tid=0x0000000106e34240
    shared-uuid=3da094bc-348b-11e2-ad25-b9ac6f12aafc
    unique-uuid=3da094cf-348b-11e2-ad25-b9ac6f12aafc
    label=""
    prune-min=00:00:00
    operating as a MASTER
    snapshots directory defaults to /var/hammer/<pfs>
negix# hammer pfs-slave /pfs/negi shared-uuid=3da094bc-348b-11e2-ad25-b9ac6f12aafc
Creating PFS #9 succeeded!
/pfs/negi
    sync-beg-tid=0x0000000000000001
    sync-end-tid=0x0000000000000001
    shared-uuid=3da094bc-348b-11e2-ad25-b9ac6f12aafc
    unique-uuid=5c88ff4f-348b-11e2-ad25-b9ac6f12aafc
    slave
    label=""
    prune-min=00:00:00
    operating as a SLAVE
    snapshots directory defaults to /var/hammer/<pfs>
negix# touch /pfs/miku/mikumiku
negix# hammer mirror-copy /pfs/miku /pfs/negi
Prescan to break up bulk transfer
Prescan 1 chunks, total 0 MBytes (520)
Mirror-read /pfs/miku succeeded
negix# ls /pfs/negi
mikumiku
negix# touch /pfs/negi/rinrin
touch: /pfs/negi/rinrin: Read-only file system
negix# touch /pfs/miku/rinrin
negix# ls /pfs/negi
mikumiku
negix# hammer mirror-copy /pfs/miku /pfs/negi
Prescan to break up bulk transfer
Prescan 1 chunks, total 0 MBytes (312)
Mirror-read /pfs/miku succeeded
negix# ls /pfs/negi
mikumiku        rinrin

スレーブPFSにコピー元のマスタと同じshared-uuidを設定していない場合、 mirror-copyを行う際に怒られるので注意。shared-uuid等を更新する場合は pfs-updateサブコマンドを用いる。

negix# hammer mirror-copy /pfs/miku /pfs/rin
mirror-write: source and target have different shared-uuid's!
negix# hammer pfs-update /pfs/rin
shared-uuid=3da094bc-348b-11e2-ad25-b9ac6f12aafc
/pfs/rin
    sync-beg-tid=0x0000000000000001
    sync-end-tid=0x0000000000000001
    shared-uuid=3da094bc-348b-11e2-ad25-b9ac6f12aafc
    unique-uuid=b11665b3-34d7-11e2-ad25-b9ac6f12aafc
    slave
    label=""
    prune-min=00:00:00
    operating as a SLAVE
    snapshots directory defaults to /var/hammer/<pfs>

5.2 スレーブからマスタへのコピー

mirror-copyの宛先にマスタPFSは指定できないため、一旦スレーブPFSとマス タPFSを切り替えてからコピーを行い、その後元に戻す。マスタPFSとスレーブ PFSの切り替えはpfs-upgradeとpfs-downgradeサブコマンドを用いる。

negix# touch /pfs/miku/lukaluka
negix# hammer mirror-copy /pfs/negi /pfs/miku
mirror-write: target must be in slave mode
negix# hammer pfs-upgrade /pfs/negi
pfs-upgrade of PFS#9 () succeeded
negix# hammer pfs-status /pfs/negi
/pfs/negi       PFS #9 {
    sync-beg-tid=0x0000000000000001
    sync-end-tid=0x0000000106e3c6f0
    shared-uuid=3da094bc-348b-11e2-ad25-b9ac6f12aafc
    unique-uuid=5c88ff4f-348b-11e2-ad25-b9ac6f12aafc
    label=""
    prune-min=00:00:00
    operating as a MASTER
    snapshots directory defaults to /var/hammer/<pfs>
}
negix# hammer pfs-downgrade /pfs/miku
pfs-downgrade of PFS#8 () succeeded
negix# hammer pfs-status /pfs/miku
/pfs/miku       PFS #8 {
    sync-beg-tid=0x0000000000000001
    sync-end-tid=0x0000000106e3c730
    shared-uuid=3da094bc-348b-11e2-ad25-b9ac6f12aafc
    unique-uuid=3da094cf-348b-11e2-ad25-b9ac6f12aafc
    slave
    label=""
    prune-min=00:00:00
    operating as a SLAVE
    snapshots directory defaults to /var/hammer/<pfs>
}
negix# hammer mirror-copy /pfs/negi /pfs/miku
Prescan to break up bulk transfer
Prescan 1 chunks, total 0 MBytes (0)
Mirror-read /pfs/negi succeeded
negix# ls /pfs/miku
mikumiku        rinrin
negix# hammer pfs-status /pfs/miku
/pfs/miku       PFS #8 {
    sync-beg-tid=0x0000000000000001
    sync-end-tid=0x0000000106e3c790
    shared-uuid=3da094bc-348b-11e2-ad25-b9ac6f12aafc
    unique-uuid=3da094cf-348b-11e2-ad25-b9ac6f12aafc
    slave
    label=""
    prune-min=00:00:00
    operating as a SLAVE
    snapshots directory defaults to /var/hammer/<pfs>
}
negix# hammer pfs-status /pfs/negi
/pfs/negi       PFS #9 {
    sync-beg-tid=0x0000000000000001
    sync-end-tid=0x0000000106e3cb70
    shared-uuid=3da094bc-348b-11e2-ad25-b9ac6f12aafc
    unique-uuid=5c88ff4f-348b-11e2-ad25-b9ac6f12aafc
    label=""
    prune-min=00:00:00
    operating as a MASTER
    snapshots directory defaults to /var/hammer/<pfs>
}
negix# hammer pfs-downgrade /pfs/negi
pfs-downgrade of PFS#9 () succeeded
negix# hammer pfs-upgrade /pfs/miku
pfs-upgrade of PFS#8 () succeeded

5.3 ssh経由でのファイルシステムのミラーリング

マスタPFSとスレーブPFSが別ホストのHAMMERファイルシステム上で運用されて いて、それを同期したい場合は、mirror-copyとmirror-streamサブコマンドが 便利である。

mirror-copyの場合はその時点でのコピーがスレーブPFSに作成される。

negix# hammer mirror-copy root@127.0.0.1:/pfs/miku \
> root@127.0.0.1:/pfs/negi
Prescan to break up bulk transfer
Prescan 1 chunks, total 0 MBytes (0)
Mirror-read /pfs/miku succeeded

mirror-streamの場合はssh接続が維持され、ファイルの変更があった際にスレー ブPFSに自動的に同期が行われる。

negix# hammer mirror-stream root@127.0.0.1:/pfs/miku \
> root@127.0.0.1:/pfs/negi
Prescan to break up bulk transfer
Prescan 1 chunks, total 0 MBytes (6616)
.....

ファイルシステムの操作にはroot権限が必要であるため、sshd_configは デフォルトでPermitRootLogin without-passwordとなっており、鍵ペアを事前 に用意しrootログインが可能になるようにしておく。

6 スナップショット

6.1 スナップショットの作成

マスタPFSのデフォルト設定では毎日スナップショットが作成される。手動で 作成する場合はsnap、snaplo、snapqサブコマンドを用いる。以前はsnapshot サブコマンドを用いていたようだが、現在は非推奨となっている。

negix# hammer snap /miku
negix# hammer snapls /miku
Snapshots on /miku     PFS #8
Transaction ID          Timestamp               Note
0x0000000106e4d170      2012-11-22 20:03:44 JST -
negix# touch /pfs/miku/neginegi
negix# hammer snap /miku "add neginegi"
negix# hammer snapls /miku
Snapshots on /miku     PFS #8
Transaction ID          Timestamp               Note
0x0000000106e4d170      2012-11-22 20:03:44 JST -
0x0000000106e552a0      2012-11-22 20:06:42 JST add neginegi

ディレクトリのスナップショットを作成したい場合はsnaploサブコマンドを用 いる。

negix# mkdir -p /miku/hachune/negi
negix# hammer snaplo /miku/hachune "hachune directory"
negix# hammer snapls /miku | tail -n 1
0x000000010b40f540      2012-11-26 18:55:04 JST hachune directory
negix# ls -l /miku/hachune/snap-20121126-1855
lrwxr-xr-x  1 root  miku  33 Nov 26 18:55 /miku/hachune/snap-20121126-1855
 -> /miku/hachune@@0x000000010b40f540

また、スナップショットへのシンボリックリンクを作成せずにスナップショッ トのみを作成する場合は、snapqサブコマンドを用いる。snapqコマンドでは、 作成したスナップショットへのパスが標準出力に出力される。

negix# hammer snapq /miku/hachune "neginegi"
/miku/hachune@@0x000000010b40f660

注意点として、null mountしていない状況で/pfs以下のシンボリックリンクに 対しsnapサブコマンドを実行すると、シンボリックリンクの対象がおかしくな る点が挙げられる。

negix# umount /miku
negix# hammer snap /pfs/miku symlinktest
negix# hammer snapls /pfs/miku | tail -n 1
0x000000010b40f8e0      2012-11-26 19:10:18 JST symlinktest
negix# ls -l /pfs/miku/snap-20121126-1910
lrwxr-xr-x  1 root  miku  22 Nov 26 19:10 /pfs/miku/snap-20121126-1910
 -> //@@0x000000010b40f8e0

snaploはディレクトリ基準でシンボリックリンクが作成されるため問題になら ず、snapqは自分でシンボリックリンクを作成するため問題にならない。

6.2 スナップショットの利用

特定のディレクトリにスナップショットを纏めておきたい時は、このsnapqを 用いればよさそう。

negix# mkdir /snaps
negix# ln -s `hammer snapq /miku/hachune "neginegi"` /snaps/miku.hachune-121126_2000
negix# ls -l /snaps/miku.hachune-121126_2000
lrwxr-xr-x  1 root  wheel  33 Nov 26 19:01
/snaps/miku.hachune-121126_2000
 -> /miku/hachune@@0x000000010b40f760
negix# ls -l /snaps/miku.hachune-121126_2000/
total 0
drwxr-xr-x  1 root  miku   0 Nov 26 18:54 negi
lrwxr-xr-x  1 root  miku  33 Nov 26 18:55 snap-20121126-1855
 -> /miku/hachune@@0x000000010b40f540

作成したスナップショットから過去の状態を参照する場合は、TransactionID を指定し各コマンドを実行する。スナップショットのTransactionIDはsnapls サブコマンドで確認できる。

negix# hammer snapls /miku
Snapshots on /miku      PFS #8
Transaction ID          Timestamp               Note
0x0000000106e4d170      2012-11-22 20:03:44 JST -
0x0000000106e552a0      2012-11-22 20:06:42 JST add neginegi
0x0000000106e55440      2012-11-22 20:11:48 JST -
0x0000000106e555a0      2012-11-22 20:15:04 JST -
0x0000000106e55b60      2012-11-22 20:23:28 JST -
0x0000000106e55da0      2012-11-22 20:38:37 JST -
0x0000000106e55ea0      2012-11-22 20:40:04 JST -
0x0000000106e56000      2012-11-22 20:47:21 JST -
0x0000000106e560c0      2012-11-22 20:48:36 JST -
0x0000000106e56140      2012-11-22 20:48:49 JST -
0x0000000106e56260      2012-11-22 20:49:56 JST -
negix# ls /miku/@@0x0000000106e55da0
mikumiku                snap-20121122-2003      snap-20121122-2023
neginegi                snap-20121122-2006
rinrin                  snap-20121122-2015

ディレクトリのスナップショットに対しシンボリックリンクを貼ることで、リー ドオンリーの状態でそのディレクトリ以下の過去の状態を参照できる。

negix# ln -s /miku/@@0x0000000106e55da0 /tmp/miku
negix# ls /tmp/miku 
mikumiku                rinrin                  snap-20121122-2006    snap-20121122-2023
neginegi                snap-20121122-2003      snap-20121122-2015

スナップショット間のdiffも同様に指定することで閲覧できる。

negix# diff /home/miku/.history@@0x0000000106892480 \
> /home/miku/.history@@0x0000000106cf8170
56a57,88
> #+1353130082
> ls
> #+1353130085
> top
> #+1353130086
> ls
> #+1353130094
> tmux
> #+1353130103
> ls /usr/pkg/bin/zsh
> #+1353130111
> chsh -s /usr/pkg/bin/zsh
> #+1353130119

historyサブコマンドにより、ファイル毎のトランザクション履歴を確認する こともできる。この履歴はスナップショットに関わらず作成されるため、作業 中にうっかりファイルを壊してしまった場合などに有用である。

negix# hammer history ~/.history
/root/.history  0000000102c5113d clean {
    0000000102c61ca0 16-Nov-2012 21:53:05
    0000000106895e40 17-Nov-2012 14:27:32
    00000001068960a0 17-Nov-2012 14:29:55
    0000000106cf6fb0 21-Nov-2012 21:50:28
    0000000106e3cdf0 22-Nov-2012 19:52:30
    0000000106e66d20 22-Nov-2012 21:33:22
}

残念ながら、ファイルを一旦rmしてしまうとhistoryでは追えなくなってしま うようだ。(過去のTransactionIDが分かれば一応参照はできる)

negix% rm miku.txt
negix% hammer history miku.txt
miku.txt        No such file or directory
negix% cat miku.txt@@0x000000010b4100a0
miku
mikumiku
mikumikumiku
negix% touch miku.txt
negix% hammer history miku.txt
miku.txt        000000010a01792d dirty {
}

また、historyを元に行う操作はundoコマンドを用いて行うこともできる。 "undo -a"で全履歴の表示、"undo -t TransactionID -u"でTransactionID時点 にロールバックした.undoファイルの作成が行える。

negix% echo luka > luka.txt
negix% echo lukaluka >> luka.txt
negix% echo lukalukaluka >> luka.txt
negix% undo -a luka.txt
luka.txt: ITERATE ENTIRE HISTORY

>>> luka.txt 0001 0x000000010b432a20 03-Dec-2012 03:00:56

luka
lukaluka
lukalukaluka

>>> luka.txt 0002 0x000000010b432ee0 03-Dec-2012 03:01:50

luka

>>> luka.txt 0003 0x000000010b432fa0 03-Dec-2012 03:02:02

luka
lukaluka
lukalukaluka
negix% undo -t 0x000000010b432ee0 -u luka.txt
negix% cat luka.txt.undo.0000
luka

スナップショット以外にもトランザクション履歴を追える機能などは、Linux のnilfs2の機能と似ているかもしれない。

6.3 マスタのスナップショットからスレーブへのコピー

マスタPFSをスナップショットの時点に戻せないのかと思い、mirror-copyサブ コマンドを実行する際にスナップショットのTransactionIDを追加してみたが、 何も指定しなかった時と同様に現時点の状態でコピーされた。

negix# hammer mirror-copy /pfs/miku/@@0x0000000106e55440 /pfs/rin                 
Prescan to break up bulk transfer
Prescan 1 chunks, total 0 MBytes (7160)
Mirror-read /pfs/miku/@@0x0000000106e55440 succeeded
negix# ls /pfs/rin
mikumiku                rinrin                  snap-20121122-2006
snap-20121122-2023      snap-20121122-2040
neginegi                snap-20121122-2003      snap-20121122-2015
snap-20121122-2038
negix# ls /pfs/miku/@@0x0000000106e55440
mikumiku                neginegi                rinrin
snap-20121122-2003      snap-20121122-2006

もしスナップショットの時点のディレクトリ以下のファイルを復旧したい場合 は、cpdupコマンドを用いる。

negix# cpdup /pfs/miku/@@0x0000000106e552a0 /rin/
negix# ls /rin
mikumiku                neginegi                rinrin
snap-20121122-2003

cpdupではPFSの状態(snapshot等)はコピーされない点については注意が必要か も知れない。(過去のスナップショット時点へのロールバックはできない?)

ある時点のスナップショット「以降」の変更をスナップショットごとコピーし たい(古いスナップショットはコピーしない)場合は、mirror-readサブコマン ドとmirror-writeサブコマンドを用い、またmirror-readサブコマンド実行時 にコピーしておきたい時点のTransactionIDを指定する。

negix# hammer mirror-read /pfs/miku 0x0000000106e55440 | 
> hammer mirror-write /pfs/rin
Prescan to break up bulk transfer
Prescan 1 chunks, total 156 MBytes (164220376)
Mirror-read /pfs/miku succeeded
Source can update synctid to 0x0000000106eb6670

7 掃除

7.1 Dedup

重複の排除は、hammer version5でサポートされたdedupサブコマンドを用いて 実行できる。以下の例では、0埋めした1GBのファイルを/home以下に保存し、 dedupを実行している。dedup-simulateサブコマンドでは、dedupを実行した際 どの程度まで圧縮可能かを確認できる。

negix# df -h
Filesystem        Size   Used  Avail Capacity  Mounted on
ROOT              539G   5.2G   534G     1%    /
devfs             1.0K   1.0K     0B   100%    /dev
/dev/mfid0s1a     756M   213M   483M    31%    /boot
/pfs/@@-1:00001   539G   5.2G   534G     1%    /var
/pfs/@@-1:00003   539G   5.2G   534G     1%    /usr
/pfs/@@-1:00004   539G   5.2G   534G     1%    /home
/pfs/@@-1:00005   539G   5.2G   534G     1%    /usr/obj
/pfs/@@-1:00006   539G   5.2G   534G     1%    /var/crash
/pfs/@@-1:00007   539G   5.2G   534G     1%    /var/tmp
procfs            4.0K   4.0K     0B   100%    /proc
/pfs/@@-1:00008   539G   5.2G   534G     1%    /miku
negix# hammer dedup-simulate /pfs/home
Dedup-simulate running
Dedup-simulate /pfs/home succeeded
Simulated dedup ratio = 4198.66
negix# hammer dedup /pfs/home                                         
Dedup running
Dedup /pfs/home succeeded
Dedup ratio = 301.21
     1024 MB referenced
     3481 KB allocated
     3232 KB skipped
           0 CRC collisions
           0 SHA collisions
           0 bigblock underflows
       16342 new dedup records
    1070350336 new dedup bytes
negix# hammer dedup-simulate /pfs/home
Dedup-simulate running
Dedup-simulate /pfs/home succeeded
Simulated dedup ratio = 4198.66
negix# df -h
Filesystem        Size   Used  Avail Capacity  Mounted on
ROOT              539G   4.3G   535G     1%    /
devfs             1.0K   1.0K     0B   100%    /dev
/dev/mfid0s1a     756M   213M   483M    31%    /boot
/pfs/@@-1:00001   539G   4.3G   535G     1%    /var
/pfs/@@-1:00003   539G   4.3G   535G     1%    /usr
/pfs/@@-1:00004   539G   4.3G   535G     1%    /home
/pfs/@@-1:00005   539G   4.3G   535G     1%    /usr/obj
/pfs/@@-1:00006   539G   4.3G   535G     1%    /var/crash
/pfs/@@-1:00007   539G   4.3G   535G     1%    /var/tmp
procfs            4.0K   4.0K     0B   100%    /proc
/pfs/@@-1:00008   539G   4.3G   535G     1%    /miku

7.2 Prune

スナップショット間のトランザクションの履歴を掃除する場合はpruneサブコ マンドを実行する。pfs-updateでprune-minを変更することでpruneされる間隔 を指定することもできるようだ。

negix# hammer prune /pfs/home
TID 0000000106ed17c0 - 0000000106faffc0
TID 0000000106e682a0 - 0000000106ed17c0
TID 0000000106cf8370 - 0000000106e682a0
TID 0000000106cc1af0 - 0000000106cf8370
TID 0000000106cbc7f0 - 0000000106cc1af0
TID 0000000106cb74f0 - 0000000106cbc7f0
TID 0000000106c7a0a0 - 0000000106cb74f0
TID 00000001068929c0 - 0000000106c7a0a0
TID 0000000000000001 - 00000001068929c0
Prune /pfs/home/: 9 snapshots
Prune /pfs/home/: objspace 8000000000000000:0000 7fffffffffffffff:ffff pfs_id 4
Prune /pfs/home/: prune_min is 0d/00:00:00
Prune /pfs/home/ succeeded
Pruned 0/18874 records (0 directory entries) and 0 bytes

7.3 Rebalance

rebalanceサブコマンドでは、B-Treeのバランスを再調整することができる。 rebalanceは、PFS毎に行う必要がある。

negix# hammer rebalance /pfs/usr
rebalance start 8000000000000000:0000
Rebalance /pfs/usr succeeded
Rebalance:
    11011 btree nodes scanned
    4 btree nodes deleted
    0 collision retries
    5122 btree nodes rebalanced

7.4 Reblock

reblockサブコマンドでは、いわゆるデフラグを行うことができる。rebalance と同様に、 PFS毎に行う必要がある。

negix# hammer reblock /pfs/miku
reblock start 8000000000000000:0000 free level 0
Reblock /pfs/miku succeeded
Reblocked:
    51/51 btree nodes
    2371/2371 data elements
    145759632/145759632 data bytes

7.5 Cleanup

ここまでのお掃除サブコマンドをいちいち全て行うのは面倒であるので、これ らの作業とrecopy、そして古いスナップショットの整理を纏めて行うためのコ マンドとしてcleanupが用意されている。

negix# hammer cleanup /pfs/miku
cleanup /pfs/miku            - HAMMER UPGRADE: Creating snapshots
        Creating snapshots in /var/hammer/pfs/miku
 handle PFS #8 using /var/hammer/pfs/miku
           snapshots - run
               prune - run
           rebalance - run..
             reblock - run....
              recopy - run....

7.6 Periodic

cleanupを手作業で行うのも面倒であるので、それをcronで実行するシステム がデフォルトで有効になっている。実行間隔の設定は、configサブコマンドで 参照でき、viconfigサブコマンドで変更できる。

negix# hammer config /pfs/miku
snapshots 1d 60d
prune     1d 5m
rebalance 1d 5m
#dedup     1d 5m
reblock   1d 5m
recopy    30d 10m

この例の場合、以下のように設定されている。

  • スナップショットを1日毎に作成し、作成してから60日経過したスナップ ショットは削除する。
  • 1日毎に5分間だけprune、rebalance、reblockを行う。
  • dedupは行わない。(コメントアウトされている)
  • recopyを30日毎、10分間だけ行う。

8 復旧

8.1 破損したファイルシステムからのファイルのリカバリ

recoverサブコマンドを用いることで、破損したHAMMERファイルシステムが存 在するブロックデバイスをスキャンし、ターゲットディレクトリに保存するこ とができる。このコマンドは、お亡くなりになったファイルシステムからデー タを復旧する「最後の防衛線」である。

negix# hammer -f /dev/mfid0s1d recover /home/miku/test
Running raw scan of HAMMER image, recovering to /home/miku/test
mkinode (dir) /home/miku/test/PFS00000
dir  0000000000000001:00000 entry 000000010000046d "sbin"
dir  0000000000000001:00000 entry 000000010000048b "dev"
dir  0000000000000001:00000 entry 000000010000049a "mnt"
dir  0000000000000001:00000 entry 00000001000004b7 "root"
dir  0000000000000001:00000 entry 00000001000004bb "usr"
dir  0000000000000001:00000 entry 00000001000004f0 "sys"
dir  0000000000000001:00000 entry 0000000100000551 "bin"
dir  0000000000000001:00000 entry 000000010000055e "proc"
dir  0000000000000001:00000 entry 0000000100000567 "tmp"
dir  0000000000000001:00000 entry 0000000100000575 "etc"
dir  0000000000000001:00000 entry 0000000100000637 "boot"
dir  0000000000000001:00000 entry 0000000100000688 "pfs"
dir  0000000000000001:00000 entry 000000010000076e "var"
dir  0000000000000001:00000 entry 000000010000078e "home"
dir  0000000000000001:00000 entry 00000001000007e2 "COPYRIGHT"
mkinode (dir) /home/miku/test/PFS00000/sbin
...

8.2 /pfs以下を誤って削除してしまった場合

/pfs以下にあるものはただのシンボリックリンクなので、hammer infoでPFSID を確認してシンボリックリンクを作り直す。以下は、PFSIDが8の/pfs/mikuを 削除してしまった場合の復旧例である。

negix# /pfs/miku
negix# hammer info 
Volume identification
        Label               ROOT
        No. Volumes         1
        FSID                5c95cbb8-302f-11e2-8c0e-b9ac6f12aafc
        HAMMER Version      6
Big block information
        Total           69038
        Used              603 (0.87%)
        Reserved           39 (0.06%)
        Free            68396 (99.07%)
Space information
        No. Inodes     110786
        Total size       539G (579132719104 bytes)
        Used             4.7G (0.87%)
        Reserved         312M (0.06%)
        Free             534G (99.07%)
PFS information
        PFS ID  Mode    Snaps  Mounted on
             0  MASTER      8  /
             1  MASTER      8  /var
             2  MASTER      0  /tmp
             3  MASTER      8  /usr
             4  MASTER      8  /home
             5  MASTER      0  /usr/obj
             6  MASTER      8  /var/crash
             7  MASTER      0  /var/tmp
             8  MASTER      -  not mounted
             9  SLAVE       -  not mounted
            10  SLAVE       -  not mounted
negix# ln -s @@-1:00008 /pfs/miku
negix# ls /pfs/miku 
hoge                    pf.conf            snap-20121122-2006      snap-20121122-2038      test2
mikumiku                rinrin             snap-20121122-2015      snap-20121122-2040
neginegi                snap-20121122-2003 snap-20121122-2023      test

9 その他

9.1 TransactionIDの手動作成

スナップショットを作成せずにTransactionIDのみを手動生成する場合、 synctidサブコマンドを用いる。

negix# hammer synctid /pfs/miku
0x0000000106feb9d0

9.2 B-Treeの統計情報の参照

B-Treeの統計情報を参照する場合はbstatsサブコマンドを用いる。

negix# hammer bstats
  elements iterations    lookups    inserts    deletes     splits
         0          0          0          0          0          0
      1464       7100         59          0          0          0
       999       3873         41          0          0          0
       990        116         80          7          0          0
         0          0          0          0          0          0
       350         59         29          0          0          0
     26282       8211       1333          0          0          0

9.3 I/Oの統計情報の参照

I/Oの統計情報を参照する場合はiostatsサブコマンドを用いる。PFS毎のI/Oの 統計情報は見れない(?)模様。

negix# hammer iostats
  file-rd   file-wr  dev-read dev-write inode_ops ino_flsh cmmit     undo
        0         0         0         0         0        0     0        0
        0         0         0         0         0        0     0        0
   190952         0         0         0       148        0     0        0
        0         0         0         0         0        0     0        0
        0         0         0    458752         0       23     2    27800
        0         0         0         0         0        0     0        0
        0         0         0         0         0        0     0        0
   133619         0         0         0       293        0     0        0

9.4 ファイルのHash値を参照する

ファイル毎のHAMMERディレクトリハッシュを参照する場合は、namekey1、 namekey2、namekey32サブコマンドを利用する。

negix# hammer namekey1 /
0x79d3d2d400000000
negix# hammer namekey2 /
0x3c00000f79d3d2d4
negix# hammer namekey32 /
0x79d3d2d4

9.5 blockmap

ブロックデバイス上のブロックマップをdumpする。

negix# hammer -f /dev/mfid0s1d blockmap | head -n 10
zone btree            next 2000000000000000 alloc 2fffffffffffffff
  layer1 4000000000000000 @2000000000800000 blocks-free 68410
        4000000000000000 zone=4 app=8388608 free=0
        4000000000800000 zone=4 app=8388608 free=0
        4000000001000000 zone=3 app=8388608 free=0
        4000000001800000 zone=3 app=8388608 free=0
        4000000002000000 zone=3 app=8388608 free=0
        4000000002800000 zone=3 app=8388608 free=0
        4000000003000000 zone=3 app=8388608 free=0
        4000000003800000 zone=3 app=8388608 free=0

9.6 checkmap

ブロックデバイス上のブロックマップの割り当て情報をチェックする。

negix# hammer -f /dev/mfid0s1d checkmap
Volume header   records=0 next_tid=0000000107046570
                bufoffset=0000000044040000
Collecting allocation info from B-Tree: done

9.7 show

ブロックデバイス上のB-Treeをダンプする。エラーが見つかった場合は"B"と 表示されるらしい。

negix# hammer -f /dev/mfid0s1d show| head -n 25
Volume header   records=0 next_tid=0000000107046570
                bufoffset=0000000044040000
                zone 0  next_offset=0000000000000000
                zone 1  next_offset=0000000000000000
                zone 2  next_offset=0000000000000000
                zone 3  next_offset=30000000165cb908
                zone 4  next_offset=2000000000000000
                zone 5  next_offset=0000000000000000
                zone 6  next_offset=0000000000000000
                zone 7  next_offset=0000000000000000
                zone 8  next_offset=80000002d4b96000
                zone 9  next_offset=9000000293be13f0
                zone 10 next_offset=a000000345890000
                zone 11 next_offset=b00000033cbdae70
                zone 12 next_offset=c000000000000000
                zone 13 next_offset=d000000000000000
                zone 14 next_offset=e000000000000000
                zone 15 next_offset=f000000000000000
show 80000002cf6db000 depth 0
     NODE 80000002cf6db000 cnt=05 p=0000000000000000 type=I depth=0 
       mirror 0000000107046550 fill=z8:1438=100% {
G------ ELM  0 I obj=8000000000000000 key=8000000000000000 lo=00000000 rt=00 ot=00
               d tids 0000000000000001:0000000000000001 suboff=800000029d8f8000 mirror 0000000107046550
G------ ELM  1 I obj=00000001042a3d5d key=348524d485d90000 lo=00030001 rt=11 ot=02
                 tids 00000001068912e0:0000000000000000 suboff=80000002cf711000 mirror 0000000106f5da70
G------ ELM  2 I obj=00000001044742d2 key=0000000000001fb0 lo=00030002 rt=10 ot=02

9.8 show-undo

ブロックデバイス上のUndo/Redoマップをダンプする。

negix# hammer -f /dev/mfid0s1d show-undo | head -n 10
Volume header UNDO 30000000165cb908-30000000165cb908/3000000023000000
Undo map is 560MB
3000000000000000 UNDO(0168) seq=0037fafd dataoff=200000025412bec0 bytes=320
3000000000000168 UNDO(0098) seq=0037fafe dataoff=200000025412c000 bytes=112
3000000000000200 UNDO(0200) seq=0037faff dataoff=200000025412c070 bytes=472
3000000000000400 UNDO(0200) seq=0037fb00 dataoff=200000025412c248 bytes=472
3000000000000600 UNDO(0200) seq=0037fb01 dataoff=200000025412c420 bytes=472
3000000000000800 UNDO(0200) seq=0037fb02 dataoff=200000025412c5f8 bytes=472
3000000000000a00 UNDO(0200) seq=0037fb03 dataoff=200000025412c7d0 bytes=472
3000000000000c00 UNDO(0200) seq=0037fb04 dataoff=200000025412c9a8 bytes=472

10 最後に

自宅用に静かな実験鯖が欲しいですヾ(@⌒ー⌒@)ノ

ておくれの理に導かれたmikutterユーザ会VPSは今週中に直します。

ヽ('ω')ノ三ヽ('ω')ノもうしわけねぇもうしわけねぇ

11 参考