MySQL の OPTIMIZE で未使用領域の解放

MySQL は未使用領域の解放をしようとしたら、DBバックアップしてDROPしてからリストアしかないと思ってましたが間違ってました。

innodb_file_per_table = 1 つけておけば、テーブルごとにファイルが生成されます。この状態だとテーブルの未使用領域が解放できます。テーブルスペースファイル内のデータが入ってない部分(行の削除などによってできた未使用部分)をOSに返却できます。

mysql のコンソールから OPTIMIZE TABLE tablename; でいけます。こんなかんじ。

mysql> optimize table history_uint;
+---------------------+----------+----------+-----------------------------------+
| Table               | Op       | Msg_type | Msg_text                          |
+---------------------+----------+----------+-----------------------------------+
| zabbix.history_uint | optimize | note     | Table does not support optimize,  |
|                     |          |          |  doing recreate + analyze instead |
| zabbix.history_uint | optimize | status   | OK                                |
+---------------------+----------+----------+-----------------------------------+
2 rows in set (36 min 28.14 sec)

実行中は対象のテーブルにロックがかかって書き込みできなくなりますけど、止めるよりはいいよね。

pt-online-schema-change なんかを使うとオンラインなままロックせずサービスを継続したままで未使用領域の解放ができるのですが、PRIMARY KEY を持たないテーブルは処理できないので、PRIMARY KEY がない場合は OPTIMIZE TABLE を使うしかないです。