start

ZFSのギャングブロックについて理解を深める

ZFS(のZIL)の断片化では「ギャングブロック」がキーのようなので、理解を深めるべくzio.cのギャングブロックの説明を翻訳してみた。

ギャングブロックは、DMUのような1つの大きなブロックを模倣した、小さなブロックの集合体です。 プールが殆ど満杯だったり深刻な断片化が原因で、zio_dva_allocate()が要求サイズのブロックを見つけられなかった時、それは小さなフラグメントからブロックを構築するためにzio_write_gang_block()を呼びます。

ギャングブロックは、1つのギャングヘッダ(zio_gbh_phys_t)と最大3つ(SPA_GBH_NBLKPTRS)のギャングメンバーから構成されます。 ギャングヘッダは丁度インダイレクトブロックのようなもので、ブロックポインタの配列です。 ギャングヘッダは1セクタしか消費しません。それ故に、断片化にかかわらず確保可能です。 ギャングヘッダのbp(訳注:blkptr_t)はギャングメンバーを指し、それがデータを保持します。

ギャングブロックは、SHA256チェックサムの一意性を保証するための検証値にbpのvdev, offset, txgを用いた自己チェックサムを行います。 重要なのは、そのギャングブロックのbpのblk_cksumはデータのチェックサムであり、ギャングヘッダのものではないという事です。 これは、データブロックシグネチャ(重複排除に必要)の物理的な格納状態に依存しない事を保証します。

ギャングブロックは入れ子になり得ます。つまりギャングメンバーはそれ自体がギャングブロックかもしれません。 それ故に、全てのギャングブロックは、根および全ての内部のノードがギャングヘッダーである木です。また、葉はユーザーデータを含む普通のブロックです。 ギャングツリーの根はギャングリーダーと呼ばれます。

ギャングブロックへのあらゆる操作(読み込み、書き込み、解放、要求)遂行のため、zio_gang_assemble()はまず、ギャングリーダーとその下の全てのギャングヘッダーを再帰的に読むことにより、オリジナルの論理I/Oのio_gang_treeフィールドにギャングツリーを組み立てます(データリーフを除く)。 これは、全てのギャングヘッダとその全てのギャングブロックを構成するためのbpを含む、コア内ツリー(in-core tree)を生成します。

今しがた組み立てられたギャングツリーで、zio_gang_issue()はそのギャングツリーを走査し、各bpのコールバックを呼びます。 ギャングブロックの解放のために、zio_gang_issue()zio_free_gang()zio_free()のちょっとしたラッパーを各bpに対して呼びます。 zio_claim_gang()は、同様にzio_claim()のラッパーを提供します。 zio_read_gang()は、ギャングヘッダの読み込みを除くzio_read()のラッパーです。なぜならば、それらはio_gang_treeで既に持っているからです。 zio_rewrite_gang()は、上述したようなギャングヘッダのblk_cksumを更新するために、データのzio_rewriteを、あるいはギャングヘッダについては、ギャングヘッダのzio_reqrite()とデータのzio_checksum_compute()を実行します。

two-phase assemble/issueモデルは部分的失敗の問題─もし、ギャングブロックの一部を読んでいた時に、別の部分へのギャングヘッダが読めなかったらどうなるでしょうか?─を解決します。 解放や確保、書き込みの実際の作業の開始前に、まずギャングツリー全体を組み立てる事は、全ての必須のギャングヘッダーI/Oの成功を保証します。 いったんギャングツリーが組み立てられれば、解放と確保はメモリに対する操作となり、失敗する事はありません。

ギャング書き込み失敗イベントでは、全ての確保済み領域を直ちに解放(すなわち空き領域マップの後ろに追加)するために、zio_dva_unallocate()がギャングツリーを走査します。 これは、あてにならないデバイス(flaky device)が原因のサスペンド・レジュームが繰り返されている間に、ENOSPCを受け取らない事を保証します。

ギャングの再書き込みはsync-to-convergenceの間にだけ発生します。 ギャングツリーを組み立てられなかった場合、そのブロックが変更される事はありません。従って、その解放は安全に保留する事が出来ます。(知っての通りブロックはまだ無傷です。) ギャングツリーを組み立てる事が出来た場合、たとえ再書き込みのうちの幾つかが失敗しても、zio_dva_unallocate()は構成要素の各bpを解放し、次の同期パスで新しいブロックを確保する事が出来ます。

全てのケースにおいて、ギャングツリーは部分的失敗からの完全な復旧に対応します。

ZFS Fragmentation issue – examining the ZILの翻訳

