/var/lib/mysql 配下がいつの間にかディスクをほぼ埋め尽くしている」「binlog.000xxx というファイルが大量に溜まって容量が足りなくなった」そんな経験を持つLinuxサーバー管理者は少なくありません。バイナリログはMySQLのデータ変更履歴を記録する重要なファイルですが、適切に管理しないと数GB、場合によっては数十GBに膨れ上がり、最終的にはMySQLが書き込みを停止してしまいます。
この記事では、MySQLのバイナリログの仕組みから自動削除の設定(
binlog_expire_logs_seconds)と手動削除(PURGE BINARY LOGS)の実践的な手順を、RHEL 9.4 / MySQL 8.0.36環境で動作確認しながら解説します。この記事のポイント
・binlog_expire_logs_secondsで古いバイナリログを自動削除できる
・PURGE BINARY LOGSで今すぐ手動削除する方法も解説
・レプリケーション中は削除前にSHOW REPLICA STATUSで確認が必須
・SHOW BINARY LOGSでサイズと本数を把握してから操作する
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
MySQLのバイナリログとは
MySQLのバイナリログ(binary log)は、データベースに対する変更操作(INSERT・UPDATE・DELETE・DDLなど)をバイナリ形式で記録したファイルです。主に以下の2つの用途で使われます。・レプリケーション:ソースサーバーのバイナリログをレプリカが読み取り、同じ変更を再実行することでデータを同期します。
・ポイントインタイムリカバリ(PITR):定期バックアップ(mysqldump等)を復元した後、バイナリログを再生することで障害直前の状態までデータを戻せます。
バイナリログは有効にしておくと確かに便利ですが、データ更新が多い本番環境では1日に数百MB~数GBのバイナリログが生成されます。定期的に削除しなければデータディレクトリがあっという間に満杯になります。
バイナリログの有効状態と一覧を確認する
1. バイナリログが有効かどうかを確認する
まずMySQLに接続してバイナリログの有効状態を確認します。mysql -u root -p mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | +---------------+-------+ 1 row in set (0.00 sec)
Value が ON であればバイナリログは有効です。OFF の場合は /etc/my.cnf の [mysqld] セクションに log_bin = /var/lib/mysql/binlog を追加してMySQLを再起動してください。スタンドアロン構成でレプリケーションもPITRも不要であれば、
skip_log_bin(MySQL 8.0以降)を指定して無効化するのも選択肢の1つです。無効化するとファイルが生成されないため、ディスク管理の手間が不要になります。2. バイナリログの一覧とサイズを確認する
現在存在するバイナリログの一覧とファイルサイズを確認します。mysql> SHOW BINARY LOGS;
+---------------+-----------+-----------+ | Log_name | File_size | Encrypted | +---------------+-----------+-----------+ | binlog.000021 | 1073 | No | | binlog.000022 | 1048576 | No | | binlog.000023 | 1048576 | No | | binlog.000024 | 524288 | No | | binlog.000025 | 156 | No | +---------------+-----------+-----------+ 5 rows in set (0.00 sec)
File_size の単位はバイトです。OSコマンドでデータディレクトリ全体の使用量を確認することもできます。# バイナリログファイルの合計サイズを確認する du -sh /var/lib/mysql/binlog.* # データディレクトリ全体の使用量を確認する df -h /var/lib/mysql
mysql> SHOW MASTER STATUS\G
*************************** 1. row *************************** File: binlog.000025 Position: 156 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set, 1 warning (0.00 sec)
File 列が現在書き込み中のファイルです。PURGE BINARY LOGS はこのファイルより前のファイルのみ対象になるため、実行中のファイルを誤って消す心配はありません。バイナリログの自動削除を設定する
1. MySQL 8.0以降:binlog_expire_logs_secondsで保持期間を設定する
MySQL 8.0以降では、binlog_expire_logs_seconds(秒単位)でバイナリログの保持期間を設定します。デフォルトは2592000秒(30日)です。mysql> SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';
+----------------------------+---------+ | Variable_name | Value | +----------------------------+---------+ | binlog_expire_logs_seconds | 2592000 | +----------------------------+---------+ 1 row in set (0.01 sec)
/etc/my.cnf の [mysqld] セクションに以下を追加します。[mysqld] binlog_expire_logs_seconds = 604800
systemctl restart mysqld
SET GLOBAL を使います。ただし、MySQLを再起動すると設定ファイルの値に戻るため、my.cnf への記載も必ず合わせて行ってください。mysql> SET GLOBAL binlog_expire_logs_seconds = 604800; Query OK, 0 rows affected (0.00 sec)
2. MySQL 5.7以前:expire_logs_daysの設定
MySQL 5.7以前ではbinlog_expire_logs_seconds は存在せず、代わりに expire_logs_days(日単位)を使います。MySQL 8.0では非推奨ですが後方互換として動作します(両方を設定した場合は binlog_expire_logs_seconds が優先されます)。# MySQL 5.7以前の設定例(/etc/my.cnf) [mysqld] expire_logs_days = 7
3. 自動削除のタイミングについて
自動削除は以下のタイミングでトリガーされます。・MySQLの起動時:サービス起動時に保持期間を超えたファイルを自動的に削除します。
・バイナリログのローテーション時:現在のファイルが
max_binlog_size(デフォルト1GB)を超えて新しいファイルに切り替わる際に削除します。更新量が少ないサーバーではローテーションが発生しないため、自動削除もかかりにくくなります。その場合は次節の手動削除を使います。
バイナリログを手動で削除する(PURGE BINARY LOGS)
1. 削除前にレプリケーション状態を確認する
レプリケーションを組んでいる場合、レプリカがまだ参照中のバイナリログを削除するとレプリカが壊れます。必ず削除前に確認してください。# ソースサーバーでレプリカの読み取り位置を確認する(MySQL 8.0以降) mysql> SHOW REPLICA STATUS\G # MySQL 5.7以前の構文 mysql> SHOW SLAVE STATUS\G
Relay_Master_Log_File と Exec_Master_Log_Pos でレプリカが現在どのバイナリログのどの位置まで実行済みかを確認できます。この位置より前のファイルのみ削除してください。スタンドアロン構成(レプリケーションなし)の場合はこの確認は不要です。
2. 日付を指定して削除する
指定した日付より前のバイナリログをまとめて削除するにはPURGE BINARY LOGS BEFORE を使います。# 7日前より前のバイナリログを削除する mysql> PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY); Query OK, 0 rows affected (0.03 sec)
SHOW BINARY LOGS で一覧を確認してみます。mysql> SHOW BINARY LOGS; +---------------+-----------+-----------+ | Log_name | File_size | Encrypted | +---------------+-----------+-----------+ | binlog.000024 | 524288 | No | | binlog.000025 | 156 | No | +---------------+-----------+-----------+ 2 rows in set (0.00 sec)
3. ファイル名を指定して削除する
指定したファイル名より前のバイナリログを削除するにはPURGE BINARY LOGS TO を使います。# binlog.000024 より前のファイルをすべて削除する mysql> PURGE BINARY LOGS TO 'binlog.000024'; Query OK, 0 rows affected (0.01 sec)
binlog.000024 自身は残り、それより前の番号のファイルが削除されます。【注意】 現在書き込み中のファイル(
SHOW MASTER STATUS の File 列)は削除できません。削除しようとしても自動的にスキップされます。バイナリログがディスクを圧迫するのを防ぐ運用設計
運用上の観点から、以下のポイントを押さえておきましょう。・保持期間は7日が現実的:本番DB環境では mysqldump によるフルバックアップを毎日取得し、PITRが必要な場合はその日のバイナリログを参照します。7日分あれば十分なケースがほとんどです。デフォルトの30日保持は多くの環境で過剰です。
・max_binlog_sizeを意識する:デフォルトの1GBのままでも問題ありませんが、1ファイルあたりのサイズが大きすぎるとローテーションが発生せず自動削除もかかりにくくなります。更新量に合わせて256MBなどに調整するケースもあります。
・cronでのrm直接削除は厳禁:MySQLが管理するバイナリログをOSコマンドで直接
rm すると、インデックスファイル(binlog.index)との不整合が発生してMySQLが起動できなくなることがあります。削除には必ず PURGE BINARY LOGS を使ってください。・データディレクトリを監視する:
df -h /var/lib/mysql を定期的に確認するか、ZabbixやNagiosなどの監視ツールで使用率が80%を超えたらアラートを出す設定を入れておきましょう。トラブルシュート
「Out of space」でMySQLが停止した場合の緊急対処
ディスクが100%になるとMySQLは書き込みを停止し、「ERROR 28 (HY000): Out of space error writing '...'」が発生するようになります。緊急対処の手順は以下のとおりです。
・ステップ1:MySQLが起動していれば
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 1 DAY) を実行して古いバイナリログを即時削除します。・ステップ2:MySQLが起動しない場合は、一時的に他のファイル(古いログ等)を別の場所に退避してディスク空きを作り、MySQLを起動してからPURGEを実行します。
・ステップ3:対処後は
binlog_expire_logs_seconds の設定を見直し、再発を防ぐ設定に変更してください。binlog_expire_logs_secondsを設定しても削除されない場合
更新量が少なくバイナリログのローテーションが発生しないと、自動削除もなかなか実行されません。この場合は
FLUSH BINARY LOGS でローテーションを強制してから、PURGE BINARY LOGS を実行することで削除できます。# 現在のバイナリログを強制的にローテーションする mysql> FLUSH BINARY LOGS; Query OK, 0 rows affected (0.01 sec) # その後、期限切れファイルを削除する mysql> PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY); Query OK, 0 rows affected (0.00 sec)
「ERROR: Could not find log file」が出る場合
binlog.index に記録されているファイル名とディスク上の実ファイルが食い違っている状態です。PURGE BINARY LOGS を使わずに rm で直接削除したときに起こります。修正するにはインデックスファイルを直接編集して存在しないファイル名の行を削除するか、MySQLを停止して
--skip-log-bin オプション付きで一時起動し、インデックスを再構築します。このトラブルを避けるためにも、バイナリログの削除は必ず PURGE BINARY LOGS コマンドで行うことを徹底してください。まとめ
MySQLのバイナリログ管理で押さえておくべき操作をまとめます。| やりたいこと | コマンド・設定 |
|---|---|
| バイナリログの有効確認 | SHOW VARIABLES LIKE 'log_bin' |
| バイナリログの一覧とサイズ確認 | SHOW BINARY LOGS |
| 現在書き込み中のファイル確認 | SHOW MASTER STATUS |
| 自動削除の保持期間設定(秒) | binlog_expire_logs_seconds = 604800(/etc/my.cnf) |
| 日付を指定して手動削除 | PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY) |
| ファイル名を指定して手動削除 | PURGE BINARY LOGS TO 'binlog.000024' |
| バイナリログを強制ローテーション | FLUSH BINARY LOGS |
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds' で現在の設定を確認して、本番環境に合った値に調整してみてください。
Linux Master Pro Seminar の詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:PostgreSQLのデータベース一覧とディスク使用量を調べる方法|pg_databaseとpg_database_sizeで容量を把握する
- この記事の属するカテゴリ:データーベース管理へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます