Windowsトラブル解決事例──容量可変VHD肥大化の犯人とその解消山市良のうぃんどうず日記(164)

Hyper-Vの容量可変タイプのVHD/VHDXファイルは、割り当てサイズではなく、使用量に応じて拡大していくため、評価環境などパフォーマンスへの影響を許容でき、Hyper-Vホストのストレージを効率的に利用したい場合に有効です。そんな容量可変タイプのVHDXファイルが、割り当てサイズ近くにまで肥大化しているのを発見しました。物理環境でも長く使用していれば発生し得る空き領域不足のトラブルと思うので、問題の調査から解決までをレポートします。

» 2019年10月23日 05時00分 公開
[山市良テクニカルライター]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「山市良のうぃんどうず日記」のインデックス

山市良のうぃんどうず日記

100GBのディスクを使い果たしてしまったWindows 8.1、その犯人は?

 筆者はサポート期間中であるかどうかにかかわらず、WindowsやMicrosoft Officeのさまざまな組み合わせの環境を「Hyper-V」や「Microsoft Azure」の仮想マシンとして保持し、サポート期間中の場合は毎月のWindows Updateで更新し続けています。

 その中の1台、Windowsインストーラー形式の「Office Professional 2013 Service Pack 1(SP1)」(以下、MSI版Office 2013)がインストールされている「Windows 8.1(x64)」のHyper-V仮想マシンが、いつの間にか大変なことになっていました。

 このHyper-V仮想マシンには、OSディスクとしては容量可変タイプの100GBのVHDXを割り当てているのですが、空き領域が残り数GBしかなく、当然のことながら容量可変タイプのVHDXファイルのサイズは容量固定タイプと同じくらいに肥大化していたのです(画面1)。せっかくの容量可変タイプのVHDXファイルなのに、これではHyper-Vホストのストレージがもったいないし、バックアップしたり、コピーしたりする際の扱いも大変です。

画面1 画面1 MSI版Office 2013がインストールされているWindows 8.1(x64)の仮想マシン。容量可変タイプのVHDXがいつの間にか割り当てサイズ100GB近くまで肥大化していた。ゲストOSのC:ドライブの空き容量は6GBを切っていた

 何がディスクをこんなに使用しているのか、「Windows Sysinternals」の「Disk Usage(du.exe)」を使用すると簡単に調査できます。

  • Disk Usage[英語](Windows Sysinternals)

 C:ドライブのルートにあるディレクトリを次のコマンドラインを実行して1つずつ確認してみると、「C:\Windows」が約85GBもあり、ディスク使用率を圧迫していることがすぐに判明しました。

du -nobanner "<ディレクトリのフルパス>"

 続いて、次のようなコマンドラインを実行します。

du -nobanner -l 1 -ct "C:\Windows" | clip

  このコマンドラインは、「C:\Windows」の1つ下のディレクトリ階層(-l 1)までのディスク使用状況をタブ区切り形式(-ct)で出力し、クリップボードに貼り付けます(| clip)。クリップボードを「Microsoft Excel」の空のワークシートに貼り付け、「DirectorySizeOfDisk」列でソートすると、「C:\Windows\Installler」が約50GBと最もディスク使用量が大きく、次が「C:\Windows\WinSxS」の約24GBであることが分かりました(画面2)。

画面2 画面2 Windows SysinternalsのDisk Usage(du.exe)でディレクトリごとのディスク使用量を調べてみると、「C:\Windows\Installler」が約50GBと最も大きく、「C:\Windows\WinSxS」の約24GBが続く

WinSxS肥大化の犯人はWindows Update、最適化で22GBを解放、所要時間は22時間

 「C:\Windows\WinSxS」は、Windowsのバイナリ(実行可能ファイル、ライブラリ、ドライバなど)が格納されているコンポーネントストアで、「Windows Vista」から導入された「CBS(Component-Based Servicing)」という技術で管理されています。

 Windows Updateで更新プログラムがインストールされると、更新されたファイルは「C:\Windows\WinSxS」に格納され、「System32」ディレクトリなどのパス(C:\Windows\System32\ntoskrnl.exeなど)にリンクされます。更新プログラムをアンインストールできるように、置き換えられた過去のバージョンのバイナリもまた、「C:\Windows\WinSxS」に保持されています。

 コンポーネントストア「C:\Windows\WinSxS」は、「ディスククリーンアップ」(Cleanmgr.exe)で最適化することができます。「C:\Windows\WinSxS」の最適化のために、「ディスククリーンアップ」を管理者として開始し、「Windows Updateのクリーンアップ」を含む、全ての項目を選択して実行しました。

 「Windows Updateのクリーンアップ」の項目の削除により23.4GB、合計23.5GBの領域が解放されると表示されましたが、実際に解放されたのは約20GBでした。以下の画面3の右は、クリーンアップ開始から8時間が経過したところです。完了するまでは、なんと20時間を要しました。完了した時点でCBSのログ(C:\Windows\Logs\CBS\CBS.log)を参照してみると、その内容はともかく、1万6000以上のトランザクション(Created NT transaction (seq 16402))が実施されていたことを確認できました。

