一度使い出したらその便利さに抜け出せなくZFS。ZFSの提供するさまざまな機能を使わなくても基本的な使い方だけでも便利なものですが、
- Do zdb for ZFS analysis
ZFSは壊れにくいファイルシステムだと言われてはいますが、
なんらかの原因で壊れることもあります。スクラブで直らない場合にはzdb(1M)で直すのが順当な修正方法となります。ただし、 zdb(1M)はそもそもZFSの開発者が利用するために提供されているものなので、 ドキュメントもありませんし、 動作の詳細を知りたい場合にはソースコードを読む必要があります。 ここではとくにzdb(1M)の使い方の中でも利用率が高いだろうと思われる方法を紹介しておきます。ただし、
将来のバージョンで同じ処理がサポートされ続けるとは限らず、 また、 問題が発生しないとも限りません。使用する場合には開発者向けのコマンドであることを理解したうえで使用してください。 まず、
問題が発生したプールはexportします。importした状態のまま処理を行うと処理がカーネルを経由するためにパニックしやすくなるからです。LiveCDから起動して処理を実施してもかまいません。最近のFreeBSDインストーラはZFSも扱うことができます。 「zdb -e -d プール」 にてまずはプール内部の構成を確認します。 # zdb -e -d zpool Dataset mos [META], ID 0, cr_
txg 4, 116K, 46 objects Dataset zpool/ ports [ZPL], ID 37, cr_ txg 8, 1. 09G, 332771 objects Dataset zpool [ZPL], ID 21, cr_ txg 1, 31. 0K, 7 objects # 「-e」 はexportされたプールであることを指定しています。importした状態であれば次のように 「-e」 をはずせば同じことが実施されます。ただし、 importした状態での作業はお薦めできません。 # zdb -d zpool Dataset mos [META], ID 0, cr_
txg 4, 116K, 46 objects Dataset zpool/ ports [ZPL], ID 37, cr_ txg 8, 1. 09G, 332771 objects Dataset zpool [ZPL], ID 21, cr_ txg 1, 31. 0K, 7 objects # 「zdb -l デバイスファイル」 を指定すれば直接プールの情報をチェックできます。プール名がわからない場合などはこちらを使ってプール名のチェックを実施します。 # zdb -l /dev/
ada1 -------------------------------------------- LABEL 0 -------------------------------------------- version: 28 name: 'zpool' state: 0 txg: 175 pool_ guid: 6769210400753061927 hostid: 3333601617 hostname: 'freebsd. ongs. co. jp' top_ guid: 8290673747710924871 guid: 8290673747710924871 vdev_ children: 1 vdev_ tree: type: 'disk' id: 0 guid: 8290673747710924871 path: '/dev/ ada1' phys_ path: '/dev/ ada1' whole_ disk: 1 metaslab_ array: 30 metaslab_ shift: 29 ashift: 9 asize: 85894627328 is_ log: 0 create_ txg: 4 -------------------------------------------- LABEL 1 -------------------------------------------- version: 28 name: 'zpool' state: 0 txg: 175 pool_ guid: 6769210400753061927 hostid: 3333601617 hostname: 'freebsd. ongs. co. jp' top_ guid: 8290673747710924871 guid: 8290673747710924871 vdev_ children: 1 vdev_ tree: type: 'disk' id: 0 guid: 8290673747710924871 path: '/dev/ ada1' phys_ path: '/dev/ ada1' whole_ disk: 1 metaslab_ array: 30 metaslab_ shift: 29 ashift: 9 asize: 85894627328 is_ log: 0 create_ txg: 4 -------------------------------------------- LABEL 2 -------------------------------------------- version: 28 name: 'zpool' state: 0 txg: 175 pool_ guid: 6769210400753061927 hostid: 3333601617 hostname: 'freebsd. ongs. co. jp' top_ guid: 8290673747710924871 guid: 8290673747710924871 vdev_ children: 1 vdev_ tree: type: 'disk' id: 0 guid: 8290673747710924871 path: '/dev/ ada1' phys_ path: '/dev/ ada1' whole_ disk: 1 metaslab_ array: 30 metaslab_ shift: 29 ashift: 9 asize: 85894627328 is_ log: 0 create_ txg: 4 -------------------------------------------- LABEL 3 -------------------------------------------- version: 28 name: 'zpool' state: 0 txg: 175 pool_ guid: 6769210400753061927 hostid: 3333601617 hostname: 'freebsd. ongs. co. jp' top_ guid: 8290673747710924871 guid: 8290673747710924871 vdev_ children: 1 vdev_ tree: type: 'disk' id: 0 guid: 8290673747710924871 path: '/dev/ ada1' phys_ path: '/dev/ ada1' whole_ disk: 1 metaslab_ array: 30 metaslab_ shift: 29 ashift: 9 asize: 85894627328 is_ log: 0 create_ txg: 4 # 対象となるプールがパニックを誘発する状態にあるかどうかは次のように
「zdb -e プール」 で調査することができます。すべてのチェックが実施されるのできわめて大量のログが出力されます。 # zdb -e zpool Configuration for import: vdev_
children: 1 version: 28 pool_ guid: 6769210400753061927 name: 'zpool' state: 1 hostid: 3333601617 hostname: 'freebsd. ongs. co. jp' vdev_ tree: type: 'root' id: 0 guid: 6769210400753061927 children[0]: type: 'disk' id: 0 guid: 8290673747710924871 phys_ path: '/dev/ ada1' whole_ disk: 1 metaslab_ array: 30 metaslab_ shift: 29 ashift: 9 asize: 85894627328 is_ log: 0 create_ txg: 4 path: '/dev/ ada1' MOS Configuration: version: 28 name: 'zpool' state: 1 txg: 229 pool_ guid: 6769210400753061927 hostid: 3333601617 hostname: 'freebsd. ongs. co. jp' vdev_ children: 1 vdev_ tree: type: 'root' id: 0 guid: 6769210400753061927 children[0]: type: 'disk' id: 0 guid: 8290673747710924871 path: '/dev/ ada1' phys_ path: '/dev/ ada1' whole_ disk: 1 metaslab_ array: 30 metaslab_ shift: 29 ashift: 9 asize: 85894627328 is_ log: 0 create_ txg: 4 Uberblock: magic = 0000000000bab10c version = 28 txg = 229 guid_ sum = 15059884148463986798 timestamp = 1316524683 UTC = Tue Sep 20 22:18:03 2011 All DDTs are empty Metaslabs: vdev 0 metaslabs 159 offset spacemap free --------------- ------------------- --------------- ------------- metaslab 0 offset 0 spacemap 33 free 23. 0M segments 190 maxsize 733K freepct 4% metaslab 1 offset 20000000 spacemap 42 free 19. 7M segments 201 maxsize 8. 95M freepct 3% metaslab 2 offset 40000000 spacemap 44 free 447M segments 44 maxsize 441M freepct 87% metaslab 3 offset 60000000 spacemap 46 free 512M segments 5 maxsize 512M freepct 99% metaslab 4 offset 80000000 spacemap 0 free 512M segments 1 maxsize 512M freepct 100% metaslab 5 offset a0000000 spacemap 0 free 512M segments 1 maxsize 512M freepct 100% metaslab 6 offset c0000000 spacemap 0 free 512M segments 1 maxsize 512M freepct 100% metaslab 7 offset e0000000 spacemap 0 free 512M segments 1 maxsize 512M freepct 100% metaslab 8 offset 100000000 spacemap 0 free 512M segments 1 maxsize 512M freepct 100% metaslab 9 offset 120000000 spacemap 0 free 512M segments 1 maxsize 512M freepct 100% metaslab 10 offset 140000000 spacemap 0 free 512M .... これまでの操作が実施できない場合、
次のように/dev/ dskというリンクファイルを作成してから作業してみてください。FreeBSDでは/devに仮想デバイスが展開されますが、 Solarisでは/dev/ dskに仮想デバイスが展開されているため、 zdbがそちらをチェックしに行って失敗している可能性があります。最新版では修正されていると思いますが、 再び同じ状況に戻るとも限らないのでこの方法は覚えておくと便利です。 cd /dev; ln -s . dsk
プールの状況を調べる基本的なzdb(1M)の使い方はこんなところです。これ以上深入りする必要があるようだと、
なにかと失敗する可能性が出てくるのでこのあたりで止めておいたほうが良いでしょう。