web-dev-qa-db-ja.com

InnoDBテーブルを修復するにはどうすればよいですか?

(明らかに)昨夜、Solaris MySQLデータベースエンジンの実行が不十分でした。少なくともいくつかのInnoDBテーブルが破損しており、トランザクションログにタイムスタンプ順不同エラーがあり、インデックスの破損に関する特定のエラーがあります。

MyISAMテーブルの修復に使用できるツールについては知っていますが、InnoDBには何も見つかりません。

サイドノート:テーブルの最適化を試みると(破損したインデックスを再構築しようとすると)、データベースサーバーがクラッシュします。

33
lefticus

まず第一に サーバーを停止し、ディスクをイメージングします。これで1発しか持っていても意味がありません。次に、 here を見てください。

26
Jon Topper

アプリケーションを停止するか、新しい行が追加されないようにスレーブを停止します

create table <new table> like <old table>;
insert <new table> select * from <old table>;
truncate table  <old table>;
insert <old table> select * from <new table>;

サーバーまたはスレーブを再起動します

21
Sandro Frattura

次のソリューションは、上記のSandroのヒントに触発されました。

警告:それは私のために働いたが、私はそれがあなたのために働くかどうかわかりません。

私の問題は次のとおりでした:テーブルから特定の行を読み取る(このテーブルをbrokenと呼びましょう)と、MySQLがクラッシュします。 SELECT COUNT(*) FROM brokenでもそれを殺すでしょう。このテーブルに_PRIMARY KEY_があることを願っています(次のサンプルでは、​​idです)。

  1. 破損したMySQLサーバーのバックアップまたはスナップショットがあることを確認します(手順1に戻って別のことを試してみたい場合に備えて!)
  2. _CREATE TABLE broken_repair LIKE broken;_
  3. INSERT broken_repair SELECT * FROM broken WHERE id NOT IN (SELECT id FROM broken_repair) LIMIT 1;
  4. DBがクラッシュするまで手順3を繰り返します(_LIMIT 100000_を使用してから、_LIMIT 1_を使用してDBをクラッシュするまで、より低い値を使用できます)。
  5. すべて揃っているかどうかを確認します(SELECT MAX(id) FROM brokenを_broken_repair_の行数と比較できます)。
  6. この時点で、明らかにすべての行がありました(おそらくInnoDBによってひどく切り捨てられた行を除く)。一部の行が欠落している場合は、OFFSETLIMITを追加してみてください。

がんばろう!

6
jpetazzo

MySQLが提供するソリューションは次のとおりです。 http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html

4
freytag

この記事を参照してください: http://www.unilogica.com/mysql-innodb-recovery/ (これはポルトガル語です)

innodb_force_recoveryおよびinnodb_file_per_tableの使用方法を説明しています。単一のibdata1でクラッシュしたデータベースを回復する必要がある後に、これを発見しました。

Innodb_file_per_tableを使用すると、InnoDBのすべてのテーブルは、MyISAMのような分離されたテーブルファイルを作成します。

0
Ragen Dazs