web-dev-qa-db-ja.com

レプリケーションA-> B-> Cでは、Aをbinlog_format = STATEMENTに、Bをbinlog_format = ROWにできますか?

オンプレミスのMySQL 5.6サーバー(A)と別のオンプレミスのMySQL 5.6サーバー(B)の間でレプリケーションを設定しています。移行してレプリケートしたいAWS DMSインスタンス(C)をセットアップしていました。すると、binlog_formatをROWベースのレプリケーションに設定する必要があったことがわかりました。

これは実現可能ですか? Aの変更がCに正しく複製されることを期待できますか?

3
Aaron R.

STATEMENTROW絶対に有効な構成です。

おそらく見落としているのは、サーバーBでlog_slave_updatesを有効にする必要があることです。そうしないと、AからCに何も複製されません。


しかし、当面の問題に対処するために、構成された@@binlog_formatと実際にサーバーのバイナリログに書き込まれるものとの比較を説明する次の表を検討してください。 Aがマスターで、BがAのスレーブであり、Bに直接変更が加えられていないと仮定します。もちろん、Bでlog_slave_updatesが有効になっています。

A binlog_format | A actually writes | B binlog_format | B actually writes
-------------------------------------------------------------------------
STATEMENT         STATEMENT           STATEMENT         STATEMENT
STATEMENT         STATEMENT           MIXED             MIXED
STATEMENT         STATEMENT           ROW               ROW

MIXED             MIXED               STATEMENT         TOTALLY FAILS EVENTUALLY
MIXED             MIXED               MIXED             MIXED
MIXED             MIXED               ROW               ROW

ROW               ROW                 STATEMENT         TOTALLY FAILS VERY QUICKLY
ROW               ROW                 MIXED             ROW
ROW               ROW                 ROW               ROW

何が起きてる?

Bがそのバイナリログに書き込むとき、Bは行った変更をreplicateに書き込みます。ローカルオプティマイザが使用する必要があると判断する形式でこれらのエントリを書き込みます。 STATEMENTまたはROWモードが有効な場合は、これが唯一の選択肢であるため、受信STATEMENTは、送信ROWになります。サーバーBは、着信イベントを実行し、ローカルデータで挿入/更新/削除した行とそれらの行の列の値をログに記録するだけなので、簡単に変換できます。

各MySQLサーバーは独自のバイナリログ形式のみを設定できます(binlog_formatがグローバルスコープまたはセッションスコープで設定されているかどうかにかかわらず)。つまり、レプリケーションマスターのログ形式を変更しても、スレーブはログ形式を一致するように変更しません。 [...]

レプリケーションの進行中にマスターでバイナリログ形式を変更するか、スレーブでも変更しないと、行イベントの実行エラーなどのエラーでレプリケーションが失敗する可能性があります:'Cannot execute statement: impossible to write to binary log since statement is in row format and BINLOG_FORMAT = STATEMENT.'

http://dev.mysql.com/doc/refman/5.7/en/binary-log-setting.html

これは、上記でTOTALLY FAILSを使用して言及したものです。唯一のinvalid構成は、サーバーがSTATEMENTモードにあり、少なくとも1つの上流マスターがROWまたはMIXEDにあることです。

どうして? STATEMENT形式は完全に確定的であるため、ROW形式で表すことができるすべてのクエリは、常にROW形式で表すことができます。逆に、ROW形式でレプリケートされたクエリは、その後STATEMENT形式でレプリケートeverできません。

MIXED形式は、ローカルオプティマイザーに、レプリケート方法--STATEMENTまたはROW-によるクエリごとのオプションを提供するだけですが、受信レプリケーションイベントがROWの場合、送信される選択肢はROWのみです。


また、STATEMENTモードは非常にひどいものです。できるだけ早くそれから離れてください。それまでは、AがSTATEMENTモードの場合、Bのデータが同期からずれやすくなり、検出されなくなる可能性があるため、BのデータがAのデータとすべての点で同一であることを確認することが極めて重要です。

4

個人的には、マスターとスレーブの間で異なる binlog_format 設定に慣れていません(1.5年前の私の古い投稿を参照してください MySQL v5.1.73-binlog_formatがマスターとスレーブの間に異なることはありますか?

あなたの特定のケースでは、私はスレーブSTATEMENTまたはマスターROWを作成します。おそらく、スレーブでMIXEDを使用することで回避できます。スレーブがROWまたはMIXEDの場合は、より大きなログに備えてください。

私の以前の投稿 で、実験する必要があると述べました。

これが私がうまくいくと信じているものです

  • MIXEDスレーブはROWマスターまたはSTATEMENTマスターから複製できます
  • ROWスレーブはROWマスターまたはMIXEDマスターから複製できます
  • STATEMENTスレーブはSTATEMENTマスターからのみ複製できます

ステージングサーバーでこれをテストして確認する必要があります。

2
RolandoMySQLDBA

短い答え-はい、できます。レプリケーションA-> B-> Cは正しく機能します。 ROWSTATEMENTの長所と短所がそれぞれ適用されます。

STATEMENTを使用しても正当化できません。

1
akuzminsky