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


17.5.1.34 レプリケーションとトランザクションの非一貫性

リレーログから実行された一連のトランザクションの不整合は、レプリケーション構成によって発生する可能性があります。 このセクションでは、不整合を回避し、問題の原因を解決する方法について説明します。

次のタイプの不整合が存在する可能性があります:

  • 半消込済トランザクション。 非トランザクションテーブルを更新するトランザクションが、そのすべてではなく一部の変更を適用しました。

  • ギャップ。 外部化されたトランザクションセット内のギャップは、順序付けられたトランザクションのシーケンスが指定された場合に、シーケンス内の後のトランザクションがシーケンス内の他のトランザクションより前に適用されるときに表示されます。 ギャップは、マルチスレッドのレプリカを使用している場合にのみ表示されます。 ギャップが発生しないようにするには、slave_preserve_commit_order=1 を設定します。 この設定では、MySQL 8.0.18 まで、バイナリロギング (log_bin) およびレプリカ更新ロギング (log_slave_updates) も有効にする必要があります。これは、MySQL 8.0 のデフォルト設定です。 MySQL 8.0.19 からは、バイナリロギングおよびレプリカ更新ロギングは、slave_preserve_commit_order=1 を設定するためにレプリカでは必要なく、必要に応じて無効にできます。 すべてのリリースで、slave_preserve_commit_order=1 を設定するには、slave_parallel_type がデフォルト設定ではない LOGICAL_CLOCK に設定されている必要があります。 一部の特定の状況では、slave_preserve_commit_order の説明に示されているように、slave_preserve_commit_order=1 を設定してもレプリカのコミット順序を保持できないため、レプリカリレーログから実行された一連のトランザクションにギャップが表示される場合があります。

  • ソースバイナリログの位置ラグ。 ギャップがなくても、Exec_master_log_pos が適用された後のトランザクションが発生する可能性があります。 つまり、N までのすべてのトランザクションが適用され、N が適用された後のトランザクションは適用されませんが、Exec_master_log_pos の値は N より小さくなります。 この場合、Exec_master_log_pos は適用されたトランザクションの「最低水位標」であり、最後に適用されたトランザクションの位置より遅れています。 これはマルチスレッドのレプリカでのみ発生します。 slave_preserve_commit_order を有効にしても、ソースバイナリログの位置ラグは妨げられません。

次のシナリオは、半導体で適用されるトランザクション、ギャップ、およびソースバイナリログの位置ラグの存在に関連します:

  1. レプリケーションスレッドの実行中に、ギャップと半数適用のトランザクションが発生する場合があります。

  2. mysqld が停止します。 クリーンな停止とクリーンでない停止の両方により、進行中のトランザクションが中断され、ギャップと半数適用のトランザクションが残る可能性があります。

  3. レプリケーションスレッドの KILL (シングルスレッドレプリカを使用する場合は SQL スレッド、マルチスレッドレプリカを使用する場合はコーディネータスレッド)。 これにより、進行中のトランザクションが中断され、ギャップや半数適用のトランザクションが残る可能性があります。

  4. 適用者スレッドでエラーが発生しました。 これによりギャップが生じる可能性があります。 エラーが混合トランザクション内にある場合、そのトランザクションは半適用されます。 マルチスレッドのレプリカを使用する場合、エラーを受信していないワーカーはキューを完了するため、すべてのスレッドの停止に時間がかかることがあります。

  5. マルチスレッドのレプリカを使用している場合は STOP REPLICA | SLAVESTOP REPLICA | SLAVE の発行後、レプリカはギャップが一杯になるまで待機し、Exec_master_log_pos を更新します。 これにより、前述のいずれかのケース (つまり、STOP REPLICA | SLAVE が完了する前、エラーが発生する前、別のスレッドが KILL を発行する前、またはサーバーが再起動する前) を除き、ギャップまたはソースバイナリログの位置ラグが保持されることはありません。 このような場合、STOP REPLICA | SLAVE は正常に戻ります。

  6. リレーログ内の最後のトランザクションが半数受信のみで、マルチスレッドレプリカコーディネータスレッドがワーカーへのトランザクションのスケジュールを開始した場合、STOP REPLICA | SLAVE はトランザクションが受信されるまで最大 60 秒待機します。 このタイムアウト後、コーディネータはトランザクションを中止します。 トランザクションが混在している場合は、半完了のままにすることができます。

  7. シングルスレッドレプリカを使用する場合の STOP REPLICA | SLAVE。 進行中のトランザクションがトランザクションテーブルのみを更新する場合、トランザクションテーブルはロールバックされ、STOP REPLICA | SLAVE はただちに停止します。 進行中のトランザクションが混在している場合、STOP REPLICA | SLAVE はトランザクションが完了するまで最大 60 秒待機します。 このタイムアウト後、トランザクションは中断されるため、半分完了のままになります。

