ラベル zfs の投稿を表示しています。 すべての投稿を表示
ラベル zfs の投稿を表示しています。 すべての投稿を表示

2013年7月18日木曜日

FreeBSD/amd64 9系でzfs(+nfs) を使いメモリ不足に陥る

FreeBSD 9.0-RELEASE(amd64)にzfsでファイルシステムを構築し、職場のPCのサーバとして使っていたのですが、先日サーバがメモリ不足の症状でダウンしまして、なんだこりゃ?と。USBキーボードの抜き差しすら対応出来なくなるという。おそろしや…

どうも目一杯vfs.zfs.arc_maxまでカーネルメモリを使い込んだようで、他のサービスにおけるメモリ使用とぶつかってしまっていたようです。さらに、職場のサーバはLinux機をクライアントに持っていて、ユーザの /home/ 領域をnfsでサービスしています。9.0-RELEASEのzfsにはnfsを利用するとメモリリークが起きる、というバグがあり、9.1-RELEASEでは修正されています。(事実誤認してたかも知れないので削除。)というわけで、
・OSをFreeBSD 9.1-RELEASEへ更新 (freebsd-updateでさっと更新。楽でした。)
・zfsのメモリ利用量を見直す
という対応を取りました。

昨今のLinux機のデスクトップ環境(特にブラウザ類)はホームディレクトリへのアクセスが頻繁に起こりますので、zfsのarc利用頻度が高く、nfsもメモリを使います。あとWeeklyのcronが走った後もarcにメモリが大量に使われた形跡がありました。locatedbの作成かなにかでしょうか。

FreeBSD 9.1-RELEASE (amd64) ではメモリのチューニングがよく行われていて、8GBのメモリを搭載したPCでは目一杯メモリをzfs、特にarcで使うような設定が施されているように見えます。例えばこんな感じ。(sysctl -a で確認)

        kern.maxusers:                          384
        vm.kmem_size:                           8216244224
        vfs.zfs.arc_min:                        892812800
        vfs.zfs.arc_max:                        7142502400

ARC以外1GBもあれば足りるでしょ、みたいな実にギリギリを攻めるパラメータ。
しかしそれでは怖い。かなり。というわけで、/boot/loader.conf に

vfs.zfs.arc_max="5120M"

の記述を追加し、少しメモリに余裕が出来るようにしてみました。本体8GBですからファイルシステム以外の部分に3GB、と考えれば大丈夫、のはず。Xも使ってないし。


        kern.maxusers:                          384
        vm.kmem_size:                           8216244224
        vfs.zfs.arc_min:                        671088640
        vfs.zfs.arc_max:                        5368709120

数日稼働させて、zfs-stats -M の実行結果はこんな数値。
(zfs-stats は ports にあります。)

System Memory:

        0.26%   20.27   MiB Active,     1.52%   118.75  MiB Inact
        71.22%  5.45    GiB Wired,      0.00%   0 Cache
        27.00%  2.07    GiB Free,       0.01%   736.00  KiB Gap

        Real Installed:                         8.00    GiB
        Real Available:                 98.93%  7.91    GiB
        Real Managed:                   96.68%  7.65    GiB

        Logical Total:                          8.00    GiB
        Logical Used:                   72.73%  5.82    GiB
        Logical Free:                   27.27%  2.18    GiB

Kernel Memory:                                  3.49    GiB
        Data:                           99.41%  3.47    GiB
        Text:                           0.59%   21.19   MiB

Kernel Memory Map:                              7.57    GiB
        Size:                           40.64%  3.08    GiB
        Free:                           59.36%  4.49    GiB

ARC関係の数値だと

ARC Summary: (HEALTHY)
ARC Misc:
ARC Size:                               76.20%  3.81    GiB

となっているので、Logical Used が 5.82GiBに対して ARC Sizeが 3.81GiB ということは、ARC以外で約2GB使っている、ということですから、やはり /boot/loader.conf で vfs.zfs.arc_max を絞る設定はしておいたほうがよいみたいですね。しばらくこれでいってみたいと思います。

2012年2月3日金曜日

zfs雑感

zfsの基本はハードディスクを論理的に利用する、すなわち物理ディスクとして利用する際に様々な工夫をこらして利用する、Linuxで言うところのLVM(論理ボリュームマネジメント)です。 ハードディスクとファイルシステムとの間には一段クッションが挟まり、例えば柔軟なハードディスク容量の割り当て、冗長性の確保、ドライブエラーに対処しやすい、などといった様々な恩恵が得られるわけです。

しかし、ファイルシステムの障害そのものがなくなるというわけではありません。zfsで何かしらの障害が発生した際は、使い慣れた ufs や FAT といった従来のファイルシステムで起こっていたものとは異なる種類の障害が発生する可能性が高いわけです。対処法はもはや物理的直感に頼れるものではなく、zfsに対する高度な知識と経験を必要とすることでしょう。(ここでいう物理的直感に頼る対処法とは、例えば破損セクタのみを無理矢理読み飛ばす dd_rescue のような対処法のことを指します。)

そのため、zfsにしたからといってバックアップを怠ってはならないのです。 幸いなことに、zfsのバックアップ/リストア自体は比較的容易に出来るようになっているので、うまく活用しましょう。もちろんファイルシステムに依存しないバックアップ方法や運用の経験も十分活かせます。

 ……というのが、まあこのへんとかこのへんとかの話を読んで思ったことでした。そんな感想文。

2011年2月2日水曜日

FreeBSD 8.2-RC3に更新した(実機編)

使用中のPC(core i7-860/ P55 chipset)を8.0-RELEASE-p4(amd64)から 8.0-RELEASE-p6に更新したところ、

kernel: interrupt storm detected on "irq19:"; throttling interrupt source

を頻発するようになったのが、今回8.2-RC3に更新しようと思ったきっかけです。
vmstat -i で見たところ、原因は

interrupt total rate
irq19: atapci0+++ 29162 7

上記の例は8.2-RC3の場合なのですが、8.0-RELEASE-p6のときは、ここの割り込み数がトータルで10桁以上になっており、rateも7桁以上の数字になっていました。(うろ覚え)

調べた結果、Intel 5系のチップセットに対応するのは 8.2-RELEASEからのようで。じゃあ今まで何故平気だったのかというと、どういう訳かICH8として認識してたようです。

8.0-RELEASE-p4 までは ICH8 として認識していたのですが、8.0-RELEASE-p6 にした時点でatapciの認識がSATAじゃないコントローラとして認識したようで、そこで扱いが狂ってinterrupt stormが起こっていると判断した、のかな?(8.0-RELEASE-p6にした後、interrupt stormが頻発するので BIOSで AHCI を切ったかも知れません。)

データ領域にzfsを使っているのですが、8.0から8.2に上がるとzfsのバージョンが上がるため、作業として問題ないのかどうか確かめたのが、先日書いたブログの内容でした。

実機での移行は問題なく終了しました。先日書いたブログでは、8.2-RC3更新後に py-zfs を入れる、と書きましたが、更新し忘れたまま zfs upgrade しても問題なく動いていました。何だったんだろう…

2011年2月1日火曜日

FreeBSD 8.0→8.2に伴いzfsを更新してみる

FreeBSD 8.0で構築したzfsを、FreeBSD 8.2にupgradeした際に正しく更新することは出来るのか? という話です。zfsbootとか複雑なことをしていない限り、あっさり更新出来るはず。ちょっとvmware上で試してみました。

FreeBSD 8.0-RELEASE (i386) の環境構築


まず8.0-RELEASEを入れ、カーネルをリコンパイルします。GENERICに書くので /usr/src を make update したときは注意すること。

options KVA_PAGES=512

次にzfsを有効にする。(vmware)

vm.kmem_size="768M"
vm.kmem_size_max="768M"
vfs.zfs.arc_max="80M"

そして

# bsdlabel /dev/ad0s1
# /dev/ad0s1:
8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 1048576 0 4.2BSD 0 0 0
b: 6223488 1048576 swap
c: 41942817 0 unused 0 0 # "raw" part, don't edit
d: 5208064 7272064 4.2BSD 0 0 0
e: 1048576 12480128 4.2BSD 0 0 0
f: 8388608 13528704 4.2BSD 0 0 0
g: 20025505 21917312 4.2BSD 0 0 0
# bsdlabel /dev/ad1
bsdlabel: /dev/ad1: no valid label found

ad0s1g と ad1 がzfspool候補。

# zpool create zp0 ad0s1g
# zpool create zp1 ad1

# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
zp0 9.50G 72K 9.50G 0% ONLINE -
zp1 7.94G 72K 7.94G 0% ONLINE -

こうなる。

# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/ad0s1a 507630 208682 258338 45% /
devfs 1 1 0 100% /dev
/dev/ad0s1e 507630 12 467008 0% /tmp
/dev/ad0s1f 4058062 2226374 1507044 60% /usr
/dev/ad0s1d 2521070 37264 2282122 2% /var
zp0 9805696 0 9805696 0% /zp0
zp1 8192896 0 8192896 0% /zp1

/usr/src, /usr/portsをzfsに置いておく。

# cd /usr
# tar -cpf - src | ( cd /zp0/ ; tar -xf - )
# tar -cpf - ports | ( cd /zp1/ ; tar -xf - )
# mv ports ports.orig
# ln -s /zp0/src src
# ln -s /zp1/ports ports

これで試行準備完了。

ここからFreeBSD 8.2

RELENG_8_2 に更新。/usr/src/Makefileの教えに従い滞りなく終了。sysutils/py-zfs は8.2に上げてから導入or更新。

Before:(8.0-RELEASE-p6)

%zpool status -v
pool: zp0
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
zp0 ONLINE 0 0 0
ad0s1g ONLINE 0 0 0

errors: No known data errors

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

NAME STATE READ WRITE CKSUM
zp1 ONLINE 0 0 0
ad1 ONLINE 0 0 0

errors: No known data errors

%zpool upgrade
This system is currently running ZFS pool version 13.

All pools are formatted using this version.

%zfs upgrade
This system is currently running ZFS filesystem version 3.

All filesystems are formatted with the current version.

After:(8.2-RC3)

# zpool status -v
pool: zp0
state: ONLINE
status: The pool is formatted using an older on-disk format. The pool can
still be used, but some features are unavailable.
action: Upgrade the pool using 'zpool upgrade'. Once this is done, the
pool will no longer be accessible on older software versions.
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
zp0 ONLINE 0 0 0
ad0s1g ONLINE 0 0 0

errors: No known data errors

pool: zp1
state: ONLINE
status: The pool is formatted using an older on-disk format. The pool can
still be used, but some features are unavailable.
action: Upgrade the pool using 'zpool upgrade'. Once this is done, the
pool will no longer be accessible on older software versions.
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
zp1 ONLINE 0 0 0
ad1 ONLINE 0 0 0

errors: No known data errors

# zpool upgrade
This system is currently running ZFS pool version 15.

The following pools are out of date, and can be upgraded. After being
upgraded, these pools will no longer be accessible by older software versions.

VER POOL
--- ------------
13 zp0
13 zp1

Use 'zpool upgrade -v' for a list of available versions and their associated
features.

# zfs upgrade
This system is currently running ZFS filesystem version 4.

The following filesystems are out of date, and can be upgraded. After being
upgraded, these filesystems (and any 'zfs send' streams generated from
subsequent snapshots) will no longer be accessible by older software versions.


VER FILESYSTEM
--- ------------
3 zp0
3 zp1

ということでupgrade推奨されるので…(例によってバックアップはしっかりとりましょう)

# zfs upgrade -a
zp0: can not be upgraded; the pool version needs to first be upgraded
to version 15

zp1: can not be upgraded; the pool version needs to first be upgraded
to version 15

0 filesystems upgraded
これはzpoolのupgradeをする前に zfs をupgradeしようとしたのでエラーになった。順番が重要です。

# zpool upgrade -a
This system is currently running ZFS pool version 15.

Successfully upgraded 'zp0'

Successfully upgraded 'zp1'
数秒で終わる。

# zfs upgrade -a
2 filesystems upgraded
十数秒で終わる。

# zpool upgrade
This system is currently running ZFS pool version 15.

All pools are formatted using this version.

# zfs upgrade
This system is currently running ZFS filesystem version 4.

All filesystems are formatted with the current version.

# zpool status
pool: zp0
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
zp0 ONLINE 0 0 0
ad0s1g ONLINE 0 0 0

errors: No known data errors

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

NAME STATE READ WRITE CKSUM
zp1 ONLINE 0 0 0
ad1 ONLINE 0 0 0

errors: No known data errors
かくて滞りなくOSの更新もzfsの更新も終了。


注意事項、というか、正直よく分かっていない事項として、8.0→8.2になった際に物理ドライブの位置が変更されてしまった場合に(ad0がad4になったり、別のデバイス名になったら)どうなるのだろう?という点。zfsとして読み込めていれば問題はないのでしょうか?

