4

MySQL 5.0.45 でいくつかのデータベースを実行しており、レガシー データベースを改訂されたスキーマと同期させようとしているので、両方を並べて実行できます。新しいデータベースにトリガーを追加してこれを行っていますが、レプリケーションで問題が発生しています。私のセットアップは次のとおりです。

サーバー「マスター」

  • データベース「legacydb」は、サーバー「スレーブ」に複製されます。
  • データベース「newdb」には、「legacydb」を更新するトリガーがあり、レプリケーションはありません。

サーバー「スレーブ」

  • データベース「legacydb」

「newdb」への更新は正常に実行され、トリガーが開始されました。「マスター」サーバーで「legacydb」を更新します。ただし、変更はスレーブに複製されません。"SELECT DATABASE();"MySQL のドキュメントによると、簡単にするために、レプリケーションでは、どのクエリをレプリケートするかを決定する際に、クエリの結果を見るのではなく、現在のデータベース コンテキスト (例: ) を確認します。私のトリガーはデータベース「newdb」のコンテキストから実行されるため、レプリケーションは更新を無視します。

updateステートメントを「legacydb」のストアドプロシージャに移動しようとしました。「マスター」に接続して手動で実行すると、これは正常に機能します(つまり、データがスレーブに複製されます)"USE newdb; CALL legacydb.do_update('Foobar', 1, 2, 3, 4);"。ただし、このプロシージャがトリガーから呼び出された場合、複製は行われません。

これまでのところ、これを修正する方法についての私の考えは、次のいずれかです。

  • トリガーに強制的に新しい現在のデータベースを設定させます。これは最も簡単ですが、これは不可能だと思います。これは、ストアド プロシージャで実現したかったことです。

  • 両方のデータベースをレプリケートし、マスターとスレーブの両方にトリガーを設定します。これは可能ですが、設定するのは面倒です。

  • 現在のデータベース コンテキストに関係なく、レプリケーションが "legacydb" へのすべての変更を取得するように強制します。

  • レプリケーションが高すぎるレベルで実行されると、トリガーによって実行される更新が表示されることさえありません。

これを達成する方法についての助けをいただければ幸いです。

4

1 に答える 1

3

これはそれと関係があるかもしれません:

ストアド ファンクションは、実行前にテーブル ロックを取得します。これは、ステートメントが実行される順序とログに表示されるタイミングの不一致によるバイナリ ログの不整合を回避するためです。関数内で実行されるステートメントではなく、関数を呼び出すステートメントが記録されます。したがって、同じ基になるテーブルを更新するストアド ファンクションは並列に実行されません。

対照的に、ストアド プロシージャはテーブル レベルのロックを取得しません。ストアド プロシージャ内で実行されるすべてのステートメントは、バイナリ ログに書き込まれます。

さらに、トリガーに関する問題の全リストがあります: http://dev.mysql.com/doc/refman/5.0/en/routine-restrictions.html

于 2008-09-19T03:34:40.463 に答える