サブスクライバにデータが配信されない

データがサブスクライバに配信されない場合、大きく分けて以下の 2 つの理由が考えられます。

  • フィルタ選択、エージェントの問題、またはその他のレプリケーション エラーのため、データが適用されていない。
  • データが適用された後、サブスクライバで削除されている。

説明

データがサブスクライバに配信されない場合には、以下のようなさまざまな原因が考えられます。

  • テーブルがフィルタ選択されており、指定のサブスクライバに配信される変更が存在しない。
  • 1 つ以上のエージェントが実行されていない、またはエラーによる障害が発生している。
  • トランザクション サブスクリプションがスナップショットなしで初期化されており、パブリケーションの作成以降にパブリッシャでデータが変更されている。
  • トランザクション パブリケーションに対するストアド プロシージャ実行のレプリケーションを行うと、サブスクライバでは結果が異なる。
  • トランザクション アーティクルが使用する INSERT ストアド プロシージャの条件が満たされていない。
  • ユーザー、レプリケーション スクリプト、またはその他のアプリケーションによってデータが削除されている。
  • トリガによってデータが削除されている、またはトリガに ROLLBACK ステートメントが含まれている。

ユーザーの操作

サブスクライバにデータが配信されない原因について診断を行う前に、検証または tablediff ユーティリティを使用して、行が存在していないかどうかを確認することをお勧めします。

  • ディストリビューション エージェントまたはマージ エージェントを実行できる場合は、バイナリ チェックサム検証を実行して、データが不足しているかどうかを判別します。行数検証も使用できますが、この方法では、データの内容の違いは示されません。詳細については、「レプリケートされたデータの検証」を参照してください。
  • ディストリビューション エージェントまたはマージ エージェントを実行できない場合は、tablediff ユーティリティを実行して、データが存在しないかどうかを判別します。レプリケートされたテーブルでこのユーティリティを使用する方法の詳細については、「レプリケートされたテーブルを比較して相違があるかどうかを確認する方法 (レプリケーション プログラミング)」を参照してください。

データが存在しない原因への対処

