.ibdファイルをインポートする
提供:MySQL Practice Wiki
目次 |
概要
InnoDBでは--innodb-files-per-tableというステキなオプションがある。このオプションを有効にすると、共有テーブルスペースではなくテーブルが個別のテーブルスペース(.ibdファイル)に作成される。.ibdファイルが置かれる場所は.frmファイルと同じである。
手順
.ibdファイルは、物理的にバックアップをとっておけば後からファイルごとにリストアが可能になる。インポートする場合には以下の手順が必要になる。
- 既存のテーブルスペース(.ibdファイル)を削除する。
- mysql> ALTER TABLE tbl_name DISCARD TABLESPACE;
- バックアップファイル(.ibdファイル)を.frmファイルと同じディレクトリにコピーする。
- shell> cp ...(略)...
- テーブルスペースをインポートする。
- mysql> ALTER TABLE tbl_name IMPORT TABLESPACE;
.ibdファイルのバックアップ
.ibdファイルは
- MySQLサーバが稼働していないとき
- .ibdファイルへの更新が完了したとき(InnoDBの更新がアイドルになったとき)
にファイルをコピーすることで行われる。InnoDBを意図的にアイドル状態にするには、FLUSH TABLES WITH READ LOCKSコマンドを利用するといい。
または商用のInnoDB Hot Backupツールによりバックアップを作成可能である。
問題点
.ibdファイルには「テーブルスペースID」というものが含まれている。この番号は1から始まり(共有テーブルスペースが0)、.ibdファイルが作成された順番に番号つけられる。番号は1ずつ増加する。
.ibdファイルの問題点は、テーブルスペースIDが異なるとインポートに失敗するということである。例えば以下のような場合を考えよう。
- .ibdファイルのバックアップを作成する。
- ALTER TABLEによりテーブル定義を変更する。(インデックスやカラムの追加など)
- テーブルスペースを削除する。(ALTER TABLE tbl_name DISCARD TABLESPACE)
- 以前の.ibdファイルをインポートする。
この手順は失敗する。2番目の手順でALTER TABLEを行っているが、ALTER TABLEではごく少数の場合(RENAMEなど)を除いて、テーブルの再作成が内部的に行われる。その際、.ibdファイルも再作成され、テーブルスペースIDが変わってしまうのだ。
クラッシュなどにより、ログファイルなどが壊れてしまった場合には共有テーブルスペースとログファイルを再作成する必要があるが、そうすると共有テーブルスペースに記録されている各.ibdファイルのテーブルスペースIDの情報が失われてしまう。そのため、以下の手順は(ほとんどの場合)失敗する。
- .ibdファイルをバックアップする。
- InnoDBデータファイルとログファイルを削除する。
- --innodb-files-per-tableオプションつきでMySQLサーバを起動する。
- 空のInnoDBテーブルを作成し、テーブルスペースを削除する。
- .ibdファイルをバックアップから戻し、インポートする。
対策
テーブルスペースIDを合わせる必要がある。テーブルスペースIDはインポートを試みて、失敗した際にエラーログに記録される。従って、対象のテーブルが.ibdと同じテーブルスペースIDを持つように、ダミーのテーブルを作成すると良い。例えばテーブルスペースIDが3の時は以下のような手順でインポートすることが出来る。
- .ibdファイルをバックアップする。
- InnoDBデータファイルとログファイルを削除する。
- --innodb-files-per-tableオプションつきでMySQLサーバを起動する。
- ダミーのInnoDBテーブルを2つ作成する。
- インポート対象と同じテーブル定義のテーブルを作成し、そのテーブルスペースを削除する。
- .ibdファイルをバックアップから戻し、インポートする。
もし、クラッシュリカバリの目的で.ibdファイルを利用する場合には、MySQLサーバを--innodb-force-recovery=6オプションつきで起動する必要がある。