事務複制的基本機制,在聯機文檔上也有介紹。
如圖,主要依靠2個代理,1.日志讀取代理(log reader agent),2.分發代理(distribution agent)。
其中log reader agent,負責從釋出資料庫上讀取日志并且寫入到分發資料庫(distribution)中。然後distribution agent負責從distribution讀取資料并且寫入到訂閱中。
開profiler,使用tsql模闆即可。在已經有複制環境的狀态下,對釋出項目執行:
BEGIN TRAN
go
INSERT INTO dbo.rename_sc DEFAULT VALUES
GO 10
COMMIT
最主要的部分:
如圖,Log Reader Agent使用會話55去釋出庫的日志上讀取事務,如果發現有需要分發的,那麼會調用sp_MSadd_replcmds,這個存儲過程會把抓到的指令存放到dbo.MSrepl_commands和MSrepl_transactions2個表中。然後就會使用過程sp_repldone标記事務已經被複制。
SELECT spid,program_name FROM sys.sysprocesses WHERE spid IN( 57,55)
在sql server中查詢sys.sysprocesses 這2個spid 會發現program_name='Repl-LogReader-0-p1-9
也就是log reader agent在sql server 上有2個會話一個負責讀,一個負責寫。這樣Log Reader Agent的一次讀取完成。
Log Reader Agent寫入完之後就是有Distribution Agent 把事務應用到訂閱庫。
在存儲過程sys.sp_MSget_repl_commands對表dbo.MSrepl_commands讀取,之後就是在訂閱伺服器上面運作sp_MSins指令。
仔細觀察其實不難發現msrepl_command表中存的是明碼,通過和sp_browsereplcmds對比就能發現,那麼也就是說其實在插入MSrepl_commands的時候就已經知道了。
但是這裡有個問題Agent是怎麼知道要調用這個存儲過程的。
在這裡會注意到有2個不同的會話在處理,一個負責讀,一個負責寫入,其中65負責從分發庫中讀取,51負責應用到訂閱庫
SELECT spid,program_name FROM sys.sysprocesses WHERE spid IN( 65 ,51)
最後會修改訂閱伺服器中的MSreplication_subscriptions中的一些字段,其中最終要的是timestamp,這個字段表示現在訂閱已經應用到了那個事務。奇特的事情又出現,會發現有2個update語句。不知道是不是為了版本相容。
UPDATE MSreplication_subscriptions
SET transaction_timestamp = CAST(@P1 AS BINARY(15))
+ CAST(SUBSTRING(transaction_timestamp, 16, 1) AS BINARY(1)) ,
"time" = @P2
WHERE UPPER(publisher) = UPPER(@P3)
AND publisher_db = @P4
AND publication = @P5
AND subscription_type = 1
AND( SUBSTRING(transaction_timestamp, 16, 1) = 0
OR DATALENGTH(transaction_timestamp) < 16
)
+ CAST(CASE DATALENGTH(transaction_timestamp)
WHEN 16
THEN ISNULL(SUBSTRING(transaction_timestamp, 16, 1), 0)
ELSE 0
END AS BINARY(1)) ,
Distribution Agent完成一次分發。
本文轉自 Fanr_Zh 部落格園部落格,原文連結:http://www.cnblogs.com/Amaranthus/p/4271522.html,如需轉載請自行聯系原作者