次の操作は、「説明」で示した原因への対処方法です。

  • テーブルがフィルタ選択されており、指定のサブスクライバに配信される変更が存在しない。
    サブスクライバに行が存在しないのは、その行がパブリケーションのフィルタの条件を満たしていないためにレプリケートされなかったことが原因と考えられます。すべての種類のレプリケーションで静的フィルタがサポートされており、またマージ レプリケーションではパラメータ化されたフィルタと結合フィルタもサポートされています。詳細については、「パブリッシュされたデータのフィルタ選択」を参照してください。パブリケーションで 1 つ以上のアーティクルがフィルタ選択されている場合、以下のプロシージャを実行してフィルタ句の値を確認します。
    • スナップショット パブリケーションおよびトランザクション パブリケーションの静的フィルタでは、sp_helparticle (Transact-SQL) によって filter_clause 列が返されます。
    • マージ パブリケーションの静的フィルタまたはパラメータ化されたフィルタでは、sp_helpmergearticle (Transact-SQL) によって subset_filterclause 列が返されます。
    • マージ パブリケーションの結合フィルタでは、sp_helpmergefilter (Transact-SQL) によって join_filterclause 列が返されます。
      このフィルタ句を使用して、存在しない行がフィルタの条件を満たすかどうかを確認します。たとえば、パブリッシャのテーブルに対してフィルタ句を実行することで、返されたデータがサブスクライバのデータに一致するかどうかを判別できます。
  • 1 つ以上のエージェントが実行されていない、またはエラーによる障害が発生している。
  • トランザクション サブスクリプションがスナップショットなしで初期化されており、パブリケーションの作成後パブリッシャでデータが変更されている。
    • バックアップからのパブリケーションの初期化が有効になっている場合、パブリケーションが作成されるとすぐに、パブリッシュされたテーブルに対する変更が追跡され、パブリケーション データベースのログに記録されるようになります。サブスクリプションが初期化されると、ディストリビューション データベースで使用可能な場合に限り、保留中の変更がサブスクライバに配信されます。
    • [レプリケーションのサポートのみ] オプションを使用してサブスクリプションを初期化する場合、バックアップを使用して初期化する場合と異なり、サブスクリプションを追加した時点でデータとスキーマが正しく同期されていることを手動またはアプリケーションで確認する必要があります。たとえば、データとスキーマをサブスクライバにコピーしてからサブスクリプションを追加するまでの間にパブリッシャ上で処理が実行されると、この処理による変更がサブスクライバにレプリケートされない場合があります。
      詳細については、「スナップショットを使用しないトランザクション サブスクリプションの初期化」を参照してください。
  • トランザクション パブリケーションに対するストアド プロシージャ実行のレプリケーションを行うと、サブスクライバでは結果が異なる。
    ストアド プロシージャの実行をレプリケートする場合は、サブスクリプションを初期化したときに、プロシージャの定義がサブスクライバにレプリケートされます。プロシージャがパブリッシャで実行されると、レプリケーションは対応するプロシージャをサブスクライバで実行します。詳細については、「トランザクション レプリケーションにおけるパブリッシング ストアド プロシージャの実行」を参照してください。
    ストアド プロシージャによって、サブスクライバで異なる操作が実行された場合、またはパブリッシャとは異なるデータが処理された場合、データの未集約が発生する可能性があります。計算を実行してから、この計算に基づいたデータを挿入するプロシージャの場合について考えます。サブスクライバがフィルタ選択され、サブスクライバでの計算が別のデータに基づいている場合は、サブスクライバに挿入される結果が異なる可能性、または挿入が発生しない可能性があります。
  • トランザクション アーティクルが使用する INSERT ストアド プロシージャの条件が満たされていない。
    既定では、トランザクション レプリケーションは、一連のストアド プロシージャを使用して変更をサブスクライバに反映します。これらのプロシージャをカスタマイズして、アプリケーションで必要となるビジネス ロジックを含めることもできます。詳細については、「トランザクション アーティクルに変更を反映する方法の指定」を参照してください。INSERT ストアド プロシージャのロジックで条件が満たされない場合、挿入処理は実行されません。あるテーブル (テーブル A) の特定の値を別のテーブル (テーブル B) に挿入する前に確認するようにカスタマイズされたプロシージャについて考えてみます。エラーまたはデータのレプリケートが完了していないためにテーブル A の値が利用できない場合、テーブル B に挿入されるはずの行が存在しなくなります。
  • ユーザー、レプリケーション スクリプト、またはその他のアプリケーションによってデータが削除されている。
    • ユーザーがサブスクライバでデータを削除できるようにする場合は、マージ レプリケーション、更新可能なサブスクリプションを使用したトランザクション レプリケーション、またはピア ツー ピア トランザクション レプリケーションを使用します。データの削除はパブリッシャに反映されます。その結果、パブリッシャとサブスクライバのデータは最終的に集約されます。詳細については、「マージ レプリケーションの概要」および「トランザクション レプリケーションで使用するパブリケーションの種類」を参照してください。

    • ユーザーがサブスクライバでデータ削除を行えないようにする場合は、ROLLBACK という語を含み、NOT FOR REPLICATION オプション (レプリケーション エージェントが操作を実行するときにトリガが起動されないようにする) を使用する各テーブルに対して、トリガを作成します。以下に例を示します。

      USE AdventureWorks
      GO
      CREATE TRIGGER prevent_user_dml
      ON Person.Address
      FOR INSERT, UPDATE, DELETE
      NOT FOR REPLICATION
      AS
      ROLLBACK
      

      詳細については、「CREATE TRIGGER (Transact-SQL)」および「NOT FOR REPLICATION を使用した制約、ID、およびトリガの制御」を参照してください。

    • レプリケーションでは、スナップショット適用前、適用後および同期中にスクリプトを実行できます。sp_addpublicationsp_addmergepublication@pre_snapshot_script パラメータと @post_snapshot_script パラメータを使用すると、スナップショットの適用前と適用後にスクリプトが実行されるように指定できます。詳細については、「スナップショット適用前および適用後のスクリプトの実行」を参照してください。ストアド プロシージャ sp_addscriptexec を使用すると、同期処理中に、スクリプトを実行できます。詳細については、「同期中にスクリプトを実行する方法 (レプリケーション Transact-SQL プログラミング)」を参照してください。
      これらのスクリプトは、通常、サブスクライバでのログインの追加など、管理タスクに使用されます。スクリプトがサブスクライバで読み取り専用として扱われるデータの削除に使用される場合、管理者は、結果が未集約にならないことを確認する必要があります。

  • トリガによってデータが削除されている、またはトリガに ROLLBACK ステートメントが含まれている。
    サブスクライバでのトリガは、未集約やその他の問題点の原因とならないように適切に管理する必要があります。
    • トリガは、マージ レプリケーション、更新可能なサブスクリプションを使用したトランザクション レプリケーション、またはピア ツー ピア トランザクション レプリケーションを使用した場合にのみ、サブスクライバでデータが変更されるようにする必要があります。詳細については、「マージ レプリケーションの概要」および「トランザクション レプリケーションで使用するパブリケーションの種類」を参照してください。
    • 多くの場合、トリガは NOT FOR REPLICATION オプションを使用する必要があります。トリガに ROLLBACK ステートメントが含まれており、そのトリガが NOT FOR REPLICATION オプションを使用しない場合、サブスクライバにレプリケートされた行は、適用されない可能性があります。
    • トランザクション レプリケーションの場合、XACT_ABORT の設定、およびトリガ内での COMMIT および ROLLBACK ステートメントの使用に関するその他の注意事項があります。詳細については、「トランザクション レプリケーションに関する注意点」の「トリガ」を参照してください。

参照

概念

レプリケーションのトラブルシューティング

ヘルプおよび情報

SQL Server 2005 の参考資料の入手