VirtualBOXによる仮想サーバー作りすぎ問題
VirtualBoxで手元にテスト環境を構築していると、論理的にサーバーをポンポン作れるのでとても快適だ。しかしホストOSが管理するファイルシステムに作られたファイルを仮想ストレージとしてマウントするので、ホストOSの邪魔にならない程度の容量で抑える必要がある。FreeBSD9と10と11、CentOS6と7、apache22とapache24、nginx、postgresqlとMySQLなどなど、環境ごとにたくさんサーバー作りたいし、そこで動かす成果物ごとにもサーバーを用意したい。開発環境とテスト環境も分けたりしたい。一つ一つの仮想サーバーはポンポンとコピーしていくらでも環境を増やせる程度の大きさにしておきたい。その昔、FreeBSD9で検証用Webサーバーを作っていたころは、一つのサーバーを8Gバイトで作っていた。FreeBSD11になってからはさすがにしんどくなったのでメインのファイルシステムは16Gバイトで作っている。一つの仮想サーバーにつきこのくらいの大きさなら何も考えずにポンポンコピーしてもテラバイトオーダーのHDDが当たり前になった今、ホストOSには蚊に刺された程度の影響しかない。なので当面は16Gバイトあたりで手を打って置きたい。
容量くってる犯人の特定
そんなこんなで仮想サーバーの少ないストレージでやりくりしていると、うっかりすればすぐに容量を食いつぶしてパンクしてしまう。パンクしたならば、何がいったいファイルシステムの容量を圧迫しているのか確認せねばなるまい。まずはdfコマンドでファイルシステム毎の使用率を確認してみる。
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/ada0p2 15224828 11791176 2215668 84% /
devfs 1 1 0 100% /dev
#
とってもシンプル。一つしかないファイルシステムが84%やばい。ディスク容量監視の仕組みが導入されているシステムならWarningがオペレーターに通知されるレベルだ。今回は一つしかなかったので確認するまでもなかったが、dfでどのファイルシステムがやばいのか分かった。ではWarningを受けたオペレーターはどうすべきか。duコマンドで何のサイズがでっかくなってるのか確かめるのである。
# du -sh /*
1.3M /bin
113M /boot
8.0K /COPYRIGHT
3.5K /dev
4.0K /entropy
2.9M /etc
0B /home
11M /lib
292K /libexec
4.0K /media
4.0K /mnt
4.0K /proc
9.2M /rescue
144K /root
6.8M /sbin
0B /sys
36K /tmp
5.9G /usr
5.2G /var
#
duコマンドは再帰的にサブディレクトリの容量まで表示してくれるので、分かりやすくするために-sでディレクトリごとの合計のみ表示させ、-hで見やすい単位に自動で選択して表示してくれるようにしている。ターゲットには、/* とルート配下をワイルドカードでまとめて指定しているが、.で始まる隠しファイルは計算に含まれないので、”du -d1 -h /”として検索するディレクトリの深さを指定した方が隠しファイルの容量も含めてくれるのでいいのかもしれない。出力結果を見るに/varか/userがでかいので削減の余地がありそうだ。特に容量が変わることが想定される者の入れ物として用意されてる/varが削減できそう。そうやって怪しいディレクトリでduコマンドを打ちまくった結果、”/var/db/mysql/”がとんでもなくでかくなってる事がわかった。
# du -sh /var/db/mysql/*
4.0K /var/db/mysql/auto.cnf
4.0K /var/db/mysql/ca-key.pem
4.0K /var/db/mysql/ca.pem
4.0K /var/db/mysql/client-cert.pem
4.0K /var/db/mysql/client-key.pem
4.0K /var/db/mysql/ib_buffer_pool
256M /var/db/mysql/ib_logfile0
256M /var/db/mysql/ib_logfile1
128M /var/db/mysql/ibdata1
128M /var/db/mysql/ibtmp1
18M /var/db/mysql/mysql
96K /var/db/mysql/mysql-bin.000001
4.0K /var/db/mysql/mysql-bin.000002
4.0K /var/db/mysql/mysql-bin.000003
635M /var/db/mysql/mysql-bin.000004
88K /var/db/mysql/mysql-bin.000005
4.0K /var/db/mysql/mysql-bin.000006
1.4G /var/db/mysql/mysql-bin.000007
4.0K /var/db/mysql/mysql-bin.000008
864K /var/db/mysql/mysql-bin.000009
1.6M /var/db/mysql/mysql-bin.000010
172M /var/db/mysql/mysql-bin.000011
4.0K /var/db/mysql/mysql-bin.000012
447M /var/db/mysql/mysql-bin.000013
4.0K /var/db/mysql/mysql-bin.000014
39M /var/db/mysql/mysql-bin.000015
304M /var/db/mysql/mysql-bin.000016
4.0K /var/db/mysql/mysql-bin.000017
40M /var/db/mysql/mysql-bin.000018
4.0K /var/db/mysql/mysql-bin.000019
39M /var/db/mysql/mysql-bin.000020
172M /var/db/mysql/mysql-bin.000021
705M /var/db/mysql/mysql-bin.000022
4.0K /var/db/mysql/mysql-bin.000023
4.0K /var/db/mysql/mysql-bin.000024
4.0K /var/db/mysql/mysql-bin.000025
4.0K /var/db/mysql/mysql-bin.000026
4.0K /var/db/mysql/mysql-bin.index
1.0M /var/db/mysql/performance_schema
4.0K /var/db/mysql/private_key.pem
4.0K /var/db/mysql/public_key.pem
4.0K /var/db/mysql/server-cert.pem
4.0K /var/db/mysql/server-key.pem
672K /var/db/mysql/sys
8.0K /var/db/mysql/webserver007-slow.log
204K /var/db/mysql/webserver007.err
4.0K /var/db/mysql/webserver007.pid
129M /var/db/mysql/fabuusdb
#
/var/db/mysql/mysql-bin.000001から始まる連番ファイルのなかにとんでもなくでかいやつがいる。
MySQLバイナリログの確認と削除
これはmysqlのバイナリログだ。テーブルの作成やデータの変更などのイベントやそれにかかった時間などが逐一記録されている。ちなみにMySQL5.6のバイナリログは以前のバージョンのバイナリログとは形式が異なったりするので、バージョンをまたいだ使用には注意がいる。MySQLがクラッシュした時にバイナリログからロールバックすることでクラッシュ前の状態まで戻ることができる。”mysql-bin.index”がバイナリログインデックスファイルと呼ばれるもので、ここでバイナリログのファイル名を管理してたりするのでrmコマンドで直接ファイル消したりするとちょっとまずいかもしれない。なので、MySQLにログインして、MySQLのルールの下で削除する。まずは、”show binary log”か”show master log”でバイナリログの一覧を確認する。binaryとmasterはシノニムなのでどっちのコマンドも同じ意味だ。どっちゃでもいい。
# mysql -u superuser -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.19-log Source distribution
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
superuser@localhost [(none)]>
superuser@localhost [(none)]>
superuser@localhost [(none)]> show binary logs;
+------------------+------------+
| Log_name | File_size |
+------------------+------------+
| mysql-bin.000001 | 97002 |
| mysql-bin.000002 | 217 |
| mysql-bin.000003 | 1779 |
| mysql-bin.000004 | 665691996 |
| mysql-bin.000005 | 87867 |
| mysql-bin.000006 | 217 |
| mysql-bin.000007 | 1541206026 |
| mysql-bin.000008 | 3963 |
| mysql-bin.000009 | 828634 |
| mysql-bin.000010 | 1630191 |
| mysql-bin.000011 | 179866341 |
| mysql-bin.000012 | 217 |
| mysql-bin.000013 | 468206036 |
| mysql-bin.000014 | 217 |
| mysql-bin.000015 | 41230880 |
| mysql-bin.000016 | 318507564 |
| mysql-bin.000017 | 217 |
| mysql-bin.000018 | 41687718 |
| mysql-bin.000019 | 217 |
| mysql-bin.000020 | 41230880 |
| mysql-bin.000021 | 180494395 |
| mysql-bin.000022 | 739098608 |
| mysql-bin.000023 | 217 |
| mysql-bin.000024 | 397 |
| mysql-bin.000025 | 217 |
| mysql-bin.000026 | 194 |
+------------------+------------+
26 rows in set (0.00 sec)
“PURGE BINARY LOGS”で消したいログファイル名を指定すると一つ一つ消せる。
superuser@localhost [(none)]> purge master logs to 'mysql-bin.000001';
Query OK, 0 rows affected (0.01 sec)
superuser@localhost [(none)]>
superuser@localhost [(none)]> show binary logs;
+------------------+------------+
| Log_name | File_size |
+------------------+------------+
| mysql-bin.000002 | 217 |
| mysql-bin.000003 | 1779 |
| mysql-bin.000004 | 665691996 |
| mysql-bin.000005 | 87867 |
| mysql-bin.000006 | 217 |
| mysql-bin.000007 | 1541206026 |
| mysql-bin.000008 | 3963 |
| mysql-bin.000009 | 828634 |
| mysql-bin.000010 | 1630191 |
| mysql-bin.000011 | 179866341 |
| mysql-bin.000012 | 217 |
| mysql-bin.000013 | 468206036 |
| mysql-bin.000014 | 217 |
| mysql-bin.000015 | 41230880 |
| mysql-bin.000016 | 318507564 |
| mysql-bin.000017 | 217 |
| mysql-bin.000018 | 41687718 |
| mysql-bin.000019 | 217 |
| mysql-bin.000020 | 41230880 |
| mysql-bin.000021 | 180494395 |
| mysql-bin.000022 | 739098608 |
| mysql-bin.000023 | 217 |
| mysql-bin.000024 | 397 |
| mysql-bin.000025 | 217 |
| mysql-bin.000026 | 194 |
+------------------+------------+
25 rows in set (0.00 sec)
バイナリログは行った操作のログであり途中が抜けるとそれ以前のログが残ってても遡ることができなくなるのであまり意味がない。そのため一つ一つログを消すのは非効率である場合が多い。そのため、日時を指定するとそれ以前のログをまとめて消してくれる仕組みが用意されている。
superuser@localhost [(none)]> purge binary logs before '2017-08-18 01:10:00';
Query OK, 0 rows affected (0.00 sec)
superuser@localhost [(none)]>
superuser@localhost [(none)]> show binary logs;
+------------------+------------+
| Log_name | File_size |
+------------------+------------+
| mysql-bin.000021 | 180494395 |
| mysql-bin.000022 | 739098608 |
| mysql-bin.000023 | 217 |
| mysql-bin.000024 | 397 |
| mysql-bin.000025 | 217 |
| mysql-bin.000026 | 194 |
+------------------+------------+
6 rows in set (0.00 sec)
“RESET MASTER”を使うと、バイナリログを全部いっぺんに消すことができる。”SHOW”と”PURGE”は”MASTER”と”BINARY”がシノニムになっていたのでどっちゃでもよかったが、”RESET”はシノニムになっていないので”MASTER”でなければならない。“RESET MASTER”を使うと、バイナリログのナンバリングがリセットされて”mysql-bin.000001″が作成される。
superuser@localhost [(none)]> reset master;
Query OK, 0 rows affected (0.00 sec)
superuser@localhost [(none)]>
superuser@localhost [(none)]> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 154 |
+------------------+-----------+
1 row in set (0.00 sec)
でっかいファイルがあらかた消えたので、ファイルシステムもすっかり空きができた。
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/ada0p2 15224828 8306040 5700804 59% /
devfs 1 1 0 100% /dev
#
めでたしめでたし。