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


15.6.5 redo ログ

redo ログは、不完全なトランザクションによって書き込まれたデータを修正するためにクラッシュリカバリ中に使用されるディスクベースのデータ構造です。 通常の操作中、redo ログは、SQL ステートメントまたは低レベルの API コールによって発生したテーブルデータを変更するリクエストをエンコードします。 予期しないシャットダウンの前にデータファイルの更新を終了しなかった変更は、初期化中、および接続が受け入れられる前に自動的にリプレイされます。 クラッシュリカバリにおける redo ログの役割の詳細は、セクション15.18.2「InnoDB のリカバリ」 を参照してください。

デフォルトでは、redo ログはディスク上で ib_logfile0 および ib_logfile1 という名前の 2 つのファイルによって物理的に表されます。 MySQL は、redo ログファイルに循環して書き込みます。 redo ログ内のデータは、影響を受けるレコードに関してエンコードされます。このデータはまとめて redo と呼ばれます。 redo ログを介したデータの受渡しは、増加する LSN 値で表されます。

関連情報については、redo ログファイル構成,およびセクション8.5.4「InnoDB redo ロギングの最適化」を参照してください。

redo ログの保存データ暗号化の詳細は、redo ログの暗号化 を参照してください。

redo ログファイルの数またはサイズの変更

redo log ファイルの数またはサイズを変更するには、次のステップを実行します:

  1. MySQL サーバーを停止し、エラーなしでシャットダウンされることを確認します。

  2. my.cnf を編集して、ログファイルの構成を変更します。 ログファイルのサイズを変更するには、innodb_log_file_size を構成します。 ログファイルの数を多くするには、innodb_log_files_in_group を構成します。

  3. MySQL サーバーを再起動します。

InnoDB は、innodb_log_file_size と redo ログファイルのサイズが異なることを検出すると、ログチェックポイントを書き込み、古いログファイルを閉じて削除し、リクエストされたサイズで新しいログファイルを作成し、新しいログファイルを開きます。

redo ログフラッシュのグループコミット

InnoDB は、他の ACID 準拠のデータベースエンジンと同様に、コミット前にトランザクションの redo log をフラッシュします。 InnoDB では、group commit 機能を使用してこのような複数のフラッシュリクエストをグループ化し、コミットごとに 1 つのフラッシュを回避します。 グループコミットでは、InnoDB はログファイルに単一の書込みを発行して、ほぼ同時にコミットする複数のユーザートランザクションに対してコミットアクションを実行し、スループットを大幅に向上させます。

COMMIT やその他のトランザクション操作のパフォーマンスの詳細は、セクション8.5.2「InnoDB トランザクション管理の最適化」を参照してください。

redo ログのアーカイブ

redo ログレコードをコピーするバックアップユーティリティは、バックアップ操作の進行中に redo ログの生成に対応できない場合があり、その結果、それらのレコードが上書きされるために redo ログレコードが失われます。 この問題は、多くの場合、バックアップ操作中に重大な MySQL サーバーアクティビティが発生し、redo ログファイルストレージメディアがバックアップストレージメディアより高速に動作する場合に発生します。 MySQL 8.0.17 で導入された redo ログアーカイブ機能は、redo ログファイルに加えて redo ログレコードをアーカイブファイルに順次書き込むことで、この問題に対処します。 バックアップユーティリティでは、必要に応じてアーカイブファイルから redo ログレコードをコピーできるため、データが失われる可能性を回避できます。

redo ログアーカイブがサーバーで構成されている場合、MySQL Enterprise Edition で使用可能な MySQL Enterprise Backup は、MySQL サーバーのバックアップ時に redo ログアーカイブ機能を使用します。

サーバーで redo ログアーカイブを有効にするには、innodb_redo_log_archive_dirs システム変数の値を設定する必要があります。 この値は、ラベル付き redo ログアーカイブディレクトリのセミコロン区切りリストとして指定されます。 label:directory ペアはコロン (:) で区切られます。 例:

mysql> SET GLOBAL innodb_redo_log_archive_dirs='label1:directory_path1[;label2:directory_path2;…]';

label は、アーカイブディレクトリの任意の識別子です。 コロン (:) を除いて、任意の文字列を指定できますが、これは許可されません。 空のラベルも使用できますが、この場合もコロン (:) が必要です。 directory_path を指定する必要があります。 redo ログアーカイブがアクティブ化されている場合は、redo ログアーカイブファイル用に選択されたディレクトリが存在する必要があります。存在しない場合は、エラーが返されます。 パスにはコロン (':') を含めることができますが、セミコロン (;) は使用できません。

redo ログアーカイブをアクティブ化する前に、innodb_redo_log_archive_dirs 変数を構成する必要があります。 デフォルト値は NULL で、redo ログアーカイブのアクティブ化は許可されません。

メモ

