DMセーフモード

セーフ モードは、DM が増分レプリケーションを実行するための特別な操作モードです。セーフ モードでは、DM 増分レプリケーションコンポーネントがbinlogイベントをレプリケートするときに、DM はダウンストリームで実行する前にINSERTUPDATEステートメントをすべて強制的に書き換えます。

セーフ モードでは、冪等性が保証された状態で、1 つのbinlogイベントをダウンストリームに繰り返し複製できます。したがって、増分レプリケーションは安全です。

データ レプリケーション タスクをチェックポイントから再開した後、DM は一部のbinlogイベントを繰り返しレプリケートする可能性があり、これにより次の問題が発生します。

  • インクリメンタル レプリケーション中、DML の実行操作とチェックポイントの書き込み操作は同時に行われません。チェックポイントの書き込みおよびダウンストリーム データベースへのデータの書き込み操作はアトミックではありません。したがって、 DM が異常終了した場合、チェックポイントは終了ポイントより前の復元ポイントのみを記録する可能性があります
  • DM がレプリケーション タスクを再開し、チェックポイントから増分レプリケーションを再開すると、チェックポイントと終了ポイントの間の一部のデータが異常終了する前にすでに処理されている可能性があります。これにより、一部の SQL ステートメントが繰り返し実行されます
  • INSERTステートメントが繰り返し実行されると、主キーまたは一意のインデックスで競合が発生し、レプリケーションの失敗につながる可能性があります。 UPDATEステートメントが繰り返し実行されると、フィルター条件で以前に更新されたレコードを見つけることができない可能性があります。

セーフ モードでは、DM は SQL ステートメントを書き換えて前述の問題を解決できます。

動作原理

セーフ モードでは、DM は SQL ステートメントを書き換えることによってbinlogイベントの冪等性を保証します。具体的には、次の SQL ステートメントが書き換えられます。

  • INSERTのステートメントはREPLACEのステートメントに書き換えられます。
  • UPDATEステートメントが分析されて、主キーの値または更新された行の一意のインデックスが取得されます。次に、次の 2 つの手順でUPDATEステートメントがDELETE + REPLACEステートメントに書き換えられます。DM は主キーまたは一意のインデックスを使用して古いレコードを削除し、 REPLACEステートメントを使用して新しいレコードを挿入します。

REPLACEデータを挿入するための MySQL 固有の構文です。 REPLACEを使用してデータを挿入し、新しいデータと既存のデータに主キーまたは一意制約の競合がある場合、MySQL は競合するレコードをすべて削除し、「強制挿入」と同等の挿入操作を実行します。詳細については、MySQL ドキュメントのREPLACE参照してください。

dummydb.dummytblテーブルに主キーidがあるとします。このテーブルに対して次の SQL ステートメントを繰り返し実行します。

INSERT INTO dummydb.dummytbl (id, int_value, str_value) VALUES (123, 999, 'abc'); UPDATE dummydb.dummytbl SET int_value = 888999 WHERE int_value = 999; -- Suppose there is no other record with int_value = 999 UPDATE dummydb.dummytbl SET id = 999 WHERE id = 888; -- Update the primary key

セーフ モードを有効にすると、前述の SQL ステートメントがダウンストリームで再度実行されると、次のように書き換えられます。

REPLACE INTO dummydb.dummytbl (id, int_value, str_value) VALUES (123, 999, 'abc'); DELETE FROM dummydb.dummytbl WHERE id = 123; REPLACE INTO dummydb.dummytbl (id, int_value, str_value) VALUES (123, 888999, 'abc'); DELETE FROM dummydb.dummytbl WHERE id = 888; REPLACE INTO dummydb.dummytbl (id, int_value, str_value) VALUES (999, 888888, 'abc888');

前述のステートメントでは、 UPDATE DELETE + INSERTではなくDELETE + REPLACEに書き換えられます。ここでINSERTが使用されている場合、 id = 999を含む重複レコードを挿入すると、データベースは主キーの競合を報告します。このため、代わりにREPLACEが使用されます。新しいレコードは既存のレコードを置き換えます。

SQL ステートメントを書き換えることにより、DM は重複した挿入または更新操作を実行するときに、新しい行データを使用して既存の行データを上書きします。これにより、挿入操作と更新操作が繰り返し実行されることが保証されます。

セーフモードを有効にする

セーフ モードは自動または手動で有効にできます。このセクションでは、詳細な手順について説明します。

自動的に有効にする

DM がチェックポイントから増分レプリケーション タスクを再開すると (DM ワーカーの再起動やネットワークの再接続など)、DM は一定期間 (デフォルトでは 60 秒) セーフ モードを自動的に有効にします。

