MySQL のバイナリログを整理してディスクを空けた話

株式会社オズビジョンの @terra_yucco です。
Qiita 投稿自体久々なのですが、また地道に自分のログを書き溜めていこうと思います。
※まだログしかありませんが、以前にオススメいただいた Qrunch も始めました。アカウントに `-` や `_` が使えなかったので [@terrayucco](https://qrunch.net/@terrayucco) でやっております。

本日は自分の開発環境をあふれさせ、ディスク拡張ではなく不要ファイル整理で解消したのでそちらのメモを置いておきます。

# TL; DR
本番環境のデータ dump を import した MySQL を local vagrant 上で動かしていたら、ディスク領域が 100% になったので、拡張ではなく不要ファイル削除で対応した話。

# より詳しく
## 事象説明

本番環境のデータ (100 万件くらい) を dump して local vagrant の MySQL にリストアし、バッチ処理を流すテストを何度も実施。(リランのテストなど兼ねていたので)

そうしたら、何回目かで

 `"Error writing file '\/tmp\/MYuQz1fV' (Errcode: 28)"` 的なメッセージを吐き出してバッチが全く動かないようになった。

## 状況

ほんの少しだけ空いていますが、ルートディスクを 100% 使い切っていました。

```
$ df
ファイルシス                      1K-ブロック      使用    使用可 使用% マウント位置
/dev/mapper/centos-root             8775680   8775000      680  100% /
devtmpfs                             498600         0   498600    0% /dev
tmpfs                                508684         0   508684    0% /dev/shm
tmpfs                                508684      6668   502016    2% /run
tmpfs                                508684         0   508684    0% /sys/fs/cgroup
/dev/sda1                            508588    149056   359532   30% /boot
192.168.33.1:/C/work/batch-code   248611840 212789792 35822048   86% /vagrant
tmpfs                                101740         0   101740    0% /run/user/0
```

`du -sch ./*` を繰り返して階層を下って行ったところ、大きかったのは以下の場所。

```
$ du -sch /usr/local/mysql/*
20K     /usr/local/mysql/COPYING
132K    /usr/local/mysql/INSTALL-BINARY
4.0K    /usr/local/mysql/README
155M    /usr/local/mysql/bin
5.1G    /usr/local/mysql/data
16K     /usr/local/mysql/docs
704K    /usr/local/mysql/include
15M     /usr/local/mysql/lib
760K    /usr/local/mysql/man
122M    /usr/local/mysql/mysql-test
16K     /usr/local/mysql/scripts
2.5M    /usr/local/mysql/share
2.8M    /usr/local/mysql/sql-bench
100K    /usr/local/mysql/support-files
5.4G    合計
```

`/usr/local/mysql/data` ということで、消えても local のデータなので良いだろうということでここを空けました。

## 空け方
### 一覧

`mysql-bin.000xxx` は MySQL のバイナリログファイルということで、レプリケーションが終わっていれば (特に個人の local では) 消して良いもの。[^1]
なんと一年以上消していなかったらしく、そりゃ溜まるはずだという感じでした。

```
$ ls -ltr
合計 5274624
drwxr-xr-x 2 mysql mysql         19  3月 18  2016 test
drwx------ 2 mysql mysql       4096  3月 18  2016 performance_schema
drwx------ 2 mysql root        4096  3月 18  2016 mysql
-rw-rw---- 1 mysql mysql        264  3月 18  2016 mysql-bin.000001
        : // mysql-bin.000xxx が連番で続く
drwx------ 2 mysql mysql       8192 11月 22 12:05 hoge
-rw-rw---- 1 mysql mysql    5242880 11月 26 09:57 ib_logfile1
-rw-rw---- 1 mysql mysql       2717 12月  4 14:06 mysql-bin.index
-rw-rw---- 1 mysql mysql          5 12月  4 14:06 localhost.localdomain.pid
-rw-rw---- 1 mysql mysql 1193279488 12月  4 15:05 ibdata1
-rw-rw---- 1 mysql mysql    5242880 12月  4 15:05 ib_logfile0
-rw-rw---- 1 mysql mysql  153083532 12月  4 15:33 mysql-bin.000143
-rw-r----- 1 mysql root      457642 12月  4 15:33 localhost.localdomain.err
```

### コマンド

ここで `rm` してはダメで、
mysql 上で (権限のあるユーザで) 以下を実行します。

上記の例では、最新のバイナリログファイルは `mysql-bin.000143` なので、このファイルだけを残しました。

```sql 
mysql> PURGE BINARY LOGS TO 'mysql-bin.000142';
Query OK, 0 rows affected (0.02 sec)
```

結果はスッキリ。
ひそかに `mysql-bin.index` も更新されていました。

```
[root@localhost data]# ls -ltr
合計 1424124
drwxr-xr-x 2 mysql mysql         19  3月 18  2016 test
drwx------ 2 mysql mysql       4096  3月 18  2016 performance_schema
drwx------ 2 mysql root        4096  3月 18  2016 mysql
drwx------ 2 mysql mysql       8192 11月 22 12:05 hoge
-rw-rw---- 1 mysql mysql    5242880 11月 26 09:57 ib_logfile1
-rw-rw---- 1 mysql mysql          5 12月  4 14:06 localhost.localdomain.pid
-rw-rw---- 1 mysql mysql 1193279488 12月  4 15:05 ibdata1
-rw-rw---- 1 mysql mysql    5242880 12月  4 15:05 ib_logfile0
-rw-rw---- 1 mysql mysql  153083532 12月  4 15:33 mysql-bin.000143
-rw-r----- 1 mysql root      457642 12月  4 15:33 localhost.localdomain.err
-rw-rw---- 1 mysql mysql         38 12月  4 15:39 mysql-bin.index
```

# まとめ

MySQL 利用環境で Disk 利用率が高くなったら、バイナリログの整理でスッキリできることも。

`Vagrant` `ディスクフル` などで検索すると、ディスク容量を増やす方法の方がよく出てきますが、不要なものであれば削除してスッキリ使いたい派なので、このエントリを書くに至りました。
local 環境であれば普段本番では触れられない MySQL の管理系コマンドも試せるので、いろいろと学びになりました。[^2]

[^1]: [Is it safe to delete mysql-bin files?](https://dba.stackexchange.com/questions/41050/is-it-safe-to-delete-mysql-bin-files)

[^2]: ローカル環境であれば my.cnf に `expire_logs_days=7` とか書いておけば回避できそうです。(書いてなかった)