在事務複製裡,如果乙個article被更新,distributionagent會呼叫相應的儲存過程將資料更新到訂閱端。 這些儲存過程分別是[sp_msins_dbotablename],[sp_msdel_dbotablename]和 [sp_msupd_dbotablename],
分別對應插入,刪除和更新操作。這些儲存過程是在快照初始化時建立的。不過您可能曾經觀察到還有其它兩個儲存過程被呼叫過:sp_msins_dbotablename_msrepl_ccs,sp_msdel_dbotablename_msrepl_ccs。
那麼兩個儲存過程的作用是什麼呢?
當sp_addpublication 的引數sync_method值為concurrent時,生成快照時article是允許被更新的,這些更新隨後也會被應用到訂閱端。 如果是使用預設的命令去更新,那麼就可能遇到下面的情況:
假設表ta有2行資料,snapshot agent已經讀取第一行和第二行資料,這時插入了第三條資料。接下來snapshot會去讀第三條資料,並將三行資料打包到bcp檔案中。而第三條資料的日誌也會被logreader傳遞到分發。 這樣就會產生乙個問題:如果仍然使用sp_msins_dbotablename,就會造成主鍵衝突,出現1033錯誤:violation of %ls constraint '%.*ls'. cannot insert duplicate key in object '%.*ls'. the duplicate key value is %ls.
當操作是更新時,先判斷改行是否存在,如果存在,則使用更新操作。
如果是更新操作,則會先呼叫css的刪除操作,然後呼叫css的插入命令,以避免20598錯誤。
所以在初始化的階段,你會看到多出了兩種儲存過程。不過在初始化完成後,這兩個儲存過程就會從訂閱段刪除掉。
下面列出了三個命令的呼叫截圖。 請注意,這類msrepl_ccs的型別有別於普通的儲存過程,其值為-2147483618。
插入操作。sp_msins_dbotablename會被解釋成sp_msins_dbotablename_msrepl_ccs。
更新操作。sp_msupd_dbotablename會分解為兩個操作,現將資料刪除,然後插入新的資料。
刪除操作。sp_msdel_dbotablename會被解釋成sp_msdel_dbotablename_msrepl_ccs。
儲存過程的定義
create procedure [dbo].[sp_msins_dbota_msrepl_ccs]
@c1 int,
@c2 int
as begin
if exists (select *
from [dbo].[ta]
where [id] = @c1)---------在普通的儲存過程中,是沒有這段判斷邏輯的。
begin
update [dbo].[ta] set
[c] = @c2
where [id] = @c1
end
else
begin
insert into [dbo].[ta](
[id],
[c]
) values (
@c1,
@c2 )
end
end
go create procedure [dbo].[sp_msdel_dbota_msrepl_ccs]
@pkc1 int
as begin
delete [dbo].[ta]
where [id] = @pkc1
---------在普通的儲存過程中,還有一段額外的邏輯: 如果影響行為0,則丟擲異常。
end
go
一段刪除的記錄
跳過事務複製中的錯誤
前些天部署了一套事務複製環境,訂閱端只需要最近五年的資料。複製採用的是備份檔案初始化,複製搭好後用了乙個指令碼在訂閱端刪除五年前的資料。導致堆積了大量的未分發命令。解決方案1 根據在分發資料庫上執行 sp helpsubscriptionerrors publisher publisher publ...
快照複製,事務複製,合併複製的區別
簡單來說 1.快照複製和事務複製是單向的 2005及以後的版本中加入了訂閱端可更新的事務複製 2.合併複製是雙向的。1.快照複製對錶結構沒有要求 2.事務複製要求表有主鍵 3.合併複製要求表有 rowguid 列 快照複製 1 概念 快照複製是完全按照資料和資料庫物件出現時的狀態來複製和分發它們的過...
事務複製工作機制
事務複製由 sql server 快照 日誌讀取器 和分發 實現。快照 準備快照檔案 其中包含了已發布表和資料庫物件的架構和資料 然後將這些檔案儲存在快照資料夾中,並在分發伺服器中的分發資料庫中記錄同步作業。日誌讀取器 監視為事務複製配置的每個資料庫的事務日誌,並將標記為要複製的事務從事務日誌複製到...