セーフモードを有効にするかどうかはチェックポイントのsafemode_exit_pointに関係します。増分レプリケーション タスクが異常停止すると、DM はメモリ内のすべての DML ステートメントをダウンストリームにレプリケートしようとし、DML ステートメント内の最新のbinlog位置をsafemode_exit_pointとして記録し、最後のチェックポイントに保存されます。

詳細なロジックは次のとおりです。

  • チェックポイントにsafemode_exit_pointが含まれている場合、増分レプリケーション タスクは異常に一時停止されます。 DM がタスクを再開すると、再開されるチェックポイントのbinlog位置 (開始位置) はsafemode_exit_pointより前になります。これは、開始位置とsafemode_exit_pointの間のbinlogイベントがダウンストリームで処理された可能性があることを表します。そのため、再開プロセス中に、一部のbinlogイベントが繰り返し実行される可能性があります。したがって、セーフ モードを有効にすると、これらのbinlogの位置を安全にすることができます。binlog位置がsafemode_exit_pointを超えると、セーフ モードが手動で有効にされない限り、DM はセーフ モードを自動的に無効にします。

  • チェックポイントにsafemode_exit_point含まれていない場合は、次の 2 つのケースが考えられます。

    1. これは新しいタスクであるか、このタスクは予想どおり一時停止されています。
    2. このタスクは異常に一時停止されましたが、DM がsafemode_exit_pointを記録できなかったか、DM プロセスが異常終了しました。

    2 番目のケースでは、DM はチェックポイント後のどのbinlogイベントがダウンストリームで実行されるかを知りません。繰り返し実行されるbinlogイベントによって問題が発生しないようにするために、DM は最初の 2 つのチェックポイント間隔でセーフ モードを自動的に有効にします。 2 つのチェックポイント間のデフォルトの間隔は 30 秒です。つまり、通常の増分レプリケーション タスクが開始されると、最初の 60 秒 (2 * 30 秒) はセーフ モードが適用されます。

    通常、増分レプリケーション タスクの開始時にセーフ モード期間を調整するためにチェックポイント間隔を変更することはお勧めできません。ただし、変更が必要な場合は、同期設定のセーフモードを手動で有効にする (推奨) またはcheckpoint-flush-interval項目を変更できます。

手動で有効にする

シンサー構成のsafe-mode項目を設定して、レプリケーション プロセス全体でセーフ モードを有効にすることができます。 safe-modeは bool 型パラメータで、デフォルトはfalseです。 trueに設定すると、DM は増分レプリケーション プロセス全体に対してセーフ モードを有効にします。

以下は、セーフ モードが有効になっているタスク構成の例です。

syncers: # The running configurations of the sync processing unit. global: # Configuration name. # Other configuration items are not provided in this example. safe-mode: true # Enables safe mode for the whole incremental replication process. # Other configuration items are not provided in this example. # ----------- Instance configuration ----------- mysql-instances: - source-id: "mysql-replica-01" # Other configuration items are not provided in this example. syncer-config-name: "global" # Name of the syncers configuration.

セーフモードに関する注意事項

安全上の理由から、レプリケーション プロセス全体でセーフ モードを有効にする場合は、次の点に注意してください。

  • セーフ モードでの増分レプリケーションは、余分なオーバーヘッドを消費します。 DELETE + REPLACEの操作を頻繁に行うと、主キーまたは一意のインデックスが頻繁に変更されるため、 UPDATEステートメントのみを実行する場合よりもパフォーマンスのオーバーヘッドが大きくなります。
  • セーフ モードでは、同じ主キーを持つレコードの置換が強制されるため、ダウンストリームでデータが失われる可能性があります。シャードを上流から下流にマージして移行する場合、構成が正しくないと、主キーまたは一意キーの多数の競合が発生する可能性があります。この状況でセーフ モードが有効になっていると、ダウンストリームで例外が表示されずに大量のデータが失われる可能性があり、その結果、深刻なデータの不整合が発生します。
  • セーフ モードは、主キーまたは一意のインデックスに基づいて競合を検出します。ダウンストリーム テーブルに主キーまたは一意のインデックスがない場合、DM はREPLACEを使用してレコードを置換および挿入できません。この場合、セーフ モードが有効になっていて DM がINSERTREPLACE個のステートメントを書き換えたとしても、重複レコードは引き続きダウンストリームに挿入されます。

要約すると、アップストリーム データベースに重複した主キーを持つデータがあり、アプリケーションが重複レコードの損失とパフォーマンスのオーバーヘッドを許容する場合は、セーフ モードを有効にしてデータの重複を無視できます。

このページは役に立ちましたか?