続 サービス稼働中に不要なDBのテーブルを安全に削除する方法
前回の続編です。
前回まで
前回はdropするテーブルのデータファイルにハードリンクを貼ることでdrop時にファイル削除されることを回避することができました。
しかしioniceで優先度を下げても、巨大なテーブルのデータファイルなどを削除する際はCPU使用率など見る限り負荷がかかっていました。 ioniceは緩やかに削除というより実行の順番の優先度を下げるという挙動のようです。
なので、次に負荷をかけずに巨大なファイルを削除するということで下記を参考にさせてもらいました。 www.nari64.com
truncateコマンドで徐々にファイルサイズを削り、小さくした後に削除するというやり方です。
安全にテーブルdropする手順
まとめて下記のような流れで処理しました
- 削除前に念のため、dump取る
mysqldump DB_NAME hoge_table > dump_hoge_table.sql
- 対象テーブルのデータファイルにハードリンクを貼る
ln /usr/local/mysql/data/DB_NAME/hoge_table.ibd /root/hoge_table.ibd ln /usr/local/mysql/data/DB_NAME/hoge_table.frm /root/hoge_table.frm
- drop tableを実行
mysql DB_NAME -e "DROP TABLE hoge_table"
- ハードリンクを貼ったファイルをtruncateコマンドで徐々にサイズを削った後に、rmを実行
//ファイルサイズ取得 $file_size = 0; $cmd = "du -m {$file_path} | awk '{print $1}'"; exec($cmd, $output, $ret); if($ret == 0) $file_size = $output[0]; //truncateで徐々に切り詰める if($file_size){ $i = 1; while ($i <= $file_size) { $tmp_size = $file_size - $i; $cmd = "truncate -s {$tmp_size}M {$file_path}"; exec($cmd, $output, $ret); //0.1sec sleep usleep(100000); $i++; } //ファイル削除 $cmd = "rm {$file_path}"; $res = exec($cmd, $output, $ret);
的な感じで、稼働中の本番DBで百数テーブル、260GB程度削除しましたが、負荷なく実行できました。 そこそこ時間はかかりますが、、、truncateの部分はもっと攻めて良さそうですがそれはまた次の機会に・・・
これでどんどん不要なテーブル消せますね!
感謝致します。