close

當Transaction Replication 發佈端的資料表更新或刪除某筆記錄時,原則上會通知訂閱端的資料表更新或刪除某筆資料(假設我們的Replication 是push 機制)
反過來看,若訂閱端的資料表內容被使用者或其他AP異動過,則發佈端進行更新或修改資料時,通知訂閱端同步異動資料時找不到這筆資料。則會發生下列錯誤訊息。(下圖模擬的錯誤畫面為,訂閱端的記錄先行刪除了,因此執行複寫的刪除預存程序,傳回受影響記錄筆數 0,引發錯誤):

image

開啟效能監視器,切換至All Subscription畫面,檢視錯誤訊息(上圖)。
在Subscriton的錯誤細節中,取得錯誤編號如下圖所示
image
解法一

Step1:根據上圖提供的交易序號(Transaction sequence number xact_seqno)和命令識別碼(Command ID command_id)搭配 Distribution 系統資料庫內的 sp_browsereplcmds 系統預存程序,或是直接查詢 MSrepl_commands 系統資料表。(註:此查詢,要用image 文字顯示,而非 grid,且參數是數值型,轉成文字會變成亂碼)

select command_id,
CONVERT(nvarchar(max),case when datalength(command) > 6 then right(command,datalength(command)-6) else command end),command
from distribution.dbo.MSrepl_commands
where xact_seqno=0x0000023C0000172000040000000 and command_id=1


執行結果如下:
command_id                                                                                                                                               
----------------------------------------------------------------------------------------------------------------------------------------------
C A L L   [ d b o ] . [ s p _ MSdel_dbotblMapKsDetail]
   ( ? , ? , ? , ? , ? , ? , ? , ? , ? ) }           162       04        B2                       699                                                                                  0x7A00000009007B00430041004C004C0020005B00640062006F005D002E005B00730070005F004D005300640065006C005F00640062006F00740062006C004D00610070004B007300440065007400610069006C005D00200028003F002C003F002C003F002C003F002C003F002C003F002C003F002C003F002C003F0029007D00


Step2:執行以下的預存程序(要初始化的個別資料表不大,整個Publication也不大的情況下)

exec distribution.dbo.sp_browsereplcmds
@xact_seqno_start = '0x0000023C000010BF000800000000',
@xact_seqno_end = '0x0000023C000010BF000800000000'

執行結果如下圖所示。在cmmand欄位可發現 Transaciton replication 發佈端所觸發的執行語法,應在訂閱端執行成功卻失敗的指令。

image

以本例來看,是因為訂閱端有三筆資料先行被刪除,因此使用下列步驟中的 Iinsert 指令,先將訂閱端簡單恢復。
主要目的是讓讓Distribution Agent可以正常執刪除指令。

Step3

insert into dbo.tblMapKsDetail(companyID,AcctCtrl1,AcctCtrl2,AcctCtrl3,AcctCtrl4,
AcctCtrlNo1,AcctCtrlNo2,AcctCtrlNo3,AcctCtrlNo4)
values('162','04','B2','  ','  ','699','','','',0,0,0,0,GETDATE()),
('162','04','B2','  ','  ','721','','','',0,0,0,0,GETDATE()),
('162','04','B2','  ','  ','848','','','',0,0,0,0,GETDATE())

 

  • 解法二

若資料表內容複雜,不想要個別修改紀錄,而從 Publisher 初始化該資料表,但又不影響整個 Publication 所有的資料表,可以執行以下的預存程序(要初始化的個別資料表不大,整個Publication也不大的情況下)

--要在提供 Publication 的資料庫下執行,而非 Distribution
exec sp_reinitsubscription
    @publication = 'test',
    @article ='t',
    @subscriber ='P714P4USER',
    @destination_db ='d',
    @for_schema_change =1,
    @invalidate_snapshot =1

--產生 Snapshot
--這會產生整個 publication 的,但Distributor會僅對上述標示要 Initialize 的資料表
--利用 snapshot 執行個別資料表的初始化,這可以從 UI 做
EXEC sp_startpublication_snapshot @publication='test'

arrow
arrow
    全站熱搜

    小草 發表在 痞客邦 留言(0) 人氣()