MySQLとMariaDBのGTIDベースのマスタースレーブの同期


MySQLとMariaDBのGTIDベースのマスタースレーブの同期
最近、データベースの同期を行っています.主なビジネスシーンは、現在のミドルウェアのライブラリ分割テーブルのライブラリテーブルを単一のライブラリ単一テーブルに同期してOLAPを行うことです.前期の同期はbinlog filenameとposに基づいており、先日DBAが可能なリスクをお知らせしましたが、よく考えてみると確かにそうです.もしメインノードが掛かっていて、ノードから昇格するのが主であれば、実はメインスレーブのbinlog posが一致していないので、登録を続ける上で同期から問題があるに違いありません.また、現在dbで使用されているのはvipです.切り替えが感知されない可能性があるのはノードからで、それではやはり隠れた危険があります.
我々の同期サービスは,ノードから偽装し,プライマリノードから送信されたbinlogデータを絶えず解析しmysql文に変換した同期である.
そこで考えてbinlog posの機能でgtidベースの同期を再サポートすることにした.どうしてこの方面の資料は本当に少なすぎて、数日資料を調べて、mysqlとmariadbの主従をかじって、やっと大体この問題を解決しました.
まずmysqlとmariadbのgtidベースの同期について概説します.
mysql gtid同期
mysql gtidフォーマット
mysqlでは、各serverにグローバル一意のserver_があります.uuid、これはソースを区別するために使用されます.
mysqlのgtidフォーマットはgtidSetであり、mysqlはマルチソースレプリケーションをサポートするため、setという概念が存在し、各set内の各要素はソースのgtid情報である.
一方、要素であるgtidは、対応するソースの同期情報が保存されており、ほぼserver_uuid:START-END形式であり、実行されたgtid情報を表し、1つのソースに複数のgtidがある可能性がある.
もちろん、私たちの同期は単一のソース同期にすぎません.また、簡略化するために、gtidフォーマットは一般的にserver_uuid:1-ENDです.つまり、最後に実行されたgtidの値を記録するだけでいいです.
mysql gtid同期プロセス
マスターノードが開いていると仮定gtid_modeでは、従として、以下のいくつかのステップがあります.
1.通常モードと同様に、ノードから登録されたパケットCOM_を送信するREGISTER_SLAVE 2.COM_を送信BINLOG_DUMPパッケージは、同期の位置情報を指定するために使用されます.ここではCOMを指定する必要があります.BINLOG_DUMP_GTIDコマンドはgtid同期をオンにすることができ、binlog filenameとposは空と4に設定する必要があります.
このパッケージのバイナリ構造は次のとおりです.
1 byte command-id COM\_BINLOG\_DUMP\_GTID
2 bytes flag 
4 bytes server_id server_uuid
mysql-string binlog-filename
8 bytes binlog-pos
encoded gtidSet

最初からコピーする必要がある場合は、空のgtidSetを符号化するだけでいいです.
COM_を使用するとBINLOG_DUMP_GTIDが同期をオンにすると、mysqlからGTIDEventが届きます.以下はGTIDEventのバイナリ構造です.
1 byte commitFlag
16 bytes SID
8 bytes GNO

SIDは符号化されたserver_uuid、GNOは現在のトランザクション番号であり、gtid文字列をフォーマットすることができます.
GTIDEventを解析した後、通常の流れに従って、このGTIDEventの後続のイベントが実行された後、現在のgtidを継続して、次回の同期を継続します.
mariadb gtidフォーマット
mariadbのフォーマットはmysqlとは異なり、大まかな概念はそれほど悪くないが、server_が存在している.uuidとsequenceの概念.以下、単一gtidの文字列値domainID-serverID-sequence同時にmariadbが同期してきたgtid eventもmariadbと一致せず、mariadbが拡張したもので、以下はmariadbのGTIDEventのバイナリフォーマットです.
8 bytes sequence
4 bytes domainID

上記のフォーマットに比べてserverIDが欠けていると思われるかもしれませんが、実際にserverIDはbinlog eventのヘッダに入っているので、情報は一致しています.
mariadb gtid同期プロセス
mysqlとの違いは比較的大きく、mariadbの同期には主に以下の手順があります.
  • slaveがgtid eventを解析できることをmasterに知らせるために、
  • というコマンドを実行する必要があります.SET @mariadb_slave_capability=4
    2.現在の同期gtidを登録するSET @slave_connect_state='xxx'
    3.COM_を送信BINLOG_DUMPパケット、binlog filename posを空にします.
    binlog pos同期の場合、gtidモードに自動的に切り替わります
    現在走っているサービスはbinlog posに基づいているので、まず解決しなければならない問題はgtidモードに自動的に切り替えることです.mariadbの後期バージョンの同期はmysqlとは異なるため、別々に解決する必要があります.
    mysqlの解決方法はまだ見つかっていないので、先に置いておきます.何か解決策があれば、メッセージも歓迎します.オンラインランニングのほとんどのサービスはmariadbなので、サポートしなくてもしばらくは可能です.
    mariadbの解決方法は非常に簡単で、mariadbにはbinlog_gtid_posという関数が内蔵されているので、この関数を使用してbinlog posに対応するgtidをクエリーすることができます.SELECT binlog_gtid_pos('mysql-bin.000001', 1234)
    対応するgtidが得られると,このgtidを用いて同期することができ,人工的な介入を必要としない.