200GB のダンプファイルを一部のみリストアした話

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 からでもいいと思います。

  • このエントリーをはてなブックマークに追加

この記事を読んだ人にオススメ