Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 27.1Mb
PDF (A4) - 27.2Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


14.19.2 InnoDB のリカバリの強制的な実行

データベースページの破損を調査するために、SELECT ... INTO OUTFILE を使用して、データベースからテーブルをダンプできます。通常は、この方法で取得されたデータのほとんどが完全な状態にあります。重大な破損では、SELECT * FROM tbl_name ステートメントまたは InnoDB のバックグラウンド操作がクラッシュまたは表明したり、場合によっては InnoDB のロールフォワードリカバリがクラッシュしたりすることもあります。このような場合は、テーブルをダンプできるように、innodb_force_recovery オプションを使用して、バックグラウンド操作が実行されないようにして InnoDB ストレージエンジンを強制的に起動させることができます。たとえば、サーバーを再起動する前に、オプションファイルの [mysqld] セクションに次の行を追加できます。

[mysqld]
innodb_force_recovery = 1
警告

innodb_force_recovery を 0 を超える値に設定するのは、緊急の状況で InnoDB を起動し、テーブルをダンプできるようにする場合だけにしてください。それを行う前に、データベースの再作成が必要になった場合に備えて、データベースのバックアップコピーがあることを確認してください。4 以上の値を指定すると、データファイルが永続的に破損する場合があります。本番サーバーインスタンス上で 4 以上の innodb_force_recovery 設定を使用するのは、使用するデータベースの個別の物理コピーでその設定を正常にテストしたあとだけにしてください。InnoDB のリカバリを強制的に実行する場合は、常に innodb_force_recovery=1 から始め、必要がある場合にのみこの値を 1 ずつ増やすようにしてください。

innodb_force_recovery は、デフォルトでは 0 です (リカバリが強制的に実行されない通常の起動)。innodb_force_recovery の許可される 0 以外の値は 1 から 6 までです。大きい方の値には、小さい方の値の機能が含まれています。たとえば、3 の値には、値 1 と 2 のすべての機能が含まれています。

3 以下の innodb_force_recovery 値を使用してテーブルをダンプできる場合は、破損した個々のページ上の一部のデータしか失われないため、比較的安全です。4 以上の値は、データファイルが永続的に破損する場合があるため、危険であるとみなされます。6 の値は、データベースページが廃止された状態のままになり、それによって B ツリーやその他のデータベース構造にさらに多くの破損が導入される可能性があるため、きわめて危険であるとみなされます。

安全策として、innodb_force_recovery が 0 より大きい場合、InnoDBINSERTUPDATE、または DELETE 操作を回避します。MySQL 5.6.15 の時点では、4 以上の innodb_force_recovery 設定は InnoDB を読み取り専用モードにします。

  • 1 (SRV_FORCE_IGNORE_CORRUPT)

    破損したページを検出した場合でも、サーバーが動作できるようにします。SELECT * FROM tbl_name での破損したインデックスレコードおよびページの飛び越しを試行します。これが、テーブルのダンプに役立ちます。

  • 2 (SRV_FORCE_NO_BACKGROUND)

    マスタースレッドや、すべてのパージスレッドが実行されないようにします。パージ操作中にクラッシュが発生しそうになった場合は、このリカバリの値によって回避されます。

  • 3 (SRV_FORCE_NO_TRX_UNDO)

    クラッシュリカバリのあとにトランザクションロールバックを実行しません。

  • 4 (SRV_FORCE_NO_IBUF_MERGE)

    挿入バッファーのマージ操作を回避します。その操作によってクラッシュが発生しそうになった場合は、それが回避されます。テーブル統計を計算しません。この値を指定すると、データファイルが永続的に破損する場合があります。この値を使用したあと、すべてのセカンダリインデックスを削除して再作成するように準備してください。MySQL 5.6.15 の時点では、InnoDB を読み取り専用に設定します。

  • 5 (SRV_FORCE_NO_UNDO_LOG_SCAN)

    データベースを起動するときに、Undo ログを参照しません。InnoDB は、未完了のトランザクションでさえコミット済みとして処理します。この値を指定すると、データファイルが永続的に破損する場合があります。MySQL 5.6.15 の時点では、InnoDB を読み取り専用に設定します。

  • 6 (SRV_FORCE_NO_LOG_REDO)

    リカバリに関連した Redo ログのロールフォワードを実行しません。この値を指定すると、データファイルが永続的に破損する場合があります。データベースページを廃止された状態のままにし、それによって B ツリーやその他のデータベース構造にさらに多くの破損が発生する可能性があります。MySQL 5.6.15 の時点では、InnoDB を読み取り専用に設定します。

テーブルからの SELECT を実行してテーブルをダンプしたり、3 以下の innodb_force_recovery 値を使用してテーブルの DROP または CREATE を実行したりすることができます。ロールバック時に特定のテーブルでクラッシュが発生することがわかっている場合は、そのテーブルを削除できます。失敗した大量のインポートまたは ALTER TABLE によってロールバックの暴走が発生する場合は、mysqld プロセスを強制終了し、innodb_force_recovery3 に設定してロールバックなしでデータベースを起動したあと、ロールバックの暴走の原因になっているテーブルの DROP を実行することができます。

テーブルデータ内の破損のためにテーブルの内容全体をダンプできない場合は、ORDER BY primary_key DESC 句を含むクエリーで、破損した部分のあとにあるテーブルの部分をダンプできる可能性があります。

InnoDB を起動するために innodb_force_recovery を大きな値にする必要がある場合は、複雑なクエリー (WHEREORDER BY、またはその他の句を含むクエリー) を失敗させることがある破損したデータ構造が存在する可能性があります。この場合は、基本的な SELECT * FROM t クエリーしか実行できない可能性があります。


User Comments
  Posted by Vector Thorn on July 9, 2011
I ran into a problem where, when dealing with HUGE tables, there was an innodb page error, and mysql would try over and over to repair it, and would inform me that it could not repair it (and would then try again, etc).

I came to this page after receiving the "error 2002 Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) when trying to connect" error, and read the instructions, and had some luck with them, without even getting all the way through the steps.

I put the force_recovery mode to 1, then restarted mysqld, exported the entire database (i expected to get an error when it got to the bad table, but i never had a problem). After dumping the database, i removed the force_recovery option from my.cnf and restarted the service, and after a few moments, it started back up, and the problem was gone.

I suspect that dumping the database to disk may have cleaned the filesystem's cache, maybe? Anyway, before dropping tables, try seeing if just exporting the database and restarting in normal mode will work (it may not; i may have just gotten lucky).
  Posted by Bei Xu on January 21, 2012
totally agree with you, I dumped my currupted table too, that resolved the problem without reloading it
Sign Up Login You must be logged in to post a comment.