MySQL 8.0 リファレンスマニュアル


15.18.2 InnoDB のリカバリ

このセクションでは、InnoDB のリカバリについて説明します。 内容は次のとおりです:

Point-in-Time リカバリ

物理バックアップが作成された時点から InnoDB データベースをリカバリするには、バックアップを取得する前でも、バイナリロギングを有効にして MySQL サーバーを実行する必要があります。 バックアップをリストアしたあとにポイントインタイムリカバリを実現するには、バックアップが作成されたあとに発生した変更をバイナリログから適用できます。 セクション7.5「Point-in-Time (増分) リカバリ」を参照してください。

データ破損またはディスク障害からのリカバリ

データベースが破損するか、またはディスク障害が発生した場合は、バックアップを使用してリカバリを実行する必要があります。 破損の場合は、まず、破損していないバックアップを見つけます。 ベースバックアップをリストアしたあと、mysqlbinlog および mysql を使用してバイナリログファイルからポイントインタイムリカバリを実行することにより、バックアップが作成されたあとに発生した変更をリストアします。

データベース破損の場合によっては、破損したテーブルの 1 つまたはいくつかをダンプ、削除および再作成するだけで十分です。 CHECK TABLE ステートメントを使用して、テーブルが破損しているかどうかを確認できますが、CHECK TABLE では、すべての種類の破損を自然に検出できません。

場合によっては、見た目はデータベースページの破損だが、実際にはオペレーティングシステムによる独自のファイルキャッシュの破損であり、ディスク上のデータは正常であることがあります。 最初にコンピュータを再起動することをお勧めします。 それにより、データベースページの破損に見えたエラーが解消される可能性があります。 InnoDB の一貫性の問題が原因で MySQL の起動にまだ問題がある場合は、セクション15.21.2「InnoDB のリカバリの強制的な実行」 でインスタンスをリカバリモードで起動するステップを参照してください。これにより、データをダンプできます。

InnoDB のクラッシュリカバリ

予期しない MySQL サーバーの終了からリカバリするには、MySQL サーバーを再起動する必要があります。 InnoDB はログを自動的にチェックし、データベースの現時点へのロールフォワードを実行します。 InnoDB は、クラッシュの時点で存在していたコミットされていないトランザクションを自動的にロールバックします。 リカバリ中、mysqld には次のような出力が表示されます:

InnoDB: The log sequence number 664050266 in the system tablespace does not match
the log sequence number 685111586 in the ib_logfiles!
InnoDB: Database was not shutdown normally!
InnoDB: Starting crash recovery.
InnoDB: Using 'tablespaces.open.2' max LSN: 664075228
InnoDB: Doing recovery: scanned up to log sequence number 690354176
InnoDB: Doing recovery: scanned up to log sequence number 695597056
InnoDB: Doing recovery: scanned up to log sequence number 700839936
InnoDB: Doing recovery: scanned up to log sequence number 706082816
InnoDB: Doing recovery: scanned up to log sequence number 711325696
InnoDB: Doing recovery: scanned up to log sequence number 713458156
InnoDB: Applying a batch of 1467 redo log records ...
InnoDB: 10%
InnoDB: 20%
InnoDB: 30%
InnoDB: 40%
InnoDB: 50%
InnoDB: 60%
InnoDB: 70%
InnoDB: 80%
InnoDB: 90%
InnoDB: 100%
InnoDB: Apply batch completed!
InnoDB: 1 transaction(s) which must be rolled back or cleaned up in total 561887 row
operations to undo
InnoDB: Trx id counter is 4096
...
InnoDB: 8.0.1 started; log sequence number 713458156
InnoDB: Waiting for purge to start
InnoDB: Starting in background the rollback of uncommitted transactions
InnoDB: Rolling back trx with id 3596, 561887 rows to undo
...
./mysqld: ready for connections....

