- origin側はgtid_mode=OFF, binlog_format=MIXEDでこれを変えてはいけない
- MySQLはこのケースに限り 8.0.28 以外でも良い
- メンテナンスには入れられる。ただし、メンテナンスウィンドウ内でMyDumperをかけられるほどデータは小さくない
- なおGroupReplication ≠ InnoDB Clusterとした。つまりMySQL Shellの支援とMySQL Routerプロセスは使わない
- シングルプライマリーモード。MySQL Routerは使わないけど到達性の問題は 俺以外の誰か が何とかするものとする(実際、何とかしてくれた)
まずはフツーに空っぽの状態でGroupReplicationを組む。
これはほぼGetting Startedの通りにいった気がする(3か月くらい前なので既にやや記憶が曖昧)
深く考えずにデータを引っこ抜いて、GroupReplicationのPRIMARYノードに入れる。
Non-GTID環境からGTID環境への非同期レプリケーションは8.0.23でサポートされていたので、遠慮なくそれを使う。
GroupReplication側から
CHANGE REPLICATION SOURCE TO source_host = 'origin_replication_source', source_log_file= .., source_log_pos = .., ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTION = local FOR CHANNEL 'migration' ;
本当は(?) gtid_executedをすっきりさせたかったので group_replication_replication_name を割り当てたかったんだけど、それをやろうとするとError 4021で怒られた。
ERROR 4021 (HY000): CHANGE MASTER TO ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS = <UUID> cannot be executed because the UUID value is equal to the group_replication_group_name.
local
だと自分(GroupReplication PRIMARY)の server_uuid
を割り当ててくれる。まあそのへんのマシンで uuidgen
して持ってきても大して変わらない。
ともあれこれでレプリケーションを開始…
ERROR 3098 (HY000): The table does not comply with the requirements by external plugin
早速レプリケーション止まった…(´・ω・`)
原因は2つ、HealthCheckに使っていたMEMORYストレージエンジン(GroupReplicationはInnoDBのテーブル以外は更新できない)と、Primary KeyのないInnoDBテーブル(GroupReplicationはPKもしくはPKE.. Every table that is to be replicated by the group must have a defined primary key, or primary key equivalent where the equivalent is a non-null unique key.
.. つまり全カラムがNOT NULLかつUNIQUE制約がついているインデックスが無いとエラーで更新を拒否する。
なおこの2つは同じエラーを返すので、実際はエラーになったSQLスレッドのエラーを見てどっちが原因かを判断する。
MySQL error code MY-003098 (ER_BEFORE_DML_VALIDATION_ERROR): The table does not comply with the requirements by an external plugin.
この2つ(Non-InnoDBテーブルをすべてGR側だけでもInnoDB化し、PKが無いテーブルにすべてPKをつける)が終わればようやくレプリケーションが開始できるが、今回は残念ながら新たにPKを足すという選択肢が無かったので
MySQL :: MySQL 8.0 Reference Manual :: 13.1.20.11 Generated Invisible Primary Keys
MySQL 8.0.30とそれ以降のコイツを使わせてもらうことにした。
基本的にはGR側にデータを突っ込む時だけで良いはずだけれど、過渡期(Asyncレプリケーションを組んだままの期間)が長くてorigin側にPKのないテーブルを追加で作られてしまいそうな場合は CHANGE REPLICATION SOURCE TO
に一ひねり加える。
CHANGE REPLICATION SOURCE TO .., REQUIRE_TABLE_PRIMARY_KEY_CHECK = GENERATE;
REQUIRE_TABLE_PRIMARY_KEY_CHECK = GENERATEにして初めて、「originではPKが無かったものをレプリケーションの途中で横取りしてGIPKを足す」になる。これを忘れるとPKが無いままGR側にやってきてまた3098の洗礼を食らうので注意。
(なお、過渡期の間にそんなテーブルをCREATEするな、というネゴシエーションがとれるならこれは別に要らない。正直検証はしたけど、その期間にPKなしでCREATE TABLEされたテーブルなどなかった)
で、取り敢えず頭の図の状態には持って行けたが、もうひと悶着あったのでそれは次回にでも。