前回に引き続き、ZFSのフラグメンテーションを調査してて有益な記事を見つけた。これまた筆者のThomas Gouverneur氏に翻訳の許可を貰ったので翻訳してみる。

翻訳には細心の注意を払っていますが、誤訳や変な箇所があればご指摘下さい。例によって、本記事を利用した事で生じた如何なる結果について、翻訳者は責を負いかねます。また本翻訳について原著者への問い合わせはご遠慮願います。

Original Post: ZFS Fragmentation issue – examining the ZIL
Author: Thomas Gouverneur
Date: June 9, 2011, 2:32 pm

このところ私は、重いデータベースで使われている幾つかのZFSプールのトラブルシューティングに取り組んでいました。 顧客から報告された問題は、クラスタの再起動を最後に性能が著しく低下したというものでした。 この問題は遂に解決し、そして原因はZFSの断片化問題だと特定するに至りました。

まず最初に、ドリルダウン方式でその性能問題を調査しました。TeamQuestを用いて現在と前週の違いを視覚化し私たちが見たのは、データベースのDBFがあるプールのI/Oの、文字通りの爆発でした。 ある時は、その病んだプールの異なるvdevを均等に横切る50K IOPS以上の書き込みがありました。

プールは実際に次のように構成されていました:

# zpool status i-ora-pro06-dat1-pl
  pool: i-ora-pro06-dat1-pl
 state: ONLINE
 scrub: none requested
config:
 
        NAME                                       STATE     READ WRITE CKSUM
        i-ora-pro06-dat1-pl                        ONLINE       0     0     0
          mirror-0                                 ONLINE       0     0     0
            c6t60060E800571FC00000071FC000020C3d0  ONLINE       0     0     0
            c6t60060E800570FB00000070FB000020C3d0  ONLINE       0     0     0
          mirror-1                                 ONLINE       0     0     0
            c6t60060E800571FC00000071FC000020C4d0  ONLINE       0     0     0
            c6t60060E800570FB00000070FB000020C4d0  ONLINE       0     0     0
          mirror-2                                 ONLINE       0     0     0
            c6t60060E800571FC00000071FC000020C5d0  ONLINE       0     0     0
            c6t60060E800570FB00000070FB000020C5d0  ONLINE       0     0     0
          mirror-3                                 ONLINE       0     0     0
            c6t60060E800571FC00000071FC000020C6d0  ONLINE       0     0     0
            c6t60060E800570FB00000070FB000020C6d0  ONLINE       0     0     0
 
errors: No known data errors

背後にあるSANディスクは大量のI/Oを捌くことが可能で、またSANはあらゆる不具合について点検がなされましたが異常はなく、この問題はLUNにおける大量のI/O処理負荷でした。

続いて、私たちの考えの裏付けを取るためにzpool iostat -v i-ora-pro06-dat1-pl 2を実行し続けました。 これにより、vdevに対する激しい書き込みを確認しました。

再びTeamQuestで、私たちはディスクに行われた書き込み操作の種類を見る事ができ、実際に見たところ、それらは非常に小さなブロックの書き込みでした。

その後、私たちはオラクル-SUNサポートのサポートケースを開き、私たちが向き合う問題が露見している幾つかのGUDSトレースをアップロードしました。 本問題の検出・修正方法はもちろん、完全な説明を以下に述べます。

基本的に、この問題は“ZFS断片化”と呼ばれています。 ZFSが話題の利用可能なドキュメントで断片化の内部について言及した物はありませんが、これはどうして起るのでしょうか? 無論、ZFS断片化の検出や解決のためのツールはありません。

断片化が如何にして、利用が適さないまでにプールを退化させ得るかを少しばかり理解するために、私はZIL (ZFS Intent Log)とZILのプール内での扱われ方について、今から話します。 また、プールを使うOracleデータベースがどのように振る舞うかについての、いくつかの基礎的な情報から始めます。

問題のあるZFSプールで実行中のデータベースは、私の顧客企業内で最も重要なDBのひとつでした。 それは“リアルタイム”データベースと見なされますが、それはつまり大量のINSERTが毎秒行われる事を意味します。 このデータベースはまた、その会社のビジネスの上で非常にクリティカルな事柄をモニターしていました。 それらの関係は、フロントエンドでのINSERT指示とデータベースへの実際の反映の間で、1時間の遅れがあるというものでした。

Oracle DBの階層では、データベース書き込みスレッド群が、ディスクの大変なサービス時間が原因で書き込み操作を抱えている事実を除き、特に何も見られませんでした。

