この記事では、マージレプリケーションの行レベルと列レベルの追跡オプションと、マージレプリケーション中の競合の検出にこれらがどのように使用されるかを確認しましょう。
マージレプリケーション: マージレプリケーションは、パブリッシャーからサブスクライバーへ、およびサブスクライバーからパブリッシャーへの両方の方法でデータをレプリケートするために使用されます。
オブジェクトの初期スナップショットが取得され、サブスクライバーに適用されます。増分データの変更とスキーマの変更は、トリガーを使用して追跡され、サブスクライバーがパブリッシャーと同期するときにサブスクライバーに適用されます。
競合:
マージレプリケーションでは、サブスクライバーとパブリッシャーの両方が独立しており、データは任意のノードで変更できます。
レプリケーションサイクル内でパブリッシャーとサブスクライバーの両方でデータが変更された場合、およびサブスクライバーがパブリッシャーと同期した場合、競合が発生します。マージエージェントは、競合解決機能に応じて、両側の勝者を決定します。デフォルトでは、勝者はクライアントまたはサーバーのサブスクリプション、プルまたはプッシュのサブスクリプションなどのさまざまなパラメーターによって決定されます。
競合の検出:
競合の検出は、記事に対して構成する追跡のタイプによって異なります。
- 行レベルの追跡: 両端の同じ行のいずれかの列にデータ変更が加えられた場合、それは競合と見なされます。
- 列レベルの追跡: 両端の同じ列でデータの変更が行われた場合、この変更は競合と見なされます。
解決者:
リゾルバーは、競合が発生したときに両端に勝者データを適用します。
デフォルトでは、パブリッシャーとサブスクライバーの間に競合がある場合、パブリッシャーが常に勝ちます。
2つのサブスクライバー間で競合が発生した場合、勝者はクライアント/サーバーサブスクライバーとプル/プッシュサブスクリプションによって決定されます。
デフォルトのリゾルバーに加えて、カスタムリゾルバーもほとんどありません。カスタムリゾルバについては、今後の記事で説明します。
行レベルの追跡を使用してマージレプリケーションを構成します:
出版社データベース:pub_db
サブスクライバーデータベース:sub_db
「TBL_EMP」テーブルを作成し、それを追加してレプリケーションをマージしましょう。
CREATE TABLE TBL_EMP (EmpID INT, Emp_FName varchar(100),Emp_Lname varchar(100)) INSERT INTO TBL_EMP VALUES (1,'Jhon','P') INSERT INTO TBL_EMP VALUES (2,'Alison','P') INSERT INTO TBL_EMP VALUES (3,'Angela','P')
マージレプリケーションを構成するには、ローカル配布またはリモート配布を使用するようにパブリッシャーを構成する必要があります。
ディストリビューションを構成したら、SSMSのレプリケーションフォルダーに移動し、ローカルパブリケーションを右クリックします。
次へをクリックします パブリケーションデータベースを選択し、[次へ]をクリックします マージレプリケーションを選択し、2008以降を選択して、テーブルをレプリケーションに追加します。
次に、記事のプロパティをクリックして、強調表示された記事のプロパティを選択します。
行レベルの追跡となる追跡レベルを選択します。
デフォルトでは、行レベルの追跡になります。 [OK]、[次へ]、[次へ]をクリックします 。特定のデータをサブスクライバーに送信する場合はフィルターを追加します。それ以外の場合は無視し、作成を有効にします。 スナップショットすぐに 、必要に応じてエージェントのセキュリティを構成し、パブリケーションの作成を有効にします 、パブリケーションの名前を指定して、[完了]をクリックします 。
最初のスナップショットが生成されたら、サブスクライバーを追加します。
パブリッシャーのレプリケーションフォルダーに作成したパブリケーションに移動し、右クリックして[新しいサブスクリプション]を選択します。
次へをクリックします 、パブリケーションを選択し、[次へ]をクリックして、必要に応じてプルサブスクリプションまたはプッシュサブスクリプションを選択します。この場合、プッシュサブスクリプションを使用しました。
サブスクリプションデータベースを選択し、次へをクリックします 、マージエージェントのログイン資格情報を設定し、[次へ]をクリックします 。
必要に応じてエージェントのスケジュールを選択してください。この場合、オンデマンドでのみ実行を使用しました 。 次へをクリックします 、すぐに初期化を選択します サブスクリプションタイプとしてクライアントを選択し、[次へ]をクリックします 、サブスクリプションの作成を有効にします 、[次へ]をクリックします および終了 。
最初のスナップショットが適用されたら、パブリッシャーで以下のステートメントを実行してレコードを更新します。
update TBL_EMP set Emp_Fname = 'Amanda' where empid = 1
次に、サブスクライバーデータベースで、以下のステートメントを実行して、名前を更新します。
update TBL_EMP set Emp_Lname = 'A' where empid = 1
これで、同じレプリケーションサイクル内で、パブリッシャーデータベースとサブスクライバーデータベースの両方で同じ行が変更されました。
設定した追跡オプション、つまり行レベルの追跡に従って、変更は競合と見なされ、マージエージェントの実行時に競合テーブルに記録されます。
作成したパブリケーションに移動し、パブリケーションを展開してサブスクリプションを表示します。サブスクリプションを右クリックし、[同期ステータスの表示]を選択して、[開始]をクリックします。
マージエージェントが正常に実行されたら、サブスクライバーに移動し、以下のステートメントを使用してデータを確認します。
use sub_db select * from TBL_EMP where empid = 1
パブリッシャーからの変更が勝ち、サブスクライバーからの変更が失われたことがわかります。
競合情報は競合テーブルに保存され、競合ビューアで表示できます。
パブリッシャーに移動し、右クリックして[競合の表示]を選択します。
競合テーブルを選択し、[OK]をクリックして詳細を表示します。
追跡レベルの変更
次に、追跡レベルを列レベルの追跡に変更しましょう。パブリケーションに移動し、右クリックして[パブリッシャーのプロパティ]を選択します。 [記事]をクリックし、テーブルを選択し、[記事のプロパティ]をクリックし、強調表示されたテーブル記事のプロパティを設定し、[列レベルの追跡]を選択し、[OK]をクリックし、[OK]をクリックして、[再初期化のためにマーク]をクリックします。
これにより、既存の追跡レベルを新しい追跡レベルに変更するため、すべてのサブスクライバーに再初期化のマークが付けられます。
パブリケーションに移動し、パブリケーションを右クリックして、スナップショットエージェントのステータスを表示をクリックします。 、[開始]をクリックします 新しいスナップショットを生成します。スナップショットを生成する方法は他にもあります。
次に、パブリッシャーに対して以下のステートメントを実行して、レコードを更新します。
update TBL_EMP set Emp_Fname = 'Amanda' where empid = 2
次に、サブスクライバーデータベースに対して以下のステートメントを実行して、名前を更新します。
update TBL_EMP set Emp_Lname = 'A' where empid = 2
マージエージェントを手動で実行します。 2つの異なる列を更新し、追跡レベルを列レベルに設定したにもかかわらず、レコードに競合が表示されます。
競合ビューアで詳細を確認できます。既存の追跡レベルの変更は機能しませんでした。そこで、パブリケーションを再構成し、最初のスナップショットを生成する前に、追跡レベルを列レベルの追跡に設定しました。スナップショットが作成され、サブスクライバーがパブリケーションに追加されました。
最初のスナップショットがサブスクライバーに適用されたら、パブリッシャーデータベースで次のステートメントを実行します。
update TBL_EMP set Emp_Fname = 'Amanda' where empid = 3
サブスクライバデータベースで次のステートメントを実行します。
update TBL_EMP set Emp_Lname = 'A' where empid = 3
マージエージェントを手動で実行します。次に、サブスクライバデータベースで、TBL_EMPテーブルをクエリします。
パブリッシャーとサブスクライバーからの更新は、両方が異なる列にあり、追跡レベルが列レベルの追跡に設定されているため、競合とは見なされません。競合テーブルに競合は記録されず、異なる列のパブリッシャーとサブスクライバーの両方の更新が失われることはありません。
出版社と購読者の同じ列を更新しましょう。
パブリッシャーデータベースに対して次のステートメントを実行します。
use pub_db update TBL_EMP set Emp_Lname = 'B' where empid = 1
サブスクライバデータベースに対して次のステートメントを実行します。
use sub_db update TBL_EMP set Emp_Lname = 'C' where empid = 1
マージエージェントを実行し、サブスクライバーでTBL_EMPテーブルを照会します。サブスクライバーの更新は失われ、競合がログに記録されます。
パフォーマンス:
大幅な更新がある場合、行レベルの追跡と比較して、列レベルの追跡ではパフォーマンスのオーバーヘッドが発生する可能性があります。しかし、私の場合、テーブルの構造が単純である(つまり、列が非常に少ない)可能性があり、サブスクライバーとパブリッシャーは同じSQLサーバーインスタンス上にあります。
注:
- デフォルトでは、マージレプリケーションが構成されている場合は常に行レベルの追跡になります。
- 追跡レベルオプションはテーブルによって異なります。したがって、あるテーブルに行レベルを、別のテーブルに列レベルを設定できます。
- これらのオプションは、更新に基づいて競合が検出された場合にのみ役立ち、解決はしません。
- 既存の追跡レベルを変更しても機能しない場合は、パブリケーションを再構成します。
- ビジネスニーズに応じて追跡レベルを設定します。