マージ レプリケーションで変更を追跡および列挙する方法

パブリケーションまたはサブスクリプションの初期化後、マージ レプリケーションによって、パブリッシュされたテーブル内のデータに対するすべての変更が追跡および列挙されます。変更は、トリガ (パブリッシュされた各テーブルに対してレプリケーションが作成) と、パブリケーション データベースおよびサブスクリプション データベースのシステム テーブルにより追跡されます。レプリケーション システム テーブルには、変更を反映するかどうかを示すメタデータが格納されます。同期中にマージ エージェントを実行すると、変更がエージェントにより列挙され、必要に応じてパブリッシャおよびサブスクライバに適用されます。

変更の追跡

マージ レプリケーションでは、以下のトリガおよびシステム テーブルを使用して、パブリッシュされたすべてのテーブルの変更を追跡します。

  • MSmerge_ins_<GUID> : 挿入トリガ (GUID の値は sysmergearticles から派生。以下同様)

  • MSmerge_upd_<GUID> : 更新トリガ

  • MSmerge_del_<GUID> : 削除トリガ

  • MSmerge_contents

  • MSmerge_tombstone

  • MSmerge_genhistory

フィルタ選択されたテーブルの変更を追跡する場合は、さらに以下のシステム テーブルも使用します。

  • MSmerge_partition_groups

  • MSmerge_current_partition_mappings

  • MSmerge_past_partition_mappings

注意

上記のシステム テーブルは、データベースのすべてのマージ パブリケーションおよびサブスクリプションで使用されます。たとえば、パブリケーション データベースに複数のパブリケーションがある場合、MSmerge_contents には、すべてのパブリケーションのアーティクルの行が格納されます。

フィルタ選択されていないテーブルの変更の追跡

システム テーブル

フィルタ選択されていないテーブルとフィルタ選択されたテーブルの両方で使用されるシステム テーブルには、以下のメタデータが格納されます。

  • MSmerge_contents には、データベース内のパブリッシュされたテーブルで挿入または更新された行ごとに 1 行のデータが格納されます。

  • MSmerge_tombstone には、データベース内のパブリッシュされたテーブルから削除された行ごとに 1 行のデータが格納されます。

  • MSmerge_genhistory には、生成結果ごとに 1 行のデータが格納されます。生成結果とは、パブリッシャまたはサブスクライバに配信される変更の集まりです。生成結果はマージ エージェントが実行されるたびに閉じられます。データベースでのその後の変更は、1 つ以上の開いている生成結果に追加されます。

変更の追跡プロセス

以下の変更の追跡プロセスが、すべてのフィルタ選択されていないテーブルに対して使用されます。

  • パブリッシュされたテーブルで挿入または更新が発生すると、MSmerge_ins_<GUID> トリガまたは MSmerge_upd_<GUID> トリガが起動され、MSmerge_contents システム テーブルに行が挿入されます。MSmerge_contentsrowguid 列に、挿入または更新された行の GUID が格納され、この GUID を基に、次に同期が発生したときに、ユーザー テーブルで挿入または変更された行に対応する行がパブリッシャまたはサブスクライバに送信されます。その後ユーザー テーブルの行で更新が発生すると、MSmerge_contents の行が更新されて内容が反映されます。

  • パブリッシュされたテーブルで削除が発生すると、MSmerge_del_<GUID> トリガが起動され、MSmerge_tombstone システム テーブルに行が挿入されます。MSmerge_tombstonerowguid 列に、削除された行の GUID が格納され、この GUID を基に、次に同期が発生したときに、ユーザー テーブルで削除された行に対応する行の削除がパブリッシャまたはサブスクライバに送信されます。削除された行が (前回の同期以降に挿入または更新されたために) MSmerge_contents で参照されている場合、MSmerge_contents からその行が削除されます。

フィルタ選択されたテーブルの変更の追跡

システム テーブル

