GTID またはグローバルトランザクション識別子 MySQL5.6.5で導入されました。 GTIDは、GTID対応のMySQLホスティングサーバーで実行されるすべてのトランザクションに与えられるグローバルに一意のIDです。 GTIDは、特定のトランザクションがコミットされたサーバーのUUIDと、その特定のサーバーでのそのトランザクションのシーケンス番号の組み合わせです。これにより、GTIDはグローバルにユニークになります。
MySQLレプリケーション
GTIDベースのレプリケーションは、古いbinlogベースのレプリケーションと比較してはるかに柔軟性があります。 GTIDベースのセットアップでは、スレーブはレプリケーションを開始するためにマスターbinlogファイルと位置を必要としません。 GTIDベースのレプリケーションの詳細をご覧ください。このブログ投稿では、GTIDベースのレプリカセットをデプロイするときに発生する一般的なMySQLレプリケーションの問題について説明します。
誤った取引 は、他のノードで複製する必要のない1つ以上のスレーブに適用されるトランザクションです。これらは、スレーブに適用される断続的な修正、またはアプリケーションによるスレーブへの偶発的な書き込みである可能性があります。
これらの誤ったトランザクションの問題は、誤ったトランザクションを含むスレーブがマスターに昇格したときに発生します。 GTIDベースのレプリケーションの場合、これにより問題が発生します。新しいマスターは、スレーブが誤ったトランザクションを実行していないことを認識します。次の2つのいずれかが発生する可能性があります:
(1)誤ったトランザクションはマスターのbinlogにまだ存在し、スレーブに送信されます。これにより、データが破損したり、エラーが発生したりする可能性があります。
(2)トランザクションがbinlogに存在しないため、スレーブに送信できないため、レプリケーションエラーが発生します。
予防
これらの手順に従って、誤ったトランザクションを積極的に防ぐことができます。スレーブに修正を適用する必要がある場合、誤ったトランザクションを軽減する1つの方法は、スレーブのバイナリロギングを一時的にオフにすることです。誤ったクエリを実行する前にsql_bin_log=0を実行すると、うまくいくはずです。後でsql_bin_log=1を実行してbinlogを有効にできます。アプリケーションがスレーブに書き込むのを防ぐには、サーバーがスレーブとして構成されている場合、サーバーで読み取り専用を有効にする必要があります。
検出
GTIDベースのMySQLレプリカセットで誤ったトランザクションを検出するのは簡単です。 MySQLは、使用しているMySQLのバージョンに基づいて、実行されたすべてのGTIDをパフォーマンススキーマ/情報スキーマテーブルに保存します。現在のスレーブで実行されたGTIDを取得し、現在のマスターで実行されたGTIDからそれらを差し引くと、その特定のスレーブでのすべての誤ったトランザクションが得られます。 mysqlfailoverやmysqlrpladminなどのユーティリティも、誤ったトランザクションの検出に役立ちます。
ソリューション
誤ったトランザクションが検出されたら、フェイルオーバー後に発生したレプリケーションエラーを修正する方法が2つあります。 1つの方法は、誤ったトランザクションのGTIDをスレーブGTID実行履歴から削除することです。このように、スレーブがマスターに昇格したときに、誤ったトランザクションがすべてのノードに複製されることはありません。誤ったトランザクションを処理する別の方法は、他のすべてのスレーブに誤ったトランザクションをスキップするように指示することです。これには、誤ったトランザクションと同じGTIDを持つ空のトランザクションをレプリカセット内の他のすべてのノードに挿入することが含まれます。これにより、他のすべてのノードは、このトランザクションがすでに適用されていると見なされ、スキップされます。 MySQLには、これを行うための専用のMysqlslavetrxというユーティリティがあります。このユーティリティを使用して、指定されたGTIDで空のトランザクションを挿入できます。ここで説明するように、空のトランザクションを追加することには、他の用途もあります。