Oracle DB自身は、ある意味ではあらゆる書き込み操作後にディスクを使用しますが、データベースがfsync()を呼ぶと、OSによる書き込み操作のディスクへの直接コミットが生じます。 これは全てのOracleデータベースについて言えます。

既にご存知の方もいるでしょうが、ZFSはUFSファイルシステムの古いジャーナルをZIL (ZFS Intent Log)と呼ばれるものに置き換えました。 要するに、プールに対する全ての操作は、プール操作のリクエスタの完了を保証するためにZILトランザクションを引き起こします。 従って、書き込み操作の場合、実行予定の全ての操作を含む1つのZILブロックが作成され、このZILトランザクションが完了するとすぐに、リクエスタはリクエストの成功を告げられます。たとえ実際にはデータのプールへの書き込みが未完了だったとしてもです。 ZILトランザクションは、処理が適切に行われたであろう事を保証するでしょう。

ZILトランザクションのコミット後、関連するZILブロックは解放され、このZILトランザクションによってディスクに確保された一時領域は放出されます。 ZILレベルで思いがけず生じる他のメカニズムもありますが、それらは本記事の後でカバーします。

ZFSファイルシステムのアンマウント毎にZILはチェックされ、ディスクへコミットされ、そして完全に解放されます。 マウント毎にZFSはZILエントリーの存在を確認しますが、エントリーがあれば、それはファイルシステムが正しくアンマウントされなかった事を示し、ファイルシステムがマウントされる前に見つかったZILエントリーはコミットされます。

リクエスタがfsync()を発行すると、ZILトランザクションはワークメモリの代わりに強制的にディスクに書き込みされるという事も知っておくと良いでしょう。

データベースが大量のINSERTを行い続けると、大量のZILトランザクションの作成、プールのディスクへの一時的な書き込み、そして削除に直結します。 とても小さいブロックの大量確保と解放がZILトランザクションのために発生し、それがディスクに連続して書かれるべき本来のデータに対して何の役にも立たないであろうことは、容易に理解出来ます。 それでも、これは問題ではありません。

それらの実行時間の果てに、ZILのトランザクションエントリーに連続ブロックを確保出来なくなる時が訪れます。 そうして、ギャングブロック機構が働きます。 ギャングブロックはZILの一部で、そしてまさに断片化したZILブロックです。

1つのギャングブロックは、1つのヘッダと最大3つのギャングメンバーから成ります。 ヘッダは、ZILトランザクションのデータを実際に保持するギャングメンバーへのただのポインタです。 ヘッダはただ1つのブロックのみを消費し、それ故にプールの断片化レベルにかかわらず確保することが出来ます。 他に留意すべき事は、ギャングブロックは入れ子となり得るため、ギャングメンバーもまたギャングブロックから構成することが出来ます。

ギャングブロック使用中、ZILは必要とされるたびに、ギャングツリー全体のメモリへの読み込みを強いられます。 ZILトランザクションがディスクに反映される時、ギャングブロックの削除は各ギャングメンバーとその子供の削除を意味します。

これが断片化の生じる場所です! ディスクに確保と解放が行われる全てのZILトランザクションは、ZILエントリーおよびプールのデータの間に隙間を生じます。 我々のzpool iostatが以前に報告した膨大な書き込み操作数についても説明します。 これら書き込み操作はディスクを読み込み、そしてアプリケーションが使用可能なプールの実帯域幅を狭めます。

問題を見るために、私たちはZILがどのように作用しているか見るべきです。 私たちが通常の方法でZILトランザクションの生成と削除を見るだけでは、どんな極度の断片化の発生も推定する事は出来ません。 別の方法で、私たちはより深くへ行くことが可能です。

実際にギャンギングがシステム全体のレベルで問題を起こしているかどうか見つけ出すには、lockstatを使います:

# /usr/sbin/lockstat -CcwP -n 50000 -D 20 -s 40 sleep 2

ギャングブロックによる問題がシステムに本当にあるならば、あなたは次のような項目を目にするでしょう:

# grep gang lockstat-*
lockstat-C.out:     32768 |@@                             26        zio_gang_tree_assemble_done+0x74
lockstat-C.out:    262144 |                               7         zio_gang_tree_assemble_done+0x74
lockstat-C.out:      4096 |@@@@@                          146       zio_gang_tree_issue+0x78
lockstat-C.out:      8192 |@@@@@@@@@@@@@@@@@@@@@          586       zio_gang_tree_issue+0x78
lockstat-C.out:     16384 |                               13        zio_gang_tree_issue+0x78
lockstat-C.out:                                                     zio_gang_tree_issue+0x78
lockstat-C.out:                                                     zio_gang_tree_issue+0x78
lockstat-C.out:                                                     zio_gang_issue+0x48     
lockstat-C.out:      2048 |                               14        zio_gang_tree_issue+0x78
lockstat-C.out:      4096 |@@@@@@@                        192       zio_gang_tree_issue+0x78
lockstat-C.out:      8192 |@@@@@@@@@@@@@@@@@@@@           496       zio_gang_tree_issue+0x78
lockstat-C.out:     16384 |                               1         zio_gang_tree_issue+0x78
lockstat-C.out:                                                     zio_gang_tree_issue+0x78
lockstat-C.out:                                                     zio_gang_issue+0x48     
lockstat-C.out:      2048 |@@                             11        zio_gang_tree_assemble_done+0x74
lockstat-C.out:     16384 |@@@@                           18        zio_gang_tree_assemble_done+0x74
lockstat-C.out:      4096 |@                              2         zio_gang_tree_assemble+0x5c
lockstat-C.out:      8192 |@@@@@@@@@@                     15        zio_gang_tree_assemble_done+0x74
lockstat-C.out:     65536 |                               0         zio_gang_tree_assemble_done+0x74
lockstat-C.out:      2048 |@@                             3         zio_gang_tree_assemble+0x5c
lockstat-C.out:      4096 |@@@@                           6         zio_gang_tree_assemble_done+0x74
lockstat-C.out:     32768 |                               2         zio_gang_tree_assemble_done+0x74
lockstat-C.out:    262144 |                               1         zio_gang_tree_assemble_done+0x74
lockstat-C.out:                                                     zio_gang_tree_assemble_done+0x74

この時点から、実際にギャングブロックの問題を持っていると認められます。

この問題を完全に直すには、UFSの断片化したファイルシステムがそうであったように、正攻法はプールを再作成する事です。 問題の再発を防ぐための解決方法は、ミラー(もしくは非ミラー)のログデバイスをプールに追加します。これによりZILトランザクションはログデバイスに書き込まれ、プールのデータ用vdevの断片化を避けられます。

このケースが上手く動くのは、追加したログデバイスがオンラインになり、進行中のZILトランザクションがフラッシュされるまで少し待ち、そして新規トランザクションが独立したデバイスへ書き込まれるようになってからです。

注意: この解決策は性能向上の助けとなりますが、ZILが引っ掻き回した後のゴーダチーズのようなデータvdevのデフラグにはなりません。 今のところは、直面した問題への手助けとなっています。プール再作成にはダウンタイムを要しますが、デバイスの追加はそうではないので。

プールのギャングブロックの使用状況について時々システムを監視することで、あなたは積極的にこの問題に対して取り組むことが可能となります。

# dtrace -qn 'fbt::zio_gang_tree_issue:entry { @[pid]=count();  }' -c "sleep 300"
    26574               61
        0             7141
    26575            18949
    26570           416399
# ps -eaf|egrep "26574|26575|26570"
    root 26574     0   0   May 26 ?        2778:02 zpool-i-ora-pro06-arc1-pl
    root 26570     0   0   May 26 ?        9155:49 zpool-i-ora-pro06-dat1-pl
    root 26575     0   0   May 26 ?         574:51 zpool-i-ora-pro06-rdo1-pl
# 

注意: 時としてギャンギングは平静を装いますが、これらプールはまだギャンギングの影響は出ていないようです。 しかし、実際にギャンギング問題が出たプールを特定するための多少の経験になったかもしれません。そして、ZIL断片化が本当の性能問題に変わる前に、先を見越してプールにログデバイスを追加する措置を取るのが良いかもしれません。

  • Openindiana source code
  • #opensolaris-fr @ freenode

Effects of ZFS Fragmentation on Underlying Storageの翻訳

ZFSの断片化を調べていたら、英国ケント大学のITインフラチームのblogに事例が載っていた。原文へのリンクを張る事を条件に翻訳の許可を貰ったので訳してみた。

翻訳には細心の注意を払っていますが、誤訳や変な箇所があればご指摘下さい。例によって、本記事を利用した事で生じた如何なる結果について、翻訳者は責を負いかねます。また本翻訳について原著者への問い合わせはご遠慮願います。

以前よりZFSの断片化の影響は知られていますが、それは典型的にプールの使用率が80%を超えると問題化します。こうした事実にも関わらず、我々は断片化の影響が、負荷量によって使用率70~90%のどこでも出始める事例を見てきました。 大抵は、性能の低下および空き領域の小さな塊の探索、ならびに結合で必要となるディスク書き込みが引き起こすIO負荷の増大を目にする事になります。 ここに目を覆いたくならんばかりの技術的詳細の良い要約があります。

