Documentation Home
MySQL 8.0 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 36.1Mb
PDF (A4) - 36.2Mb


このページは機械翻訳したものです。

18.4.2.2 トランザクション一貫性保証の構成

トランザクション同期ポイント のセクションでは概念的に説明していますが、選択できる同期ポイントは 2 つあります: 読取り時または書込み時、これらの用語は簡略化されており、グループレプリケーションで使用される用語は次のとおりです: トランザクション実行の前後。 このセクションで示すように、一貫性レベルは、グループによって処理される読取り専用 (RO) トランザクションと読取り/書込み (RW) トランザクションに異なる影響を与える可能性があります。

次のリストは、トランザクションの一貫性保証を高めるために、group_replication_consistency 変数を使用してグループレプリケーションで構成できる一貫性レベルを示しています:

  • EVENTUAL

    RO トランザクションと RW トランザクションはどちらも、実行前に先行するトランザクションが適用されるのを待機しません。 これは、group_replication_consistency 変数が追加される前の Group Replication の動作でした。 RW トランザクションは、他のメンバーがトランザクションを適用するのを待機しません。 つまり、あるメンバーでトランザクションを外部化してから別のメンバーに外部化できます。 つまり、プライマリフェイルオーバーが発生した場合、新しいプライマリは、前のプライマリトランザクションがすべて適用される前に新しい RO および RW トランザクションを受け入れることができます。 RO トランザクションは古い値になる可能性があり、RW トランザクションは競合のためロールバックする可能性があります。

  • BEFORE_ON_PRIMARY_FAILOVER

    古いプライマリからバックログを適用している、新しく選択されたプライマリを持つ新しい RO または RW トランザクションは、バックログが適用されるまで保持されます (適用されません)。 これにより、プライマリフェイルオーバーが意図的に発生したかどうかにかかわらず、クライアントには常にプライマリの最新の値が表示されます。 これにより一貫性が保証されますが、バックログが適用されている場合、クライアントは遅延を処理できる必要があります。 通常、この遅延は最小限に抑える必要がありますが、バックログのサイズによって異なります。

  • BEFORE

    RW トランザクションは、先行するすべてのトランザクションが完了するまで待機してから適用されます。 RO トランザクションは、先行するすべてのトランザクションが完了するまで待機してから実行されます。 これにより、トランザクションのレイテンシにのみ影響を与えることで、このトランザクションが最新の値を読み取るようになります。 これにより、RO トランザクションでのみ同期が使用されるようになるため、すべての RW トランザクションでの同期のオーバーヘッドが削減されます。 この一貫性レベルには、BEFORE_ON_PRIMARY_FAILOVER によって提供される一貫性保証も含まれます。

  • AFTER

    RW トランザクションは、その変更が他のすべてのメンバーに適用されるまで待機します。 この値は RO トランザクションには影響しません。 このモードでは、トランザクションがローカルメンバーでコミットされたときに、後続のトランザクションが書込み値またはグループメンバーのより新しい値を読み取ることが保証されます。 このモードは、主に RO 操作に使用されるグループとともに使用して、適用された RW トランザクションがコミット後のすべての場所に確実に適用されるようにします。 これは、後続の読取りで最新の書込みを含む最新のデータがフェッチされるようにするために、アプリケーションで使用できます。 これにより、RW トランザクションでのみ同期が使用されるようになるため、RO トランザクションごとの同期のオーバーヘッドが削減されます。 この一貫性レベルには、BEFORE_ON_PRIMARY_FAILOVER によって提供される一貫性保証も含まれます。

  • BEFORE_AND_AFTER

    RW トランザクションは、1) 前のすべてのトランザクションが適用されるまで待機し、2) 変更が他のメンバーに適用されるまで待機します。 RO トランザクションは、先行するすべてのトランザクションが完了するまで待機してから実行されます。 この一貫性レベルには、BEFORE_ON_PRIMARY_FAILOVER によって提供される一貫性保証も含まれます。

