200GB のダンプファイルを一部のみリストアした話
なんかすでに梅雨がきてしまったかのような天気ですね。昔雨が嫌いだった kimoto です。今はふつう。
先日、とあるサービスのデータを、社内の開発環境にリストアしなければならない事がありまして。
MySQL のダンプファイルなんですが、これがまた大きい大きい。
テーブル数は 2000 以上、ダンプファイルの容量は 200GB を超えていました。
社内の環境のスペックがそれほど高くなかったこともあり、普通にリストアするととんでも無い時間がかかりそうな雰囲気。
実際は一部しか必要ないのに全部リストアするのもなあ…という事で、ちょっとやり方を考えました。
結論としては、とにかくデカすぎるファイルから、目当てのテーブルについて書かれている部分のみを抽出して、そこからリストアすることにしました。
1. まずはざっくりと切り出し
まずは目当てのテーブルについて書かれている行の割り出しです。
たとえば、「users」というテーブルの記述部分が欲しいとして、正規表現で行数を割り出します。
egrep -n '^DROP TABLE IF EXISTS `users`' dump.sql
これだけ大きくなると、正規表現による grep もかなり時間がかかりました。待つこと20分程。
27970:DROP TABLE IF EXISTS `users`;
こんな感じで行数がわかります。しかし、何行目までが users についての記述なのかがわかりません。
とりあえず、2000行分ほど切り出すことにしました。
sed -n '27970,30000p' dump.sql > users.sql
ここでもかなり時間がかかりました。これも多分、待つこと20分程。
無事 users 関連から 2000 行分の記述が切りだされました。
2. さらに細かく切り出す
さて、ここから余分なものを省きます。
テーブル名を指定せず、テーブル削除の記述のみを検索します。
egrep -n '^DROP TABLE IF EXISTS' users.sql
1:DROP TABLE IF EXISTS `users`;
1249:DROP TABLE IF EXISTS `user_access_logs`;
1922:DROP TABLE IF EXISTS `user_action_logs`;
これで、1249 行目から先は違うテーブルの記述だとわかりました。ということで、先ほどと同じ要領で、users のみ切り出します。
1249 から別テーブルなので、1248 行目を指定します。
sed -n '1,1248p' users.sql > cut_users.sql
3. リストアする
これで切り抜き完了したので、念のためテキストエディタ辺りで開いて確認後、リストアしました。
mysql -umysql_user -p db_name < cut_users.sql
ちなみに
今回は少し回りくどいやり方をしましたが、容量などの状況により、1 は省いていきなり 2 からでもいいと思います。