XtraBackupシリーズで今回はテーブル単位のデータ抽出&リストアです。
通常は全データベースを対象としますが、テスト用とかで部分的に本番データが欲しい時などに利用できます。用意されている2種類の方法を紹介します。
利用条件
どちらの方法も、バックアップ/リストアの両サーバにおいて innodb_file_per_table 設定が有効な必要があります。部分的なバックアップ
Partial Backups より。正規表現指定 –tables
通常のバックアップと基本は同じで、–tables オプションを指定することで特定のテーブルのみを抽出できます。この例では sbtestデータベースの、test* テーブルのみ取り出しており、sbtestテーブルがスキップされていることがわかります。
1 2 3 4 5 6 7 8 9 |
# xtrabackup --backup --datadir=/fio/mysql/ --target-dir=/fio/backup_partial/ \ --tables="^sbtest[.]test.*" ~snip~ [01] Copying ./ibdata1 to /fio/backup_partial/ibdata1 [01] ...done [01] Skipping ./sbtest/sbtest.ibd [01] Copying ./sbtest/test.ibd to /fio/backup_partial/./sbtest/test.ibd [01] ...done ~snip~ |
リストアも手順は同じですが、prepare時に、存在しなくなったテーブルの警告がでます。
prepareの後はデータディレクトリとして普通に利用できます。
1 2 3 4 5 6 |
# xtrabackup --prepare --target-dir=/fio/backup_partial/ 120919 13:15:09 InnoDB: Error: table 'sbtest/sbtest' InnoDB: in InnoDB data dictionary has tablespace id 11, InnoDB: but tablespace with that id or name does not exist. It will be removed from data dictionary. 120919 13:15:09 Percona XtraDB (http://www.percona.com) 1.0.17-12.5 started; log sequence number 2701793303 |
テーブルリストのファイル指定 –tables-file
テーブルリストを書いたファイルを利用することでもテーブルを指定できます。リストの値は dbname.table を完全一致させて書きます。
1 2 3 4 5 6 |
# cat /tmp/tables.txt sbtest.test sbtest.export # xtrabackup --backup --datadir=/fio/mysql/ --target-dir=/fio/backup_partial/ \ --tables-file=/tmp/tables.txt |
テーブルのExportとImport
Exporting and Importing Tables より。参考:任意のテーブルの IMPORT TABLESPACE – DB改造屋雑記
データディレクトリ丸ごとのリストアではなく、テーブル単位で出し入れしたい時にこれを利用します。InnoDBのテーブルデータは、単に .ibd と .frm ファイルをデータディレクトリにコピーしてもテーブルとして利用することができないためです。
Export
innodb_file_per_table ONのバックアップデータに対して、–export をつけて –prepare すると、.ibd の横に .exp ファイルが出来上がります。これ自体はデータを取り出してるわけじゃないのでExportって言うと違和感がありますね…
1 2 3 4 5 6 7 8 9 10 11 12 |
# testテーブルだけ抽出して mkdir /fio/backup_export xtrabackup --backup --datadir=/fio/mysql/ --target-dir=/fio/backup_export/ \ --tables="^sbtest[.]test.*" # Exportすると (Import用のデータにすると) xtrabackup --prepare --target-dir=/fio/backup_export/ --export # .expができました ls -1 /fio/backup_export/sbtest/ test.exp test.ibd |
Import
このデータを稼働中のMySQLにインポートします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 全く同じCREATE文でテーブルを作成します(テーブル名はtestからimportに変えてみた) mysql> CREATE TABLE import (`num` int); # ibdファイルだけ削除します mysql> ALTER TABLE import DISCARD TABLESPACE; # DBディレクトリの下に import.frm だけ残っているので # 同じ階層に、Exportした .exp と .ibd をmvやcpで配置します cp /fio/backup_export/sbtest/test.exp /fio/mysql/sbtest/import.exp cp /fio/backup_export/sbtest/test.ibd /fio/mysql/sbtest/import.ibd chown mysql:mysql /fio/mysql/sbtest/import.* # リストアします mysql> SET GLOBAL innodb_import_table_from_xtrabackup = 1; mysql> ALTER TABLE import IMPORT TABLESPACE; # 参照できれば成功です mysql> SELECT * FROM import; |
innodb_expand_import はv5.5.10で
innodb_import_table_from_xtrabackup に名称変更されています。
innodb_import_table_from_xtrabackup に名称変更されています。
既存のテーブルと入れ替えたい場合で、外部キーがあるデータの場合は一時的に無効にしてからImportする必要があります。(参照:Expand Table Import)
1 2 3 4 |
mysql> SET FOREIGN_KEY_CHECKS = 0; mysql> ALTER TABLE import DISCARD TABLESPACE; ~以下同~ |
このExport & Import は、ちょっと手順をミスるとテーブル操作ができなくなったりするので、テスト環境で納得するまで遊んでみるとよいです。
MySQL5.6 からはInnoDBテーブル単位での移行ができるようになるみたいで、.exp が .cfg になっているところが似た匂いを感じますが、
例で UNLOCK TABLES; を実行しているところをみると、テーブル単位でのオンラインバックアップができないと実用には少し遠いかも知れません。Percona Serverも5.6になった時、この辺の扱いがどうなるかは注目せざるを得ないところですね。