SQL Server 同步複製中的MSSQL_REPL-2147201001問題處理

weixin_34344677發表於2011-05-18

引述


 

先,說我為什麼寫這篇文章,它讓你瞭解到什麼,對你是否有幫助。要是你是剛接觸SQL Server同步複製,那麼你可能會碰到各種各樣的問題,你可能不會從哪裡入手解決,或者你從Baidu,Google上找到解決問題的方法,但你很多時候只看到別人說的答案,很少有人去寫分析其中的原因,倘若你沒有找其他資料或查閱幫助文件瞭解為什麼,以後你碰到同樣問題,你也只能照搬之前的答案,有時候碰巧正確,你會突然的喜悅,但始終你不知道為什麼那樣,正如我們在學校學習,說的知其然而不知其所以然。

 

回到主題,以下內容使用我記錄的繁體筆記,測試環境是SQL Server 2005 (SP3) ,因時間原因,沒有作簡體轉換,如有哪一朋友需要,我可以測試個簡體的版本放上來。無論如何,如果你有什麼意見和見解,可以通過文章後面的釋出評論與我交流,或者通過Email方式,與我交流。我Email是:glal@163.com

 

問題描述


 

在合併式複製,當初始化訂閱時候,發生了錯誤,圖示:

dfg

錯誤資訊,文字描述如下:

嘗試執行的命令:
{call sp_MSsetconflicttable (N'Product', N'MSmerge_conflict_ReplicationDB-Merge_Product', N'PC143\SQL2005DE2', N'ReplicationDB', N'ReplicationDB-Merge')}
錯誤訊息:
•    接近 'ProductID' 之處的語法不正確。 (來源: MSSQLServer,錯誤號碼: 102)
取得說明:
http://help/102
•    合併處理無法將快照集傳遞給訂閱者。如果使用 Web 同步處理,可能是合併處理無法建立或寫入訊息檔。執行疑難排解時,請使用詳細資訊歷程記錄來重新啟動同步處理,並指定寫入的輸出檔。 (來源: MSSQL_REPL,錯誤號碼: MSSQL_REPL-2147201001)
取得說明:
http://help/MSSQL_REPL-2147201001

 

問題分析


 

從MSDN的聯機幫助文件中,查詢到SQL Server 2008 R2版本錯誤編碼MSSQL_REPL-2147201001的描述資訊:

說明

XML 訂閱者的 COM 物件初始化失敗。合併式複寫為何未能將結構描述變更套用到訂閱者的某些原因包括以下專案:

· 建立目錄來寫入暫時快照集檔案時,可能發生了失敗狀況。

· 列舉結構描述發行項時,可能發生了失敗狀況。

· 對於 SQL Server Compact 訂閱者而言,重新初始化訂閱時可能發生了失敗狀況。

· 如果物件是以訊息為根據,則表示寫入訊息檔案時可能發生了失敗狀況。

使用者動作:

執行 SQL Server Profiler 並檢查 replmerg.log 看看是否有失敗狀況。如果您正在使用 Web 同步處理,請提高 websync 記錄檔的嚴重性、重新執行此案例,然後檢查 websync.log 檔案中的錯誤。

如果您正在使用 Web 同步處理,可以啟動 Replmerg.exe 並傳遞 -T 106 選項來使用追蹤旗標 106。如此可讓您看到送給發行者以及發行者所傳送的訊息。代理程式會藉由將追蹤旗標新增到 Replmerg.exe 代理程式命令列,將使用者端的輸入訊息寫入到名為 ExchangeID(guid).IN.XML 的檔案中,並將輸出訊息寫入到名為 ExchangeID(guid).OUT.XML 的檔案中 (在這些檔案名稱中,guid 是 Exchange Server 工作階段的 GUID)。這些檔案會建立在之前叫用 Replmerg.exe 的目錄中。為了安全性起見,您應該在完成之後刪除這些檔案。

 

在SQL Server 2005版本上找不到對應的解決方法。然而,上面說一點“列舉結構描述發行項時,可能發生了失敗狀況”,可以從發行資料庫和訂閱資料庫的表結構上分析。

原始表Product結構:

Create Table Product

(

ProductID uniqueidentifier Not Null Default(Newid()),

Name nvarchar(50) Not null,

ProductNumber nvarchar(50) Not null,

Constraint PK_Product_ProductID Primary Key(ProductID Asc)

)

發行資料庫上的表Product結構:

CREATE TABLE [dbo].[Product](

[ProductID] [uniqueidentifier] NOT NULL DEFAULT (newid()),

[Name] [nvarchar](50) NOT NULL,

[ProductNumber] [nvarchar](50) NOT NULL,

[rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [MSmerge_df_rowguid_C03B37723F2840DAB64E7E25AB0AECBC] DEFAULT (newsequentialid()),

CONSTRAINT [PK_Product_ProductID] PRIMARY KEY CLUSTERED

(

[ProductID] ASC

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

) ON [PRIMARY]

這裡可以發行在發行資料庫中表Product多了一個欄位rowguid.而且設定了ROWGUIDCOL屬性,標誌唯一識別碼。根據猜測,rowguid這裡可能導致了初始化出問題。我們來看發行項的屬性設定:

如果表名稱使用中,則採取刪除資料的方式處理。問題可能出現在這裡了,在發行資料庫中表Product多欄位rowguid,應用與合併複寫,而這裡初始化時候,插入資料前沒有建立rowguid欄位導致資料列不一致,從而發生錯誤。

提示:
名稱為 rowguid 的資料行會加入到每個已發行的資料表中,除非該資料表中已含有設定了 ROWGUIDCOL 屬性之資料型別 uniqueidentifier 的資料行 (在此狀況下會使用此資料行)。rowguid 資料行用來唯一識別每個已發行資料表中的每個資料列。若從發行集卸除資料表,rowguid 資料行會遭到移除;若現有資料行用來進行追蹤,則不會移除資料行。

 

問題解決


 

接下來,就是根據上面分析的結果 ,去把問題給解決。下面從三個方面去解決。

1、在訂閱資料庫中表Product增加欄位guid,並加入rowguidcol屬性。

Alter Table Product Add rowguid uniqueidentifier rowguidcol Default(newsequentialid())

2、刪除當前的訂閱和發行集,重新設定合併複製,在發行項屬性中“如果名稱使用,則採用”選項,選擇“卸除現有物件重建立新物件”。

dffff2

3. 刪除當前的訂閱和發行集,在發行資料庫和訂閱資料庫中的表Product表欄位ProductID,加入ROWGUIDCOL屬性。

Alter Table Product alter Column ProductID Add rowguidcol

然後重新設定合併複製,在發行專案中“如果名稱使用,則採用”,根據實際需要選擇其中一種方式。

提示:
根據實際的環境選擇其中一種解決方法。如果要求處理問題速度,可以採用第1中處理方法,個人建議使用第3種解決方法。還有,在發行項屬性中“如果名稱使用,則採用”選項,選擇“卸除現有物件重建立新物件”時,特別要注意是其他表有外來鍵關聯,和與它有關聯的含(WITH SCHEMABINDING)的檢視(View),否則會導致無法卸除物件(Drop Table).

 



 

之前,我也記錄過類似這篇的同步複製中一問題的解決方法《可更新訂閱的事務複製錯誤:列名 'msrepl_tran_version' 無效》,http://www.cnblogs.com/wghao/archive/2011/05/10/2041714.html
 
 

 

相關文章