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 PREPARE
とXA 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 トランザクションを正しくレプリケートできませんでした。