RO および RW トランザクションでは、BEFOREBEFORE_AND_AFTER の両方の一貫性レベルを使用できます。 RO トランザクションは変更を生成しないため、AFTER の一貫性レベルは RO トランザクションに影響しません。

整合性レベルの選択方法

一貫性レベルが異なると、両方の DBA に柔軟性が提供されます。DBA は、DBA を使用してインフラストラクチャを設定できます。また、アプリケーション要件に最適な整合性レベルを使用できる開発者にも柔軟性があります。 次のシナリオでは、グループの使用方法に基づいて一貫性保証レベルを選択する方法を示します:

  • シナリオ 1では、失効した読取りを気にすることなく読取りのロードバランシングを行う場合、グループの書込み操作はグループの読取り操作よりかなり少なくなります。 この場合、AFTER を選択する必要があります。

  • シナリオ 2には、大量の書込みを適用するデータセットがあり、失効したデータの読取りを気にすることなく、場合によっては読取りを実行する必要があります。 この場合、BEFORE を選択する必要があります。

  • シナリオ 3では、ワークロード内の特定のトランザクションが常にグループから最新のデータを読み取るようにし、機密データ (ファイルの資格証明や類似データなど) が更新されるたびに常に最新の値を読み取るように強制します。 この場合、BEFORE を選択する必要があります。

  • シナリオ 4には、主に読取り専用 (RO) データを持つグループがあり、コミットされたすべての場所に読取り/書込み (RW) トランザクションを適用して、後続の読取りが最新の書込みを含む最新データに対して実行され、すべての RO トランザクションで同期を支払わず、RW トランザクションでのみ行われるようにします。 この場合、AFTER を選択する必要があります。

  • シナリオ 5には、主に読取り/書込み (RW) トランザクションが含まれるグループがあり、読取り/書込み (RW) トランザクションは常にグループから最新のデータを読み取り、コミットされるとすべての場所に適用されるため、後続の読取りは最新の書込みを含む最新のデータに対して実行され、読取り専用 (RO) トランザクションごとに同期化を支払わずに RW トランザクションに対してのみ行われます。 この場合、BEFORE_AND_AFTER を選択する必要があります。

一貫性レベルが適用されるスコープを自由に選択できます。 整合性レベルをグローバルスコープで設定すると、グループのパフォーマンスに悪影響を与える可能性があるため、これは重要です。 したがって、異なるスコープで group_replication_consistency システム変数を使用して、グループの一貫性レベルを構成できます。

現在のセッションで整合性レベルを強制するには、セッションスコープを使用します:

> SET @@SESSION.group_replication_consistency= 'BEFORE';

すべてのセッションで整合性レベルを強制するには、グローバルスコープを使用します:

> SET @@GLOBAL.group_replication_consistency= 'BEFORE';

特定のセッションで一貫性レベルを設定できるため、次のようなシナリオを利用できます:

  • シナリオ 6特定のシステムは、強力な整合性レベルを必要としない命令をいくつか処理しますが、一方の命令には強力な整合性が必要です: ドキュメントへのアクセス権の管理。 このシナリオでは、システムによってアクセス権限が変更され、すべてのクライアントに正しい権限が表示されるようにする必要があります。 これらの手順では SET @@SESSION.group_replication_consistency= ‘AFTER’のみが必要で、他の手順はグローバルスコープで設定された EVENTUAL で実行するように残しておきます。

  • シナリオ 7シナリオ 6 で説明したのと同じシステムでは、命令は毎日分析処理を実行する必要があるため、常に最新のデータを読み取る必要があります。 これを実現するには、その特定の手順でのみ SET @@SESSION.group_replication_consistency= ‘BEFORE’を実行する必要があります。

要約すると、特定の一貫性レベルですべてのトランザクションを実行する必要はありません (特に、一部のトランザクションのみが実際に必要な場合)。

