天天看點

SQL Server 合并複制遇到identity range check報錯的解決

    最近幫一個客戶搭建跨洋的合并複制,由于資料庫非常大,跨洋網絡條件不穩定,是以隻能通過備份初始化,在初始化完成後向海外訂閱端插入資料時發現報出如下錯誤:

Msg 548, Level 16, State 2, Line 2 

The insert failed. It conflicted with an identity range check constraint in database %s, replicated table %s, column %s. If the identity column is automatically managed by replication, update the range as follows: for the Publisher, execute sp_adjustpublisheridentityrange; for the Subscriber, run the Distribution Agent or the Merge Agent.

原因?

    在SQL Server中,對于自增列的定義是對于每一條新插入的行,都會自動按照順序新生成一個遞增的數字,改數字通常和業務無關且被用于作為主鍵。但如果該表用于可更新事務複制或者合并複制,那麼該自增列的區間範圍則由複制管理。

    此時,複制可以保證自增列可控,因為複制代理插入行時不會導緻自增列自增,隻有使用者顯式插入時才會導緻自增列自增。

    讓我們來做一個實驗。首先建立表,表定義如下:

CREATE TABLE [dbo].[Table_1](

    [c1] [int] IDENTITY(1,1),

    [c2] [int] NULL,

    [ROWGUID] [uniqueidentifier] NOT NULL,

    [rowguid4] [uniqueidentifier] ROWGUIDCOL  NOT NULL,

 CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED 

(

    [c1] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

) ON [PRIMARY]

    此時我們對建立合并複制,并把該表包含在内,并使用快照代理初始化複制,當完成該步驟時,我們發現該表上自動多了兩個限制,如圖1所示。

image

圖1.合并複制所加的限制

     我們看到該限制的定義隻允許4002到5002以及5002到6002之間的資料被插入。

     此時如果出現了一些BUG或者人為改動了該表自增列種子的值,則會報錯,如圖2所示。

圖2.改動種子值導緻插入資料出錯

    該限制會由合并代理自動遞增,比如說我們用如下代碼插入2000條資料,則發現該限制會自動遞增如圖3所示。

DECLARE @index INT=1

WHILE @index<2000

BEGIN

INSERT INTO table_1(c2,ROWGUID) VALUES(2,NEWID())

SET @index=@index+1

END

   圖3.限制區間自動遞增滑動

解決辦法  

    此時我已經找出了上面報錯的原因,因為是由于從備份初始化,那麼備份以及備份傳輸期間釋出庫又有新的資料插入,此時釋出庫比如說,該表的種子大小已經增加到了6000,而備份中該表大小還是5000,而限制已經滑動到了6000,那麼在訂閱端插入資料時就會發生這種問題。

解決辦法1

    在釋出端使用sp_adjustpublisheridentityrange 存儲過程使得限制範圍自動向後滑動,比如從6000-8000滑動到8000-10000。缺點自增值之間會有一個GAP。如果業務允許,推薦使用該做法。

    sp_adjustpublisheridentityrange @table_name=’表名稱‘

解決辦法2

    在釋出端運作SELECT  IDENT_CURRENT('表名稱'),找到釋出表的種子值。在訂閱端通過DBCC CHECKIDENT (表名稱,RESEED, 設定為上面值)指令将兩端種子值設定為一緻。

解決辦法3

    在訂閱端運作合并代理,即可修複資料。如果此方法不行,則再次嘗試上述方法。

解決辦法4

    不用自增列,而使用GUID列,但這涉及到表結構以及程式的修改,而且需要重新初始化複制,是以不是每一個環境都有條件這麼做。

此時,就可以正常插入資料了。

分類: SQL Server Replication

本文轉自CareySon部落格園部落格,原文連結:http://www.cnblogs.com/CareySon/p/4778854.html如需轉載請自行聯系原作者

下一篇: css規範