MySQL はステートメントベースロギング (SBL)、行ベースロギング (RBL)、または混合形式ロギングを使用します。使用されるバイナリログの種類は、ロギングのサイズと効率に影響します。このため、行ベースレプリケーション (RBR) またはステートメントベースレプリケーション (SBR) の選択は、アプリケーションと環境に依存します。 このセクションでは、行ベース形式ログを使用するときの既知の問題について説明し、これをレプリケーションで使用する際のベストプラクティスをいくつか紹介します。
詳細については、セクション17.1.2「レプリケーション形式」およびセクション17.1.2.1「ステートメントベースおよび行ベースレプリケーションのメリットとデメリット」を参照してください。
MySQL Cluster レプリケーションに固有の問題について詳しくは (行ベースレプリケーションに依存します)、セクション18.6.3「MySQL Cluster レプリケーションの既知の問題」を参照してください。
-
一時テーブルの行ベースロギング セクション17.4.1.22「レプリケーションと一時テーブル」で説明したように、行ベース形式を使用する場合、一時テーブルは複製されません。混合形式ロギングを使用する場合、一時テーブルを使用する「安全な」ステートメントは、ステートメントベース形式を使用してログが記録されます。詳細については、セクション17.1.2.1「ステートメントベースおよび行ベースレプリケーションのメリットとデメリット」を参照してください。
行ベース形式を使用する場合、一時テーブルは複製されません (必要がないため)。また、一時テーブルはそれらを作成したスレッドからのみ読み取れるため、ステートメントベース形式を使用する場合でも、それらを複製することから得られるメリットはまずありません。
MySQL 5.6 では、一時テーブルが作成された場合でも、ステートメントベースから行ベースにバイナリロギングモードを切り替えることができます。ただし、行ベース形式の使用中は、MySQL サーバーは所定の一時テーブルが作成されたときに有効であったロギングモードを特定できません。このため、このようなケースのサーバーは、所定のクライアントセッションが終了するときに、そこにまだ存在する各一時テーブルの
DROP TEMPORARY TABLE IF EXISTS
ステートメントのログを記録します。これは、一部のケースで不必要なDROP TEMPORARY TABLE
ステートメントのログが記録される可能性があることを意味しますが、このステートメントは無害であり、テーブルが存在しない場合でもIF NOT EXISTS
オプションがあることでエラーになりません。MySQL 5.6.6 以前では、行ベースロギングを使用するときに
--disable-gtid-unsafe-statements
オプションを使用すると、一時テーブルを使用する非トランザクション DML ステートメントがエラーで失敗していました (バイナリログに書き込まれないという事実にかかわらず)。MySQL 5.6.7 以降は、ステートメントが影響を与える非トランザクションテーブルが一時テーブルであるかぎり、binlog_format=ROW
を使用するときにこのようなステートメントが許可されます (Bug #14272672)。 非トランザクションテーブルの RBL と同期 多くの行が影響を受ける場合、変更のセットは複数のイベントに分割されます。ステートメントがコミットすると、これらのイベントのすべてがバイナリログに書き込まれます。スレーブで実行中は、使用されるすべてのテーブルにテーブルロックが適用され、行はバッチモードで適用されます。(これは、スレーブによるテーブルコピーに使用されるエンジンに応じて効果的であったりなかったりします。)
待機時間およびバイナリログサイズ RBL は各行の変更をバイナリログに書き込むため、そのサイズは急激に増える場合があります。このため、マスターでの変更に対応する変更をクライアントで行うために必要な時間が大きく増える可能性があります。アプリケーションでこのような遅延が発生する可能性を意識してください。
バイナリログの読み取り mysqlbinlog は、
BINLOG
ステートメントを使用してバイナリログ内の行ベースイベントを表示します(セクション13.7.6.1「BINLOG 構文」を参照してください)。このステートメントは base 64 でエンコードされた文字列 (その意味は明白ではありません) としてイベントを表示します。--base64-output=DECODE-ROWS
および--verbose
オプションを付けて呼び出されたときは、mysqlbinlog はバイナリログの内容を人間が読める形式にします。バイナリログイベントが行ベース形式で書き込まれ、それらを読み取ったりレプリケーションまたはデータベース障害からリカバリしたりしたい場合は、このコマンドでバイナリログの内容を読み取ることができます。詳細については、セクション4.6.8.2「mysqlbinlog 行イベントの表示」を参照してください。-
バイナリログ実行エラーと slave_exec_mode
slave_exec_mode
がIDEMPOTENT
の場合は、元の行が見つからないために RBL から変更を適用できないときでも、エラーをトリガーしたり、レプリケーションが失敗したりしません。これは、更新がスレーブに適用されない可能性があるため、マスターとスレーブが同期されなくなったことを意味します。slave_exec_mode
がIDEMPOTENT
のときの、RBR での待機時間問題と非トランザクションテーブルの使用によって、マスターとスレーブとの相違がさらに広がる可能性があります。slave_exec_mode
の詳細については、セクション5.1.4「サーバーシステム変数」を参照してください。注記slave_exec_mode=IDEMPOTENT
は一般的に、MySQL Cluster (IDEMPOTENT
がデフォルト値) で循環レプリケーションまたはマルチマスターレプリケーションの場合にのみ役立ちます。ほかのシナリオの場合、
slave_exec_mode
をSTRICT
に設定することで通常は十分で、これがデフォルト値です。注記以前は MySQL Cluster を使用するときのデフォルト値は
slave_exec_mode=IDEMPOTENT
でしたが、MySQL Cluster NDB 7.3 以降ではこれは本当ではありません。 バイナリログチェックサムがない RBL はチェックサムを使用しないため、バイナリログを処理するときにネットワーク、ディスク、およびその他のエラーが特定されない場合があります。ネットワーク破損なしでデータを確実に転送するには、レプリケーション接続に SSL を使用します。
CHANGE MASTER TO
ステートメントには、SSL を使用するレプリケーションを有効にするオプションがあります。SSL を使用する MySQL のセットアップに関する一般的な情報については、セクション13.4.2.1「CHANGE MASTER TO 構文」を参照してください。サーバー ID に基づくフィルタリングはサポートされない MySQL 5.6 では、
CHANGE MASTER TO
ステートメントでIGNORE_SERVER_IDS
オプションを使用することで、サーバー ID に基づいてフィルタできます。このオプションは、ステートメントベースおよび行ベースロギング形式で使用できます。一部のスレーブで変更を除外するための別の方法は、UPDATE
およびDELETE
ステートメントで、関係@@server_id <>
句を含むid_value
WHERE
句を使用することです。たとえば、WHERE @@server_id <> 1
。ただし、これは行ベースロギングでは正しく動作しません。ステートメントフィルタリングにserver_id
システム変数を使用するには、ステートメントベースロギングを使用します。データベースレベルレプリケーションオプション
--replicate-do-db
、--replicate-ignore-db
、および--replicate-rewrite-db
オプションの効果は、行ベースまたはステートメントベースのどちらのロギングが使用されるかに応じてかなり異なります。このため、データベースレベルオプションは避け、代わりに--replicate-do-table
や--replicate-ignore-table
などのテーブルレベルオプションを使用することをお勧めします。これらのオプションと、レプリケーション形式がそれらの動作にどのように影響するかについて詳しくは、セクション17.1.4「レプリケーションおよびバイナリロギングのオプションと変数」を参照してください。RBL、非トランザクションテーブル、および停止したスレーブ 行ベースロギングを使用するときに、スレーブサーバーが停止していて、スレーブスレッドが非トランザクションテーブルを更新している場合、スレーブデータベースが矛盾状態に到達する可能性があります。このため、行ベース形式を使用して複製されたすべてのテーブルに、
InnoDB
などのトランザクションストレージエンジンを使用することをお勧めします。スレーブ MySQL サーバーをシャットダウンする前にSTOP SLAVE
またはSTOP SLAVE SQL_THREAD
を使用することは、問題発生の回避に役立ち、使用するロギング形式やストレージエンジンにかかわらず常に推奨されます。