前のセクションで説明したシステム テーブルに加え、パブリケーション データベースの 3 つのテーブルに、フィルタ選択されたテーブルの変更を追跡するためのメタデータが格納されます。

  • MSmerge_partition_groups には、パブリケーションで定義されたパーティションごとに 1 行のデータが格納されます。パーティションは次のいずれかで定義または作成されます。

    • sp_addmergepartition または [パブリケーションのプロパティ] ダイアログ ボックスの [データ パーティション] ページを使用して明示的に定義

    • まだ MSmerge_partition_groups にエントリのないパーティションがサブスクライバに必要な場合、サブスクライバの同期時に自動的に作成

  • MSmerge_current_partition_mappings には、MSmerge_contents の行と MSmerge_partition_groups の行の一意の組み合わせごとに 1 行のデータが格納されます。たとえば、あるユーザー テーブルの行が 2 つのパーティションに属していて、その行が更新された場合、その更新を反映する 1 行が MSmerge_contents に挿入され、2 行が MSmerge_current_partition_mappings に挿入されます。これは、更新された行が 2 つのパーティションに属していることを示します。

  • MSmerge_past_partition_mappings には、特定のパーティションに属さなくなった行ごとに 1 行のデータが格納されます。行は、以下の場合にパーティションから移動されます。

    • 行が削除された場合。行がユーザー テーブルから削除された場合、MSmerge_tombstone に 1 行が挿入され、MSmerge_past_partition_mappings に 1 つ以上の行が挿入されます。

    • フィルタ選択に使用する列の値が変更された場合。たとえば、パラメータ化されたフィルタが企業の本社のある州に基づいていて、本社が移転した場合、その企業の行 (および他のテーブルの関連する行) は、1 人の販売員のデータ パーティションから別の販売員のパーティションに移動します。既にパーティションに属していないなど、行が更新されている場合は、MSmerge_contents に 1 行が挿入または更新され、1 つ以上の行が MSmerge_past_partition_mappings に挿入されます。

注意

パーティションあたり 1 つのサブスクリプションがある重複しないパーティション (sp_addmergearticle@partition_options パラメータの値が 3) を使用した場合、各行は 1 つのパーティションにのみ属し、1 つのサブスクライバでのみ変更されるため、システム テーブル MSmerge_current_partition_mappingsMSmerge_past_partition_mappings は行のパーティション マッピングの追跡には使用されません。

変更の追跡プロセス

フィルタ選択されていないテーブルに対する上記の手順 (「フィルタ選択されていないテーブルの変更の追跡」) は、フィルタ選択されたテーブルの場合にも使用され、さらに以下が追加されます。

  • パブリッシュされたテーブルで挿入が発生すると、データの更新または MSmerge_contents への挿入に加え、行が属するパーティションごとに、パーティション マッピングが MSmerge_current_partition_mappings に追加されます。

  • パブリッシュされたテーブルで更新が発生すると、データの更新または MSmerge_contents への挿入に加え、パーティション マッピングが存在しない場合は、行が属するパーティションごとに MSmerge_current_partition_mappings に追加されます。更新により、あるパーティションから別のパーティションに行が移動した場合、MSmerge_current_partition_mappings で行が更新され、MSmerge_past_partition_mappings に行が追加されます。

  • パブリッシュされたテーブルで削除が発生すると、MSmerge_tombstone への行の挿入に加え、MSmerge_current_partition_mappings で行が削除され、MSmerge_past_partition_mappings に行が追加されます。

変更の列挙

システム テーブルおよびプロシージャ

