web-dev-qa-db-ja.com

ファイルが移動されたInnoDBテーブルを回復する方法

レプリケーションストリームにセットアップされたテストデータベースサーバーがあります。名前の上に、スレーブのdatadirのスペースをすぐにいっぱいにする最適化が行われました。 Mysqlは忠実にもう少しスペースを待っていました。

このdatadirは、mysqlのdatadirとしてのみ使用されるファイルシステムであるため、解放するものは他にありませんでした。

レプリケーションストリームの一部ではない4ギガのinnodbテストテーブルがあったので、それが機能するかどうかを確認するために何かを試してみようと思いました。

これが私が取った手順です

  1. 移動しようとしたテーブルをフラッシュしました
  2. それに読み取りロックを設定しました(何も書き込まれておらず、レプリケーションストリームになかった場合でも)
  3. .frmと.ibdを予備の部屋のあるファイルシステムにコピーした
  4. テーブルのロックを解除しました
  5. そのテーブルを切り捨てました-これにより、最適化が完了するのに十分なスペースが解放され、レプリケーションが再び動き始めました。
  6. Mysqlの停止/シャットダウン
  7. Tmpからファイルをデータディレクトリにコピーします。
  8. Mysqlを再起動します

.errログには何も表示されません。問題はありません。私はmydbに接続して使用します。そして、私がショーテーブルでいじっていたテーブルを見てください。しかし、私がしようとすると

select * from testtable limit 10;

エラーが出る

ERROR 1146 (42S02): Table 'mydb.testtable' doesn't exist

これまでのところ、他のすべてのテーブルから問題なく読み取ることができ、問題なくレプリケーションが再開されました。

この時点から回復するために何かできることはありますか?必要に応じて一から再構築できますが、このベンチャー全般について他の人がどう思っているのか興味がありました。私が行った一連のステップについて、より完璧な結果に終わってしまうものはありましたか?

これがテストサーバーでない場合、「ライブで実行」して何が起こるかを確認することはできません。私がそれを好きにならなければならなかった場合、プロダクションスレーブのスペースを一時的に解放する最良の方法は何でしょうか?

14
atxdba

ほとんどの人がTRUNCATE TABLEについて忘れている最大のことは、 TRUNCATE TABLEがDDLであり、DML ではないことです。 InnoDBでは、ibdata1内のメタデータにInnoDBテーブルの番号付きリストが含まれています。 TRUNCATE TABLEを使用すると、InnoDBテーブルの内部メタデータIDがシフトします。これは、TRUNCATE TABLEが効果的に以下を実行するために発生します。

例:mydb.mytbというInnoDBテーブルを切り捨てる

USE mydb
CREATE TABLE newtb LIKE mytb;
ALTER TABLE mytb RENAME oldtb;
ALTER TABLE newtb RENAME mytb;
DROP TABLE oldtb;

したがって、新しいmytbは異なる内部メタデータIDを持ちます。

.ibdファイルを他の場所にコピーした場合、.ibdには元の内部メタデータIDが含まれています。 .ibdファイルを単に戻すだけでは、内部メタデータIDとibdata1のIDとの調整は行われません。

あなたがしなければならないことはこれです:

InnoDBテーブルの.ibdファイルをコピーします。次に、これを実行します

ALTER TABLE tablename DISCARD TABLESPACE;

後でそれを戻すには、.ibdファイルをdatadirにコピーして実行します。

ALTER TABLE tablename IMPORT TABLESPACE;

これにより、内部メタデータIDが保持されます。

.frmが常に存在することを確認してください。

私はかつて、クライアントが同じ方法でホースした30のInnoDBテーブルを復元するのを手伝いました。別のDBサーバーを使用し、InnoDBテーブルを追加およびドロップしてゲームをプレイし、正しい内部メタデータIDを見つけ出さなければなりませんでした。

クライアントはこの記事を見つけました: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file 。私たちはそれを使用し、それは大きな助けとなりました。お役に立てば幸いです。

15
RolandoMySQLDBA