グループレプリケーションではすべての読取り/書込みトランザクションが完全に順序付けされるため、現在のセッションの一貫性レベルを AFTER に設定した場合でも、このトランザクションはその変更がすべてのメンバーに適用されるまで待機します。つまり、セカンダリキューに存在する可能性のあるこのトランザクションおよびそれより前のすべてのトランザクションを待機します。 実際には、一貫性レベルの AFTER は、このトランザクションまで、およびこのトランザクションを含むすべてを待機します。

整合性レベルの影響

一貫性レベルを分類する別の方法は、グループへの影響、つまり、一貫性レベルが他のメンバーに与える影響です。

トランザクションストリームでの順序付けとは別に、BEFORE の整合性レベルはローカルメンバーにのみ影響します。 つまり、他のメンバーとの調整は不要で、トランザクションに再フォーカスはありません。 つまり、BEFORE は、使用されているトランザクションにのみ影響します。

AFTERBEFORE_AND_AFTER の一貫性レベルは、他のメンバーで実行される同時トランザクションに副作用します。 これらの一貫性レベルでは、AFTER または BEFORE_AND_AFTER とのトランザクションの実行中に EVENTUAL 一貫性レベルのトランザクションが開始されると、他のメンバートランザクションが待機します。 他のメンバーは、他のメンバートランザクションに EVENTUAL 一貫性レベルがある場合でも、そのメンバーで AFTER トランザクションがコミットされるまで待機します。 つまり、AFTER および BEFORE_AND_AFTERall ONLINE グループメンバーに影響します。

これをさらに説明するために、3 つのメンバー、M1、M2 および M3 を持つグループを想定します。 メンバー M1 では、クライアントは次を発行します:

> SET @@SESSION.group_replication_consistency= AFTER;
> BEGIN;
> INSERT INTO t1 VALUES (1);
> COMMIT;

次に、前述のトランザクションが適用されている間に、メンバー M2 でクライアントが発行します:

> SET SESSION group_replication_consistency= EVENTUAL;

この状況では、2 つ目のトランザクションの一貫性レベルは EVENTUAL ですが、最初のトランザクションが M2 ですでにコミットフェーズにある間に実行を開始するため、2 つ目のトランザクションは最初のトランザクションがコミットを終了するまで待機する必要があり、その後実行できるだけです。

ONLINE メンバーで使用できるのは一貫性レベルの BEFOREAFTER および BEFORE_AND_AFTER のみで、他の状態のメンバーで使用しようとするとセッションエラーが発生します。

一貫性レベルが EVENTUAL でないトランザクションは、wait_timeout 値で構成されたタイムアウトに達するまで実行を保持し、デフォルトは 8 時間です。 タイムアウトに達すると、ER_GR_HOLD_WAIT_TIMEOUT エラーがスローされます。

プライマリ選択に対する整合性の影響

このセクションでは、グループの一貫性レベルが、新しいプライマリを選択した単一プライマリグループに与える影響について説明します。 このようなグループは、障害を自動的に検出し、アクティブなメンバー (メンバーシップ構成) のビューを調整します。 さらに、グループがシングルプライマリモードでデプロイされている場合、グループメンバーシップが変更されるたびに、グループにプライマリメンバーがまだ存在するかどうかを検出するチェックが実行されます。 存在しない場合は、セカンダリメンバーのリストから新しいメンバーが選択されます。 通常、これはセカンダリプロモーションと呼ばれます。

システムが障害を自動的に検出して再構成するという事実を考慮すると、ユーザーは昇格が行われると、新しいプライマリが古いプライマリのデータに関する正確な状態になることを期待する場合もあります。 つまり、レプリケートされたトランザクションの読取りおよび書込みが可能になると、そのトランザクションのバックログが新しいプライマリに適用されないことが予想される場合があります。 実際には、アプリケーションが新しいプライマリにフェイルオーバーすると、一時的に古いデータを読み取ったり、古いデータレコードに書き込んだりする機会がなくなります。

