MySQL 8.0 リファレンスマニュアル


MySQL 8.0 リファレンスマニュアル  /  ...  /  ステートメントベースおよび行ベースレプリケーションのメリットとデメリット

17.2.1.1 ステートメントベースおよび行ベースレプリケーションのメリットとデメリット

それぞれのバイナリロギングの形式にメリットとデメリットがあります。 ほとんどのユーザーにとって、データの完全性とパフォーマンスの最善の組み合わせが得られるのは、混合レプリケーション形式であるはずです。 ただし、特定のタスクを実行するときにステートメントベースまたは行ベースレプリケーション形式固有の機能を利用する場合、関連するメリットとデメリットのサマリーを記述したこのセクションの情報を使用して、どちらがニーズに最適であるかを決めることができます。

ステートメントベースレプリケーションのメリット
  • 実績のあるテクノロジー。

  • ログファイルに書き込まれるデータが少ないです。 更新または削除が多くの行に影響を与える場合、これによってログファイルに必要なストレージ容量がかなり少なくなります。 つまり、バックアップの取得とリストアをより短時間で達成できます。

  • ログファイルには変更があったすべてのステートメントが含まれるため、データベースの監査に使用できます。

ステートメントベースレプリケーションのデメリット
  • SBR にとって安全でないステートメント.  データを変更するすべてのステートメント (INSERT DELETEUPDATEREPLACE ステートメントなど) を、ステートメントベースレプリケーションを使用して複製できるわけではありません。 ステートメントベースレプリケーションを使用する場合、非決定的動作は複製が困難です。 このようなデータ変更言語 (DML) ステートメントの例を次に示します:

    • 非決定的な UDF またはストアドプログラムに依存するステートメント。そのような UDF またはストアドプログラムによって返される値は、それに提供されるパラメータ以外の要因に依存するため。 (ただし、行ベースのレプリケーションでは、UDF またはストアドプログラムによって返される値が単にレプリケートされるため、テーブルの行およびデータに対する影響はソースとレプリカの両方で同じです。) 詳細は、セクション17.5.1.16「呼び出される機能のレプリケーション」を参照してください。

    • ORDER BY なしで LIMIT 句を使用する DELETE および UPDATE ステートメントは非決定的です。 セクション17.5.1.18「レプリケーションと LIMIT」を参照してください。

    • NOWAIT または SKIP LOCKED オプションを使用する読取りステートメント (SELECT ... FOR UPDATE および SELECT ... FOR SHARE) のロック。 NOWAIT および SKIP LOCKED による読取り同時実行性のロックを参照してください。

    • 決定論的 UDF をレプリカに適用する必要があります。

    • 次のいずれかの関数を使用するステートメントは、ステートメントベースレプリケーションでは適切に複製できません。

      • LOAD_FILE()

      • UUID()UUID_SHORT()

      • USER()

      • FOUND_ROWS()

      • SYSDATE() (ソースとレプリカの両方が --sysdate-is-now オプションで起動されていない場合)

      • GET_LOCK()

      • IS_FREE_LOCK()

      • IS_USED_LOCK()

      • MASTER_POS_WAIT()

      • RAND()

      • RELEASE_LOCK()

      • SLEEP()

      • VERSION()

      ただし、NOW() などを含めてほかのすべての関数はステートメントベースレプリケーションで正しく複製されます。

      詳細については、セクション17.5.1.14「レプリケーションとシステム関数」を参照してください。

    ステートメントベースレプリケーションで正しく複製できないステートメントは、ここに示すもののような警告でログが記録されます。

    [Warning] Statement is not safe to log in statement format.

    このような場合、類似の警告がクライアントにも発行されます。 クライアントは SHOW WARNINGS を使用してそれを表示できます。

  • INSERT ... SELECT は、行ベースレプリケーションよりも多くの行レベルロックが必要です。

  • WHERE 句でインデックスが使用されていないためにテーブルスキャンを必要とする UPDATE ステートメントは、行ベースレプリケーションの場合より多くの行をロックする必要があります。

  • InnoDB の場合: AUTO_INCREMENT を使用する INSERT ステートメントは、競合しないほかの INSERT ステートメントをブロックします。

  • 複雑なステートメントの場合、行が更新または挿入される前に、ステートメントを評価してレプリカで実行する必要があります。 行ベースのレプリケーションでは、レプリカは影響を受ける行のみを変更する必要があり、完全なステートメントは実行しません。

  • 特に複雑なステートメントの実行時にレプリカの評価でエラーが発生した場合、ステートメントベースのレプリケーションによって、影響を受ける行のエラーのマージンが徐々に増加する可能性があります。 セクション17.5.1.29「レプリケーション中のレプリカエラー」を参照してください。

  • ストアドファンクションは、呼び出し元のステートメントと同じ NOW() 値で実行します。 ただし、これはストアドプロシージャーには当てはまりません。

  • 決定論的 UDF をレプリカに適用する必要があります。

  • テーブル定義は、ソースとレプリカで (ほぼ) 同一である必要があります。 詳細については、セクション17.5.1.9「ソースとレプリカで異なるテーブル定義を使用したレプリケーション」を参照してください。

  • MySQL 8.0.22 の時点では、(結合リストまたはサブクエリーを介して) MySQL 付与テーブルからデータを読み取るが、変更しない DML 操作は、MySQL 付与テーブルに対する非ロック読取りとして実行されるため、ステートメントベースのレプリケーションでは安全ではありません。 詳細は、テーブル同時実行性の付与を参照してください。