本問題への適切な対処は独立のZFSインテントログ(ZIL)デバイスを持つ事ですが、我々が持つZFSルートディスクを利用する物理・仮想サーバの数的に現実的ではありません。 また残念ながら、それは問題のある既存プールの修復にはなりませんし、そしてZFSのデフラグツールは存在しません。 問題を解決するためには、あなたはデータを削除するか、追加ストレージをプレゼントする必要があります。

次のグラフはこの問題を簡潔に示しています。 下記のボリュームは競合する2つの仕事をしていました──1つが大量の読み込み(緑)で、もう1つが少量の書き込みI/O(青、マイナス軸)です。 12:00に新しいボリュームがプールに追加されました。

新規ストレージ追加前のZFS IO

この時点で、既存の断片化したディスクへの書き込みは止まり、そして読み込みジョブのために2~300 IOPSを開放しました(今やCPUバウンドに達しています。) 下のグラフで、あなたは新しい断片化されていないボリュームに対する劇的に削減された書き込みオペレーションを見る事ができます:

新規ストレージ追加後のZFS IO

~200 IOPSが~4 IOPSに下がった訳ですが、書き込みオペレーションが50倍に増幅されていたのです。 さらに、RAID-6の書き込みによって余分なI/Oが発生し、下層のTier-3のSATAディスクは極めて激しく動かされていました。

デバイスビジー率

当然、このファイルシステム(および本RAIDグループを共有している他の物)の性能は著しく向上しています。

ターミナルが応答しなくなるほどZFSが超遅くなる謎現象

2011年にZFSを使い始めてから早4年、小規模なファイルサーバ運用ではまず困る事がないくらいにはZFSの扱いには慣れたが、未だ解決できていない問題が1つある。 システムが応答しなくなるほど、ZFSへのアクセスが遅くなる現象である。

ハッキリとした発生条件は未だ掴めていないが、概ね以下の条件を満たすと発生する。

  • 良い感じに使い古されたプール(断片化が進んでる状態?)
  • プールの空き容量が少ない
  • 幾つかの書き込みを同時に行う(ブラウザで2〜3個同時にダウンロードするなど)

問題の状態になると、ターミナルで入力が困難になるほどシステムの応答性が低下する。記憶があいまいだが、ロードアベレージ的には特に問題ない値だったハズ。

尚、プールの種類に関係なく発生するっぽい……といっても、ミラーとRAID-ZとRAID-Z+0でしか使った事はないが、何れでも発生している。途中マシン&HDDが変わったり、OSもFreeBSD 8.2→9.0→9.2と更新してるので、特定のハード&ソフトが関係する問題でもないと思われる。まぁ、FreeBSDのZFS実装がタコい可能性もないとは言い切れないが、本家以外のZFSでは老舗の部類に入る実装で、流石にそれはないだろう。

何となくだけど、断片化の線が怪しいんじゃないかなと。というのも、先だって遭遇したプールでは800GB中360GBが未使用だったから空き容量が原因とは考えにくい。ただし、以前、空き容量が100GBを割った事があり、FSの状態としてはそこそこ劣化していると考えられる。また、激遅ゾーン?を抜けるとまた普通の速度に戻るので、書き込もうとしてる領域の状態が悪いとダメっぽい気がする。

で、先日、ようやっと原因究明の糸口になりそうなデータが取れた。

