ステートメントベースレプリケーションでは、ソースで実行されたトリガーもレプリカで実行されます。 行ベースのレプリケーションでは、ソースで実行されたトリガーはレプリカで実行されません。 かわりに、トリガーの実行によって生成されたソースの行変更がレプリケートされ、レプリカに適用されます。
この動作は設計によります。 行ベースのレプリケーションでは、レプリカがトリガーおよびトリガーによって発生した行の変更を適用した場合、変更はレプリカに 2 回適用され、ソースとレプリカのデータが異なります。
ソースとレプリカの両方でトリガーを実行する場合は、おそらくソースとレプリカで異なるトリガーがあるため、ステートメントベースのレプリケーションを使用する必要があります。 ただし、レプリカ側トリガーを有効にするには、ステートメントベースのレプリケーションを排他的に使用する必要はありません。 この効果が必要なステートメントでのみステートメントベースレプリケーションに切り替え、残りの時間は行ベースレプリケーションを使用することで十分です。
AUTO_INCREMENT
カラムを更新するトリガー (または関数) を呼び出すステートメントは、ステートメントベースレプリケーションを使用して正しく複製されません。 MySQL 8.0 はこのようなステートメントを安全でないとマークします。 (Bug #45677)
トリガーは、トリガーイベント (INSERT
, UPDATE
, DELETE
) とアクション時間 (BEFORE
、AFTER
) の様々な組合せに対してトリガーを持つことができ、複数のトリガーが許可されます。
簡潔にするために、ここでの「「複数のトリガー」」は「「同じトリガーイベントおよびアクション時間を持つ複数のトリガー」」の短縮形です。
Upgrades. MySQL 5.7 より前のバージョンでは、複数のトリガーはサポートされていません。 MySQL 5.7 より前のバージョンを使用するレプリケーショントポロジのサーバーをアップグレードする場合は、まずレプリカをアップグレードしてから、ソースをアップグレードします。 アップグレードされたレプリケーションソースサーバーに、複数のトリガーをサポートしていない MySQL バージョンを使用する古いレプリカがまだ存在する場合、トリガーイベントとアクション時間がすでに同じトリガーを持つテーブルのソースでトリガーが作成されると、それらのレプリカでエラーが発生します。
Downgrades. 複数のトリガーをサポートするサーバーをサポートしていない古いバージョンにダウングレードすると、ダウングレードは次の影響を受けます:
トリガーを持つテーブルごとに、すべてのトリガー定義はテーブルの
.TRG
ファイルにあります。 ただし、トリガーイベントとアクション時間が同じトリガーが複数ある場合、サーバーはトリガーイベントが発生したときにいずれか一方のみを実行します。.TRG
ファイルの詳細は、https://dev.mysql.com/doc/index-other.html で入手可能な MySQL Server Doxygen ドキュメントの「テーブルトリガー記憶域」に関するセクションを参照してください。ダウングレード後にテーブルのトリガーが追加または削除されると、サーバーはテーブルの
.TRG
ファイルを書き換えます。 リライトされたファイルには、トリガーイベントとアクション時間の組合せごとに 1 つのトリガーのみが保持され、他のトリガーは失われます。
これらの問題を回避するには、ダウングレードする前にトリガーを変更します。 トリガーイベントとアクション時間の組合せごとに複数のトリガーを持つテーブルごとに、次のようにトリガーの各セットを単一のトリガーに変換します:
トリガーごとに、トリガー内のすべてのコードを含むストアドルーチンを作成します。
NEW
およびOLD
を使用してアクセスされる値は、パラメータを使用してルーチンに渡すことができます。 トリガーにコードからの単一の結果値が必要な場合は、ストアドファンクションにコードを配置し、その関数で値を戻すことができます。 トリガーにコードからの複数の結果値が必要な場合は、ストアドプロシージャにコードを配置し、OUT
パラメータを使用して値を返すことができます。テーブルのすべてのトリガーを削除します。
作成したストアドルーチンを呼び出すテーブルに対して、新しいトリガーを作成します。 したがって、このトリガーの効果は、トリガーが置換する複数のトリガーと同じです。