InnoDBクラッシュリカバリは、次のいくつかのステップで構成されます。

  • テーブルスペースの検出

    テーブルスペース検出は、redo ログアプリケーションを必要とするテーブルスペースを識別するために InnoDB で使用されるプロセスです。 クラッシュリカバリ中のテーブルスペースの検出を参照してください。

  • Redo log アプリケーション

    redo ログアプリケーションは、接続を受け入れる前に初期化中に実行されます。 停止またはクラッシュ時にすべての変更が buffer pool から tablespaces (ibdata* および *.ibd ファイル) にフラッシュされた場合、redo ログアプリケーションはスキップされます。 起動時に redo ログファイルが欠落している場合、InnoDB は redo ログアプリケーションもスキップします。

    • 現在の最大自動増分カウンタ値は、値が変更されるたびに redo ログに書き込まれるため、クラッシュが安全になります。 リカバリ中に、InnoDB は redo ログをスキャンしてカウンタ値の変更を収集し、インメモリーテーブルオブジェクトに変更を適用します。

      InnoDB による自動増分値の処理方法の詳細は、セクション15.6.1.6「InnoDB での AUTO_INCREMENT 処理」 および InnoDB AUTO_INCREMENT カウンタの初期化 を参照してください。

    • インデックスツリーの破損が発生すると、InnoDB は破損フラグを redo ログに書き込み、破損フラグをクラッシュセーフにします。 また、InnoDB は、インメモリー破損フラグデータを各チェックポイントのエンジン専用システムテーブルに書き込みます。 リカバリ中、InnoDB は、インメモリーテーブルおよびインデックスオブジェクトを破損としてマークする前に、両方の場所から破損フラグを読み取り、結果をマージします。

    • redo ログを削除してリカバリを高速化することは、一部のデータ損失が許容される場合でもお薦めしません。 redo ログの削除は、innodb_fast_shutdown0 または 1 に設定してクリーンシャットダウンした後にのみ考慮する必要があります。

  • 不完全な transactionsRoll back

    未完了のトランザクションは、予期しない終了時または fast shutdown でアクティブだったトランザクションです。 未完了のトランザクションをロールバックするためにかかる時間は、サーバーの負荷に応じて、そのトランザクションが中断される前にアクティブであった期間の 3 または 4 倍になる場合があります。

    ロールバックされているトランザクションは取り消せません。 極端なケースとして、トランザクションのロールバックに膨大な時間がかかると予測される場合は、innodb_force_recovery の設定を 3 以上にして InnoDB を起動した方が速いことがあります。 セクション15.21.2「InnoDB のリカバリの強制的な実行」を参照してください。

  • Change buffer マージ

    インデックスページがバッファプールに読み込まれるため、変更バッファ (system tablespace の一部) からセカンダリインデックスのリーフページに変更を適用します。

  • Purge

    アクティブなトランザクションに表示されなくなった削除マーク付きレコードを削除しています。

Redo ログの適用に続く各ステップは (書き込みのロギングを除き) Redo ログには依存しないため、通常の処理では並列に実行されます。 これらのうち、クラッシュリカバリに固有なのは未完了のトランザクションのロールバックだけです。 挿入バッファーのマージとパージは、通常の処理中に実行されます。

Redo ログの適用のあと、InnoDB は、ダウンタイムを短縮するために接続をできるだけ早く受け入れようとします。 クラッシュリカバリの一環として、InnoDB は、サーバーの終了時にコミットされなかったトランザクションまたは XA PREPARE 状態のトランザクションをロールバックします。 このロールバックは、新しい接続からのトランザクションと並列に実行されているバックグラウンドスレッドによって実行されます。 新しい接続では、ロールバック操作が完了するまで、リカバリされるトランザクションとのロック競合が発生する可能性があります。

ほとんどの状況では、重いアクティビティの途中で MySQL サーバーが予期せず強制終了された場合でも、リカバリプロセスは自動的に実行され、DBA によるアクションは必要ありません。 ハードウェア障害や重大なシステムエラーのために InnoDB データが破損した場合は、MySQL が起動を拒否する可能性があります。 この場合は、セクション15.21.2「InnoDB のリカバリの強制的な実行」を参照してください。

バイナリログおよび InnoDB のクラッシュリカバリについては、セクション5.4.4「バイナリログ」を参照してください。

クラッシュリカバリ中のテーブルスペースの検出

リカバリ中に、最後のチェックポイント以降に書き込まれた redo ログが InnoDB で検出された場合は、影響を受けるテーブルスペースに redo ログを適用する必要があります。 リカバリ中に影響を受けるテーブルスペースを識別するプロセスは、テーブルスペースの検出と呼ばれます。

テーブルスペースの検出は、起動時にテーブルスペースファイルをスキャンするディレクトリを定義する innodb_directories 設定に依存します。 innodb_data_home_dirinnodb_undo_directory および datadir によって定義されたディレクトリは、innodb_directories オプションが明示的に構成されているかどうかに関係なく、起動時にスキャンするディレクトリのリストを作成するときに innodb_directories 引数値に自動的に追加されます。 絶対パスで定義されたテーブルスペースファイル、または innodb_directories 設定に自動的に追加されたディレクトリの外部に存在するテーブルスペースファイルは、innodb_directories 設定に追加する必要があります。 redo ログで参照されているテーブルスペースファイルがまだ検出されていない場合、リカバリは終了します。


関連キーワード:  InnoDB, テーブル, リカバリ, スペース, ログ, 構成, トランザクション, 破損, 実行, インデックス