Hyper-Vの仮想ディスクの最適化って案外手間ですね
2016/07/13 修正
コメントでの指摘によりちょっと調べなおしたところ、 わざわざ SDeleteで0埋めしなくても、ちゃんと切り詰めてくれることがわかりましたので、 手順をバッサリ変更しました。
全面的に開発環境をリモートのHyper-Vサーバに格納して数日が経ちました。 ベッドや外出時には6万ちょっとのお手頃マシンで、仕事机ではMacBookPro15 の Fusion上で、1366x768のサイズの リモートデスクトップのウィンドウを複数表示させながら、まぁなんとかやりくりできるようになってきています。
容量可変の仮想ディスク
VMは仮想ディスクに 可変容量のVHDX形式を指定できます。最初はコンパクトに始めて、データが増えるに従ってディスク容量も勝手に拡張されるというあれです。
ナカバヤシの増えるアルバムみたいなものって説明で分かる世代はどのあたりまででしょうか(^^;
もちろん、拡張時には余計な処理が必要なため、レスポンス重視の環境では容量固定が推奨されていますが、、開発環境ならこっちで十分ですよね。
clean up
さて、勝手にディスク容量が拡張されるということは、ファイル削除などでデータが減った際には 使われなくなった部分が発生するということでもあります。
この使われなくなった部分を適度に解放して、他のVMやシステムに優しい運用を心掛けるとみんなが幸せになれますよね。 VMWare FusionでもそうやってMacのSSDをやりくりしていました。
仮想ディスクがどんどん膨らんでいく
もちろんHyper-Vにもclean upに相当するものがあり、Hyper-Vマネージャのディスクの編集から 仮想ディスクの最適化が行えるようになっています。
なっているはずなのですが、メニューから何度試してもちっとも小さくならないのでおかしいなというのが今日の本題。
肝はreadonlyでのマウント
どうやら Hyper-Vの最適化は、仮想ディスクをreadonlyモードでマウントしてから実行しないといけないらしいです。 (ダイアログに一言書いておけばそれで済む話なのにしないところがMSぽい)
の -Modeの説明に書かれているように、 Quick(削除済となったblockのみを解放)もFull(0埋め領域も併せて調べる)も readonlyでマウントされてる時にのみ動くらしい。
--Quick reclaims unused blocks, but does not scan for zero blocks. (Allowable only if the virtual hard disk is mounted read-only.)
--Full scans for zero blocks and reclaims unused blocks. (Allowable only if the virtual hard disk is mounted read-only.)
手順メモ
仮想ディスクをマウント
mount-vhd 'd:¥hyper-v¥disks¥test.vhdx' -readonly
Quickモードで最適化
Hyper-Vマネージャのディスクの編集の最適化の正体がこれ。ついでなのでコマンドレットでやっちゃいましょう。
optimize-vhd 'd:¥hyper-v¥disks¥test.vhdx' -mode quick
マウントを解除
dismount-vhd 'd:¥hyper-v¥disks¥test.vhdx'
マウント作業がめんどくさいですが、psファイルとして保存しておけば、次からクリック一発ですね。
以下 修正前の手順
最適化の方針が違う?
どうやらHyper-Vの最適化というのは、ディスク領域の中で未使用の0で埋められた領域だけを削除し、そうでない領域は再利用可にするという、ある意味合理的なアプローチらしいということがわかりました。
VMWareのツールだとどちらも解放されていたため、すっかり勘違いをしていました。
というわけで手順メモ
[Windows] Hyper-Vの仮想ディスクの最適化でサイズが圧縮されない場合の対処 | mkoba のお部屋 : DREAMHIVE Staff Blog
を参考に、使われていない領域を 0で埋めてやってから解放することしてみます。
SDeleteを入手
technetのサイトで SDeleteを探してきてダウンロードし、 ゲストOSのsystem32フォルダへコピーします。
(Nano Server用に Sysinternalsもupdateされていて、SDelete64.exeなんてものができていましたので、64bit版OSならこっちを使うのが良さげです)
C:の空き領域を0で埋める
ゲスト側で実行
SDelete64 -z C:
PowerShellで仮想ディスクを最適化
PS> Optimize-VHD [vhd file] -Mode Prezeroed
Prezeroed だと 0で埋められたところを解放してくれるらしいです。 これを Fullにすると、0のところは解放され、 未使用のブロックは再利用される(そこが埋まるまではディスク拡張されない)ということらしいです。
Hyper-Vマネージャでの最適化って Quick(再利用のみ) なのでしょうね・・・
ダイエット成功
90GBだったものが 35GBまで減りました。 ゲスト側の実容量と仮想ディスクのサイズが見過ごせないほど乖離するようになったら実施してやろうと思います。
少しずつPowerShellのコマンドレットにも抵抗がなくなってきました。 どんなものがあるか覚えてしまえば簡単なんですよね・・・