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

こんにちわ。せじまです。
引き続き replication の話をします。

はじめに

第三回です。

前回は THD::decide_logging_format() を通じて、 binlog_format=ROW についてぼちぼち学びました。今回は binlog_row_image に関する話を踏まえつつ、ちょっと応用編っぽい話もします。

解説

binlog_format=ROW についてさらに学ぶべく、まずはMySQL Internals Manualを読んでみましょう。

ただ、

MySQL Internals Manual / The Binary Log / Event Data for Specific Event Types をみると

Write_rows_log_event/WRITE_ROWS_EVENT には次のように書いてあります。

[TODO: following needs verification; it's guesswork]

なるほど、binlog_format=ROW について込み入ったことが知りたいなら、最終的には自分でソースコード読んだ方が早そうですね。

で、 Rows_log_event::print_verbose()Rows_log_event::print_verbose_one_row() を読むと、「なるほど binlog_format=ROW の中身はこんなものか」と想像はつきます。

Rows_log_event::print_verbose_one_row() を呼び出す mysqlbinlog -vv を実行すると、update takanori set val2=val2+2000 where id=3 のような SQLは、次のように表示されます。

binlog_row_image=minimal のときは次のようになります

そして、おそらく、 Row-based replication や binlog_row_image=minimal について最も詳細な資料は、Worklog 5092 であり、上記の binlog の中身を説明するものでもあります。

Worklog 5092

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

だいたい全部重要なんですが抜粋しますと

これを読んでいただくといろいろわかると思うのですが、どうもUPDATE時に評価されているのはPKEのみであり、それ以外のColumnは見てないようです。

binlog_format=ROWのとき、 {Write,Delete,Update}_rows_log_event にはColumnの名前が保存されていません。純粋に「何番目のColumnを更新対象とするのか」としか見てないようです。
よって、RBRではmasterとslaveでカラム名が異なるtableでもreplicationできるんじゃないでしょうか?

では試してみましょう。

以下、本番環境では試さないことを推奨する、実験的な試みをします。

次のようなslaveがあるとします。

次のようなmasterがあるとします。

slaveで更新かけます。

binlog_row_image=FULL で master に更新をかけます。

slave には次のように更新が反映されます。

master の binlog を mysqlbinlog で見ると、次のとおりです。WHERE に @3=8000 と書いてありますが、これはPKEに含まれないので、実は見ていないようです。

もうちょっと試してみましょう。

slave でこうします。

master でこうします。

slave はこうなります。

binlog_row_image=FULL

  • 上記の例からわかるように、 BI(before image)はログとして残っているだけで、必ずしも、完全一致であるか評価しているわけではないようです。
  • そうであるならば、BIにすべてのデータが保存されている必要性ってあんまりないのでは?という気もします(が、ログとしては意味のあるものです)。
  • AI(after image) にすべてのデータが保存されていて、それで強制的に上書きされるのは、整合性を保つ上で望ましいことだと思います。

binlog_row_image=noblob

  • 必要がなければBIとAIにblobを含まないというのは、なかなか合理的でバランスが良い気もします。

binlog_row_image=minimal

ある意味、 Statement-Based Replication と一番挙動が近いかもしれません。

例えば、上記の master/slave 構成で試してみますと

master

slave

slaveで更新して

master で set session binlog_row_image=minimal; しつつ更新すると

slave は二番目のColumnが更新されません。

binlog_row_image=full にすると更新されます

master

slave

今日はこれまで

今回は応用編っぽい話をしました。 Worklog 5092 はとても重要なことが書いてあると思います。このあたり関心ある方は、熟読した上で、いろいろ動かしてみたり、ソースコードを読んでいただくと良いでしょう。

次回はもうちょっと踏み込んでいきます。