指定するアーカイブディレクトリは、次の要件を満たす必要があります。 (要件は、redo ログアーカイブがアクティブ化されたときに適用されます。):

  • ディレクトリが存在する必要があります。 redo ログアーカイブプロセスでは、ディレクトリは作成されません。 それ以外の場合は、次のエラーが返されます:

    ERROR 3844 (HY000): redo ログアーカイブディレクトリ'directory_path1'が存在しないか、ディレクトリではありません

  • ディレクトリはワールドアクセス可能にしないでください。 これは、redo ログデータがシステム上の権限のないユーザーに公開されないようにするためです。 それ以外の場合は、次のエラーが返されます:

    ERROR 3846 (HY000): redo ログアーカイブディレクトリ'directory_path1'には、すべての OS ユーザーがアクセスできます

  • ディレクトリには、datadir, innodb_data_home_dir, innodb_directories, innodb_log_group_home_dir, innodb_temp_tablespaces_dir, innodb_tmpdir innodb_undo_directory または secure_file_priv で定義されたディレクトリや、それらのディレクトリの親ディレクトリまたはサブディレクトリを指定できません。 それ以外の場合は、次のようなエラーが返されます:

    ERROR 3845 (HY000): redo ログアーカイブディレクトリ'directory_path1'は、サーバーディレクトリ'datadir'の下または上にあります - ' /path/to/data_directory '

redo ログアーカイブをサポートするバックアップユーティリティがバックアップを開始すると、バックアップユーティリティは innodb_redo_log_archive_start() ユーザー定義関数を起動して redo ログアーカイブをアクティブ化します。

redo ログのアーカイブをサポートするバックアップユーティリティを使用していない場合は、次に示すように、redo ログのアーカイブを手動でアクティブ化することもできます:

mysql> SELECT innodb_redo_log_archive_start('label', 'subdir');
+------------------------------------------+
| innodb_redo_log_archive_start('label') |
+------------------------------------------+
| 0                                        |
+------------------------------------------+

または:

mysql> DO innodb_redo_log_archive_start('label', 'subdir');
Query OK, 0 rows affected (0.09 sec)
注記

(innodb_redo_log_archive_start() を使用して) redo ログアーカイブをアクティブ化する MySQL セッションは、アーカイブ中はオープンのままである必要があります。 同じセッションで (innodb_redo_log_archive_stop() を使用して) redo ログアーカイブを非アクティブ化する必要があります。 redo ログアーカイブが明示的に非アクティブ化される前にセッションが終了した場合、サーバーは redo ログアーカイブを暗黙的に非アクティブ化し、redo ログアーカイブファイルを削除します。

ここで、labelinnodb_redo_log_archive_dirs によって定義されたラベルです。subdir は、アーカイブファイルを保存するために label によって識別されるディレクトリのサブディレクトリを指定するためのオプションの引数です。単純なディレクトリ名である必要があります (スラッシュ (/)、バックスラッシュ (\),またはコロン (:) は使用できません)。subdir は空または null にすることも、省略することもできます。

innodb_redo_log_archive_start() を起動して redo ログアーカイブをアクティブ化するか、innodb_redo_log_archive_stop() を使用して非アクティブ化できるのは、INNODB_REDO_LOG_ARCHIVE 権限を持つユーザーのみです。 バックアップユーティリティを実行している MySQL ユーザーまたは redo ログアーカイブを手動でアクティブ化および非アクティブ化する MySQL ユーザーには、この権限が必要です。

redo ログアーカイブファイルのパスは directory_identified_by_label/[subdir/]archive.serverUUID.000001.log です。ここで、directory_identified_by_labelinnodb_redo_log_archive_start()label 引数で識別されるアーカイブディレクトリです。subdir は、innodb_redo_log_archive_start() に使用されるオプションの引数です。

たとえば、redo ログアーカイブファイルのフルパスと名前は次のようになります:

/directory_path/subdirectory/archive.e71a47dc-61f8-11e9-a3cb-080027154b4d.000001.log

バックアップユーティリティは、InnoDB データファイルのコピーを終了した後、innodb_redo_log_archive_stop() ユーザー定義関数をコールして redo ログアーカイブを非アクティブ化します。

redo ログのアーカイブをサポートするバックアップユーティリティを使用していない場合は、次に示すように、redo ログのアーカイブを手動で非アクティブ化することもできます:

mysql> SELECT innodb_redo_log_archive_stop();
+--------------------------------+
| innodb_redo_log_archive_stop() |
+--------------------------------+
| 0                              |
+--------------------------------+

または:

mysql> DO innodb_redo_log_archive_stop();
Query OK, 0 rows affected (0.01 sec)

停止機能が正常に完了すると、バックアップユーティリティはアーカイブファイルから redo ログデータの関連セクションを検索し、それをバックアップにコピーします。

バックアップユーティリティが redo ログデータのコピーを終了し、redo ログアーカイブファイルが不要になると、アーカイブファイルは削除されます。

