GTID とは
GTID (Global Transaction ID) とは、バイナリログに記録される個々のトランザクションに、世界で固有の ID をつけるという機能となる。GTID のフォーマットは以下のようになる。
発信源となった MySQL サーバの ID : トランザクション ID
MySQL サーバの ID は UUID を用いて生成される。UUID はサーバの初回起動時に決定され、データディレクトリ配下の auto.cnf というファイルに格納される。
$ sudo cat /var/lib/mysql/auto.cnf
[auto]
server-uuid=f341ed2f-997e-11e8-8672-060b24b2563c
トランザクション ID は 1 からはじまり、単調増加する連番となり、トランザクションがコミットするごとにインクリメントされる。
以下に例を示す。
f341ed2f-997e-11e8-8672-060b24b2563c:1
トランザクション ID は数値の範囲で表現することも可能であり、最初から 999 番目の一連のトランザクションには 1-999 というような表記が用いられる。
GTID は、どのトランザクションを実行したかということをトランザクション ID の範囲で表現し、範囲で表現された一連の GTID は、GTID セットと呼ばれる。
GTID は 1:N 型のレプリケーションにおける、スレーブの自動昇格で利用される。
スレーブの昇格において問題となるのは以下の 2 点となる。
- アプリケーションからの更新先を変更する
- 新たにマスターへ昇格したスレーブから、他のスレーブがレプリケーションのための更新を受け取る
前者はアプリケーション側で接続先を変更する仕組み実装する必要がある。後者については GTID がない MySQL 5.5 以前では非常に難しい問題であった。
将来的に昇格するかもしれないスレーブは logbin オプションと logslave_updates オプションをつけることにより、バイナリログを出力する設定になっており、最も進んだスレーブのバイナリログにはマスターが行った更新が最も多く含まれていることが期待される。
しかし、スレーブ上のバイナリログの中身をみても、それぞれのイベントがマスターのどのイベントに対応するかはわからない。というのもスレーブはマスターとは違うタイミングでバイナリログのローテーションをする可能性がある上、一見同じイベントに見えてもたまたま更新の内容が同じだっただけかもしれないためである。
また、スレーブが複数あっても、スレーブ間で何か連携が取られているわけではなく、個々のスレーブそれぞれがマスターのバイナリログを受け取って各々のペースで再生するだけとなる。
スレーブの負荷次第でもレプリケーションの進み具合に差が生じてしまい、もし IO スレッドが受け取ったバイナリログの進み具合に差があると、それを埋める作業を行う必要があり、それはコストの高い操作となる。何故なら、スレーブ地震が生成するバイナリログと、マスターが生成したバイナリログの間の関係を示す情報がないためである。
GTID があることにより、個々のトランザクションは一意に識別できるため、根本的にこのような問題は発生しない。
MySQL 5.6 における GTID については、以下の資料が参考になる。