次の方法で共有


トランザクション レプリケーションを構成するときのエラー 1205

この記事は、SQL Server でトランザクション レプリケーションを構成するときに発生する問題を解決するのに役立ちます。

元の製品バージョン: SQL Server
元の KB 番号: 2674882

現象

以下のシナリオについて考えてみます。

  • SQL Server でトランザクション レプリケーションを構成します。
  • トランザクション レプリケーション トポロジは、複数のパブリッシャーで構成されます。
  • パブリッシャーは、同じサブスクライバー データベースにデータをレプリケートします。
  • ディストリビューション エージェントは継続的に実行されるか、頻繁なスケジュールで実行されます。 たとえば、ディストリビューション エージェントは 1 分ごとに実行されます。

このシナリオでは、ディストリビューション エージェントがデッドロック シナリオに関与し、デッドロックの対象として選択される可能性があります。 この問題が発生すると、次のようなエラー メッセージが表示されることがあります。

エラー 1205
トランザクション (プロセス ID %d) が、%.*ls 個のリソースで他のプロセスとデッドロックして、このトランザクションがそのデッドロックの対象となりました。 トランザクションを再実行してください。

トレース フラグ 1222 を有効にしてデッドロック情報を SQL Server エラー ログにリダイレクトすると、次のいずれかのエラー メッセージが表示されます。

  • update MSreplication_subscriptions set transaction_timestamp = cast(@P1 as binary(15)) + cast(case datalength(transaction_timestamp) when 16 then isnull(substring(transaction_timestamp, 16, 1, 0) else 0 end as binary(1)), "time" = @P2 upper(publisher) = UPPER(@P3) and publisher_db = @P4 and publication = @P5 and subscription_type = 0

  • update MSreplication_subscriptions set transaction_timestamp = cast(@P1 as binary(15)) + cast(substring(transaction_timestamp, 16, 1) as binary(1)), "time" = @P2 where UPPER(publisher) = UPPER(@P3) and publisher_db = @P4 and publication = @P5 and subscription_type = 0 and (substring(transaction_timestamp, 16, 1) = 0 or datalength(transaction_timestamp) < 16)

原因

この問題は、システム テーブル MSreplication_subscriptions 数の行数の見積もりが正しくない場合に発生します。 行数の見積もりが正しくない場合は、SQL Server データベース エンジンが正しくない方法を使用してデータベースを更新する可能性があります。

Note

通常、正しい行数の見積もりは、データベース内のサブスクリプションの数と同じです。 サブスクリプション ストリーム機能を使用する場合、行数の見積もりは、サブスクリプションの数に、各サブスクリプションに構成されているストリームの数を乗算した値に等しくなります。

解決方法

この問題を解決するには、次のいずれかのメソッドを使用します。

  • 方法 1: DBCC UPDATEUSAGE コマンドを使用します。

    この問題を解決するには、正しくない行数の値を更新します。 そのためには、次のコマンドを実行します。

    DBCC UPDATEUSAGE (**subscriber_database_name** **,**'MSreplication_subscriptions') WITH COUNT_ROWS
    

    Note

    DBCC UPDATEUSAGE コマンドは、テーブル内の各パーティションの行、使用済みページ、予約ページ、リーフ ページ、およびデータ ページ数の正しい値を決定します。 これらの値が正しい場合、 DBCC UPDATEUSAGE コマンドはデータを返しません。 不正確な値が見つかり、修正された場合、 DBCC UPDATEUSAGE は更新された行と列を返します。

  • 方法 2: ALTER INDEX ステートメントを使用します。

    この問題を解決するには、 MSreplication_subscriptions テーブルに関連付けられているインデックスを再構築します。 これを行うには、次のステートメントを使用します。

    ALTER INDEX ALL ON [dbo].[MSreplication_subscriptions] REBUILD
    

詳細

Symptoms セクションで説明されている問題が発生した場合、MSreplication_subscriptions システム テーブルの行数の見積もりは、4,294,967,296 に設定できます。 行数の値を確認するには、次のいずれかの方法を使用します。

  • 方法 1: SQL Server Management Studio を使用します。

    SQL Server Management Studio を使用して、 MSreplication_subscriptions システム テーブルの行数の値を確認するには、次の手順に従います。

    1. SQL Server Management Studio を起動し、サブスクライバー サーバー インスタンスに接続します。
    2. Databasesを展開し、サブスクライバー データベースを展開します。
    3. Tables を展開し、 System Tables を展開します。
    4. dbo を右クリックします。MSreplication_subscriptionsし、Properties を選択します。
    5. Storageを選択し、Row count フィールドの行数の値を確認します。
  • 方法 2: クエリ ステートメントを使用します。

    MSreplication_subscriptions システム テーブルの行数の値を確認するには、次のクエリを実行します。

    SELECT rows, * FROM sys.partitions WHERE object_id = object_id('MSreplication_subscriptions')
    

関連情報