MySQLのバイナリログローテーション事情とSIGUSR1の挙動

MySQLのログローテーションについて、改めて動作を整理してみました。
今回は特に SIGUSR1 シグナルと、バイナリログ(binlog)の扱いについてご説明します。

目次

バイナリログのローテーションと削除の仕組みのおさらい

バイナリログ(binlog)は、一定サイズを超えると自動的に新しいファイルにローテーションされます。
このサイズの上限は、max_binlog_size で制御されており、デフォルトでは 1GB です。

例えば、以下のように設定されている場合:

この場合、1ファイルあたりのバイナリログサイズが約256MBを超えた時点で、新しい binlog ファイル(例:mysql-bin.000002)が作成されます。

ローテートされたバイナリログの保管期間は、expire_logs_days または binlog_expire_logs_seconds によって制御されます。ただし、期限が過ぎたログが即座に削除されるわけではありません

削除が実行されるタイミングは以下の通りです:

  • mysqld の起動(または再起動)
  • FLUSH LOGS または FLUSH BINARY LOGS の実行
  • mysqladmin flush-logs の実行
  • PURGE BINARY LOGS の明示的な実行

📚 MySQL公式ドキュメント – binlog_expire_logs_seconds
📚 MySQL公式ドキュメント – PURGE BINARY LOGS

したがって、ログローテーション設定が有効になっておらず、mysqld を長期間再起動しない場合、バイナリログは残り続けます(これについての改善された動作は後述します)。

ログローテーションの初期設定について

MySQL を RPM パッケージでインストールすると、/etc/logrotate.d/mysql にログローテーション設定がプリセットされています。バージョンによって内容は多少異なるものの、以下のような内容が含まれます。

この設定では、mysqladmin flush-logs(= FLUSH LOGS)によって以下のログファイルが再オープンされます:

  • バイナリログ(binlog)
  • エラーログ
  • スロークエリログ
  • 一般ログ
  • ストレージエンジンログ(例:InnoDB REDO)
  • リレーログ

この処理の結果、logrotate により新しいログファイルが生成されていれば、切り替わり、古いファイルが圧縮・保管されます。

上記設定では、/var/log/mysqld.logは古いファイルはリネームして保管され、新しい/var/log/mysqld.logが作成され、再オープンによって切り替わります。

スロークエリログ、一般ログは、設定に含まれていないため、再オープンはされますがローテーションはされません。

バイナリログ、ストレージエンジンログ、リレーログについては、再オープン時にMySQLによって必要に応じてローテーションされます。

📚 MySQL公式ドキュメント – FLUSH LOGS

mysqladminコマンドの認証と課題

/usr/bin/mysqladmin を使って flush-logs を実行するには、mysqld に対する認証情報が必要です。
プリセットの logrotate 設定ファイルでは、この認証情報が明示されていません。
このような場合、MySQLはOSユーザと同じ名前のユーザで接続するため、 root ユーザが通常使用されます。
root ユーザにパスワードがかかっていなければ、ローテートは成功しますが、本番環境では推奨されません。

対応方法は以下の通りです:

  • mysqladmin -u <user> -p<password> のように認証情報をコマンドに付与
  • mysql_config_editor を使い、ログインパスに資格情報を保存(推奨)
  • /etc/my.cnf~/.my.cnf[mysqladmin] セクションを追加

ただし、平文でパスワードを保存する点、設定の手間がかかる点など、実運用ではやや扱いにくさが残ります。

OSシグナルによるローテーション(SIGUSR1)

MySQL 8.0.19 以降では、UNIX シグナルを用いてログをローテートすることが可能になりました。特に SIGUSR1 によって、次のログが再オープンされます:

  • エラーログ(error log)
  • スロークエリログ(slow log)
  • 一般ログ(general log)

この方法では、MySQLに対する認証情報の保持が不要になり、セキュアかつシンプルにログローテーションを実行できます。

📚 MySQL公式 – UNIX Signal Response


logrotate 設定の変更案

上記の SIGUSR1 を活用すれば、認証情報なしで安全にログローテーションを行えます。logrotate の設定例は以下の通りです:

この方法で、エラーログやスロークエリログのローテーションは対応可能です。
ただし、バイナリログは対象外のため、このシグナルの実装初期(8.0.19~)は、log_binが有効な環境ではやはり mysqladmin flush-logs を使うことが一般的でした。

MySQL 8.0.29 以降の改善点:binlog 自動削除

MySQL 8.0.29 からは、以下の設定がデフォルトで有効になっています:

📚 MySQL公式 – binlog_expire_logs_auto_purge

この設定により、バイナリログの有効期限(binlog_expire_logs_seconds)を超えたログは、自動的に削除されるようになりました。
そのため、SIGUSR1 を使ったローテーションだけでも、バイナリログが蓄積し続けるリスクは無くなりました。

バージョンごとの比較

MySQLバージョン SIGUSR1でのログローテート バイナリログ自動削除 備考
8.0.19〜8.0.28 error / slow / general のみ ×(手動対応) FLUSH LOGS などが必要
8.0.29以降 error / slow / general のみ ◯(自動削除あり) SIGUSR1 で十分な場合が多い

まとめ

MySQL におけるログローテーションは、バージョンによって挙動が異なります。
特に 8.0.29 以降は、SIGUSR1 による安全なログローテーションと、バイナリログの自動削除機能により、運用負荷が軽減されています。

従来のように mysqladmin による認証情報の管理や、手動での FLUSH LOGS を組み込む必要は少なくなりつつあり、今後の構成では SIGUSR1 の活用がより一般的になっていくと思われます。

必要に応じて、ログ削除ポリシーや保持期間の設定も合わせて見直しておくと安心です。

スマートスタイルTECHブログについて

スマートスタイルTECHブログでは、日頃MySQLのサポート業務に従事している有資格者で構成された技術サポートチームがMySQLに関する技術情報を発信しています。データベースのお困りごとはお気軽にご相談下さい。

よかったらシェアしてね!
  • URLをコピーしました!
目次