この症状が発生している時は、書き込みしているにもかかわらず、なぜか物凄い読み込みが発生している。以下、zpool iostatのログ。

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    501     48  62.6M   210K
  mirror     491G   357G    501     48  62.6M   210K
    ada3p4      -      -    238     10  29.7M   210K
    ada1p4      -      -    263      7  32.9M   166K
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    451     25  56.4M   111K
  mirror     491G   357G    451     25  56.4M   111K
    ada3p4      -      -    237      4  29.7M   111K
    ada1p4      -      -    213      0  26.7M      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    289      0  36.0M      0
  mirror     491G   357G    289      0  36.0M      0
    ada3p4      -      -    133      0  16.6M      0
    ada1p4      -      -    155     13  19.4M   154K
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    273      0  33.9M      0
  mirror     491G   357G    273      0  33.9M      0
    ada3p4      -      -    135      0  17.0M      0
    ada1p4      -      -    137      0  16.9M      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    375     48  45.7M   313K
  mirror     491G   357G    375     48  45.7M   313K
    ada3p4      -      -    185     18  22.5M   313K
    ada1p4      -      -    189     13  23.2M   475K
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    321      0  39.8M      0
  mirror     491G   357G    321      0  39.8M      0
    ada3p4      -      -    160      0  19.8M      0
    ada1p4      -      -    161      0  19.9M      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    423     25  53.0M   317K
  mirror     491G   357G    423     25  53.0M   317K
    ada3p4      -      -    205      8  25.7M   317K
    ada1p4      -      -    217      4  27.2M   158K
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    432     12  53.9M   158K
  mirror     491G   357G    432     12  53.9M   158K
    ada3p4      -      -    223      4  28.0M   158K
    ada1p4      -      -    208      8  25.9M   317K
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    204      0  25.0M      0
  mirror     491G   357G    204      0  25.0M      0
    ada3p4      -      -    103      0  12.8M      0
    ada1p4      -      -    100      0  12.3M      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    370     25  45.7M   317K
  mirror     491G   357G    370     25  45.7M   317K
    ada3p4      -      -    176     12  21.7M   333K
    ada1p4      -      -    194     10  24.0M   321K
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    380     46  47.2M   305K
  mirror     491G   357G    380     46  47.2M   305K
    ada3p4      -      -    209      6  25.9M   305K
    ada1p4      -      -    170     63  21.3M  7.07M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    199    119  24.4M  7.07M
  mirror     491G   357G    199    119  24.4M  7.07M
    ada3p4      -      -     96     63  11.7M  7.07M
    ada1p4      -      -    102      1  12.8M  23.8K
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    334      0  40.9M      0
  mirror     491G   357G    334      0  40.9M      0
    ada3p4      -      -    148      0  18.1M      0
    ada1p4      -      -    186      0  22.8M      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    401      9  49.7M  39.6K
  mirror     491G   357G    401      9  49.7M  39.6K
    ada3p4      -      -    190      2  23.3M  39.6K
    ada1p4      -      -    211      2  26.4M  47.5K
----------  -----  -----  -----  -----  -----  -----

正常な時はこんな感じ。

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0    402      0  32.3M
  mirror     491G   357G      0    402      0  32.3M
    ada3p4      -      -      0    324      0  32.3M
    ada1p4      -      -      0    323      0  32.3M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0      0      0      0
  mirror     491G   357G      0      0      0      0
    ada3p4      -      -      0      0      0      0
    ada1p4      -      -      0      0      0      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0    195      0  24.3M
  mirror     491G   357G      0    195      0  24.3M
    ada3p4      -      -      0    195      0  24.3M
    ada1p4      -      -      0    195      0  24.3M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0    212      0  8.56M
  mirror     491G   357G      0    212      0  8.56M
    ada3p4      -      -      0    116      0  8.57M
    ada1p4      -      -      0    120      0  8.57M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0      0      0      0
  mirror     491G   357G      0      0      0      0
    ada3p4      -      -      0      0      0      0
    ada1p4      -      -      0      0      0      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0      0      0      0
  mirror     491G   357G      0      0      0      0
    ada3p4      -      -      0      0      0      0
    ada1p4      -      -      0      0      0      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0    402      0  32.3M
  mirror     491G   357G      0    402      0  32.3M
    ada3p4      -      -      0    317      0  32.3M
    ada1p4      -      -      0    318      0  32.3M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0      0      0      0
  mirror     491G   357G      0      0      0      0
    ada3p4      -      -      0      0      0      0
    ada1p4      -      -      0      0      0      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0      0      0      0
  mirror     491G   357G      0      0      0      0
    ada3p4      -      -      0      0      0      0
    ada1p4      -      -      0      0      0      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0    405      0  32.3M
  mirror     491G   357G      0    405      0  32.3M
    ada3p4      -      -      0    323      0  32.3M
    ada1p4      -      -      0    323      0  32.3M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0      0      0      0
  mirror     491G   357G      0      0      0      0
    ada3p4      -      -      0      0      0      0
    ada1p4      -      -      0      0      0      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0      0      0      0
  mirror     491G   357G      0      0      0      0
    ada3p4      -      -      0      0      0      0
    ada1p4      -      -      0      0      0      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0    402      0  32.3M
  mirror     491G   357G      0    402      0  32.3M
    ada3p4      -      -      0    320      0  32.3M
    ada1p4      -      -      0    322      0  32.3M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G    111    128  13.9M  16.0M
  mirror     491G   357G    111    128  13.9M  16.0M
    ada3p4      -      -     50    128  6.31M  16.0M
    ada1p4      -      -     61    128  7.56M  16.0M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0      0      0      0
  mirror     491G   357G      0      0      0      0
    ada3p4      -      -      0      0      0      0
    ada1p4      -      -      0      0      0      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        491G   357G      0    385      0  17.1M
  mirror     491G   357G      0    385      0  17.1M
    ada3p4      -      -      0    203      0  17.1M
    ada1p4      -      -      0    203      0  17.1M
----------  -----  -----  -----  -----  -----  -----

どちらもdd if=/dev/zero of=~/tempした時のiostatだが、問題の方は何故かフルスピードで読み込みが走っている。コマンドを間違えたなんて事は勿論、同時並行で別の読み込みプロセスが走ってるという事もない。読み込んだデータはどこに行っているのか……。

ちなみに、ddしつつ読み込みを行い正常な時はこんな感じ。読み込みと書き込みが仲良く同居してる感じですな。

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    346     41  43.3M  2.19M
  mirror     474G   374G    346     41  43.3M  2.19M
    ada3p4      -      -    167     21  20.9M  2.19M
    ada1p4      -      -    179     48  22.4M  4.68M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    125    165  15.7M  3.03M
  mirror     474G   374G    125    165  15.7M  3.03M
    ada3p4      -      -     52     55  6.56M  3.05M
    ada1p4      -      -     73     30  9.16M   562K
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    139      0  17.3M      0
  mirror     474G   374G    139      0  17.3M      0
    ada3p4      -      -     71      0  8.76M      0
    ada1p4      -      -     68      0  8.54M      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    249    101  29.4M  3.31M
  mirror     474G   374G    249    101  29.4M  3.31M
    ada3p4      -      -    139     35  16.3M  3.31M
    ada1p4      -      -    109     36  13.0M  3.35M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    115    199  12.7M  1.44M
  mirror     474G   374G    115    199  12.7M  1.44M
    ada3p4      -      -     70     51  8.07M  1.45M
    ada1p4      -      -     45     49  4.61M  1.42M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    206      0  25.1M      0
  mirror     474G   374G    206      0  25.1M      0
    ada3p4      -      -    113      0  13.8M      0
    ada1p4      -      -     93      0  11.4M      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    275    260  34.3M  3.81M
  mirror     474G   374G    275    260  34.3M  3.81M
    ada3p4      -      -    153     93  19.0M  3.81M
    ada1p4      -      -    121     87  15.2M  3.81M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    258      0  31.7M      0
  mirror     474G   374G    258      0  31.7M      0
    ada3p4      -      -    123      3  15.1M  15.8K
    ada1p4      -      -    134      3  16.6M  15.8K
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    269      0  32.9M      0
  mirror     474G   374G    269      0  32.9M      0
    ada3p4      -      -    132      0  15.9M      0
    ada1p4      -      -    136      0  17.1M      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    402    100  50.4M  2.41M
  mirror     474G   374G    402    100  50.4M  2.41M
    ada3p4      -      -    189     24  23.6M  2.41M
    ada1p4      -      -    213     24  26.7M  2.41M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    372    124  46.5M   535K
  mirror     474G   374G    372    124  46.5M   535K
    ada3p4      -      -    182     28  22.8M   550K
    ada1p4      -      -    190     28  23.7M   550K
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    339      0  42.4M      0
  mirror     474G   374G    339      0  42.4M      0
    ada3p4      -      -    163      0  20.4M      0
    ada1p4      -      -    176      0  22.0M      0
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    387     55  48.4M  1.66M
  mirror     474G   374G    387     55  48.4M  1.66M
    ada3p4      -      -    203     16  25.5M  1.66M
    ada1p4      -      -    183     18  22.9M  1.68M
----------  -----  -----  -----  -----  -----  -----

               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zhome        474G   374G    234    130  29.3M   558K
  mirror     474G   374G    234    130  29.3M   558K
    ada3p4      -      -    111     35  14.0M   574K
    ada1p4      -      -    122     33  15.3M   550K
----------  -----  -----  -----  -----  -----  -----

断片化実験してみりゃいいんだろうけど、問題の性質上、仮想マシンではダメだろうし、かといって個人の趣味では実環境を揃えるのもなかなか大変だし(とか言いつつ、実はパーツは揃ってたりするが面倒&時間がなくて実験出来てない…)

何でこんな事が起きるのか、偉い人教えて下さい……。

家鯖をESXi 5.1U2からV2P, V2Vマイグレーション

家鯖をESXiによる仮想サーバから物理サーバにマイグレーションする事にした。

