MySQLでバイナリログを定期的に削除するmy.cnfの設定(expire_logs_days)

Djangoを使っていて、たまにsyncdb(モデルをデータベースに更新させる作業)をすると、応答がなくなる時があります。



MySQLは更新等のバイナリログを残していて、リストア(復旧)しやすいように設計されています。

バックアップ(スナップショット)をどこかの時点でとっておいて、そのあとの流れをバイナリログ等で補完するような運用が考えられます。


一方、更新が多いサービスは、このバイナリログを放置しておくと、データ容量が大きくなりすぎてしまいます。



今回は、この設定を変更して、適切なディスク容量を使えるようにしたいと思います。


応答がなくなるコマンド例(注:すぐデータベースのステータスを確認しましょう。)
#python ./manage.py syncdb 
データベースの容量確認

その場合は利用しているデータベース(MySQL)のステータスを確認してみましょう。

データベースサーバに接続して、まずは容量確認。

# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/hda2             18222732  17283948         0 100% /
/dev/hda1               101086     23801     72066  25% /boot
tmpfs                   255264         0    255264   0% /dev/shm


使用量が100%になっています。


ディスク構成はさくらのVPS(エントリーレベル)です。


少しヘヴィなサービスだとすぐ容量不足になりそうです。


またディスク容量が100%だと、同じサーバで運営している他のサービスにも影響が出てしまいます。



ここを改善していきましょう。




mysqlのバックアップデータ(バイナリログ)

mysqlのバックアップデータを確認してみましょう。



ログが配置してあるディレクトリに行ってください。

MySQL5.0以下ならdatadirで指定したディレクトリと同じにあります。

5.1以上ならPIDファイルと同じディレクトリにあります。


現在のMySQLのプロセスを見て、どこに書き込んでいるか判断してください。


なお自分で指定したい場合はmy.cnfに記述してください。(別のエントリで書きます。)



# ll /var/lib/mysql/

-rw-rw---- 1 mysql mysql      18410 Jan  1 04:10 mysql-bin.000001
-rw-rw---- 1 mysql mysql     729901 Jan  1 04:10 mysql-bin.000002
-rw-rw---- 1 mysql mysql      18410 Jan  1 04:10 mysql-bin.000003
-rw-rw---- 1 mysql mysql     729901 Jan  1 04:10 mysql-bin.000004
-rw-rw---- 1 mysql mysql        125 Jan  1 04:33 mysql-bin.000005
-rw-rw---- 1 mysql mysql      18410 Jan  1 04:28 mysql-bin.000006
-rw-rw---- 1 mysql mysql     729901 Jan  1 04:28 mysql-bin.000007
-rw-rw---- 1 mysql mysql        125 Jan  1 04:36 mysql-bin.000008
-rw-rw---- 1 mysql mysql        125 Jan  1 04:36 mysql-bin.000009
-rw-rw---- 1 mysql mysql 1073742386 Jan  5 21:55 mysql-bin.000010
-rw-rw---- 1 mysql mysql 1073741991 Jan  7 19:06 mysql-bin.000011
-rw-rw---- 1 mysql mysql 1073741893 Jan  9 16:43 mysql-bin.000012
-rw-rw---- 1 mysql mysql 1073742234 Jan 11 07:38 mysql-bin.000013
-rw-rw---- 1 mysql mysql 1073741919 Jan 12 15:02 mysql-bin.000014
-rw-rw---- 1 mysql mysql 1073741954 Jan 14 08:54 mysql-bin.000015
-rw-rw---- 1 mysql mysql 1073742007 Jan 15 23:54 mysql-bin.000016
-rw-rw---- 1 mysql mysql 1073741995 Jan 17 16:22 mysql-bin.000017
-rw-rw---- 1 mysql mysql 1073742178 Jan 19 12:08 mysql-bin.000018
-rw-rw---- 1 mysql mysql 1073741931 Jan 21 02:12 mysql-bin.000019
-rw-rw---- 1 mysql mysql 1073742031 Jan 22 16:33 mysql-bin.000020
-rw-rw---- 1 mysql mysql  525931183 Jan 23 17:14 mysql-bin.000021

1月5日以降のログがものすごくなっています。



log-binの確認

初期のmy.cnfを確認してみましょう。

vi /etc/my.cnf
# Replication Master Server (default)
# binary logging is required for replication
log-bin=mysql-bin


log-binは記述があったと思います。


もしなければ追加してください。



問題は、expire_logs_daysが明示的にmy.cnf設定されていない点です。


expire_logs_daysの確認

expire_logs_daysは、バイナリログを自動削除する日数です。


初期値は0(my.cnfにも5.1では初期に記述がないようです。)になっています。


mysqlから確認してみましょう。

#mysql -u root -p
mysql> SHOW GLOBAL VARIABLES like 'expire_logs_days';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| expire_logs_days | 0     |
+------------------+-------+
1 row in set (0.01 sec)

0に設定(自動削除しない)されていることがわかります。

my.cnfの設定(expire_logs_days)

my.cnfに書き込みましょう。例は5日間のバイナリログを残す場合です。
(バックアップ等の運用と相談して決めてください)

#vi /etc/my.cnf
expire_logs_days = 5

mysqlを再起動してよいかどうかで、設定更新の方法が異なります。


以下を参考にしてください。

再起動してもよい場合

通常どおり再起動します。

# /etc/rc.d/init.d/mysql restart
Shutting down MySQL.....                                   [  OK  ]
Starting MySQL...............                              [  OK  ]


mysqlから確認してみましょう。

#mysql -u root -p
mysql> SHOW GLOBAL VARIABLES like 'expire_logs_days';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| expire_logs_days | 5     |
+------------------+-------+
1 row in set (0.00 sec)

完成です。



再起動しないで変更する場合

mysqlから設定します。

#mysql -u root -p
mysql> SET GLOBAL expire_logs_days = 5;
Query OK, 0 rows affected (0.06 sec)

mysql> SHOW GLOBAL VARIABLES like 'expire_logs_days';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| expire_logs_days | 5     |
+------------------+-------+
1 row in set (0.00 sec)

できています。完成です。

削減の効果

# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/hda2             18222732   6412260  10869868  38% /
/dev/hda1               101086     23801     72066  25% /boot
tmpfs                   255264         0    255264   0% /dev/shm

10GB近く削減されました。

バイナリログを最後に見てみましょう。

-rw-rw---- 1 mysql mysql 1073741931 Jan 21 02:12 mysql-bin.000019
-rw-rw---- 1 mysql mysql 1073742031 Jan 22 16:33 mysql-bin.000020
-rw-rw---- 1 mysql mysql  897682000 Jan 24 06:25 mysql-bin.000021
-rw-rw---- 1 mysql mysql        106 Jan 24 06:25 mysql-bin.000022


5日前のバイナリログが自動削除されています。

成功です。