フロー制御がアクティブ化され、グループで適切にチューニングされた場合、バックログが存在しないか、または小さい必要があるため、昇格の直後に新しく選択されたプライマリから失効したデータを一時的に読み取る機会はごくわずかです。 さらに、昇格後にプライマリへのアプリケーションアクセスを制御し、そのレベルで一貫性基準を強制するプロキシレイヤーまたはミドルウェアレイヤーがある場合があります。 グループメンバーが MySQL 8.0.14 以上を使用している場合は、group_replication_consistency 変数を使用して新しいプライマリの動作を指定できます。この変数は、新しく選択されたプライマリが、バックログが完全に適用されるまで、または MySQL 8.0.13 以前を実行しているメンバーの動作まで読取りと書込みの両方をブロックするかどうかを制御します。 バックログが適用される新しく選択されたプライマリで group_replication_consistency オプションが BEFORE_ON_PRIMARY_FAILOVER に設定され、バックログの適用中に新しいプライマリに対してトランザクションが発行された場合、バックログが完全に適用されるまで受信トランザクションはブロックされます。 したがって、次の異常は回避されます:

  • 読取り専用および読取り/書込みトランザクションに対して失効した読取りはありません。 これにより、失効した読取りが新しいプライマリによってアプリケーションに外部化されるのを防ぎます。

  • 適用を待機しているバックログ内のレプリケートされた読取り/書込みトランザクションとの書込み競合のため、読取り/書込みトランザクションの擬似ロールバックはありません。

  • 読取り/書込みトランザクションでは、次のような読取りスキューはありません:

    > BEGIN;
    > SELECT x FROM t1; -- x=1 because x=2 is in the backlog;
    > INSERT x INTO t2;
    > COMMIT;

    このクエリーによって競合は発生しませんが、古い値が書き込まれます。

要約すると、group_replication_consistencyBEFORE_ON_PRIMARY_FAILOVER に設定されている場合は、新しいプライマリが選択されるたびに読取りおよび書込みが保持されるため、可用性よりも一貫性の優先順位を付けることを選択します。 これは、グループを構成する際に考慮する必要があるトレードオフです。 また、フロー制御が正常に機能している場合は、バックログを最小限に抑える必要があることにも注意してください。 BEFOREAFTER および BEFORE_AND_AFTER の一貫性レベルが高いほど、BEFORE_ON_PRIMARY_FAILOVER によって提供される一貫性保証も含まれることに注意してください。

プライマリに昇格されるメンバーに関係なく、グループが同じ一貫性レベルを提供するようにするには、グループのすべてのメンバーの BEFORE_ON_PRIMARY_FAILOVER (またはそれ以上の整合性レベル) が構成に永続化されている必要があります。 たとえば、メンバーごとに次のコマンドを発行します:

> SET PERSIST group_replication_consistency='BEFORE_ON_PRIMARY_FAILOVER';

これにより、すべてのメンバーが同じように動作し、メンバーの再起動後に構成が保持されます。

BEFORE_ON_PRIMARY_FAILOVER 整合性レベルを使用している場合、すべての書込みは保持されますが、昇格の実行後にバックログを適用している間もサーバーを検査できるように、すべての読取りがブロックされるわけではありません。 これは、デバッグ、監視、可観測性およびトラブルシューティングに役立ちます。 データを変更しないクエリーには、次のようなものがあります:

  • SHOW ステートメント

  • SET ステートメント

  • DO ステートメント

  • EMPTY ステートメント

  • USE ステートメント

  • performance_schema および sys データベースに対する SELECT ステートメントの使用

  • infoschema データベースの PROCESSLIST テーブルに対する SELECT ステートメントの使用

  • テーブルまたはユーザー定義関数を使用しない SELECT ステートメント

  • STOP GROUP_REPLICATION ステートメント

  • SHUTDOWN ステートメント

  • RESET PERSIST ステートメント

トランザクションを永久に保留にすることはできず、保留時間が wait_timeout を超えると、ER_GR_HOLD_WAIT_TIMEOUT エラーが返されます。