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

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

はじめに

第四回です。

前回、 Row-Based Replication では Column の名前を意識していないことを確認しました。今回は Row-Based Replication で online schema change できないか、そのへん試してみましょう。

まずは厳重注意

これから記述する内容を本番環境で実施する場合、リスクをともないます。まずは検証環境で試しましょう。

いちおうまとめ

  • master の方が Column が少なかった場合、 slave にしか存在していない Column の振る舞いは、 Worklog 5092 で規定されているようなものでした。デフォルトの値で更新されます。
  • よって、 slave でtableの末尾に add column する程度なら動く気がします。公式ドキュメントにもそのような記述があります。16.4.1.10 Replication with Differing Table Definitions on Master and Slave
  • ただ、 stored な generated column は、Row-Based Replication では binlog event で更新すべきようで、 slave で table の末尾に stored な generated column 追加しても、更新のたびに評価されるわけではないようです。
  • RBRでは「式を評価するのは、式が発行されたmasterでのみ行う」って考え方なんでしょうね。

でははじめます

master/slave でこのような table があります

master

slave

slave に add column して INSERT

slave で末尾に add column します。

master でカラム名指定で INSERT します

slaveにreplicationできます。masterに存在しないColumnには、デフォルトの値が入りました。この振る舞いは、WL#5092のDEFAULT VALUESの節に書かれているとおりですね。

(slave に add column した状態で)UPDATE

update し、 replication することもできます。 RBR での update は、「何番目のColumnを更新するか」を指定しているだけなので

master

slave

slave に Generated column 追加して INSERT や UPDATE

最近のMySQLは Generated column 使えるので、試しに slaveで Generated column 使ってみます 13.1.8.2 ALTER TABLE and Generated Columns

slave

master から insert したり update したりします

slave

master で update

slave

なるほど。Generated columnでは不整合が発生しました。

master で Generated column 追加して INSERT や UPDATE

STORED な generated column への更新は、RBRでは binlog の event として master から降ってこないといけないようですね。
slave で drop column したのち、 master から add column して試してみます。

slave

master

slave

binlog_row_image=full

master

slave

mysqlbinlog -vv で確認すると

binlog_row_image=minimal

slave

mysqlbinlog -vv は

補足

WL#3915: Fewer columns on slave という WorkLog を見ると、力強く次のように書いてあり

It should be possible to replicate a table that has more columns on the master
than on the slave, i.e., there are M columns in the table on the master and N
columns in the table on the slave and M > N.

When replicating in this manner, the contents of the extra columns on the master
is lost, but replication will accept the situation and keep running.

WorkLog 3259 は公開されていないようですが、 WL#3915 には次のようにも書いてあるので

This work is related to WL#3259 (RBR with more columns on slave than on master)
in that implementation of this worklog is necessary to support on-line table
definition changes (a.k.a., "schema upgrade") when using circular replication.

Row-Based Replication で、 master と slave の Column の数が一致していなくても replication できるべきだと、 MySQL の Replication teamは考えているようです。

個人的見解のような補足

ここでもう一度 WL#5092: RBR: Options for writing partial or full row images in RBR events を振り返ってみましょう。次のような記述がありました。

binlog_format=ROW な binlog には AI と BI があるので、 binlog 使ってデータを巻き戻すことが可能ではないか、という話ですが

  • master と slave の Column の数が違っても replication できる
  • master ないし slave にしか存在しない generated column があった場合、 binlog でその更新をケアできるのか
  • MySQLのバージョンが古かった場合、型変換できるのか。あるいは、 binlog を適用使用しているバージョンで、更新対象のColumnの型はサポートされているか
  • DMLはともかく、DDLはどうするのか

といったあたり踏まえると、binlog_format=ROW を熟知していないと、混乱を招く機能ではないかなぁと思います。

Alfranio、 Mats、Luís の三人は、reversible より noblob の方がユーザにとってメリットがあると考えてくれたのでしょう。個人的に、良い決断だったのではないかと思います。

今日はこれまで

今回はちょっとヤンチャなことをしてみました。 master と slave でテーブル定義が異なっていても、Row-based Replication はできるようですが、 STORED な Generated Column は、その限りではないようですね。

次回は、Row-based Replication で Column の型チェックが行われるところなどを見てみましょう。