要約
開発用 CentOS サーバーでファイル書き込みが失敗するようになったので原因を調査したところ、MySQLのバイナリログがディスク容量を消費していたことがわかり、古いバイナリログが自動削除されるように設定しました。
以下ではディスク容量不足になった場合の調査方法およびMySQLのバイナリログ自動削除の設定方法について記載しておきます。特に高度なことはしていません。
ディスク容量確認
[root@develop ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda3 97G 92G 17M 100% /
tmpfs 499M 0 499M 0% /dev/shm
/dev/vda1 243M 146M 84M 64% /boot
/ の空き容量がないことがわかります。df コマンドはディスク・ドライブの空き容量を表示してくれるコマンド(df = disk free)で、-h オプション( = --human-readable)をつけておくと K, M, G などの単位が自動で良い感じになります。
ディスク容量不足の原因を探す
[root@develop ~]# du -sh /*
787M /backup
8.0M /bin
...
51G /var
du コマンドは引数で指定したファイル・ディレクトリが使用しているディスク容量を教えてくれます(du = disk usage)。-s ( = --summarize) オプションをつけておかないと下層含めた全ファイルのファイルサイズが全部リストで出力されてしまいます。 -h は df コマンドと同じです。上記コマンドでルート直下にある各ファイル・ディレクトリのサイズを表示します。
結果みた感じ /var の容量がやばいので、今度は du -sh /var/*
とします。これを繰り返して下層のどのファイルがディスク容量を消費しているのか突き止めていきます。
削除済みのファイルでも実行中のプロセスが参照し続けているとファイルシステムから削除されないらしいので、親ディレクトリのサイズが子のサイズの総和にならない場合は、そのあたりが関係しているかもしれません。そういえば上の df コマンドで 97G - 92G = 17M かのような表示になってしまっているのも、それ関係? 今回は関係ないのでそのあたりの細かい調査は省略します。
原因は /var/lib/mysql/ ということがわかった
上記の方法で怪しいディレクトリを絞り込んでいった結果 /var/lib/mysql の容量がやたらとでかいことがわかりました。中身を見てみます。
[root@develop mysql]# ls -lah
total 50G
...
-rw-rw---- 1 mysql mysql 7.0M Jan 11 2013 mysqld-bin.000001
-rw-rw---- 1 mysql mysql 125 Jan 11 2013 mysqld-bin.000002
-rw-rw---- 1 mysql mysql 456 Jan 11 2013 mysqld-bin.000003
-rw-rw---- 1 mysql mysql 7.6M Feb 2 2013 mysqld-bin.000004
-rw-rw---- 1 mysql mysql 49M Apr 27 2013 mysqld-bin.000005
-rw-rw---- 1 mysql mysql 128M Sep 1 2013 mysqld-bin.000006
-rw-rw---- 1 mysql mysql 106 Sep 1 2013 mysqld-bin.000007
-rw-rw---- 1 mysql mysql 125 Sep 2 2013 mysqld-bin.000008
-rw-rw---- 1 mysql mysql 6.1M Dec 3 2013 mysqld-bin.000009
-rw-rw---- 1 mysql mysql 1.1M Jan 7 2014 mysqld-bin.000010
-rw-rw---- 1 mysql mysql 9.9K Jan 7 2014 mysqld-bin.000011
-rw-rw---- 1 mysql mysql 3.1M Feb 14 2014 mysqld-bin.000012
-rw-rw---- 1 mysql mysql 766K May 11 2014 mysqld-bin.000013
-rw-rw---- 1 mysql mysql 125 Jan 29 2015 mysqld-bin.000014
-rw-rw---- 1 mysql mysql 125 Jan 29 2015 mysqld-bin.000015
-rw-rw---- 1 mysql mysql 4.2M Apr 20 2015 mysqld-bin.000016
-rw-rw---- 1 mysql mysql 131K Apr 20 2015 mysqld-bin.000017
-rw-rw---- 1 mysql mysql 25K Apr 20 2015 mysqld-bin.000018
-rw-rw---- 1 mysql mysql 19M Apr 27 2015 mysqld-bin.000019
-rw-rw---- 1 mysql mysql 6.3M Jun 23 2015 mysqld-bin.000020
-rw-rw---- 1 mysql mysql 192M Dec 8 2015 mysqld-bin.000021
-rw-rw---- 1 mysql mysql 1.9M Mar 24 2016 mysqld-bin.000022
-rw-rw---- 1 mysql mysql 125 May 26 2016 mysqld-bin.000023
-rw-rw---- 1 mysql mysql 70K Jan 28 04:37 mysqld-bin.000024
-rw-rw---- 1 mysql mysql 1.1G May 18 11:55 mysqld-bin.000025
-rw-rw---- 1 mysql mysql 1.1G May 19 05:23 mysqld-bin.000026
-rw-rw---- 1 mysql mysql 1.1G May 19 22:53 mysqld-bin.000027
-rw-rw---- 1 mysql mysql 1.1G May 20 16:21 mysqld-bin.000028
-rw-rw---- 1 mysql mysql 1.1G May 21 09:50 mysqld-bin.000029
-rw-rw---- 1 mysql mysql 1.1G May 22 03:18 mysqld-bin.000030
-rw-rw---- 1 mysql mysql 1.1G May 22 23:43 mysqld-bin.000031
-rw-rw---- 1 mysql mysql 1.1G May 23 18:29 mysqld-bin.000032
...
-rw-rw---- 1 mysql mysql 520M Jun 28 18:42 mysqld-bin.000073
...
ls は(あえて書くまでもないですが)ファイル一覧を表示してくれるコマンド。 -a (= --all)で隠しファイル含めてすべて表示。-l (= --format=long, --format=verbose)はファイル名以外にも諸々ファイルの詳細を出してくれます。 -h はやはり df と同じです。ちなみに ls は list の略です。
さて、上記の通り mysqld-bin.* というファイルたちがやたらと容量を食っているようです。特に5月18日あたりからやばいことになっています。このログ生成の原因となっているSQL実行が必要なものであることはわかっているので、今回は必要のない古いバイナリログが削除されるように設定することとしました。
/etc/my.cnf の [mysqld] グループ内に以下を追加。
expire_logs_days=7
設定後は service mysqld restart
を実行します。このときディスク容量不足で起動失敗した(/var/log/mysqld.log にエラー出力される)ため、手動で古いバイナリログ消した上で service mysqld start
を実行。これで過去7日を超える古いバイナリログファイルが削除されました。
[root@develop ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda3 97G 50G 43G 54% /
tmpfs 499M 0 499M 0% /dev/shm
/dev/vda1 243M 146M 84M 64% /boot
これで解決です。