MySQL: 不要なバイナリログを削除(パージ)する shell
MySQLでレプリケーションってMASTERが吐き出すバイナリログをリレーしてレプリケーションをするわけなのですが、そのままにしておくとMasterにバイナリログがどんどん溜っていきディスクを圧迫してきます。自動削除の機能もあるのだけど・・MASTERのバイナリログをSLAVEが処理しているかなんて見ないで削除してしまう(そもそもレプリケーションのための設定ではない)ので、ちょっと怖いなあーといった感じですね。 そんなこんなで、全てのSLAVEが処理済のバイナリログを削除(purge)するshellを作ってみました。最近shellばっかり作っているな・・。
バイナリログ自動削除オプションは、例えば以下のような設定をMASTERのmy.cnfに加えてあげることによって、下記例ですと10日以上経過したログファイルを削除するってオプションなんですが、ここでは今回触れません。 [shell] set-variable = expire_logs_days=10 [/shell]
そこでこんなshellを作ってみました。
[shell]
cat master_binlog_purge.sh
!/bin/bash
#
スレーブのbin-log進捗状況を確認し、処理済みのbinlogをパージする
#
tmp ディレクトリ
_workdir=/tmp
db_config (マスター、スレーブ共にアカウントは同じことを前提)
dbuserid=root dbpasswd=rootpassword
master 情報を記載する
_master=192.168.101.44
slave 情報を記載する
slavegrp=() slavegrp=("${slavegrp[@]}" "dbm01") slavegrp=("${slavegrp[@]}" "dbm02") slavegrp=("${_slavegrp[@]}" "dbm03")
bin-logのファイル名を取得する
_binlog=()
テスト用(実際の利用時は消してください)
log_bin="mysql-bin.999999" echo $log_bin > ${_workdir}/sort.in
各SLAVEのMASTER_LOG_FILEのファイル名を取得する
for *1
do
log_bin=$(mysql -h ${slavegrp[$I]} -u ${dbuserid} -p${dbpasswd} -e 'show slave status\G;' | grep -i " Master_Log_File" | echo awk -F: '{print $2}';
)
echo $log_bin >> ${_workdir}/sort.in
done
ファイル${workdir}/sort.inを数値のソートし、ソート結果をファイル${workdir}/sort.outに出力
sort -r ${workdir}/sort.in > ${workdir}/sort.out <--- 降順ソートはこれ
sort ${workdir}/sort.in > ${workdir}/sort.out
ファイル${_workdir}/sort.outの内容を読み込み、配列に格納
while read SORTFILE do binlog=("${binlog[@]}" $SORTFILE) done < ${_workdir}/sort.out
実運用時は不要(チェック用)
for *2 do echo ${binlog[$I]} done
マスターDBのログをPURGEする
mysql -h ${master} -u ${dbuserid} -p${dbpasswd} -e "PURGE MASTER LOGS TO '${binlog[0]}';"
テンポラリファイルの削除
rm -f ${workdir}/sort.in rm -f ${workdir}/sort.out
exit 0
[/shell]
ざっくりした説明ですと、複数のスレーブのステータスを参照して、一番若い番号のbinlogを抽出して、その番号でマスタのバイナリログをパージするといったshellです。
MASTERで手動で行うPURGEコマンドはこんな感じ [sql] mysql> PURGE MASTER LOGS TO 'mysql-bin.000020'; Query OK, 0 rows affected (2 min 8.51 sec) [/sql] これだと、 mysql-bin.000020 以前(つまりmysql-bin.000020は削除されない)のバイナリログが削除されるわけです。単純にはこれをしたいがために、スレーブのバイナリログの進行状況を確認するのですが、複数のスレーブを確認するのは面倒なので、shell化しましたよ!って話でした。