マージ エージェントを実行すると、以下のさまざまなシステム テーブルおよびストアド プロシージャを使用して変更が列挙されます。

  • MSmerge_genhistory には、生成結果ごとに 1 行のデータが格納されます。生成結果とは、パブリッシャまたはサブスクライバに配信される変更の集まりです。生成結果はマージ エージェントが実行されるたびに閉じられます。データベースでのその後の変更は、1 つ以上の開いている生成結果に追加されます。

  • sysmergesubscriptions には、ノードで前回送受信した生成結果のレコードなど、サブスクリプションについての情報が格納されます。パブリケーション データベースの場合、このテーブルには、そのパブリッシャに対する 1 行のデータと、サブスクライバごとに 1 行のデータが格納されます。サブスクリプション データベースの場合は、通常、そのサブスクライバに対する 1 行のデータと、パブリッシャごとに 1 行のデータが格納されます。

  • MSmerge_generation_partition_mappings は、特定のパーティションに関連する変更が特定の生成結果に含まれているかどうかを記録するテーブルで、フィルタ選択されたテーブルに対してのみ使用されます。パブリケーション データベースのこのテーブルには、MSmerge_genhistory の行と MSmerge_partition_groups の行の一意の組み合わせごとに 1 行のデータが格納されます。

  • sp_MSmakegeneration は、列挙処理の最初に、すべての開いている生成結果を閉じます。

  • sp_MSenumchanges は、テーブルに対する変更を列挙します (この処理では、名前が sp_MSenumchanges で始まるさまざまな関連プロシージャも使用されます)。

  • sp_MSgetmetadata は、1 つのノードからの変更を別のノードに、挿入、更新、または削除として適用するかどうかを決定します。

変更の列挙プロセス

変更の列挙プロセスは以下のとおりです。

  1. システム プロシージャ sp_MSmakegeneration が呼び出されます。

    • フィルタ選択されていないテーブルとフィルタ選択されたテーブルの両方で、MSmerge_genhistory で参照されているすべての開いている生成結果を閉じます (閉じた生成結果は、列 genstatus の値が 1 または 2 になります)。

    • フィルタ選択されたテーブルには、システム テーブル MSmerge_generation_partition_mappings が設定されます。パーティションに関連する 1 つ以上の変更が生成結果に含まれている場合、システム テーブルに行が挿入されます。特定のパーティションに関連する変更が生成結果に含まれていない場合は、MSmerge_generation_partition_mappings に行は挿入されず、そのパーティションを受信したサブスクライバには変更が列挙されません。

  2. ストアド プロシージャ sp_MSenumchanges とそれに関連するプロシージャが呼び出されます。これらのプロシージャによって、前回の同期以降に発生した変更が以下のようにして列挙されます。

    1. まず、テーブル sysmergesubscriptions の列 sentgen (前回送信された生成結果) および列 recgen (前回受信された生成結果) を基に、列挙を開始する生成結果が判断されます。

      たとえば、特定のサブスクライバについてどの生成結果の変更を列挙する必要があるかを判断する場合は、サブスクライバの sentgen (パブリケーション データベースに格納) と recgen (サブスクリプション データベースに格納) が比較されます。値が同じ (パブリッシャから送信された前回の生成結果がサブスクライバで正常に受信されたことを示す) 場合、MSmerge_genhistory の次の生成結果から変更が列挙されます。値が異なる場合は、2 つの値のうち小さい方の値を使用して、要求されたすべての変更が送信されます。

    2. 以下のように変更が列挙されます。

      フィルタ選択されていないテーブルの場合、sentgen または recgen の生成結果以降の生成結果に含まれるすべての変更が列挙されます。MSmerge_genhistoryMSmerge_contents および MSmerge_tombstone に結合され、どの変更を送信する必要があるかが判断されます。

      フィルタ選択されたテーブルの場合、MSmerge_generation_partition_mappings が、MSmerge_current_partition_mappingsMSmerge_contents、および MSmerge_past_partition_mappingsMSmerge_tombstone に結合され、サブスクライバが受信するパーティションに関連した変更が判断されます。

  3. ストアド プロシージャ sp_MSgetmetadata が呼び出され、変更を挿入、更新、または削除として適用するかどうかが判断されます。この時点で競合の検出および解決が行われます。詳細については、「マージ レプリケーションで競合を検出および解決する方法」を参照してください。