グローバル変数 rpl_stop_slave_timeout は、レプリケーションスレッドを停止するプロセスとは無関係です。 STOP REPLICA | SLAVE を発行するクライアントがクライアントに戻るだけですが、レプリケーションスレッドは引き続き停止しようとします。

レプリケーションチャネルにギャップがある場合は、次の結果になります:

  1. レプリカデータベースは、ソースに存在していない可能性がある状態です。

  2. SHOW REPLICA | SLAVE STATUS のフィールド Exec_master_log_pos は、「最低水位標」のみです。 つまり、位置の前に表示されるトランザクションはコミットされていることが保証されますが、位置の後のトランザクションはコミットされているかどうかは保証されません。

  3. そのチャネルの CHANGE REPLICATION SOURCE TO ステートメントおよび CHANGE MASTER TO ステートメントは、適用者スレッドが実行中であり、ステートメントで受信者オプションのみが設定されている場合を除き、エラーで失敗します。

  4. --relay-log-recovery を使用して mysqld を起動した場合、そのチャネルのリカバリは行われず、警告が出力されます。

  5. If mysqldump is used with --dump-slave, it does not record the existence of gaps; thus it prints CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO with RELAY_LOG_POS set to the 「最低水位標」 position in Exec_master_log_pos.

    ダンプを別のサーバーに適用し、レプリケーションスレッドを開始すると、位置の後に表示されるトランザクションが再度レプリケートされます。 GTID が有効になっている場合、これは無害であることに注意してください (ただし、その場合、--dump-slave を使用することはお薦めしません)。

レプリケーションチャネルにソースバイナリログの位置ラグがあり、ギャップがない場合は、前述のケース 2 から 5 が適用されますが、ケース 1 は適用されません。

ソースバイナリログの位置情報は、内部テーブル mysql.slave_worker_info にバイナリ形式で保持されます。 START REPLICA | SLAVE [SQL_THREAD]は常にこの情報を参照して、正しいトランザクションのみを適用します。 これは、slave_parallel_workersSTART REPLICA | SLAVE の前に 0 に変更された場合、および START REPLICA | SLAVEUNTIL 句とともに使用された場合でも当てはまります。 START REPLICA | SLAVE UNTIL SQL_AFTER_MTS_GAPS では、ギャップを埋めるために必要な数のトランザクションのみが適用されます。 START REPLICA | SLAVE が、すべてのギャップを消費する前に停止するように指示する UNTIL 句とともに使用されている場合、残りのギャップは残ります。

警告

RESET REPLICA | SLAVE によってリレーログが削除され、レプリケーション位置がリセットされます。 したがって、ギャップのあるレプリカで RESET REPLICA | SLAVE を発行すると、レプリカはギャップを修正せずにギャップに関する情報を失います。


関連キーワード:  トランザクション, ギャップ, 適用, REPLICA, SLAVE, 設定, ソース, バイナリ, 位置, slave