朝から昼寝

整理しておきたいIT関連の小ネタ

仮想ディスクの未使用領域が解放される仕組み

概要

仮想環境のストレージ空き容量を管理する上で、未使用領域の解放に関する各レイヤの仕様を理解しておくことは重要です。
本記事は、VM上で削除したファイルの容量分、ストレージの空き容量が確保されるまでの仕組みをとめたものです。対象は主にシンプロビジョニング(スパース)が有効なストレージ環境を使用するVMware vSphere 6系や7系以降ですが、仕組みは他の仮想環境でも同様です。
なお本記事では、圧縮機能や重複排除機能等、またストレージ自体やバックアップの設計については触れていませんが、それらを考慮する上でも本記事の内容は基礎的な要素の一つです。

本記事の目的

  • VMのディスク使用量を削減した際に、ストレージの空き容量が確保されるまでの仕組みを把握する。

目次

基本

概要

仮想環境において、特に高集約化を図る場合、ストレージ利用効率を高めるためシンプロビジョニング機能が使用されることが多いです。
ただし、VMに割り当てたディスク容量の合計が、ストレージの物理容量を超える設計(オーバーコミット)になることもあるため、ストレージ空き容量を適切に管理することは重要です。

仮想環境では、主に以下の2か所でシンプロビジョニング機能が使用されます。

  • シンプロビジョニング(スパースファイル)が有効な仮想ディスク(仮想基盤のレイヤ)
  • シンプロビジョニングが有効なストレージボリューム(仮想基盤が使用するストレージのレイヤ)

本記事では、上記環境における下記動作の仕組みについて記載します。

  • ゲストOS上で不要ファイルを削除し、(ゲストOSから見て)ディスク空き容量を十分に確保したのに、仮想基盤上で仮想ディスクのサイズが小さくならない。
  • ゲストOS上で不要ファイルの削除後、仮想ディスクのサイズを小さくしたい場合には、ゲストOS上で未使用領域のゼロクリアを行ってから、仮想基盤上で未使用領域の解放(vSphereの場合はpunchzero)を行う必要性がある。
  • 最近のVMFS(6以降)では、未使用になった領域に対するストレージボリューム上の割り当てを自動的に解放(マッピング解除)し、ストレージボリューム上の空き領域を確保してくれる。

これらの仕組みは、長期間に渡ってディスクの書き込みと削除が繰り返し行われるシンプロビジョニング環境では把握しておいた方が良いものです。

ゲストOS上で不要ファイルを削除したのに、仮想ディスクのサイズが小さくならない

まず、なぜゲストOS上で不要ファイルを削除しただけでは仮想ディスクのサイズが小さくならず、ストレージの空き容量を確保できないのかについて記載します。

シンプロビジョニングが有効な仮想環境におけるファイル削除
シンプロビジョニングが有効な仮想環境におけるファイル削除

  • (図中の左) ゲストOS上でファイルを削除した場合、そのインデックス情報が削除されるだけで、ファイルのデータは通常残ります。別の言い方では、ゲストOSが使用するファイルシステム(WindowsであればNTFS等)のメタデータにおいて、そのファイルが存在しないものとして扱われるようになるだけで、ディスクに書き込まれたデータ自体は削除されません。
  • (図中の中央) このままでは、VMFS(仮想基盤のファイルシステム)上は、そのゲストOSの仮想ディスクサイズが小さくなることはありません。仮想基盤としては、ファイルを削除したことも、それによって空き領域を増やせることも検知できないためです。
  • (図中の右) ストレージ側のボリュームがシンプロビジョニング対応であったとしても、VMFS上で仮想ディスクのサイズが小さくならないのであれば、その使用量が削減されることはありません。

ゲストOS上でのゼロクリアと、仮想基盤上での未使用領域の解放により空き容量を確保可能

シンプロビジョニングが有効な仮想環境における空き容量確保
シンプロビジョニングが有効な仮想環境における空き容量確保

  1. ゲストOS上で削除されてもディスクに残ったままになっているファイルのデータを削除する方法は、ゼロクリア(0埋め)です。WindowsSDeleteコマンド、Linux/Unixではddコマンドによりゼロクリアが可能です(後述)。
    ゼロクリアにより、対象ファイルシステムの未使用領域全てに0が書き込まれます。0を書き込んでも、あくまで未使用領域は未使用のままなので、ゼロクリアの前後で基本的にファイルシステムの使用量は変化しません(ゼロクリア処理中は一時的に使用量が増える場合があります(細かい話なのでこれも後述))。
  2. ゼロクリアが実行された仮想ディスクに対し、仮想基盤上でpunchzero (vmkfstools -Kコマンド)を実行することにより、その仮想ディスクの容量を小さくすることができます。仮想ディスク容量のうち、ゼロクリアされた領域(未使用領域)分の容量は削減され、それ以外の使用済み領域分の容量のみが残ります。仮想ディスクの容量が小さくなった分、VMFS上の空き領域が増えます。
    このような仮想ディスクのゼロクリア領域を解放する方法は、仮想環境ごとに異なります。vSphereの場合はvmkfstools -Kコマンドですが、Hyper-Vの場合はMount-VHDコマンドレット、VirtualBoxの場合はvboxmanage modifyhd [UUID] --compactコマンドがあります。
    この他に、Storage vMotionにより同様にゼロクリア領域を解放できる場合がありますが、条件等の詳細はVMware社のdocsに記載があります。
  3. VMFSの空き領域が増えると、(VMFS6以降の場合は)自動的にストレージ側でもその分の容量が解放されるよう処理され、ストレージ上のボリュームの空き領域が増えます。
    この処理はストレージに対するSCSI UNMAP(マッピング解除)やReclaim(再クレーム、レクラメーション)と呼ばれ、VMFS6未満の場合はesxcli storage vmfs unmapコマンドにより手動実行する必要性がありましたが、VMFS6から自動的に実行されるようになりました。詳細はVMware社のdocsに説明があります。この処理は、ストレージ側のボリュームにおいてシンプロビジョニングが有効であり、マッピング解除操作をサポートしている場合に実行可能です。

上記のように、未使用領域の解放に関する各レイヤの仕様を理解することで、VMのディスク使用量を削減した際にストレージの空き容量が確保されるまでの仕組みを把握できます。

詳細

SDelete、ddによるゼロクリア

ゲストOS上で以下のコマンドを実行することで、未使用領域のゼロクリアが可能です。
これらのコマンドの実行時には、一時的にファイルシステムの空き容量が枯渇するため、重要なデータの書き込みエラーによるデータロス等が発生しないよう、必要に応じサービス停止して実行することをお勧めします。

WindowsでCドライブの未使用領域をゼロクリアする場合、以下のコマンドを実行します。

> SDelete -z C:

SDeleteコマンドは以下ページから入手できます。
- MicrosoftのSDelete配布ページ
仕組みは、上記URLの解説を理解しきれてはいないので一部推測になりますが、指定したドライブの空き領域と同じだけのサイズのファイルを作成(おそらくゼロ書き込み)し、その後それを削除するものと思われます。未使用領域を直接操作することは難しいので、そのような仕組みになると考えられます。

Linuxで/(ルート)パーティションの未使用領域をゼロクリアする場合、以下のコマンドを実行します。

# dd if=/dev/zero of=/zerofile; rm -f /zerofile

/dev/zeroの内容(0)を任意のファイル(/zefofile)に書き出した後、空き容量が無くなり次第ddコマンドがエラーで終了します。その後すぐにrmコマンドで作成したファイルを削除するというものです。