2009年5月30日土曜日

任意のテーブルの IMPORT TABLESPACE

MySQL の ALTER TABLE コマンドには、IMPORT TABLESPACE というコマンドがあります。InnoDBでは、innodb_file_per_table オプションを有効にしている場合に"クリーンな" .ibd ファイルのバックアップに差し替えることが出来ます。でもこれは色々制限があるので、利用していらっしゃる方は数少ないと思います。内部の構造/ID等が全く同じでなくてはいけないのでバックアップしたファイルをIMPORTできるようにするためには、ALTER TABLE コマンドによる内部的な表の再作成等もしてはいけないのです。

そこで、任意の表をIMPORTできるようにXtraDBを拡張してみました(innodb_expand_import)。(現在branchは https://code.launchpad.net/~percona-dev/percona-xtradb/expand-import です)
まだ、メインのbranchにはまだマージされていませんが、次のリリースには組み込まれるはずです。

さて、リンク先を見ていただければわかるのですが、まだ制限があります。 .ibd ファイルと元のCREATE TABLE文だけでは表と成すための情報が不足しているのです。『索引名と索引IDの対応』と『索引のroot page の場所』です。InnoDBは表、索引等を管理するための内部表を持っていてこれらの情報は SYS_INDEXES内部表に格納されているのでそれも元のInnoDBから抜き出してIMPORT時に利用する必要があります。

というわけで、このEXPORTにあたる対となる機能はXtraBackupに追加してみました(--exportオプション)。コピーしたトランザクションログとデータファイルを使ってリカバリーを行って利用可能なバックアップに変換する--prepareオプションと一緒に指定すると、insert buffer をちゃんと空にした"クリーンな" .ibd ファイルを索引情報を含んだ .exp ファイルも一緒に生成してくれます。

あとは、IMPORT先(要innodb_expand_import)で全く同じCREATE TABLE文で表を作成し、ALTER TABLE ... DISCARD TABLESPACEして、上記で生成された .ibd & .exp ファイルをその表の .frm ファイルと同じところに(アクセス権限に注意)置いて、ALTER TABLE ... IMPORT TABLESPACE するだけです。space_id, index_id, root page 位置の再登録などなど自動で変換してくれます。興味のある猛者はお試しください!

というわけで、興味の赴くままに書いていきますので、話の前提関係が多少滅茶苦茶ですが
(XtraDBって?XtraBackupって?などなど…)、書き続けていくうちに解決するでしょう。。。

ご挨拶

昨年末くらいからInnoDBの改造で生計を立てている者です。
流石に日本語で触れていないネタが溜まってきたので、まったり紹介していけたらと思っています。
よろしくです。