カジュアルに匿名トランザクションをGTID環境へレプリケーションしよう

MySQL 8.0

カジュアルに匿名トランザクションをGTID環境へレプリケーションしよう

MySQL 8.0.23の機能として以下が実装され、匿名トランザクション(GTIDが記録されていないトランザクション)をGTIDが有効化されたMySQLインスタンスへレプリケーションすることが可能となりました。

17.1.3.6 Replication From a Source Without GTIDs to a Replica With GTIDs

従来では、GTIDレプリケーションを行う場合、ソース・レプリカすべてのインスタンスでGTIDが有効化されている必要がありました。

今回はこの機能を使用して、カジュアルにMySQL8.0(非GTID)からMySQL8.0(GTID)へのレプリケーションを行ってみようと思います。

目次

セットアップ

dbdeployer を使用して以下の通りセットアップしました。

以下の通りGTIDが有効なインスタンスと従来型のポジションベースで動作するインスタンスを準備しました。

この状態でreplica-8023にレプリケーションソースを設定し、START REPLICAを実行してみましょう。

はい。ソースインスタンスではGTIDが有効でないためエラーが出ることが確認できました。

設定を一旦クリアします。

ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS を有効化する

非GTID環境からGTID環境へのレプリケーションはレプリケートされてきたトランザクションに、擬似的なGTIDをレプリカ側で割り振る事によって実現します。

From MySQL 8.0.23, you can set up replication channels to assign a GTID to replicated transactions that do not already have one.
This feature enables replication from a source server that does not have GTIDs enabled and does not use GTID-based replication,
to a replica that has GTIDs enabled. If it is possible to enable GTIDs on the replication source server,
as described in Section 17.1.4, “Changing GTID Mode on Online Servers”,
use that approach instead. This feature is designed for replication source servers where you cannot enable GTIDs.

擬似的なGTIDは、CHANGE REPLICATION SOURCE TO の ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS で有効化します。

ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS では、疑似的なGTIDをどのように割り振るか指定します。

指定可能な値である、LOCALと[uuid] の2パターン試してみました。

なお、基本的にはレプリケーション自体はGTIDベースではありませんので、SOURCE_AUTO_POSITION を使用することはできません。
ですので、古き良き SOURCE_LOG_FILESOURCE_LOG_POS で開始ポジションを指定します。

今回はソースインスタンスの静止点が取れるためコマンドで最新のポジションとバイナリログファイルを確認しますが、mysqldumpでレプリカを作成する場合は–master-dataで出力した内容から確認するなどご対応ください。

ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS = LOCAL

LOCALを指定すると、レプリカのGTIDとして処理します。

上記をレプリカに設定し、レプリケーションを開始します。

ソースインスタンスにworld databaseのデータをインポートし、GTIDを確認してみます。

想定通り、ソースインスタンスからレプリケートされたトランザクションが、レプリカのGTIDとして 記録されていました。

ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS = [uuid]

指定したUUIDを使用してGTIDを割り振ることも可能です。

この場合、LOCALとは異なりレプリカインスタンスでの更新によるGTIDなのか、ソースインスタンスでの更新によるGTIDなのかを判別可能です。
GTIDは aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee としました。

worldを削除してインポートします。

指定したGTIDが記録されていることが確認できました。

なお、現在のASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONSの状態については、performance_schema.replication_applier_configuration で確認することができます。

ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS 使用時の注意点

MySQL 5.7では実装されていない

MySQL では2つ以上のバージョンをレプリケーショントポロジに含めることはサポートされません。
この機能の印象からは、動的にGTIDを有効化できないMySQL 5.6をソースとしたケースで使用したくなりますが、本機能はMySQL 5.7にバックポートされておりません。

GTIDセットを転送できない

ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS によりレプリケーションされたインスタンスのGTIDセット(gtid_executed)、は他のサーバに転送することができません。
そのため1階層のレプリケーショントポロジになります。

Using ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS on a replication channel is not the same as introducing GTID-based replication for the channel. The GTID set (gtid_executed) from a replica set up with ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS should not be transferred to another server or compared with another server’s gtid_executed set. The GTIDs that are assigned to the anonymous transactions, and the UUID you choose for them, only have significance for that replica’s own use.

ソースのリストア用バックアップ・フェイルオーバ先として利用できない

フェイルオーバ時にこのレプリカをソースに昇格させたり、ソースダウン時にレプリカのバックアップを使用して復旧するケースが考えられますが、ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS が有効なレプリカはそれらの操作がサポートされません。

A replica set up with ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS on any channel cannot be promoted to replace the replication source server in the event that a failover is required, and a backup taken from the replica cannot be used to restore the replication source server. The same restriction applies to replacing or restoring other replicas that use ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS on any channel.

これについては、 ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS を指定して CHANGE REPLICATION SOURCEを実行した後、SHOW WARNINGSを実行するとメッセージが表示されます。

GTIDはレプリケートされたイベントがレプリカでコミットされるときに割り当てられる

通常、GTIDはソースでコミットされた時点で割り当てられますが、ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS によるGTIDはレプリカでのコミット時点で適用されます。
マルチスレッドスレ―ブの有効時に slave-preserve-commit-order=1 を設定すると通常ソースインスタンスのコミット順序がレプリカでも厳密に守られますが、上記の仕様により効果がありません。

トランザクションのスキップは、sql_slave_skip_counterを利用可能

基本的にはポジションベースのレプリケーションとなるため、 gtid_nextを使用したスキップ方法ではなく、sql_slave_skip_counterを使用します。

https://dev.mysql.com/doc/refman/8.0/en/replication-administration-skip.html

START REPLICA UNTIL SQL_BEFORE_GTIDSおよび UNTIL_SQL_AFTER_GTIDS は利用不可

ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS が有効なレプリケーションチャネルでは上記のオプションは利用できません。

WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS関数は利用不可

ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS が有効なレプリケーションチャネルでは上記のオプションは利用できません。

まとめ

様々な事情により、デフォルト(=非GTID)のまま本番デプロイしてはみたものの、後々やっぱりGTIDしたい!と考えたことはないでしょうか。
この機能はそのようなケースでよりカジュアルにGTIDを使うことができる機能のように思います。

MySQL 5.7の時点でGTIDのオンライン有効化は可能でしたので、例えば上記のようなケースでも本番環境でGTIDを後から有効化することは可能です。
ですが、本番環境での作業を行うことは様々なハードルがあり大変かもしれません。

そのようなケースでとりあえずGTIDを有効化したレプリカを作って評価する、ということが可能ですので、ぜひカジュアルにGTIDレプリカを構築してみてはいかがでしょうか。

スマートスタイルTECHブログについて

スマートスタイルTECHブログでは、日頃MySQLのサポート業務に従事している有資格者で構成された技術サポートチームがMySQLに関する技術情報を発信しています。データベースのお困りごとはお気軽にご相談下さい。

よかったらシェアしてね!
  • URLをコピーしました!
目次