FIX SQL Server 2005 でマージ レプリケーションのサブスクライバー上のデータを挿入しようとするときにエラー メッセージ:"Msg 548、レベル 16、状態 2、行 1 です。挿入に失敗しました"

Bug #: 50002854 (SQL 修正プログラム)
マイクロソフトでは、1 つのダウンロード可能なファイルとして Microsoft SQL Server 2005 の修正プログラムを配布します。修正プログラムは累積的であるため、新しいリリースごとにすべての修正プログラムが含まれていて、以前の SQL Server 2005 に含まれていたすべてのセキュリティ修正プログラムの更新プログラムのリリースします。

現象

以下の事例で説明します。SQL Server 2005 では、マージ パブリケーションを構成します。マージ パブリケーションに id 列を含むテーブルを追加するとします。次に、パブリッシャーのテーブルにデータを挿入します。サブスクライバーとパブリッシャー間でデータを同期して、パブリッシャーでデータを追加しようとします。このシナリオでは、パブリッシャー側で次のエラー メッセージが表示されます。
Msg 548、レベル 16、状態 2、行 1
挿入に失敗します。Id 範囲のチェック制約 'データベース名'、レプリケートされたテーブルをデータベース内で、競合しています'のスキーマです。テーブル名'、列 'ColumnName' です。Id 列はレプリケーションで自動的に管理される、する場合、範囲を次のように更新: パブリッシャー、sp_adjustpublisheridentityrange; を実行します。サブスクライバーのディストリビューション エージェントまたはマージ エージェントを実行します。
しようとすると、sp_adjustpublisheridentityrange を実行するストアド プロシージャをパブリッシャー側で、エラー メッセージで説明したように、この問題を解決できません。

この問題は、同じマージ パブリケーションに対して同時に複数のマージ エージェントがデータを同期するときに発生します。マージ パブリケーションに対して多数のサブスクライバーがある場合は、この問題を深刻化することができます。

原因

この問題は、パブリッシャー上のテーブルの現在の id 値が id 範囲のチェック制約の id の範囲内にないために発生します。この現象は、複数のマージ エージェントがパブリッシャー側で次の id 範囲を作成することによって同時に id 範囲を拡大しようとするときに発生します。

解決策

この問題に対する修正は、累積的な更新 8 で初めてリリースされました。この累積的な更新プログラム パッケージを SQL Server 2005 Service Pack 2 の入手方法に関する詳細については、マイクロソフト サポート技術情報の記事を表示するのには次の資料番号をクリックします。
951217関数形式は、SQL Server 2005 Service Pack 2 の 8 のパッケージを更新します。
注: ビルドは累積的であるため、各新しい修正プログラム リリースには、すべての修正プログラムが含まれていて、以前の SQL Server 2005 に含まれていたすべてのセキュリティ修正プログラムの更新プログラムのリリースします。マイクロソフトでは、この修正プログラムを含む最新の修正プログラム リリースを適用することを検討することをお勧めします。詳細については、次の文書番号をクリックして、マイクロソフト サポート技術情報の資料をご参照ください。
937137 SQL Server 2005 ビルド SQL Server 2005 Service Pack 2 がリリースされた後にリリースされました。
特定の SQL Server のサービス パックには、Microsoft SQL Server 2005 の修正プログラムが作成されます。SQL Server 2005 Service Pack 2 のインストールには、SQL Server 2005 Service Pack 2 修正プログラムを適用する必要があります。既定では、SQL Server のサービス パックで提供されているすべての修正プログラムは次の SQL Server のサービス パックに含まれます。

回避策

この問題を回避するには、複数の同時実行マージ同期を防ぐ必要があります。これを行うには、次のステートメントを実行して、差し込み印刷用の文書で、 max_concurrent_mergeプロパティを設定します。
sp_changemergepublication '<PublicationName>', 'max_concurrent_merge', 1
注: この回避策を使用した後、パブリケーションに対して多数のサブスクライバーがある場合にパフォーマンスが低下する可能性があります。のみ 1 つのサブスクライバーは、時にデータを同期することができますので、この現象が発生します。

状況

マイクロソフトは、この問題を「対象製品」セクションに記載されているマイクロソフト製品の問題として認識しています。

詳細

この問題が発生しているかどうかを確認する方法

