[[MySQL][Linux]]MySQLのダンプファイルから特定のテーブルのリストアデータを抽出する方法

本番データの一部を書き戻す必要があり、巨大なダンプデータから必要なテーブルのデータだけを抽出する必要があったのでメモ。

cat <ダンプファイル> | sed -n '/DROP TABLE IF EXISTS `<対象テーブル名>`/,/Table structure for table `<対象テーブルの次のテーブル名>`/p' > ~/<対象テーブル名>.sql

※ダンプデータがgzip圧縮されている場合
zcat <ダンプファイル> | sed -n '/DROP TABLE IF EXISTS `<対象テーブル名>`/,/Table structure for table `<対象テーブルの次のテーブル名>`/p' > ~/<対象テーブル名>.sql

chatsテーブルの書き戻し [ダンプデータ内でchatsテーブル、diariesテーブルの順に並んでいると仮定]

zcat dump.tar.gz | sed -n '/DROP TABLE IF EXISTS `chats`/,/Table structure for table `diaries`/p' > ~/chats.sql

ファイルにはDROP、CREATE定義なども含まれているのでそのままリストア実行可能。
mysql -u hoge -p testdb < chats.sql

※上記例ではテーブルの並び順が最後のものでは使用できないので、その場合は以下のようにダンプ終了文字列を区切りにすると良さげ。

zcat dump.tar.gz | sed -n '/DROP TABLE IF EXISTS `worlds`/,/Dump completed on/p' > ~/chats.sql

補足

csplitを利用してテーブル毎のファイルを作る方法もあるが、以下の理由により採用しなかった。

  • 他の不要なテーブルのデータが解凍されてディスク容量と処理時間が圧迫される
  • zcat&csplitの組み合わせで「csplit: メモリを使い果たしました」エラーが発生してしまうケースがある