モーグルとカバとパウダーの日記

モーグルやカバ(EXカービング)山スキー(BC)などがメインの日記でした。今は仕事のコンピュータ系のネタが主になっています。以前はスパム対策関連が多かったのですが最近はディープラーニング関連が多めです。

vagrantのVMファイルサイズを縮小する

今どきHDDの容量不足に苦しむことはあまりないと思いますが、SSDだけのマシンで多数のVMを動かしている場合なんかだと、容量不足であたらしいVMが立てられない… という悲しい状況に陥ることもあると思います。


開発用VM群の中で一台のVMが突出して容量を食っており、調べてみたところそのVMで使ってるMySQL上にアクセスログのような消しても良い、大量のデータが載っており、それを消せば何10Gか減らせることがわかりました。


しかし、実際にVMのファイルサイズが縮小されるまでには結構な手数と時間がかかったのでその手順をまとめました。


この例ではVMの名前やUUID(仮想サーバや仮想ディスクを指定するためのユニークID)が下記のようになっていたとします。

  • vagrantの仮想サーバ名「example」
  • 「example」のVirtualBoxディレクトリ名「example_default_12345」
  • 「example」のサーバUUID名「5612d588-c7f6-48c0-8ac1-0c20a541d030」
  • 「example」の元の仮想ディスクUUID名「1759a61c-7445-4c58-af32-540c348c4ff6」
  • 変換後の仮想ディスクUUID名「fcccb41b-2ed1-46c1-bb37-308610cc1229」

MySQLのデータベースファイルサイズを小さくする

VM内の不要なファイルや、データベース内の不要なデータを削除します。


truncateでテーブルを消してしまえばそれだけでファイルサイズが小さくなるそうです。

しかし、deleteでテーブル自体を残してデータだけを消した場合、データベースファイルのサイズはそのままで、小さくなりません

その場合、MySQLOPTIMIZEコマンドで削除されたデータの分を詰めて小さくします


VirtualBoxクライアント上の、MySQLのrootで

mysql> OPTIMIZE TABLE example_table;

この処理は結構な時間がかかります。


(参考)
第35回 OPTIMIZE TABLEでテーブルを最適化する:MySQL道普請便り|gihyo.jp … 技術評論社
http://gihyo.jp/dev/serial/01/mysql-road-construction-news/0035

使われなくなった領域を0で埋める

仮想ディスクを縮小する際に、使われていない部分の値が「0」である必要があります

単にファイルを削除しただけではこの状況にならないため、ディスク空き容量全体を「0」で埋めて、そのファイルを消すことで、空き容量全体の中身を空にします


VirtualBoxクライアント上のrootで

# dd if=/dev/zero of=zero bs=4k; \rm zero

この処理は結構な時間がかかります。


(参考)
仮想ディスクの圧縮 | VirtualBox Mania
http://vboxmania.net/content/%E4%BB%AE%E6%83%B3%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%81%AE%E5%9C%A7%E7%B8%AE

縮小可能な仮想ディスク形式に変換する

vagrantでマシンを生成するとVMDK形式の仮想ディスクになりますが、このVMDK形式だとディスクサイズを縮小することが出来ません

そこで縮小が可能なVDI形式の仮想ディスクへ変換してやる必要があります


VirtualBoxホスト上で、該当のディスクの情報を取得し、VDI形式に変換した仮想ディスクを新たに作成

$ vboxmanage list hdds
..略
UUID:           1759a61c-7445-4c58-af32-540c348c4ff6
Location:       /home/example/VirtualBox VMs/example_default_12345/_centos-6.6-x86_64-disk1.vmdk
Storage format: VMDK
..略

$ vboxmanage clonehd 1759a61c-7445-4c58-af32-540c348c4ff6 \
  "/home/example/VirtualBox VMs/example_default_12345/example-2.vdi" --format vdi

この処理は結構な時間がかかります。


また、一時的に同サイズの仮想ディスクが作られるため、そのファイルを作れるだけの空き容量が必要です。
一時的に他のVMイメージを他のストレージに移すなどして容量を空けます。


(参考)
VirtualBox の仮想ディスクのサイズを変更する - Qiita
http://qiita.com/niwashun/items/f71b0b805a6f97b514ec

VMの仮想ディスクを縮小する

VDI形式の仮想ディスクだとmodifyhdで「compact」という使われていない部分の仮想ディスクサイズを縮小することが出来ます。


VirtualBoxホスト上で、新たに作られたVDI形式の仮想ディスクの情報を取得し、やっと本来の目的である仮想ディスクの縮小をする

$ vboxmanage list hdds
..略
UUID:           fcccb41b-2ed1-46c1-bb37-308610cc1229
Location:       /home/example/VirtualBox VMs/example_default_12345/example-2.vdi
Storage format: vdi
..略

$ vboxmanage modifyhd fcccb41b-2ed1-46c1-bb37-308610cc1229 --compact

この処理は結構な時間がかかります。


(参考)
仮想ディスクの圧縮 | VirtualBox Mania
http://vboxmania.net/content/%E4%BB%AE%E6%83%B3%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%81%AE%E5%9C%A7%E7%B8%AE

小さくなった仮想ディスクに付けなおす

新しく作られた仮想ディスクはまだVMと紐付いていないため、元々のディスクイメージとの付け替えを行います


VirtualBoxホスト上でVMに紐付いているディスクを付け替えます。
このとき「storageattach」で「storagectl」「port」「device」で指定する値は「showvminfo」で仮想ディスクが結び付けられている行の値になります。
「storageattach」の説明されているエントリではこの値がよく違っているため、たぶんバージョンにより変わることが多いようなので、実際に「showvminfo」で確認してその値を使ったほうが良いです。

$ vboxmanage list vms
..略
"example_default_12345" {5612d588-c7f6-48c0-8ac1-0c20a541d030}
..略

$ vboxmanage showvminfo 5612d588-c7f6-48c0-8ac1-0c20a541d030
..略
IDE Controller (0, 0): /home/example/VirtualBox VMs/example_default_12345/_centos-6.6-x86_64-disk1.vmdk
  (UUID: 1759a61c-7445-4c58-af32-540c348c4ff6)
..略

$ vboxmanage storageattach 5612d588-c7f6-48c0-8ac1-0c20a541d030 --storagectl "IDE Controller" \
  --port 0 --device 0 --type hdd --medium fcccb41b-2ed1-46c1-bb37-308610cc1229

$ vboxmanage showvminfo 5612d588-c7f6-48c0-8ac1-0c20a541d030
..略
IDE Controller (0, 0): /home/example/VirtualBox VMs/example_default_12345/example-2.vdi
  (UUID: fcccb41b-2ed1-46c1-bb37-308610cc1229)
..略


(参考)
VirtualBoxの仮想ディスクをコピーしてみた。
http://takaq1.plala.jp/freebsd/9_0r/kasou_copy.html

動作を確認し不要なディスクイメージを削除する

vagrant upして問題なく起動するか確認し、問題なければ不要となった大きなディスクイメージを削除します。


VirtualBoxホスト上で

$ vboxmanage closemedium disk 1759a61c-7445-4c58-af32-540c348c4ff6 --delete


これだけやってやっとこ場所が空きますが、各処理がだいぶ時間がかかると思ってやってみてください。
自分でその辺の店に行って外付けディスク買ってきて繋いでやる!という気分になります…