読者です 読者をやめる 読者になる 読者になる

カイワレの大冒険 Third

技術的なことや他愛もないことをたまに書いてます

PURGE MASTER LOGS構文でbinlogファイル名を指定する必要はなかった

小さい頃からあまり量を食べることができず、年取って量食えなくなったら、霞しか食えなくなるんじゃないかと思っている@masudaKです。 たまにはRuby以外の話をば。

MySQLを運用していれば、expire_logs_daysはどこかで出会うシステム変数でしょう。

The number of days for automatic binary log file removal

ってことで、binlogの保持期間ですね。binlogは吐きますが、ずっと貯めていくとディスクも食うため、定期的に消したいので、expire_logs_daysで期限を設ける。そんな変数です。

そんな大きくない規模なら、この変数で適当に1週間とか指定しておけばいいのですが、規模が大きくなってくると、1日でディスク食いつぶすとかも余裕であるので、その場合はこの変数が使えなかったりします。

そんなときに使うのが、PURGE MASTER LOGS構文すな。

mysql> PURGE MASTER LOGS TO 'mysql-bin.010';

とかってやると、「mysql-bin.010」だけ残して、それより前のbinlogを綺麗に消してくれます。ってことで定期的にバッチで回せば、expire_log_daysより短いスパンで定期的にbinlog消すことができるわけでございます。

僕、ずっとこの構文、ファイル名しか指定できないと思ってたんです(すいませんすいません

んで、会社の人と話してて、その人が「ファイル情報見てるんだから、作成日とか指定できるんじゃね」とかさらりと言うわけです(発想戦闘力がやばい

んで、調べると確かにできる。

mysql> PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26';

こんな感じで、'YYYY-MM-DD hh:mm:ss'フォーマットで指定すればいいと。

ということで、こんな感じでやると、便利な感じで使えるようになる。

# 時(1時間より前のものを削除。59分間のものはキープ)
mysql> PURGE MASTER LOG BEFORE ( NOW( ) - INTERVAL 1 hour );

# 分(1分より前のものを削除。59秒間のものはキープ)
mysql> PURGE MASTER LOG BEFORE ( NOW( ) - INTERVAL 1 minute );

# 秒(1秒より前のものを削除。0.9秒間のものはキープ)
mysql> PURGE MASTER LOG BEFORE ( NOW( ) - INTERVAL 1 second );

感動的でございます。便利便利。

ただ、cronでもjenkinsでもなんでもいいですが、3時間とか6時間とか定期的に実行する場合、どこまでが消されるかは理解しておいたほうがいいでしょう。

たとえば、3時間ごとに実行(0, 3, 6, 9, 12, 15, 18, 21時実行)で、「INTERVAL 6 hour」を使う場合。6時間以上経ったファイルは当然消しますが、時刻の間隔を把握しておかないと6時間以上ってそもそもなんだということになります。 要はこんな感じ。

0時0分0秒: 削除バッチ
0時0分1秒: binlogの0001作成
3時0分0秒: 削除バッチ
6時0分0秒: 削除バッチ(0001は、6時間経ってないので、消されない)
9時0分0秒: 削除バッチ(ここで、消される)

ってことで、作成してから、6時間から8時間59分59秒まで経ったbinlogが削除されます。

まぁ、マニュアル読むの大事だと諭された出来事でございました。