この問題が発生しているかどうかを確認するのには、次の手順を実行します。
  1. 現在の id 値が id 範囲のチェック制約の最初の id 範囲の下限値よりも小さいことを確認します。

    現在の id 値を取得するには、次のステートメントを実行します。
    SELECT IDENT_CURRENT ('<TableName>')
    Id 範囲のチェック制約の id 範囲を取得するには、次のステートメントのいずれかを実行します。
    ステートメント 1
    sp_helpconstraint '<TableName>'
    ステートメント 2
    select * from MSmerge_identity_rangewhere is_pub_range <>1
    AND artid IN
    (select artid from sysmergearticles where name='<TableName>')
    AND subid in
    (select subid from sysmergesubscriptions MS
    join sysmergepublications MP
    on MS.subscriber_server=MP.publisher
    AND MS.db_name = MP.publisher_db
    WHERE name='<PublicationName>'
    )

  2. 同じ文書の別のマージ エージェント セッションで sp_MSsetup_publisher_idrange が格納されているプロシージャの実行をインターリーブを開始するかどうかを確認するのにには、SQL Server プロファイラー トレースを使用します。

    ただし、sp_MSsetup_publisher_idrange が格納されているプロシージャの実行をインターリーブ常に示していないこの問題が発生しています。マージ同期の元のすべてには、最初のエラー メッセージが生成されるとき、SQL Server プロファイラーが実行されていないためにです。ただし、sp_MSsetup_publisher_idrange が格納されているプロシージャの実行をインターリーブはこの問題が発生する可能性を増加する操作を行います。
  3. 「548」のエラー メッセージが表示されたら場合に発生する重複するマージ同期が表示されます。これを行うには、ディストリビューション データベースにマージ履歴を確認できます。これを行うには、次のステートメントを実行します。
    Use distributionGO
    select session_id, agent_id, B.publication, min(time) as StartTime, max(time) as EndTime
    into #sessiontimes
    from dbo.MSmerge_history A
    join dbo.msmerge_agents B
    on A.agent_id = B.id
    group by session_id, agent_id, publication
    order by 3 desc
    GO
    -- The left side result is the original session. The right side result is the overlapping session.
    select A.*, B.*
    from #sessiontimes A
    Join #sessiontimes B
    On B.StartTime >= A.StartTime
    AND B.StartTime <= A.EndTime
    AND A.session_id <> B.session_id
    And A.publication=B.publication
    Order By A.StartTime asc
    GO
    drop table #sessiontimes

既存の修正方法には、問題のあるテーブルの id 範囲が破損しています。

累積的な更新プログラムをインストールした後、または「回避策」に記載されているメソッドを使用した後は、テーブル内既存破損の id 範囲は修正されません。テーブルにデータを挿入し、サブスクライバー上のデータを同期しようとする場合「548」のエラー メッセージが表示されるがまま。したがって、テーブルの破損の id 範囲を手動で修正する必要があります。そのためには、以下の手順を実行します。

