MySQLのバイナリログが原因でディスクが枯渇した場合の対処方法

# はじめに
本記事はMySQLを使用していて、バイナリログが原因でディスクが枯渇した場合の対処方法について記載しています。

MySQLで使用しているデータ領域が枯渇し、ディスク使用率が100%になりMySQLが起動できない事象が発生しました。

原因を調査したところ、データ領域として使用している` /data/mysql/`配下のディレクトリに、1.1Gのバイナリログが大量に出力されていることを確認。

バイナリログを`puge`して削除したいがMySQLも起動できないため、mysqlにもログインできません。
このようなケースの暫定対応と恒久対応について記載します。

## 暫定対応
まずは、rmコマンドで一番古いバイナリログを削除し、`df`コマンドを実行して空き容量が確保されたことを確認します。

`# rm /data/mysql/binlog.000169`


```console
/dev/sdb1        50G   49G  1.1G  98% /data
```

次にmysqlを起動。正常に起動できたことを確認し、mysqlにログインする。

`# systemctl start mysql`
`# systemctl status mysql`
`# mysql -u root -p`

以下のコマンドを実行し、バイナリログの状況を確認する。

- 最新のバイナリログ

```sql
mysql> SHOW MASTER STATUS\g;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000215 |      155 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
```

- バイナログの一覧

```sql
mysql> SHOW MASTER LOGS;
+---------------+------------+-----------+
| Log_name      | File_size  | Encrypted |
+---------------+------------+-----------+
| binlog.000170 | 1073742751 | No        |
| binlog.000171 | 1073751257 | No        |
| binlog.000172 | 1073757631 | No        |
| binlog.000173 | 1073755121 | No        |
| binlog.000174 | 1073752838 | No        |
| binlog.000175 | 1073743951 | No        |
| binlog.000176 | 1073748347 | No        |
| binlog.000177 | 1073751179 | No        |
| binlog.000178 | 1073763386 | No        |
| binlog.000179 | 1073765359 | No        |
| binlog.000180 | 1073745938 | No        |
| binlog.000181 | 1073763697 | No        |
| binlog.000182 | 1073744490 | No        |
| binlog.000183 | 1073761859 | No        |
| binlog.000184 | 1073775954 | No        |
| binlog.000185 | 1073757908 | No        |
| binlog.000186 | 1073773373 | No        |
| binlog.000187 | 1073755666 | No        |
| binlog.000188 | 1073743518 | No        |
| binlog.000189 | 1073782889 | No        |
| binlog.000190 | 1073756995 | No        |
| binlog.000191 | 1073770640 | No        |
| binlog.000192 | 1073743582 | No        |
| binlog.000193 | 1073757032 | No        |
| binlog.000194 | 1073754014 | No        |
| binlog.000195 | 1073757718 | No        |
| binlog.000196 | 1073746065 | No        |
| binlog.000197 | 1073745350 | No        |
| binlog.000198 | 1073751875 | No        |
| binlog.000199 | 1073745702 | No        |
| binlog.000200 | 1073754484 | No        |
| binlog.000201 | 1073762857 | No        |
| binlog.000202 | 1073761196 | No        |
| binlog.000203 | 1073755084 | No        |
| binlog.000204 | 1073836164 | No        |
| binlog.000205 | 1073745617 | No        |
| binlog.000206 | 1073753921 | No        |
| binlog.000207 | 1073771413 | No        |
| binlog.000208 | 1073764906 | No        |
| binlog.000209 | 1073767754 | No        |
| binlog.000210 | 1073781899 | No        |
| binlog.000211 | 1073744615 | No        |
| binlog.000212 | 1073744221 | No        |
| binlog.000213 | 1073770872 | No        |
| binlog.000214 |  323286661 | No        |
| binlog.000215 |     398814 | No        |
| binlog.000216 |     896660 | No        |
+---------------+------------+-----------+
47 rows in set (0.03 sec)
```

暫定対応として蓄積された不要なバイナリログを削除する。
toは、指定したbinlog以前のファイルを削除する。

- バイナリログ削除

```sql
mysql> PURGE MASTER LOGS TO 'binlog.000212';
Query OK, 0 rows affected, 1 warning (0.00 sec)
```

再度、`df`コマンドを実行してディスク使用率が低下したことを確認。

```console
/dev/sdb1        50G  4.0G   46G   8% /data
```

## 恒久対応
事象の直接原因はMySQLの[仕様](https://dev.mysql.com/doc/refman/8.0/en/replication-options-binary-log.html#sysvar_log_bin)により、デフォルトの設定でバイナリログの出力が有効なため、バイナリログが蓄積され続けていたこと。

>以前のMySQLバージョンでは、バイナリロギングはデフォルトで無効になっており、--log-binオプションを指定した場合は有効になり ました。MySQL 8.0以降では、--log-binオプションを指定するかどうかにかかわらず、デフォルトでバイナリロギングが有効になっています。

恒久対応としてログローテーションの設定を行い、バイナリログが蓄積されないように設定変更を行う。
設定変更後は、MySQLを再起動する。

`# vi /etc/mysql/mysql.conf.d/mysqld.cnf`

```console
# binlog rotation
expire_logs_days = 7
```
上記の場合は7日でログローテーションが行われる。

# おわりに
根本原因は設計時の考慮不足です。