ESXi上で動いているのはFreeBSDとWindows 7の2つ。元々FreeBSDが物理的に動いていたが、Windowsで録画鯖を作ろうと思ってESXiを導入したという経緯がある。結局、nasneを買っちゃったし、そもそも元からテレビを見ないという致命的な不具合(笑)が発覚したので、録画鯖を仕立てる理由もなくなってしまった。ESXiの雲行きも怪しいし、良い機会なのでV2Pしちゃおうと考えた次第。

FreeBSDは物理サーバ時代からのHDDを全てRDM&PCIパススルーで動かしてた為、マイグレーションもへったくれもない。ESXiのUSBメモリを引っこ抜けば、何もしなくてもBSDが起動する素敵仕様。V2Pいっちょあがりっと。

Windowsの方はFreeBSD上のVirtualBoxにV2Vする事にした。録画鯖にはならなかったものの、PS Vitaのコンテンツ管理アシスタントのホストになってたり、巨大なエロ動画ファイルのダウンロードとかで地味に役立つので。こっちは少し苦労したため、作業内容をメモっておく。

まずはESXiのデータストアからファイルを取り出さない事には始まらない。色々やり方はあると思うが、今回はクライアント側からscpで転送した。

$ scp -rp root@esxiserver:/vmfs/volumes/path_to_datastore/Windows/ esxi_save/
Password: 
Windows.vmx                                   100% 3142     3.1KB/s   00:00    
Windows.vmxf                                  100%  262     0.3KB/s   00:00    
Windows.vmsd                                  100%    0     0.0KB/s   00:00    
Windows.nvram                                 100% 8684     8.5KB/s   00:00    
vmware-36.log                                 100%  202KB 202.1KB/s   00:00    
Windows-flat.vmdk                             100%   40GB  42.9MB/s   15:55    
Windows.vmdk                                  100%  494     0.5KB/s   00:00    
vmware-35.log                                 100%  202KB 201.6KB/s   00:00    
vmware.log                                    100%  311KB 311.1KB/s   00:00    
vmware-31.log                                 100%  176KB 175.8KB/s   00:00    
vmware-32.log                                 100%   51KB  51.4KB/s   00:00    
vmware-34.log                                 100%  202KB 201.9KB/s   00:00    
vmware-33.log                                 100%  180KB 180.2KB/s   00:00

VMの詳細は割愛。

ストレージは既存の仮想ディスクを使う。上で転送したファイルで言えばWindows.vmdkを選択する。

接続するバスは、とりあえずESXiで使っていた物と同じのにして、Windowsが起動するか試してみる。正常に起動すれば後は何もする必要はないが、十中八九「Windowsを起動しています」の画面で“STOP 0x0000007B”ブルースクリーンが出て死ぬ。その時は、接続バスを好きなものに変えて(もちろん変えなくてもいい)、次の対策を行う。

“STOP 0x0000007B”ブルースクリーンが出てWindowsを起動出来ない時は、レジストリを修正する必要がある。

  1. VM起動時にF8連打でWindowsの「詳細ブートオプション」を表示し、「コンピュータの修復」を選ぶ。コンピュータの修復が表示されていなければ、修復用のシステムがインストールされていないって事なので、WindowsのインストールCDから同等の事をする(詳細はググってくだしあ)。
  2. システム回復オプションのログイン画面が出るので、正常に動いてた時のアカウントでログイン。
  3. コマンドプロンプトを起動。
  4. コマンドプロンプトで「regedit」と打ち、レジストリエディタを起動。
  5. レジストリエディタの「HKEY_LOCAL_MACHINE」または「HKEY_USERS」を選択した状態[ファイル]>[ハイブの読み込み]を選択。
  6. d:\Windows\System32\config\SYSTEM を開く。
  7. マウントポイント名を聞かれるので、適当にattachedなどと入れる。
  8. attachedにSYSTEMレジストリが読み込まれるので、CurrentControlSet\servicesControlSetNNN\servicesの中にある下記リスト内の「Start」の値を0にする。ノードが存在しなければ飛ばしてOK。
    • aliide
    • amdide
    • atapi
    • ataport
    • cmdide
    • intelide
    • LSI_SAS
    • LSI_SAS2
    • LSI_SCSI
    • megasas
    • MegaSR
    • msahci
    • pciide
    • pciidex
    • viaide
  9. レジストリエディタ、コマンドプロンプトを終了し、再起動。

以上でマイグレーションしたWindowsが正しく起動するハズ。

  • start.txt
  • 最終更新: 2022-07-27 15:26
  • by Decomo