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 を使うしかないです。