画面3 画面3 「ディスククリーンアップ」は「Windows Updateのクリーンアップ」の項目の削除で23.4GBを解放できることを示した

 コンポーネントストアは、次のコマンドラインを管理者として実行することで、さらに圧縮できる可能性があります。今回のケースでは、さらに約2GBの領域を解放することができましたが、完了するまでに約2時間かかりました(画面4)。

DISM  /Online /Cleanup-Image /StartComponentCleanup /ResetBase

画面4 画面4 実際には「ディスククリーンアップ」により20時間かかって約20GBの領域を解放できた。「DISM」コマンドによるクリーンアップにより、さらに約2GBの領域を解放できた

巨大な「C:\Windows\Installer」に矛盾なし? 一時しのぎのNTFS圧縮で約8GBを解放

 Windows Updateのクリーンアップとコンポーネントストアの最適化により、「C:\Windows\WinSxS」のディスク使用量は約24.2GBから約9.6GBに縮小されました。一方、「C:\Windows\Installer」の方は、ファイル数、ディレクトリ数、ディスク使用量に何の変化もありません。

 「C:\Windows\Installer」は、Windowsインストーラーによってインストールされたプログラムや更新プログラムをアンインストールするために使用されるWindowsインストーラーパッケージ(.msi)やWindowsインストーラー修正プログラム(.msp)を格納している場所です。実際、コントロールパネルの「プログラムと機能」の「プログラムのアンインストールまたは変更」で削除しても影響がなさそうなものを幾つかアンインストールしてみると、ファイル数やディレクトリ数、ディスク使用量が少しだけ減りました。

 インターネットを少し検索してみれば、「C:\Windows\Installer」の肥大化を解消する民間療法的な(非公式な)方法が見つかるかもしれません。しかし、このディレクトリの中にあるものを安易に削除してしまうと、今後のプログラムのインストールやアンインストールに支障が出る可能性があるため、実行すべきではありません。

 問題の仮想マシンの「C:\Windows\Installer」の約50GBという使用量は、あまりにも多過ぎ、異常な状況に見えます。しかし、レジストリ内の対応する情報を比較してみると、矛盾は見当たりませんでした。

 例えば、「HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Patches」キーに存在するサブキーの数は、「C:\Windows\Installer\*.msp」のファイル数と一致します。レジストリの調査には、Windows SysinternalsのDisk Usage(du.exe)によく似た、「Registry Usage(ru.exe)」をお勧めします。

 「プログラムのアンインストールまたは変更」で不要なプログラムを削除しても、「C:\Windows\Installer」のディスク使用量は数GBしか解放できませんでした。そこで、一時しのぎの対応になりますが、「C:\Windows\Installer」に対して「NTFS圧縮」を適用しました。解放できた領域は約8GB、所要時間は1.5時間でした。

画面5 画面5 「C:\Windows\Installer」の肥大化の原因が分からないため、一時的な対処としてNTFS圧縮を利用して約8GBの領域を解放

 C:ドライブのディスク使用量は63.4GBに縮小、空き領域は36GBに増加しました。取りあえず、この時点で仮想マシンのチェックポイントを作成し、保持しておきます。チェックポイントは、物理環境のトラブルシューティングでは利用できない仮想環境の利点です。

共犯はMSI版Office 2013、再インストール&更新で最終的に70GB以上を解放

 ここまでの時点で筆者は、「C:\Windows\Installer」の肥大化の原因が5年前にインストールし、その後、Windows Update(Microsoft Update)で更新し続けてきたMSI版Office 2013ではないかと疑っていました。

 MSI版Officeの更新プログラムはWindows Update経由でダウンロード、インストールされますが、更新プログラムはWindowsインストーラー修正プログラム(.msp)であり、「C:\Windows\WinSxS」ではなく、「C:\Windows\Installer」が使用されます。長年の更新プログラムの蓄積が、結果として50GB近くになっているのではないかと想像しました。なお、Office 2016以降は「クイック実行(Click to Run、C2R)」形式が主流であり、C2R版Office製品の更新が「C:\Windows\Installer」を肥大化させることはないはずです。

 試しにMSI版Office 2013をアンインストールしてみました。“試しに”と言ったのは、仮想マシンのチェックポイントがあり、簡単にロールバックできるからです。アンインストールが完了した時点で、「C:\Windows\Installer」のディスク使用量は60MBに縮小され、50GB近くの領域が解放されました(画面6)。「C:\Windows\Installer」のNTFS圧縮の意味はもうないので、この時点でNTFS圧縮を解除しました。

画面6 画面6 MSI版Office 2013をアンインストールすると、「C:\Windows\Installer」から50GB近くの領域が解放された。ファイル数とディレクトリ数も劇的に削減された

 MSI版Office 2013を再インストール(Word/Excel/PowerPoint/Outlookを選択してインストール)すると、「C:\Windows\Installer」のディスク使用量は160MB程度増加しました。なお、最初のインストールの際、「2711.内部エラー」でインストールが失敗しました。この問題を解決するために、以下の公式サイトからアンインストールサポートツールをダウンロードして実行する必要がありました。

 その後、Windows Updateを実行して、MSI版Office 2013の全ての更新プログラムをインストールしました。更新が完了した時点で「C:\Windows\Installer」のディスク使用量は2.5GB程度増加しました(画面7)。これでMSI版Office 2013の更新バージョンはアンインストール以前と同じところまできました。にもかかわらず、「C:\Windows\Installer」のディスク使用量は劇的に縮小されました。

