それぞれのバイナリロギングの形式にメリットとデメリットがあります。ほとんどのユーザーにとって、データの完全性とパフォーマンスの最善の組み合わせが得られるのは、混合レプリケーション形式であるはずです。ただし、特定のタスクを実行するときにステートメントベースまたは行ベースレプリケーション形式固有の機能を利用する場合、関連するメリットとデメリットのサマリーを記述したこのセクションの情報を使用して、どちらがニーズに最適であるかを決めることができます。
ステートメントベースレプリケーションのメリット
バージョン 3.23 以来、MySQL に存在する実証済みのテクノロジーです。
ログファイルに書き込まれるデータが少ないです。更新または削除が多くの行に影響を与える場合、これによってログファイルに必要なストレージ容量がかなり少なくなります。つまり、バックアップの取得とリストアをより短時間で達成できます。
ログファイルには変更があったすべてのステートメントが含まれるため、データベースの監査に使用できます。
ステートメントベースレプリケーションのデメリット
-
SBR にとって安全でないステートメント データを変更するすべてのステートメント (
INSERT
DELETE
、UPDATE
、REPLACE
ステートメントなど) を、ステートメントベースレプリケーションを使用して複製できるわけではありません。ステートメントベースレプリケーションを使用する場合、非決定的動作は複製が困難です。そのような DML (データ変更言語) ステートメントの例には次が含まれます。非決定的な UDF またはストアドプログラムに依存するステートメント。そのような UDF またはストアドプログラムによって返される値は、それに提供されるパラメータ以外の要因に依存するため。(ただし、行ベースレプリケーションは、UDF またはストアドプログラムによって返される値を単純に置き換えるため、テーブル行およびデータに対するその影響はマスターとスレーブの両方で同じです。)詳細は、セクション17.4.1.11「呼び出される機能のレプリケーション」を参照してください。
ORDER BY
なしでLIMIT
句を使用するDELETE
およびUPDATE
ステートメントは非決定的です。セクション17.4.1.16「レプリケーションと LIMIT」を参照してください。-
次のいずれかの関数を使用するステートメントは、ステートメントベースレプリケーションでは適切に複製できません。
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.4.1.15「レプリケーションとシステム関数」を参照してください。
ステートメントベースレプリケーションで正しく複製できないステートメントは、ここに示すもののような警告でログが記録されます。
[Warning] Statement is not safe to log in statement format.
このような場合、類似の警告がクライアントにも発行されます。クライアントは
SHOW WARNINGS
を使用してそれを表示できます。 INSERT ... SELECT
は、行ベースレプリケーションよりも多くの行レベルロックが必要です。WHERE
句でインデックスが使用されていないためにテーブルスキャンを必要とするUPDATE
ステートメントは、行ベースレプリケーションの場合より多くの行をロックする必要があります。InnoDB
の場合:AUTO_INCREMENT
を使用するINSERT
ステートメントは、競合しないほかのINSERT
ステートメントをブロックします。複雑なステートメントの場合、行が更新または挿入される前に、スレーブでステートメントを評価して実行する必要があります。行ベースレプリケーションの場合、スレーブはステートメント全体を実行するのではなく、影響を受ける行だけを変更する必要があります。
スレーブでの評価でエラーがあった場合、特に複雑なステートメントを実行するときに、ステートメントベースレプリケーションでは、影響を受ける行全体でエラーのマージンが時間とともに徐々に増える場合があります。セクション17.4.1.26「レプリケーション中のスレーブエラー」を参照してください。
ストアドファンクションは、呼び出し元のステートメントと同じ
NOW()
値で実行します。ただし、これはストアドプロシージャーには当てはまりません。決定的な UDF はスレーブで適用される必要があります。
テーブル定義は、マスターとスレーブで (ほぼ) 同じでなければいけません。詳細については、セクション17.4.1.9「テーブル定義が異なるマスターとスレーブでのレプリケーション」を参照してください。
行ベースレプリケーションのメリット
-
すべての変更を複製できます。これはもっとも安全な形式のレプリケーションです。
mysql
データベースは複製されません。代わりに、mysql
データベースはノード固有データベースとして見られます。行ベースレプリケーションは、このデータベース内のテーブルでサポートされません。代わりに、GRANT
、REVOKE
、およびトリガー、ストアドルーチン (ストアドプロシージャーを含む)、およびビューの操作など、通常この情報を更新するステートメントは、ステートメントベースレプリケーションでスレーブにすべて複製されます。CREATE TABLE ... SELECT
などのステートメントの場合、CREATE
ステートメントはテーブル定義から生成されてステートメントベース形式を使用して複製される一方、行挿入は行ベース形式を使用して複製されます。 このテクノロジーはほかのほとんどのデータベース管理システムと同じです。ほかのシステムについての知識は MySQL で通用します。
-
マスターで必要な行ロックは少ないため、次の種類のステートメントでは並列性が高くなります。
INSERT ... SELECT
AUTO_INCREMENT
付きのINSERT
ステートメントキーを使用しないまたは検査された行のほとんどを変更しない
WHERE
句付きのUPDATE
またはDELETE
ステートメント。
INSERT
、UPDATE
、またはDELETE
ステートメントの場合、スレーブで必要な行ロックが少ないです。
行ベースレプリケーションのデメリット
RBR では、ログに書き込む必要があるデータが増える可能性があります。ステートメントベースレプリケーションでは、DML ステートメント (
UPDATE
、DELETE
ステートメントなど) を複製するためにステートメントだけをバイナリログに書き込みます。一方、行ベースレプリケーションでは変更されたすべての行をバイナリログに書き込みます。ステートメントが多くの行を変更する場合、行ベースレプリケーションは非常に多くのデータをバイナリログに書き込む可能性があります。このことはロールバックされるステートメントにも当てはまります。すなわち、バックアップの取得とリストアにも、より多くの時間がかかる可能性があります。また、データを書き込むためにバイナリログがロックされる時間が長くなるため、並列性の問題が発生する場合があります。大きな
BLOB
値を生成する決定的 UDF の場合は、ステートメントベースレプリケーションより行ベースレプリケーションの方が複製に時間がかかります。これは、データを生成するステートメントではなく、BLOB
カラム値がログに書き込まれるためです。-
ログを検査してもどのステートメントが実行されたかを確認できず、マスターからどのステートメントが到着して実行されたかをスレーブで確認することもできません。
ただし、オプション
--base64-output=DECODE-ROWS
および--verbose
を付けて mysqlbinlog を使用すると、何のデータが変更されたかがわかります。 MyISAM
ストレージエンジンを使用するテーブルの場合、INSERT
ステートメントを行ベースイベントとしてバイナリログに適用するときの方が、ステートメントとして適用するときよりも、スレーブでより強いロックが必要です。これは、MyISAM
テーブルでの同時挿入が、行ベースレプリケーションを使用するときにサポートされないことを意味します。