tom__bo’s Blog

MySQL!! MySQL!! @tom__bo

MySQL Casual Talks vol.12の復習

先日開催されたMySQL Casual Talks vol.12で「binlogを覗く」を発表した際のQAタイムで某瀬島さんからアドバイス頂いたWLを読んだので進捗報告です。

現在もgeneral document, internal manual, WL, source code reference(by doxygen)からbinlogの各種eventの構造を探していますが、internal manualからの情報以外が見つからず、mybinlogの開発は難航(座礁)しています。。。

普通にmysql-serverのコード読めって思うかもしれませんが、一旦バッファに書いてbinlog fileに落としているので、どうも追っていくのが大変です。。。そろそろ本気出してそこを読むしかなさそうです。
(mysqlbinlogとかio threadのbinlog(relay log)を読み込む部分でよいかも)

話を戻して、以下ではアドバイス頂いた2つのWLとその関連WLとして出てきた1つのWLについてのメモを書いています。

  • WL 5092
  • WL 5404
  • WL 4033

コメントとなっているのは僕の感想です。

WL#5092: RBR: Options for writing partial or full row images in RBR events

Affects: Server-5.6 — Status: Complete

https://dev.mysql.com/worklog/task/?id=5092

  • まとめ

    • binlog_row_imageを提案するWL
    • reversibleというPKEと変更に使われたカラムを保持するオプション値も検討されたが、現実的な利用がなく、ユーザを混乱させるとして実装されなかった
      • noblobがこれの大体になるとしている
      • (2009/09/09のskype meetingで決まったらしい)
  • メモ

    • full, minimalを選択可能にし、minimalを選択ることで、binlog disk spaceやnetwork resource, mysqld memory footprintを節約できる
    • Before Image(BI), After Image(AI)の説明
    • 以下が必要
      • write_rows_log_event -> only AI
      • delete_rows_log_event -> only BI
      • update_rows_log_event -> BI and AI
    • BIにはrowを一位に決定できる値を持っていないといけない(Primary Key Equivalent: PKE)
    • PKEは以下
      • PK
      • UK with NOT NULL
    • PKEがないときは全てのカラムをBIを利用する、もし完全に同じレコードが2つ以上あってもそのうちの1行だけを更新すれば結果はおなじになるので問題ない
    • MySQL 5.1 GAではPKEは full row(全カラムの値)としていた

この他Master, slaveでデータ件数が違う場合、indexが違う場合, table 定義(column)が違う場合にどうするか、どういう時にreplicationをstopさせるかの条件が書かれている

*Primary Key Equivalent* (PKE) is defined as:

    1. If a PK exists, the PKE is equal to the PK.

    2. Otherwise, if there exists a UK where all columns have the NOT
       NULL attribute, then that is the PKE (if there are more than
       one such UKs, then one is chosen arbitrarily).

    3. Otherwise, the PKE is equal to the set of all columns.

コメント

PKEの定義, before image, after imageをどのイベントで書くか, master, slaveでtable定義が違う場合にどう対処するかが書かれていて、とても良い。

ただ、binlogをparse, deserializeするという観点でいうと、PKEがどう判断されるかを知らなくても、直前にcolumnの定義順番にbit fieldにてどのカラムの情報を書くかが書かれているので問題なかったりする。

REFERENCESやNOTESに結構な量のバグが(20個くらい??)あるのでQAでわかったとはいえハマりどころがありそうなので、関連した実装をするときはこれも確認しておくと良さそう

WL#5404: Propagation of Rows_query log event

Affects: Server-5.6 — Status: Complete

https://dev.mysql.com/worklog/task/?id=5404

  • [RATIONALEの内容]
    • Rows_queryによってRBRの場合であってもoriginalのSQLがbinlogに書かれるようになったが、slaveでapplyするときやmysqlbinlogでdumpするときにはこれが書かれない問題があった。それを修正するためのWL
  • [Requirementsの内容]
      1. --binlog-rows_query-log-eventsが有効の時にrows_query_log eventでoriginal SQLが記録される
      1. --binlog-rows-query-log-eventsが有効の時にはmysqlginlogによってdumpされた BINLOG '...' が適用される (? これはrows_query_log_eventの構造が未知で理解できてない *1)
      1. replication filteringのルールはRows event(write_rows_eventやupdate_rows_eventのことだと思われる)と同じルールを適用する
  • [PROPOSED SOLUTIONSの内容]
      1. '#'をつけてコメントとして記載する
      1. /*! */ のように特殊なコメントとして記載する
    • 上記の2つの方法があったが、2の方法ではもとのSQLにversion commentを含んでいるとうまく動作しないという問題があって1の方法を取ることになった

コメント

RBR(RBL)環境下においてoriginalのsqlが書かれるeventとしてrows_query_logの提案理由と実装手法がわかるWLではあるが、WLのページのタブのDescription, Dependent Tasks, High Level Architecture, Low Level Architectureをみてもbinlogにこのイベントをどう書くかは書かれていない。。。

REFERENCESにWL 4033が書かれていたので読んだのが次のWL

WL#4033: Support for informational log events

https://dev.mysql.com/worklog/task/?id=4033

Affects: Server-5.6 — Status: Complete

  • WL #5404の関連WLとして出てきたもの
  • binlogのlog eventでそのバージョンで認識できないものであれば無視するという機能の追加
    • これを入れることで新しいバージョンからbinlogを受け取って、理解できなくてもエラーになることがなく無視してレプリケーションを続けられるようになる
  • これを実装したnew master/slaveと実装していないold master/slaveの挙動が簡単に整理されている、期待通り

コメント

5.6のどこかからそのサーバのversionで定義のないイベントが無視されるようになっていたのか。
たしかにGTID系のeventを認識できないせいで5.7 to 5.6のレプリが失敗するバージョンがあった気がする。(会社のwikiにある)
この解消はbinlog eventをバックポートしたのかと思っていたけど、これを使っている可能性も高い。

WLをcompleteにしたときのcommit番号か、少なくともminor versionくらいは書いてほしい。。。

他、面白そうな binlog関連WL

特に↓は良さそうなんだけど完成してない、、、

ということでこれらは読んでまとめをかくと思いますが、だれか読んでまとめてくれてもありがたいです。。。