MySQL 8.
本記事ではマルチプライマリモードにおける外部キーに関する制約と、運用上の注意点について説明します。
外部キー制約のCASCADEに対する制限
MySQLでは、関連するデータの整合性を保つために外部キー制約が用意されており、ON UPDATE / ON DELETEの参照動作として RESTRICT / NO ACTION / CASCADE / SET NULLなどを指定できます。特にCASCADE系の動作は、親テーブルへの更新・
Group Replicationのマルチプライマリモードでは、外部キーにON DELETE/
といったCASCADE動作を定義している場合に制限があります。
MySQLではシステム変数group_
に設定することで、マルチプライマリモードで更新の厳密な整合性チェックを有効にすることができます。この設定により、外部キーが含まれるテーブルに対するCASCADE動作を伴うトランザクションは、グループに同期する段階でコミットが失敗します。
たとえば、親テーブルでDELETEを実行して子テーブルの行を自動削除するようなケースでは、以下のようにエラーが発生してトランザクションがロールバックされます。
ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin.
これはクラスタを構成する複数ノードで同時に更新系クエリを実行する場合、CASCADE動作による副次的な削除・
また、ON DELETE/
も自動伝播を伴う参照動作であり、マルチプライマリモードでは同様に制限の対象となります。
group_
に設定していれば、外部キーがあるテーブルに対するCASCADE動作を含むトランザクションはエラーなく実行されますが、MySQL公式としても非推奨であり、データの不整合が発生する可能性はあるため、運用上どうしても必要な場合を除いて使用しないことが推奨されます。もしこの設定を使用する場合は、十分な検証と運用上の制御が必要となります。また、回避策としてはアプリケーション側でCASCADE相当の処理を実装するか、トリガーを使用して明示的に削除・
正常なトランザクションがロールバックされるバグ
マルチプライマリモードにおいて外部キーが絡むトランザクションでは、外部キーを持つテーブルに対して並行でINSERTを行うと、競合がない状況でも10~25%程度の高頻度でトランザクションがロールバックされるバグが報告されています
ERROR 3101 (40000): Plugin instructed the server to rollback the current transaction.
マルチプライマリモードでは複数のノードから同時に更新が可能ですが、書き込み先を単一ノードに絞っていても発生する可能性がある点には注意が必要です。一方で、シングルプライマリモードでは発生しません。
Group Replicationでは、各トランザクションがどの時点の状態を見て実行されたか
このバグは実質的に仕様上の制約に近く、短期での修正は期待しづらいため、影響を回避するためにはシングルプライマリモードへの切り替えを検討する必要があります。併せて、同一範囲のキーへの並行書き込みを避ける運用とリトライ処理を組み合わせるのが効果的です。
まとめ
Group Replicationのマルチプライマリモードはメリットもあり便利な機能ですが、外部キーを利用する場合には制限があることを認識しておく必要があります。特にMySQLのデフォルト設定ではgroup_
に設定されているため、CASCADE動作を含むクエリを実行すると気付かないうちにデータの不整合が発生している可能性があるため、注意が必要です。マルチプライマリモードでの外部キー利用においては、アプリケーション側の処理などで適切な対応をして運用することが重要になります。