行ベースレプリケーションのメリット
  • すべての変更を複製できます。 これはもっとも安全な形式のレプリケーションです。

    注記

    GRANTREVOKE およびトリガー、ストアドルーチン (ストアドプロシージャーを含む) およびビューの操作など、mysql システムスキーマ内の情報を更新するステートメントはすべて、ステートメントベースレプリケーションを使用してレプリカにレプリケートされます。

    CREATE TABLE ... SELECT などのステートメントの場合、CREATE ステートメントはテーブル定義から生成されてステートメントベース形式を使用して複製される一方、行挿入は行ベース形式を使用して複製されます。

  • 次のタイプのステートメントでは、ソースで必要な行ロックが少なくなるため、同時実行性が高くなります:

    • INSERT ... SELECT

    • AUTO_INCREMENT 付きの INSERT ステートメント

    • キーを使用しないまたは検査された行のほとんどを変更しない WHERE 句付きの UPDATE または DELETE ステートメント。

  • INSERTUPDATE または DELETE ステートメントのレプリカで必要な行ロックが少なくなります。

行ベースレプリケーションのデメリット
  • RBR では、ログに書き込む必要があるデータが増える可能性があります。 ステートメントベースレプリケーションでは、DML ステートメント (UPDATEDELETE ステートメントなど) を複製するためにステートメントだけをバイナリログに書き込みます。 一方、行ベースレプリケーションでは変更されたすべての行をバイナリログに書き込みます。 ステートメントが多くの行を変更する場合、行ベースレプリケーションは非常に多くのデータをバイナリログに書き込む可能性があります。このことはロールバックされるステートメントにも当てはまります。 これは、バックアップの作成およびリストアにさらに時間がかかる可能性があることも意味します。 また、データを書き込むためにバイナリログがロックされる時間が長くなるため、並列性の問題が発生する場合があります。 binlog_row_image=minimal を使用すると、デメリットを大幅に削減できます。

  • 大きな BLOB 値を生成する決定的 UDF の場合は、ステートメントベースレプリケーションより行ベースレプリケーションの方が複製に時間がかかります。 これは、データを生成するステートメントではなく、BLOB カラム値がログに書き込まれるためです。

  • レプリカでは、ソースから受信して実行されたステートメントは表示されません。 ただし、オプション --base64-output=DECODE-ROWS および --verbose を付けて mysqlbinlog を使用すると、何のデータが変更されたかがわかります。

    または、binlog_rows_query_log_events 変数を使用します。これを有効にすると、-vv オプションが使用されたときに、Rows_query イベントとそのステートメントが mysqlbinlog 出力に追加されます。

  • MyISAM ストレージエンジンを使用するテーブルの場合、INSERT ステートメントをバイナリログに行ベースのイベントとして適用するときは、ステートメントとして適用するときよりも強力なロックが INSERT ステートメントのレプリカに必要です。 これは、MyISAM テーブルでの同時挿入が、行ベースレプリケーションを使用するときにサポートされないことを意味します。


関連キーワード:  ステートメント, ベース, ソース, テーブル, バイナリ, データ, ログ, ステートメントベースレプリケーション, 変更, デメリット