2024-01-16 に MySQL 8.3.0 Innovation releaseがリリースされました。
https://dev.mysql.com/doc/relnotes/mysql/8.3/en/news-8-3-0.html
今回は、新たに追加された Tagged GTID(GTIDのタグ付け)のについて検証してみたいと思います。
GTIDフォーマットについて
MySQLのGTID は、リリースノートから確認する限り、Changes in MySQL 5.6.5 (2012-04-10, Milestone 8) から導入されておりますので、もうすぐ12周年という事になります…ので今更という方が多いかと思いますが、 一応GTIDのフォーマットについて簡単におさらいです。
MySQLのGTIDは以下のフォーマットとなっています。
https://dev.mysql.com/doc/refman/8.3/en/replication-gtids-concepts.html
GTID = source_id:transaction_id
source_idはmysqldごとに自動的に生成されるユニークなID(server_uuid)となり、transaction_idはsource_idのサーバで行われた更新番号(1から始まりcommitされる度に増分)です。
これによって、GTIDに紐づくバイナリログ内の更新処理がどのサーバの何番目のGTIDの処理なのかを判断することができ、また同じGTIDが記録されているサーバは同じデータを持つということが保証できます。
Tagged GTID についての検証
Tagged GTID はこれまでのGTIDフォーマットを拡張するもので、 以下の形式でGTIDを指定することができるようになりました。
※ 従来の source_id:transaction_id のGTIDフォーマットも可能です
GTID = source_id:tag:transaction_id
では、実際にどうやってタグを指定するかというと、gtid_next や gtid_purged にGTIDを設定する時に使うことができます。
システム変数 | 説明 |
---|---|
gtid_next | 次に使用するGTID。デフォルトはAUTOMATICで、次に自動生成されるGTIDを使います(transaction_id+1したもの) |
gtid_purged | 不要なGTIDセット。ローテーション等によってサーバ上から物理削除された際などに自動的に記録されたり、明示的にスキップしたいGTIDを追加することもできます。 |
デフォルトでは、 server_uuid:transaction_id
の形式で記録されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
mysql> show global variables like 'gtid_%' +----------------------------------+-------+ | Variable_name | Value | +----------------------------------+-------+ | gtid_executed | | | gtid_executed_compression_period | 0 | | gtid_mode | ON | | gtid_owned | | | gtid_purged | | +----------------------------------+-------+ mysql> create database test; mysql> show global variables like 'gtid_%' +----------------------------------+----------------------------------------+ | Variable_name | Value | +----------------------------------+----------------------------------------+ | gtid_executed | 4661756a-b691-11ee-8f2e-525400b5f371:1 | | gtid_executed_compression_period | 0 | | gtid_mode | ON | | gtid_owned | | | gtid_purged | | +----------------------------------+----------------------------------------+ |
先程の gtid_next
関数に、Tagged GTIDを指定することで一部の処理をタグ付けされたGTIDに含めることができます。
server_id:transaction_id:tag:transaction_id
の形式になっている点にご注意ください。
タグなしのGTIDのtransaction_idと、Tagged GTIDのtransaction_idは独立して増分されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
mysql> set gtid_next="automatic:tagtest"; mysql> create table test.t1 (i int primary key auto_increment); mysql> show global variables like 'gtid_%' +----------------------------------+--------------------------------------------------+ | Variable_name | Value | +----------------------------------+--------------------------------------------------+ | gtid_executed | 4661756a-b691-11ee-8f2e-525400b5f371:1:tagtest:1 | | gtid_executed_compression_period | 0 | | gtid_mode | ON | | gtid_owned | | | gtid_purged | | +----------------------------------+--------------------------------------------------+ mysql> insert into test.t1 values (1); mysql> show global variables like 'gtid_%' +----------------------------------+----------------------------------------------------+ | Variable_name | Value | +----------------------------------+----------------------------------------------------+ | gtid_executed | 4661756a-b691-11ee-8f2e-525400b5f371:1:tagtest:1-2 | | gtid_executed_compression_period | 0 | | gtid_mode | ON | | gtid_owned | | | gtid_purged | | +----------------------------------+----------------------------------------------------+ mysql> set gtid_next="automatic"; mysql> insert into test.t1 values (2); mysql> show global variables like 'gtid_%'; +----------------------------------+------------------------------------------------------+ | Variable_name | Value | +----------------------------------+------------------------------------------------------+ | gtid_executed | 4661756a-b691-11ee-8f2e-525400b5f371:1-2:tagtest:1-2 | | gtid_executed_compression_period | 0 | | gtid_mode | ON | | gtid_owned | | | gtid_purged | | +----------------------------------+------------------------------------------------------+ |
つまり、Tagged GTIDはサーバの部分的なGTIDセットに名前をつけて意味をもたせる事を目的としたもののです。
いつも参考にさせていただいているlefred氏の記事 MySQL 8.3: Purging data from your InnoDB Cluster では、この機能を使い、グループレプリケーション環境のマスタのレコードを削除し、アーカイブ用レプリカには削除イベントをレプリケーションさせないという運用方法を紹介しています。
なお、lefred氏が書いている通りタグを使わなくてもできることはできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
-- gtid_exexutedから現在のGTIDを確認 mysql-source> select @@gtid_executed; +----------------------------------------+ | @@gtid_executed | +----------------------------------------+ | 4661756a-b691-11ee-8f2e-525400b5f371:1 | +----------------------------------------+ -- gtid_nextに先に予約するGTIDを設定 -- 決め打ちで未来のtransaction_idを指定 mysql-source> set gtid_next = '4661756a-b691-11ee-8f2e-525400b5f371:100'; -- 予約済みGTIDをレプリカのgtid_purgedに設定 mysql-replica> set global gtid_purged = '+4661756a-b691-11ee-8f2e-525400b5f371:100'; -- レプリケーションさせたくない処理(ここではアーカイブ済みデータの削除)を実行します。 mysql-source> delete from test.t1 where i <= 50; -- gtid_nextをAUTOMATICに戻す mysql-source> set gtid_next = 'automatic'; |
ただこの場合、後から見てどのGTIDを意図的にスキップしたのか分かりづらいかもしれません。
また、上記では決め打ちでtransaction_idを100にしましたが、それよりも前のGTIDとの整合性が取れるかはわかりません。
Tagged GTIDを使うと独立したGTIDのように記録されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
-- server_uuidは確認しておく mysql-source> select @@server_uuid; +--------------------------------------+ | @@server_uuid | +--------------------------------------+ | 4661756a-b691-11ee-8f2e-525400b5f371 | +--------------------------------------+ -- 適当なタグでgtid_nextを予約 mysql-source> set gtid_next = 'automatic:archive'; -- 予約済みGTIDをレプリカのgtid_purgedに設定(意図せずレプリケートされないようtransaction_idはバッファを取って設定) mysql-replica> set global gtid_purged = '+4661756a-b691-11ee-8f2e-525400b5f371:archive:1-10'; -- レプリケーションさせたくない処理(ここではアーカイブ済みデータの削除)を実行します。 mysql-source> delete from test.t1 where i <= 50; -- gtid_nextをAUTOMATICに戻す mysql-source> set gtid_next = 'automatic'; |
スキップしたトランザクションも特定し易いです。
1 2 3 4 5 6 7 8 9 10 11 |
mysql-source> select @@gtid_executed,@@gtid_purged; +----------------------------------------------------+---------------+ | @@gtid_executed | @@gtid_purged | +----------------------------------------------------+---------------+ | 4661756a-b691-11ee-8f2e-525400b5f371:1-2:archive:1 | | +----------------------------------------------------+---------------+ # 以下で表示 $ mysqlbinlog -v --base64-output=decode-rows \ --include-gtids="4661756a-b691-11ee-8f2e-525400b5f371:archive:1" \ /var/lib/mysql/binlog.0* |
上記では、Tagged GTIDを除外してレプリケーションした形ですが、逆にTagged GTIDのみをレプリケートすることができるでしょうか。
おそらくレプリカにタグなしのGTIDをかなり未来までgtid_purgedに設定するということになるでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 |
mysql-source> trucnate table test.t1; mysql-source> reset master; mysql-replica> stop slave;reset master;reset slave;start slave; mysql-replica> set global gtid_purged = '+4661756a-b691-11ee-8f2e-525400b5f371:1-9999999'; mysql-source> select @@gtid_executed; +------------------------------------------------+ | @@gtid_executed | +------------------------------------------------+ | 4661756a-b691-11ee-8f2e-525400b5f371:1-9999999 | +------------------------------------------------+ |
タグなしのGTIDはgtid_puregedに設定されているのでレプリカで実行されません。
1 2 3 4 5 6 7 8 9 10 11 |
mysql-source> insert into test.t1 values (1); mysql-source> select * from test.t1; +---+ | i | +---+ | 1 | +---+ mysql-replica> select * from test.t1; Empty set (0.00 sec) |
タグ付きのGTIDは実行されました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
mysql-source> set gtid_next = 'automatic:tagged'; mysql-source> insert into test.t1 values (2); mysql-replica> select * from test.t1; +---+ | i | +---+ | 2 | +---+ mysql-replica> select @@gtid_executed; +---------------------------------------------------------+ | @@gtid_executed | +---------------------------------------------------------+ | 4661756a-b691-11ee-8f2e-525400b5f371:1-9999999:tagged:1 | +---------------------------------------------------------+ |
現在の所、タグベースのフィルタ処理機能は見当たらないので、"あるタグだけ" のような事を行う場合は mysqlbinlog
を使ったフィルタ処理等が必要になってくるでしょう。
1 2 3 |
$ mysqlbinlog -v -\ --include-gtids="4661756a-b691-11ee-8f2e-525400b5f371:tagged:1-99999999" \ /var/lib/mysql/binlog.0* | mysql -h[replica] |
サマリ
Tagged GTIDが追加された事により、柔軟かつアプリケーション主導でレプリカに同期するデータを取捨選択できるようになりました。
今後更に関連機能が充実し、使い道が増えていく事を期待したいですね(特にWrite-Scale方面に…)!
運用の使い道のヒントになれば幸いです!