SCVMM の落とし穴 その6 – 仮想マシンが「不足」する!?


こんにちは。
システムセンターサポート担当の住です。

これまでにSCVMM の管理者が遭遇しやすい障害状況などを「SCVMM の落とし穴」 としてご紹介してきましたが、とうとう 6回を数えるまでになりました。

過去の投稿についてはこちらをご覧ください。

次期製品もそろそろリリースされますので、今回は復習もかねて、頻繁にお問い合わせのある「不足」状態となった仮想マシンについて、お伝えします。

既に技術情報や Knowledge Base、US のエンジニアによるブログといった複数の方法で、情報が公開されていますが、それでもやはりお問い合わせが多い現象の一つとして「不足」な仮想マシンがあります。

今回はこの報告の多いエラーについて、その原因と解決方法をご紹介します。


現象

管理コンソール上で、仮想マシンの状態が「不足」となります。
副次的な現象として、以下の様な症状を伴う場合があります。

  • 同じホスト クラスタ内に、同名の仮想マシンが複数存在する。
  • 仮想マシンを削除することができない。(エラー 802)

なお本現象が発生しても、Hyper-V マネージャやフェールオーバー クラスタ マネージャから確認した場合には、各仮想マシン (HAVM) は正常に稼動しています。


原因

仮想マシンの状態が「不足」となるのは、仮想マシンを構成する一部のオブジェクトについてアクセスが出来ない場合となります。
つまり、「不足」とは仮想マシンを構成する幾つかのオブジェクトが「不足」している状態を意味しています。(英語環境では「missing」)
これらのエラーはおおよそ以下の様な状況で発生します。

  • ホスト ノードの突然なシャットダウンなどで、仮想マシンがフェールオーバーされた。
  • ホスト不応答など、ホスト ノードと SCVMM サーバー間で正常に通信が出来ない状況下で、仮想マシンが他のノードに移動した。
  • ホスト クラスタに新たにノードが追加され、「保留」の状態になった。

本来仮想マシンが他のホストに移動するなどした場合には、ホスト上にインストールされている VMM エージェントが状況変更を SCVMM サーバーに通知しますが、上記のような状況が発生すると、エージェントと SCVMM サーバーとが正しく情報をやり取りできず、SCVMM サーバーの持っている データベース (VMMDB) の更新が行われないまま、移動先のホストに存在するエージェントからの更新情報によってデータベースが変更されるなど、データベース上に矛盾が生じます。

この事が原因で仮想マシンの状態が「不足」となります。


解決方法

まずは「不足」となる状況をよく見極める事が大事です。

  • ホスト上の仮想マシン全てが「不足」となっている場合には、ホストがホスト クラスタに追加された後、一度も管理コンソール上から「ホストの追加」が実施されていない可能性があります。(後述の関連資料 5 をご覧ください)
    この場合には、「ホストの追加」アクションを使用して、ホストを VMM に追加します。
  • 複数の仮想マシンが「不足」となっていて、且つ同じ仮想マシン名が他にない場合には、ネットワークの過負荷による問題の可能性があります。
    この場合には、時間をおいて対象のホスト(またはホスト クラスタ)を最新の状態に更新してみてください。
  • ホスト クラスタ内で「不足」となっている仮想マシンと同じ名前の仮想マシンが存在する場合(SCVMM では、同一ホスト クラスタ内で仮想マシン名は一意です)や、ホストの状態を更新しても状況が改善しない場合には、SQL データベース (VMMDB) の不整合が疑われます。
    この場合には、以下の手順で SQL データベースをクリーンアップする必要があります。

    ※ VMMDB の直接編集は、SCVMM 全体に影響します。最悪の場合、SCVMM サービスが起動しなくなる恐れがありますので、事前に 「管理」ワークスペースの「全般」ビューから、”Virtual Machine Manager のバックアップ” アクションにて、VMMDB のバックアップを取得しておいて下さい。

  1. 以下の内容をテキスト ファイルとして適当な名前(例: RemoveMissingVMs.sql) で保存します。
    —- Text —
    BEGIN TRANSACTION T1
    
    DECLARE custom_cursor CURSOR FOR
    SELECT ObjectId from
    dbo.tbl_WLC_VObject WHERE [ObjectState] = 220
    DECLARE @ObjectId uniqueidentifier
    OPEN custom_cursor
    FETCH NEXT FROM custom_cursor INTO @ObjectId
    WHILE(@@fetch_status = 0)
     BEGIN
     DECLARE vdrive_cursor CURSOR FOR
     SELECT VDriveId, VHDId, ISOId from
     dbo.tbl_WLC_VDrive WHERE ParentId = @ObjectId
     DECLARE @VDriveId uniqueidentifier
     DECLARE @VHDId uniqueidentifier
     DECLARE @ISOId uniqueidentifier
    
     OPEN vdrive_cursor
     FETCH NEXT FROM vdrive_cursor INTO @VDriveId, @VHDId, @ISOId
     WHILE(@@fetch_status = 0)
     BEGIN
      DELETE FROM dbo.tbl_WLC_VDrive
             WHERE VDriveId = @VDriveId
      if(@VHDId is NOT NULL)
      BEGIN
            
       DELETE FROM dbo.tbl_WLC_VHD
       WHERE VHDId = @VHDId
       DELETE FROM dbo.tbl_WLC_PhysicalObject
       WHERE PhysicalObjectId = @VHDId
      END
      if(@ISOId is NOT NULL)
      BEGIN
      
       DELETE FROM dbo.tbl_WLC_ISO
              WHERE ISOId = @ISOId
       DELETE FROM dbo.tbl_WLC_PhysicalObject
       WHERE PhysicalObjectId = @ISOId
      END
     
         FETCH NEXT FROM vdrive_cursor INTO @VDriveId, @VHDId, @ISOId
       END
     CLOSE vdrive_cursor
     DEALLOCATE vdrive_cursor
    -----------------
     DECLARE floppy_cursor CURSOR FOR
     SELECT VFDId, vFloppyId from
     dbo.tbl_WLC_VFloppy WHERE HWProfileId = @ObjectId
     DECLARE @vFloppyId uniqueidentifier
     DECLARE @vfdId uniqueidentifier
     OPEN floppy_cursor
     FETCH NEXT FROM floppy_cursor INTO @vfdId, @vFloppyId
     WHILE(@@fetch_status = 0)
     BEGIN
          DELETE FROM dbo.tbl_WLC_VFloppy 
      WHERE VFloppyId = @vFloppyId
      
      if(@vfdid is NOT NULL)
      BEGIN
       DELETE FROM dbo.tbl_WLC_VFD
       WHERE VFDId = @vfdId
       DELETE FROM dbo.tbl_WLC_PhysicalObject
       WHERE PhysicalObjectId = @vfdId
      
      END
     
         FETCH NEXT FROM floppy_cursor INTO @vfdId, @vFloppyId
       END
     CLOSE floppy_cursor
     DEALLOCATE floppy_cursor
    ----------------
     DECLARE checkpoint_cursor CURSOR FOR
     SELECT VMCheckpointId from
     dbo.tbl_WLC_VMCheckpoint WHERE VMId = @ObjectId
     DECLARE @vmCheckpointId uniqueidentifier
     OPEN checkpoint_cursor
     FETCH NEXT FROM checkpoint_cursor INTO @vmCheckpointId 
     WHILE(@@fetch_status = 0)
     BEGIN
          DELETE FROM dbo.tbl_WLC_VMCheckpointRelation 
      WHERE VMCheckpointId = @vmCheckpointId
      
     
         FETCH NEXT FROM checkpoint_cursor INTO @vmCheckpointId
       END
     CLOSE checkpoint_cursor
     DEALLOCATE checkpoint_cursor
    -------------------------
    ---------Clean checkpoint
     DELETE FROM dbo.tbl_WLC_VMCheckpoint
     WHERE VMId = @ObjectID
    
            exec [dbo].[prc_VMMigration_Delete_VMInfoAndLUNMappings] @ObjectId
            DECLARE @RefreshId uniqueidentifier
            exec [dbo].[prc_RR_Refresher_Delete] @ObjectId, @RefreshId
    
            DELETE FROM dbo.tbl_WLC_VAdapter
     WHERE HWProfileId = @ObjectId
    
            DELETE FROM dbo.tbl_WLC_VNetworkAdapter
     WHERE HWProfileId = @ObjectId
                    
            DELETE FROM dbo.tbl_WLC_VCOMPort
     WHERE HWProfileId = @ObjectId
            DELETE FROM dbo.tbl_WLC_HWProfile
            WHERE HWProfileId = @ObjectId
            DELETE FROM dbo.tbl_WLC_VMInstance
            WHERE VMInstanceId = @ObjectId
     DELETE FROM dbo.tbl_WLC_VObject
     WHERE ObjectId = @ObjectId
        FETCH NEXT FROM custom_cursor INTO @ObjectId
      END
    CLOSE custom_cursor
    DEALLOCATE custom_cursor
    COMMIT TRANSACTION T1
    

    —- Text End —

  2. 管理コンソールを終了します。
  3. “Virtual Machine Manager” サービスを停止します。
  4. コマンド プロンプトを管理者として実行します。
  5. 以下のコマンドを実行します。

    > sqlcmd –S localhost\MICROSOFT$VMM$ -d VirtualManagerDB –E –i RemoveMissingVMs.sql

    ※ localhost\MICROSOFT$VMM$ は、SQL サーバーとインスタンス名に、 VirtualManagerDB はデータベース名に、それぞれ適宜変更してください。 上の例は、SCVMM と同じサーバー上にインストールされた SQL Server 2005 Express の場合の既定値です。

  6. “Virtual Machine Manager” サービスを起動します。
  7. 管理コンソールを起動し、状況が改善している事を確認してください。