アーカイブファイルの削除は、通常の状況ではバックアップユーティリティの役割を果たします。 ただし、innodb_redo_log_archive_stop() がコールされる前に redo ログのアーカイブ操作が予期せず終了した場合、MySQL サーバーはファイルを削除します。

パフォーマンスに関する考慮事項

通常、redo ログアーカイブをアクティブ化すると、書込みアクティビティが追加されるため、パフォーマンスが若干低下します。

Unix および Unix に似たオペレーティングシステムでは、パフォーマンスへの影響は、通常、高い更新率が持続しないことを前提としています。 Windows では、通常、パフォーマンスへの影響は少し大きくなります (同じことを前提としています)。

継続的に高い更新率があり、redo ログアーカイブファイルが redo ログファイルと同じ記憶域メディアにある場合、複合書込みアクティビティが原因でパフォーマンスへの影響が大きくなる可能性があります。

継続的に高い更新率があり、redo ログアーカイブファイルが redo ログファイルより低速なストレージメディア上にある場合、パフォーマンスには任意の影響があります。

redo ログアーカイブファイルへの書込みでは、redo ログアーカイブファイルの記憶域メディアが redo ログファイルの記憶域メディアよりもはるかに低速で動作し、redo ログアーカイブファイルへの書込みを待機している永続 redo ログブロックの大きなバックログがある場合を除き、通常のトランザクションロギングは妨げられません。 この場合、トランザクションロギング率は、redo ログアーカイブファイルが存在する低速の記憶域メディアで管理できるレベルに削減されます。

redo ロギングの無効化

MySQL 8.0.21 では、ALTER INSTANCE DISABLE INNODB REDO_LOG ステートメントを使用して redo ロギングを無効にできます。 この機能は、新しい MySQL インスタンスにデータをロードするためのものです。 redo ロギングを無効にすると、redo ログの書込みおよび二重書込みバッファリングが回避され、データのロードが高速化されます。

警告

この機能は、新しい MySQL インスタンスへのデータのロードのみを目的としています。 本番システムで redo ロギングを無効にしないでください。 redo ロギングが無効化されている間はサーバーを停止して再起動できますが、redo ロギングが無効化されている間に予期しないサーバーストップページが発生すると、データが失われ、インスタンスが破損する可能性があります。

redo ロギングが無効化されている間に予期しないサーバー停止ページの後にサーバーを再起動しようとすると、次のエラーで拒否されます:

[ERROR] [MY-013578] [InnoDB] Server was killed when Innodb Redo 
logging was disabled. Data files could be corrupt. You can try 
to restart the database with innodb_force_recovery=6

この場合、新しい MySQL インスタンスを初期化し、データロードプロシージャを再度開始します。

redo ロギングを有効化および無効化するには、INNODB_REDO_LOG_ENABLE 権限が必要です。

Innodb_redo_log_enabled ステータス変数を使用すると、redo ロギングステータスを監視できます。

redo ロギングが無効化されている間は、クローニング操作および redo ログアーカイブは許可されません。その逆も同様です。

ALTER INSTANCE [ENABLE|DISABLE] INNODB REDO_LOG 操作には排他的バックアップメタデータロックが必要で、これにより他の ALTER INSTANCE 操作が同時に実行されなくなります。 その他の ALTER INSTANCE 操作は、ロックが解放されるまで待機してから実行する必要があります。

次の手順は、新しい MySQL インスタンスにデータをロードするときに redo ロギングを無効にする方法を示しています。

  1. 新しい MySQL インスタンスで、redo ロギングを無効にするユーザーアカウントに INNODB_REDO_LOG_ENABLE 権限を付与します。

    mysql> GRANT INNODB_REDO_LOG_ENABLE ON *.* to 'data_load_admin';
  2. data_load_admin ユーザーとして、redo ロギングを無効にします:

    mysql> ALTER INSTANCE DISABLE INNODB REDO_LOG;
  3. Innodb_redo_log_enabled ステータス変数をチェックして、redo ロギングが無効になっていることを確認します。

    mysql> SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled';
    +-------------------------+-------+
    | Variable_name           | Value |
    +-------------------------+-------+
    | Innodb_redo_log_enabled | OFF   |
    +-------------------------+-------+
  4. データロード操作を実行します。

  5. data_load_admin ユーザーとして、データロード操作の終了後に redo ロギングを有効にします:

    mysql> ALTER INSTANCE ENABLE INNODB REDO_LOG;
  6. Innodb_redo_log_enabled ステータス変数をチェックして、redo ロギングが有効になっていることを確認します。

    mysql> SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled';
    +-------------------------+-------+
    | Variable_name           | Value |
    +-------------------------+-------+
    | Innodb_redo_log_enabled | ON    |
    +-------------------------+-------+

関連キーワード:  InnoDB, ログ, テーブル, アーカイブ, 構成, バックアップ, ロギング, データ, 操作, ディレクトリ