バイナリログ(mysql-bin)の運用について

サーバ運用における基本的な監視にディスクの容量監視があります。
ディスクの使用率が100%になるとサービスに影響がでるのはもちろんですが、
サーバ管理者として100%になるまで気が付かないと恥ずかしかったりします。
(落ちた原因はなんだよ!!! → デ、ディスクの使用率が100%です(///)ってなる)


なのでだいたい90%を閾値にディスクの使用率監視をしているのですが、
アラートを検知してそれがMySQLの動いてるサーバだとバイナリログの肥大化を疑います。


バイナリログは更新系のログが記録されますが、放っておくと際限なく増えるので
ディスク逼迫の原因になってしまいます。
ので不要なログは定期的に削除したりしますが、そのまとめ。

expire_logs_days

my.cnfに

[mysqld]
expire_logs_days=10

と設定したり、set global で

mysql> set global expire_logs_days = 10;
Query OK, 0 rows affected (0.02 sec)

mysql> 
mysql> show variables like '%days';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| expire_logs_days | 10    |
+------------------+-------+
1 row in set (0.00 sec)

mysql> 

みたくしてやるとバイナルログが自動削除されます。
↑の例だと10日間経過したバイナリログを削除します。
削除のタイミングはバイナリログのローテーション時かMySQLの再起動等を行った時です。


これはMySQLそのものが管理してくれるので確実です。
てゆうかこれが一番便利で簡単で基本です。

PURGE MASTER LOGS

バイナリログは手動でPURGEコマンドを実行しても消せます。

PURGEコマンドはバイナリログを指定したり、日付を指定して削除できたりします。

例:

PURGE MASTER LOGS TO 'mysql-bin.010';
PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26';
BEFORE 異型の date 引数は 'YYYY-MM-DD hh:mm:ss' フォーマットになり得ます。MASTER と BINARY は同義語です。

http://dev.mysql.com/doc/refman/5.1/ja/purge-master-logs.html

マニュアルの例が分かりやすのでまんま引用しますが、
BEFORE 'YYYY-MM-DD hh:mm:ss'を指定してやると日付を基準に消せるので結構便利です。
cronなんかで簡単なスクリプトを仕込んでおけば定期的にバイナリログを削除できます。

ただPURGEの場合はあくまでMySQLのコマンドなので、MySQLのアカウント/パスワードをどうするかを
考えるのが若干めんどくさいです。若干

スクリプトを使って圧縮/削除する。その1

基本的にはexpire_logs_daysを設定しますが、バイナリログを消さずに圧縮しといてって良く言われます。
自分の管轄外のサーバだったりすると、消すのはどうもなぁ…とりあえず圧縮しとくかってやったりします。


個人的には圧縮なんてやらずに消しちゃえよ派なんですが。。
まぁ本気を出せばバイナリログからリカバリが可能だったりするので
そういうの考えると…どっちでもいいんじゃね派でいいやもう


で圧縮処理を入れるとMySQLの管理から外れてしまうので別にスクリプトを組む必要があります。
こんな感じ。

#!/bin/sh

DIR=/var/lib/mysql # datadir
BINLOG="mysql-bin.[0-9]*" # log-bin

COMMAND="find $DIR -maxdepth 1 -type f -name $BINLOG"

MTIME=10
for FILE in `$COMMAND -mtime +$MTIME`; do
    #/sbin/fuser -s $FILE || echo "nice rm $FILE"
    /sbin/fuser -s $FILE || nice rm $FILE
done


MTIME=5
for FILE in `$COMMAND -mtime +$MTIME`; do
    #/sbin/fuser -s $FILE || echo "nice gzip $FILE"
    /sbin/fuser -s $FILE || nice gzip $FILE
done

簡単なシェルスクリプトですが、
10日経過したバイナリログは削除、5日経過したバイナリログは圧縮
としています。
こんなのをcronで定期的に実行して管理します。

スクリプトを使って圧縮/削除する。その2

その1は日付の経過で管理してますが、バイナリログの個数で管理したいときもあります。
そんなときは↓こんなん。

#!/bin/sh

DIR=/var/lib/mysql # datadir
BINLOG="mysql-bin.[0-9]*" # log-bin

# rm
COUNT=`find $DIR -maxdepth 1 -type f -name $BINLOG | wc -l`

REMOVE=50
if [ $COUNT -gt $REMOVE ]; then
    NUM=`expr ${COUNT} - ${REMOVE}`
    for FILE in `ls -1rt \`find $DIR -maxdepth 1 -type f -name $BINLOG\` | head -${NUM}`; do
      #/sbin/fuser -s $FILE || echo "nice rm $FILE"
      /sbin/fuser -s $FILE || nice rm $FILE
    done
fi

こっちはバイナリログが50個以上で削除…みたいにしてます。

まぁ結局

expire_logs_daysでいいんじゃね派