2009年10月9日金曜日

page fault while in kernel mode ??


ハードディスクの全セクタ検査をやっている間、VMware Workstation で実験環境を作ってみたのですが、gmirrorしたディスクの上でzfsを動かすと、何故かリブートの度に gm0 のrebuildが走ってしまい、起動時にzfsプロセスがpage fault を起こす、という、GEOMなのかzfsなのかVMware Workstationなのか原因がはっきりしないトラブルに見舞われました。とりあえず記録。あやしいことをやっていることは確かなのです(^^;

環境:VMware Workstation 6.5.3 build-185404
ホストOS: Microsoft Windows Server 'Longhorn' Business 6.0.6002, Service Pack 2 (32bit)
ゲストOS: FreeBSD/amd64 8.0-RC1 (64bit)

やったこと:
仮想メモリ1536MBの仮想PCを作成。それに30GBの仮想ドライブを2台(da0, da1)作成し接続。
うち1台(da0)にFreeBSD/amd64 を "User" インストールする。
ただし、OSのインストールには10GB程度しか使わず、残り20GBは空けておく。
OSインストール終了後、FreeBSD ハンドブックを参考にしてgmirrorでミラーリングする。
(zfsを使うよう /boot/loader.conf や /etc/rc.conf を書き換えておく。)
ミラーリング出来たら、空き容量のある mirror/gm0s1 に見えるので、
# gpart add -b xxxxx -s xxxxxx -t freebsd-zfs
で空いてる部分を mirror/gm0s1g として作成する。
この mirror/gm0s1g を使って、zfsの領域を作成、適宜マウントする。
# zpool create tank mirror/gm0s1g
# zfs create tank/home
# zfs create tank/export
# zfs create tank/ulocal
# mkdir /home /export
# zfs set mountpoint=/home tank/home
# zfs set mountpoint=/export tank/export
# zfs set mountpoint=/usr/local tank/ulocal
# zfs set mountpoint=none tank

このあたりはいろいろなサイトに載っている普通の手順かと思います。
が、どういう訳かここで再起動すると、上記スクリーンショットのようなFatal errorが起きます。原因はよく分かりません。さて、実機でも同様なことが起こるのでしょうか……?

2009年10月6日火曜日

続:FreeBSDのdump -Lってzfsに対応してますか?

昨晩書いた話の続きなんですが、一晩よく寝て改めて確認してみたら、いくつか勘違いしていることに気づきました。話を整理しましょう。

まず、dumpは伝統的に ファイルシステム単位でバックアップするものであり、tarやrsyncなどのようなファイル単位でのバックアップツールではないこと。
よって、ファイルシステムが異なる場合は、それに対応するダンプ用のコマンドを用いるのが適切であること。例えばSolarisであればufsdump/ufsrestoreという名前になっている。

zfs send は snapshotをダンプするコマンドであること。よってdump -Lとは扱いが異なる(バックアップ前に手動でsnapshotを作る作業が必要?)。dumpと同様に標準出力やファイルへの書き込みが可能なので、バックアップ先のファイルシステムは問わない。ただしFreeBSD 8.0RC1のマニュアルには
The format of the stream is evolving. No backwards compatibility is
guaranteed. You may not be able to receive your streams on future
versions of ZFS.
などと書いてあるのでOSのメジャーアップデートの際は気をつけましょう。

実際のところ、FreeBSDのdumpはzfsに対応していません。FreeBSD/amd64 8.0-RC1で実行しようとすると。

# df /home
Filesystem 1K-blocks Used Avail Capacity Mounted on
zfstank/home 850525952 58368 850467584 0% /home
basil# dump -0aLu -f /backup/home-amd64-091006.zfsdump /home
DUMP: WARNING: Cannot use -L on an unmounted filesystem.
dump: /home: unknown file system
という結果となりました。そりゃ、そうか。素直に zfs sendを使いましょう。

何故dumpにこだわるのかというと、FreeBSDにはchflags (Linuxで言うとchattr)で調整できる拡張ファイル属性があり、これがバックアップ作業に影響することがあるため。例えばrsyncなどでうまく処理出来なかったりします。

というわけで、先日のエントリで無知を晒したわけですが、いつものことなので気にしない分からなくなったらとりあえず寝てから整理する、というのは重要ですね、ということで。

debian/ubuntuでは dump パッケージを導入します。それでも ext2/3 までの対応で、snapshotを取ってダンプする機能があるようには見えませんでした。FreeBSD dump でufs2をダンプしたものを Linux restore でext2/3に移動出来るかは分かりません。他のファイルシステムについては、ext4についてはdump/restore可xfsはxfsdump/xfsrestoreがある、btrfsはよく分かりません。開発中?

2009年10月5日月曜日

FreeBSD の dump -L ってzfsに対応してますか?

職場PCを新調する機会があり、HDDを増設し、FreeBSD 8.0-RC1 を導入しました。

もののついでに、ちょっとバックアップ体制について見直したのですが、最近は dump(8) に -L オプションなるものがついていて、これを実行すると、丁寧にも一端スナップショットを取得してからdumpする、という振る舞いを見せます。つまりシングルユーザモードに落ちなくても稼働中にdumpが出来るというわけです。これはかなり便利。

ところが、このスナップショットを取得する部分が、ファイルシステムが巨大(100GB以上?)になると途端に処理が重くなります。どうも、ufs2のスナップショットを取得する /sbin/mksnap_ffs に原因があるようです。

http://www.freebsd.org/cgi/query-pr.cgi?pr=111782
600GBくらいのファイルシステムを-Lでダンプしようとするとおかしくなる?(6.x系列)
mksnap_ffs time
シリンダグループの数が多すぎると遅くなる、らしい。

そこで、最近流行の zfs に乗り換えれば、もしかしたらスナップショットの取得も早くなり、dumpも気軽に出来るのかな、と思ったのですが、ここでふと疑問。dumpオプションの-Lは zfs に対応しているのでしょうか?

(バックアップ元のファイルシステムが zfs であるときに、バックアップ先のHDDもzfsにして、zfs send/receive を使うのが筋としては適切、というのは分かるのですが、バックアップ先のHDDがzfsではない、とか、実は未だにテープを愛用している、とか、dump系のシェルスクリプトを書き直すのがちょっとなあ……等といった状況を想定しています。)

dump(8) は -L オプションが実行されると、スナップショットを取得するコマンドを用いるのですが、コードを見ると……
http://www.freebsd.org/cgi/cvsweb.cgi/src/sbin/dump/main.c?rev=1.67.2.1;content-type=text%2Fplain

char snapname[BUFSIZ], snapcmd[BUFSIZ];

snprintf(snapname, sizeof snapname, "%s/.snap", mntpt);
if ((stat(snapname, &sb) < 0) || !S_ISDIR(sb.st_mode)) {
msg("WARNING: %s %s\n",
"-L requested but snapshot location",
snapname);
msg(" %s: %s\n",
"is not a directory",
"dump downgraded, -L ignored");
snapdump = 0;
} else {
snprintf(snapname, sizeof snapname,
"%s/.snap/dump_snapshot", mntpt);
snprintf(snapcmd, sizeof snapcmd, "%s %s %s",
_PATH_MKSNAP_FFS, mntpt, snapname);
unlink(snapname);
if (system(snapcmd) != 0)
errx(X_STARTUP, "Cannot create %s: %s\n",
snapname, strerror(errno));
if ((diskfd = open(snapname, O_RDONLY)) < 0) {
unlink(snapname);
errx(X_STARTUP, "Cannot open %s: %s\n",
snapname, strerror(errno));
}
unlink(snapname);
if (fstat(diskfd, &sb) != 0)
err(X_STARTUP, "%s: stat", snapname);
spcl.c_date = _time_to_time64(sb.st_mtime);
}

ここでスナップショットを取得するコマンドが _PATH_MKSNAP_FFSとして定義されているようです。これ、どこにあるのかというと…
http://www.freebsd.org/cgi/cvsweb.cgi/src/include/paths.h?rev=1.28.2.1;content-type=text%2Fplain

#define _PATH_MKSNAP_FFS "/sbin/mksnap_ffs"

これ。で、このソースを見ると、
http://www.freebsd.org/cgi/cvsweb.cgi/src/sbin/mksnap_ffs/mksnap_ffs.c?rev=1.10.2.1;content-type=text%2Fplain

読み切れませんでしたorz

とりあえず、zfsだからといって zfs snapshot を使っているようにも見えず、正直よく分からないのですが、さて、zfsのファイルシステムを dump -L でダンプすることは出来るのでしょうか? それとも、zfsだと実はわざわざスナップショットを取る必要がない、とか?

追記:後日談を書きました。