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


13.3.8.3 XA トランザクションの制約

XA トランザクションのサポートは、InnoDB ストレージエンジンに限られています。

外部 XA の場合、MySQL Server がリソースマネージャーとして機能し、クライアントプログラムがトランザクションマネージャーとして機能します。 内部 XA の場合、MySQL サーバー内のストレージエンジンがリソースマネージャーとして機能し、サーバー自体がトランザクションマネージャーとして機能します。 内部 XA サポートは、個々のストレージエンジンの機能によって制限されています。 内部 XA は、複数のストレージエンジンが関与する XA トランザクションを処理するために必要になります。 内部 XA の実装では、ストレージエンジンがテーブルハンドラレベルでの 2 フェーズコミットをサポートしている必要であり、現在これは InnoDB にのみ当てはまります。

XA START の場合、JOIN 句および RESUME 句は認識されますが、効果はありません。

XA END の場合、SUSPEND [FOR MIGRATE]句は認識されますが、効果はありません。

xid 値の bqual 部分が、グローバルトランザクション内の XA トランザクションごとに異なる必要があるという要件が、現在の MySQL XA 実装の制限です。 これは XA の仕様によるものではありません。

XA トランザクションは、2 つの部分でバイナリログに書き込まれます。 XA PREPARE が発行されると、XA PREPARE までのトランザクションの最初の部分が初期 GTID を使用して書き込まれます。 XA_prepare_log_event は、バイナリログ内のこのようなトランザクションを識別するために使用されます。 XA COMMIT または XA ROLLBACK が発行されると、XA COMMIT または XA ROLLBACK ステートメントのみを含むトランザクションの別の部分が、別の GTID を使用して書き込まれます。 XA_prepare_log_event で識別されるトランザクションの最初の部分の後に、必ずしも XA COMMIT または XA ROLLBACK が続くわけではありません。これにより、任意の 2 つの XA トランザクションのインターリーブバイナリロギングが発生する可能性があります。 XA トランザクションの 2 つの部分は、異なるバイナリログファイルでも使用できます。 つまり、PREPARED 状態の XA トランザクションは、明示的な XA COMMIT ステートメントまたは XA ROLLBACK ステートメントが発行されるまで永続的になり、XA トランザクションがレプリケーションと互換性を持つようになります。

レプリカでは、XA トランザクションが準備されるとすぐにレプリケーションアプライヤスレッドからデタッチされ、レプリカ上の任意のスレッドによってコミットまたはロールバックできます。 これは、同じ XA トランザクションが、異なるスレッド上の異なる状態で events_transactions_current テーブルに表示されることを意味します。 events_transactions_current テーブルには、スレッド上の最新の監視対象トランザクションイベントの現在のステータスが表示され、スレッドがアイドル状態の場合、このステータスは更新されません。 そのため、XA トランザクションは、別のスレッドによって処理された後も、元のアプライヤスレッドの PREPARED 状態で表示できます。 PREPARED 状態のままでリカバリが必要な XA トランザクションを肯定的に識別するには、パフォーマンススキーマトランザクションテーブルではなく、XA RECOVER ステートメントを使用します。

XA トランザクションの使用には、次の制限があります:

  • XA トランザクションは、バイナリログに関して予期しない停止に対する完全な回復力がありません。 サーバーが XA PREPARE, XA COMMIT, XA ROLLBACK または XA COMMIT ... ONE PHASE ステートメントの実行中に予期しない停止が発生した場合、サーバーは正しい状態に回復できず、サーバーとバイナリログが一貫性のない状態のままになる可能性があります。 この状況では、バイナリログに適用されていない追加の XA トランザクションが含まれているか、適用されている XA トランザクションが失われている可能性があります。 また、GTID が有効になっている場合は、回復後に、@@GLOBAL.GTID_EXECUTED が適用されたトランザクションを正しく記述しないことがあります。 XA PREPARE の前、XA PREPAREXA COMMIT (または XA ROLLBACK) の間、または XA COMMIT (または XA ROLLBACK) の後に予期しない停止が発生した場合、サーバーおよびバイナリログは正しくリカバリされ、一貫性のある状態になります。

  • XA トランザクションと組み合せたレプリケーションフィルタまたはバイナリログフィルタの使用はサポートされていません。 テーブルをフィルタリングすると、レプリカで XA トランザクションが空になる可能性があり、空の XA トランザクションはサポートされません。 また、MySQL 8.0 のデフォルトになった InnoDB テーブルに格納されているレプリカ接続メタデータリポジトリおよびアプライヤメタデータリポジトリでは、フィルタ処理された XA トランザクションの後にデータエンジントランザクションの内部状態が変更され、レプリケーショントランザクションコンテキストの状態と一貫性がなくなる可能性があります。

    XA トランザクションがレプリケーションフィルタの影響を受けるたびに、トランザクションが空であったかどうかに関係なく、エラー ER_XA_REPLICATION_FILTERS がログに記録されます。 トランザクションが空でない場合、レプリカは実行を続行できますが、潜在的な問題を回避するために XA トランザクションでのレプリケーションフィルタの使用を中止するステップを実行する必要があります。 トランザクションが空の場合、レプリカは停止します。 その場合、レプリケーションプロセスの一貫性が損なわれる可能性のある不確定な状態にレプリカがある可能性があります。 特に、レプリカのレプリカ上の gtid_executed セットは、ソース上のものと一貫性がない可能性があります。 この状況を解決するには、ソースを分離し、すべてのレプリケーションを停止してから、レプリケーショントポロジ全体で GTID の一貫性をチェックします。 エラーメッセージを生成した XA トランザクションを元に戻し、レプリケーションを再開します。

  • XA トランザクションは、ステートメントベースレプリケーションでは安全でないとみなされます。 ソースでパラレルにコミットされた 2 つの XA トランザクションがレプリカで逆の順序で準備されている場合、安全に解決できないロック依存性が発生する可能性があり、レプリケーションがレプリカのデッドロックで失敗する可能性があります。 この状況は、シングルスレッドまたはマルチスレッドレプリカで発生する可能性があります。 binlog_format=STATEMENT が設定されている場合、XA トランザクション内の DML ステートメントに対して警告が発行されます。 binlog_format=MIXED または binlog_format=ROW が設定されている場合、XA トランザクション内の DML ステートメントは行ベースのレプリケーションを使用して記録され、潜在的な問題は存在しません。

注記

MySQL 5.7.7 より前は、XA トランザクションはレプリケーションとまったく互換性がありませんでした。 これは、PREPARED 状態の XA トランザクションが、サーバーのクリーンシャットダウンまたはクライアントの切断時にロールバックされるためです。 同様に、サーバーが異常停止してから再度起動されたが、トランザクションの内容をバイナリログに書き込めなかった場合、PREPARED 状態の XA トランザクションは PREPARED 状態のままになります。 どちらの状況でも、XA トランザクションを正しくレプリケートできませんでした。


関連キーワード:  ステートメント, XA, トランザクション, CREATE, TABLE, DROP, 状態, サーバー, サブクエリー, FUNCTION