サービス稼働中に不要なDBのテーブルを安全に削除する方法
担当サービスのDBサーバーのディスク容量の空きが少なくなり、不要なテーブルを削除することになりました。
対象のテーブルのデータ量が多く、平常時でもそこそこ負荷のあるサーバーなのですが、
テーブル削除だけのためにメンテナンスをするのもアレなので、
深夜帯にしれっとdropしたい気持ちを抑えつつ、負荷のかからないdrop tableの手順を試してみました。
サービス稼働中にテーブルdropする時の問題点
metadata lock
drop対象のテーブルに書き込みやトランザクションが貼ってあるとmeta data lockがかかってしまいます
今回は参照等がないテーブルなので、問題なし
巨大なファイルを削除するとI/O待ちが発生する
巨大なテーブルのデータファイルを削除すると他のプロセスがI/O待ちになる可能性があります
安全にテーブルdropする方法やってみた
完全にこちらを参考をさせて頂きました。
dropする前にデータファイルにハードリンクを貼り、
drop時はファイル削除を行わず、後に優先度を下げて実ファイルを削除するという流れです。
さっそく本番でもやってみました。
# データファイルにハードリンクを張る ln /usr/local/mysql/data/hoge_db/bk_hoge_tbl.ibd /home/hoge/bk_hoge_tbl.ibd time mysql -e "DROP TABLE bk_hoge_tbl" real 0m0.047s user 0m0.002s sys 0m0.002s time ionice -c 3 rm -f /home/hoge/bk_hoge_tbl.ibd real 0m14.505s user 0m0.001s sys 0m0.065s
確かに意図通り、dropはデータ量に限らず一瞬で終わり、
データ削除はデータ量によって実行時間に違いがありました。
が、、、drop中は問題ありませんでしたが、データ削除中に若干レスポンスの悪化が見られました。
巨大なファイルを低負荷で削除する方法
結局、巨大なファイルを削除する時のI/O待ちが問題なら
drop前にパーティション切ってデータ細切れにするのはどうかな?でもめんどいなーって思っていたら下記の記事を見つけました。
巨大なファイルを削除する方法
このケースが一番悩まされました。しかし、最近 truncate コマンド使えばいいのでは〜ということに気がつきました。
truncate コマンドを用いて少しずつファイルサイズを減らす
sleep をはさむ
徐々にファイルサイズを小さくして、削除すればI/O負荷軽減できそうです。
次回はこちらの手順で削除してみようかと思います♪
感謝致します。