画面7 画面7 MSI版Office 2013を最新状態に更新しても「C:\Windows\Installer」のディスク使用は数GBしか増加しなかった。以前の50GBとは大きな違い

 ディスク不足の原因特定と問題解消ができたので、仮想マシンのスナップショットを削除し、現在の状態をVHDXファイルに適用します。仮想マシンのゲストOSから見たC:ドライブの最終的なディスク使用量は21.0GBに縮小され、空き領域は78.4GBに増加しました。最初の状態(前出の画面1)から70GB以上の領域を解放できたことになります。

VHDXファイルの最適化でファイルサイズは適正サイズ約32GBに縮小

 物理環境のディスク領域不足の場合は、この時点でトラブルシューティングは完了です。今回の問題はディスク領域不足だけでなく、それに伴う仮想マシンのVHDXファイルの肥大化です。容量可変タイプのVHDXファイルのサイズは最適化しない限り、縮小されることはありません。つまり、Hyper-Vホストのストレージ上のディスク領域はまだ解放されていないのです。

 VHD/VHDXファイルの最適化は仮想マシンを停止して、「仮想ハードディスクの編集ウィザード」を使用して「最適化」を実行するか、「Optimize-VHD」コマンドレットを使用することで可能です。

 ただし、「仮想ハードディスクの編集ウィザード」による最適化は、VHD/VHDXファイルのサイズ縮小にほとんど効果がない場合があります。今回のケースでは、「仮想ハードディスクの編集ウィザード」によるVHDXファイルの最適化により、99.2GBから98GBへと、たった1.2GBしか縮小できませんでした。

 Optimize-VHDコマンドレットを使用する場合、少しトリッキーな方法で行うことで、劇的に縮小できる可能性があります。Windows PowerShellを管理者として開き、次のコマンドラインを順番に実行し、「dir」コマンドの結果を比較して効果を確認してみてください。

$targetvhd = "VHD/VHDXファイルのフルパス"
dir $targetvhd
Mount-VHD $targetvhd -Readonly
Optimize-VHD $targetvhd -Mode Quick
Optimize-VHD $targetvhd -Mode Quick
Dismount-VHD $targetvhd
dir $targetvhd

 上記のコマンドラインについて詳しい説明はしません。筆者の別の連載記事や筆者の個人ブログのフォローアップ記事をご覧ください。

 上記のコマンドラインでも期待したほど縮小されない場合は、以下の方法を試してから再実行してみてください。再配置できないファイルが存在する場合、縮小はその場所でストップしてしまいます。これらの方法は、その問題を解消できる可能性があります。特に、3つ目のバックアップとリストアは、劇的な縮小効果を得られるでしょう(画面8)。

(1)仮想マシンのゲストOSでC:ドライブを最適化(デフラグ)する。ゲストOSで最適化がうまくいかない場合は、Hyper-Vホストの「ディスクの管理」スナップインを使用して、オフラインの仮想マシンのVHD/VHDXファイルをマウントし、最適化を実行する。


(2)仮想マシンのゲストOSでC:ドライブに数GBの空き領域を残しつつ、ボリュームを縮小し、その後、再びボリュームを拡張する。C:ドライブの最適化(デフラグ)を阻んでいるファイルの配置がある場合、縮小可能なサイズが制限されることでその存在を発見できる。


(3)VHD/VHDXファイルを新規作成し、仮想マシンにバックアップ用のディスクとして割り当て、初期化、フォーマット後、仮想マシンのゲストOSでフルバックアップ(システムイメージの作成)を実行する。その後、新規のVHD/VHDXファイルをOSディスク用に割り当て、Windowsのインストールメディア(DVDまたはISOイメージ)から「Windows回復環境(WinRE)」を起動して、ベアメタル回復(イメージでシステムを復元)を実行する。


画面8 画面8 最終的なC:ドライブのディスク使用量は21GB、VHDXファイルのサイズは32.16GBに。肥大化したVHDXファイルの問題は、これで完全に解消

筆者紹介

山市 良(やまいち りょう)

岩手県花巻市在住。Microsoft MVP:Cloud and Datacenter Management(2019-2020)。SIer、IT出版社、中堅企業のシステム管理者を経て、フリーのテクニカルライターに。Microsoft製品、テクノロジーを中心に、IT雑誌、Webサイトへの記事の寄稿、ドキュメント作成、事例取材などを手掛ける。個人ブログは『山市良のえぬなんとかわーるど』。近著は『ITプロフェッショナル向けWindowsトラブル解決 コマンド&テクニック集』(日経BP社)。


Copyright © ITmedia, Inc. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。