まとめ

「不足」以外のエラーでもそうですが、まずは 管理コンソール からの回復を試みてください。(“修復” オプションの「再実行」や「無視」の実行、ホストの再起動、ホストの削除、再追加等)
管理コンソールからの回避が難しい場合には、 VMMDB での直接のクリーンアップを実行してください。
上記手順では、”Sqlcmd.exe“ を使用していますが、”SQL Server Management Studio (Express)” をお使いの方であれば、データベースに接続後、「新しいクエリ」内で上記のテキスト部分をコピーして「実行」して頂いても、同じ効果があります。

次回は、いよいよ本シリーズの最後となる、「過剰コミット」についてです。

では、また次回。


参考資料

  1. フォーラム: Virtual Machine の状態が、「不足」となってしまう
    http://social.technet.microsoft.com/Forums/ja-JP/hypervja/thread/4513019d-87fd-4830-b9dc-0a81c3272e5c/
  2. KB 983839: 不足している仮想マシンの SCVMM 2008 または SCVMM 2008 R2 を削除することはできません。(機械翻訳)
    http://support.microsoft.com/kb/983839/ja
  3. TechNet: RemoveMissingVMs (英語)
    http://technet.microsoft.com/ja-jp/library/ff641854.aspx
  4. Blog: Removing missing VMs from the VMM Administrator Console
    http://blogs.technet.com/b/m2/archive/2010/04/16/removing-missing-vms-from-the-vmm-administrator-console.aspx
  5. TechNet: VMM での高可用性バーチャル マシンをサポートするホストクラスタの構成
    http://technet.microsoft.com/ja-jp/library/cc764274.aspx

    < 抜粋 >
    クラスタ ノード追加 — ノードが VMM 外のホストクラスタに追加された場合、VMM は新しいノードを検出し VMM 管理者コンソールでそのホストクラスタ下に表示します。ノードは、VMM にホストとして追加されるまで保留状態となります。VMM にホストが追加されるまでに、ホスト クラスタ内の他のノード上の高可用性バーチャル マシンが新しいノードにフェールオーバーする場合、そのバーチャルマシンの状態は VMM で “不足” になります。
    < 抜粋ここまで>

Comments (0)

Skip to main content