注: パブリッシャーの id 値を正しく再シードするテーブルの現在の id シード値を手動でオーバーライドする手順が含まれます。破損した状態では、現在の id 値は、マージ レプリケーション id 範囲のチェック制約の最初の id 範囲未満です。手順は、マージ レプリケーションの id 範囲の check 制約で定義されている id の範囲内に id 値を手動で発生します。次の手順では、昇順の方法でユーザーが構成されていると、1 の値が増加する identity インクリメントが設定されていると仮定します。
  1. Id 増分の値が 1 であること、および id は、次の方法を昇順のことを確認します。Id 増分の値を取得するには、パブリッシャーで次のステートメントを実行します。
    SELECT IDENT_INCR( '<TableName>')
  2. 問題のある id 列の現在の id 値を検索するのにはパブリッシャーで次のステートメントを実行します。
    DBCC CHECKIDENT ('<TableName>')
    結果が表示されたら、それ以降の手順で比較のため現在の id 値の値に注意してください。いることを確認します
    valye の現在の列の値が大きいか、現在の id 値の値よりも小さい可能性があります。


    列の値を現在の値が現在の id 値の値よりも大きい場合は、列の値がトポロジ内の他の複製で発生したあり、パブリッシャーのレプリケーションを正常にマージします。列の値を現在の値が現在の id 値の値よりも小さい場合は、値が上に挿入されたパブリッシャー以前の状態でマージ レプリケーションの構成の前に SET IDENTITY_INSERT をステートメントを使用しています。
  3. パブリッシャー id 範囲の現在の id 範囲を確認して問題のあるテーブルの制約を決定するには、次のステートメントを実行します。
    Use <PublishedDatabaseName>GO
    sp_helpconstraint '<TableName>'
    GO

    結果が表示された後の値に注意してください、
    レコードのconstraint_keysの列位置の値、
    constraint_name列は、"repl_identity_range_GUID"です。GUID 値の値に対応します
    sysmergearticles システム テーブル内のアーティクルに対して列をartid 。GUID を取得するには、次のステートメントを実行します。
    select artid from sysmergearticles where name = '<TableName>'
    Id 範囲のチェック制約は、2 つの別々 の範囲にまたがっています。範囲の 2 つのセットは、隣接している必要はありません。たとえば、 constraint_keys列の値は次のようにされます。
    ([ColumnName] > (1001) と [ColumnName] < =(2001)

    または [ColumnName] >、(9001) と [ColumnName] < =(10001))
    注: この資料では、次の使用例を使用して、手順の残りの部分のコードを表示します。

    この例では、1,000 個の値が各範囲に します。1,000 は、既定の範囲のサイズです。ただし、次の方法のいずれかを使用して、id 範囲のサイズを変更できます。
    • Sp_addmergearticle ストアド プロシージャを実行するときは、 @pub_identity_rangeパラメーターを指定します。
    • 内のアーティクルのサブスクライバーの範囲サイズプロパティを変更します
      アーティクルのプロパティ] ダイアログ ボックスです。
  4. 「現象」に記載されている問題が発生した場合は、手順 2 でメモした現在の id 値が手順 3 でメモした id 範囲のチェック制約の最初の id 範囲の下限値よりも小さいはずです。

    2 つ目の id 範囲の上限値よりも大きい場合は手順 2 では、現在の id 値は、id 範囲のチェック制約、エラー メッセージで推奨されているメソッドを使用して問題を解決します。したがって、パブリッシャー側で sp_adjustpublisheridentityrange が格納されている手順を実行してください。

    Sp_adjustpublisheridentityrange が格納されている手順の詳細については、次の Microsoft Developer Network (MSDN) Web サイトを参照してください。
  5. すべての行は、id 範囲のチェック制約の現在の id 範囲内かどうかを決定する次のステートメントを実行します。
    SELECT COUNT(*) FROM TableName WHERE ([ColumnName]>(1001) AND [ColumnName]<=(2001) 
    OR [ColumnName]>(9001) AND [ColumnName]<=(10001))

    注:
    • ステートメントには、0 が返された場合、現在の id 範囲の行はされていません。ここでは、手順 6 に進みます。
    • ステートメントが 0 より大きい値を返す場合は、現在の id 範囲の id 値の最大値を取得する次のステートメントを実行します。
      SELECT MAX(ColumnName) as MaxValue FROM TableName WHERE ([ColumnName]>(1001) AND [ColumnName]<=(2001) OR 
      [ColumnName]>(9001) AND [ColumnName]<=(10001))

      、返される値をメモし、手順 7 に進みます。
  6. 有効な範囲内に問題のあるテーブルの現在の id を手動で再シードします。


    1 を加えた現在の id 範囲の最小値を現在の id を再シードします。現在の id 範囲の最小値が 1001 の場合は、最初の可能な範囲の値は 1002 id 範囲のチェック制約の範囲の下限は、大きいため不等号 (>)。これを行うには、パブリッシャーで、次のステートメントを実行し、手順 8 に進みます。
    DBCC CHECKIDENT ('TableName', RESEED, 1002)
  7. 有効な範囲内に問題のあるテーブルの現在の id を手動で再シードします。

    Id インクリメントが 1 であると仮定します。手順 5 でメモした値を現在の id を再シードし、1 を追加します。たとえば、1507 の手順 5 でメモした値が表示された場合 1508 に現在のユーザーを再シードします。これを行うには、パブリッシャー側で次のステートメントを実行します。
    DBCC CHECKIDENT ('TableName', RESEED, 1508)
  8. 548 エラーが発生せず、パブリッシャー データベース内のテーブルに新しい行を挿入できるかどうかを調べるテストを実行します。
についてどのようなファイルが変更されると、このマイクロソフト サポート技術情報資料に記載されている修正プログラムを含む累積的な更新パッケージを適用するすべての前提条件に関する情報をマイクロソフト サポート技術情報の記事を表示するのには次の資料番号をクリックしてください。
951217関数形式は、SQL Server 2005 Service Pack 2 の 8 のパッケージを更新します。

関連情報

ビルド後は、利用可能な SQL Server の Service Pack 2 の一覧については、マイクロソフト サポート技術情報の記事を表示するのには次の資料番号をクリックします。
937137 SQL Server 2005 ビルド SQL Server 2005 Service Pack 2 がリリースされた後にリリースされました。
SQL Server の増分サービス モデルについては、次の記事番号をクリックして、マイクロソフト サポート技術情報の記事を参照してください。
935897 「の増分サービス モデルは、SQL Server チームは、報告された問題に対する修正プログラムを提供
SQL Server 2005 Service Pack 2 を入手する方法の詳細については、マイクロソフト サポート技術情報の記事を表示するのには次の資料番号をクリックします。
913089 SQL Server 2005 の最新の service pack の入手方法
新機能と SQL Server 2005 Service Pack 2 で改善する方法の詳細については、次のマイクロソフト Web サイトを参照してください。SQL Server の更新プログラムの名前付けスキーマの詳細については、マイクロソフト サポート技術情報の資料を参照するのには次の資料番号をクリックします。
更新プログラム パッケージの新しい名前付けスキーマを Microsoft SQL Server ソフトウェアの822499
ソフトウェア更新プログラムの用語の詳細については、次の文書番号をクリックして、マイクロソフト サポート技術情報の資料を参照してください。
824684マイクロソフトのソフトウェア更新プログラムを記述するために使用される一般的な用語説明
プロパティ

文書番号:953481 - 最終更新日: 2017/02/05 - リビジョン: 1

フィードバック