チョットワカル Row-Based Replication・その5

こんにちわ。せじまです。
今回も replication の話をします。

はじめに

第5回です。

今回は TABLE_MAP_EVENT に関する話をします。 MySQL Internal Manual ではこちらになります。

14.10.1 TABLE_MAP_EVENT

解説

TABLE_MAP_EVENT には、更新対象の database_name.table_name と、更新対象の columnの型 の情報が保存されています。また、型の compatibility check や replicate-do-db などのチェックをするのに使われています。

では早速ソースコードを読んでいきましょう。

SQL Thread で handle_slave_sql() から降りてきます。

まずは Table_map_log_event::do_apply_event()

TABLE_MAP_EVENT に含まれる database_name.table_name が replication filter にヒット するか確認しています。

更新対象であると判断されれば、その table は rli->tables_to_lock に追加されます。

Rows_log_event::do_apply_event() も読んでみましょう

9567 行目から始まる if のブロックは 9783 行目まで続きます。たいへん長いです。

で、この中で Table_map_log_event::do_apply_event() で登録された、更新対象である table に関する処理が実行されます。

table の compatibility check ということで、型チェックが入ります。

型変換に関するチェックをする際、

チョットワカル Row-Based Replication・その2でも言及した、DATETIME や TIMESTAMP もチェックされます。

そして、table の compatibility check の後、 table id と table のマッピングがされて

table_id で更新対象の table を取得できるようになります。

チョットワカル Row-Based Replication・その1 の show binlog events の出力結果を見るとわかりますが、 UPDATE_ROWS_EVENT などの ROWS EVENT は、 table を名前ではなく、 TABLE_MAP_EVENT で割り当てた table_id 指定で更新するようです。で、UPDATE_ROWS_EVENT などはまず その table_id で更新対象の table を参照している、と。

そのあと、9799行目から 10074行目にかけて、UPDATE_ROWS_EVENT などの ROWS EVENT が処理されるんですが、これまた長いです

まずは (rli)->m_table_map.get_table(m_table_id) で NULL が返ってきた場合、 replication filter で更新対象から外されたってことになります。

Columnのメタデータなどに関する補足

binlog_format=ROW かつ binlog_row_image=FULL の場合、更新前と更新後の行のデータがすべて保存されているので、 binlog は Change data capture の用途にも使うこともできそうなわけです(わたしは Change data capture に疎いですが)。
例えば、居住地の情報を岡山県から茨城県に書き換えるトランザクションがあった場合、binlog_format=STATEMENTでは、「茨城県に書き換わった」ということしかわからないかもしれません。しかし、 binlog_format=ROW かつ binlog_row_image=FULL だった場合、「岡山県から茨城県に書き換わった」ということまで、binlogを読んだだけで確実にわかるわけです。

ちなみに、 binlog を capture するためのソフトウェアは古くから開発されており、例えば uber/storagetapper といったものも公開されています。

MySQL8.0 では、 binlog_row_metadataというパラメータが追加されており、さらに詳細なColumnのメタデータを取得できるようになりました。

詳しくは、以下の MySQL High Availability の記事で解説されています。

More Metadata Is Written Into Binary Log

Column のメタデータを binlog に追加することにより、さらに binlog の使い勝手が良くなっていきそうですね。

終わり

こちらののスライドで言及していた以下のことについて、これでだいたい触れました。

事前に調べたこと

あとは、今回の連載で取り上げたWorkLogやソースコードの関数など読み込んでもらうと、より理解が深まるでしょう。例えば、RBRにおけるColumnの型変換については、今回取り上げた Table_map_log_event や Rows_log_event は参考になるかと思います。

また、RBRに関するWorkLogはまだまだありますので、関心のある方はこちらにも目を通されると良いかもしれません。

以上で第一部・完となります。気が向いたら、またRBRに関するソースコード読んで、つらつらと書くかもしれません。