事務復制中的snapshot


   

Snapshot agent讀取article的信息,將article的內容和腳本放置到snapshot文件夾中; 接下來distribution agent會讀取這些快照文件,傳輸到訂閱,完成初始化操作。期間distribution agent需要處理很多事情,例如判斷快照是否可用,需要應用那些快照文件,傳輸過程中發生中斷怎么辦 等等。這些都需要distribution agent來協調。讀完本文之后您會對這些處理方式有所了解,也會幫助您更好地判斷當前事務復制的狀態以及進行錯誤排查。

   

在此之前,我要先簡單地介紹一下distribution agent的工作方式:

Distribution agent包含兩個進程,readerwriterReader負責從distribution 數據庫中讀取數據,Writer負責將reader讀取的數據寫入到訂閱數據庫.

reader是通過sp_MSget_repl_commands來讀取distribution數據庫中(讀取Msrepl_transactions表和Msrepl_Commands表)的數據

下面是sp_MSget_repl_commands的參數定義

CREATE PROCEDURE sys.sp_MSget_repl_commands 

( 

@agent_id int, 

@last_xact_seqno varbinary(16), 

@get_count tinyint = 0,  -- 0 = no count, 1 = cmd and tran (legacy), 2 = cmd only 

@compatibility_level int = 7000000, 

@subdb_version int = 0, 

@read_query_size int = -

) 

這個存儲過程有6個參數,在Transactional replication 中,只會使用前4個(並且第三個參數和第四個參數的值是固定不變的.分別為0和10000000)。下面是一個例子:

exec sp_MSget_repl_commands 46,0x0010630F000002A900EA00000000,0,10000000

   

@agent_id表示distribution agent id,每個訂閱都會有一個單獨的distribution agent來處理數據。 帶入@agent_id后,就可以找到訂閱對應的publication 和所有的article

@last_xact_seqno 表示上一次傳遞到訂閱的LSN

大致邏輯是:Reader讀取分發數據庫中LSN大於@last_xact_seqno的數據。 Writer將讀取到的數據寫入訂閱,並更新訂閱的LSN.( MSreplication_subscriptions表的 transaction_timestamp列)。然后Reader會繼續用新的LSN來讀取后續的數據,再傳遞給Writer,如此往復。在sp_MSget_repl_commands 的處理過程中, Msrepl_Commands表(通過type列進行區分)的數據大致分為兩種: 1快照產生的數據,2 正常更新產生的數據

   

現在基本知識介紹完畢,下面開始進入正題

   

   

如何判斷快照是否可用

   

Distribution agent 會使用存儲過程sp_MSsubscription_status(exec sp_MSsubscription_status @agendId)去判斷當前快照的狀態:

  1. 當創建發布和訂閱后,distribution 數據庫中MSsubscriptions表的status列為1(Subscribed),
  2. 如果此時運行distribution agent,會拋出21075, 21076或21088錯誤"The initial snapshot for %%  is not yet available".  
  3. 當快照生成后,snapshot agent會去更新MSsubscriptions中的status列的狀態。當status列的值為2(Actived)時,表示快照已經完成,這樣distribution agent就可以正常運行了。不過根據不同的設置,snapshot agent會將status列更新為不同的值:
  4. 如果sync_methodconcurrentsql server 2005以及以后版本的默認模式),status的值會變更為3; 如果此時運行distribution agent,會出現下面的21388的錯誤The concurrent snapshot for publication 'PublicationName' is not available because it has not been fully generated or the Log Reader Agent is not running to activate it. If generation of the concurrent snapshot was interrupted, the Snapshot Agent for the publication. 我們必須運行一下log reader agent,運行后, status就被更新為2(active)了. 這樣distribution agent就可以正常運行了。
  5. 如果sync_methodnative,那么status的值會被直接更新為2,

       

    如何應用快照文件

    Snapshot會在快照文件夾或alt_snapshot_folder生成快照文件,那么distribution agent是如何找到這些文件並應用的呢?

    Snapshot agent會將一些信息寫入到distribution 數據庫中的MSrepl_transactionsMSrepl_commands表中,下面是snapshot產生后兩張表的查詢截圖

    那么這些內容代表什么意義呢?我們可以通過sp_browsereplcmds來查看 ,

    use distribution

    go

    exec sp_browsereplcmds '0x0000001E0000008F001E','0x0000001E0000008F001E' .

    表中的內容包含了snapshot文件的名稱和路徑, distribution agent就會據這些信息將snapshot應用到訂閱數據庫中。

       

       

    如何判斷是否需要應用快照

    當一個訂閱數據庫完成初始化之后,如何避免distribuiton agent下次運行時重復應用快照呢? 系統表中並沒有單獨的字段來標記訂閱數據庫是否已經完成了快照。 實際上,這些判斷邏輯是包含在sp_MSget_repl_commands里的:

    當第一次初始化時,訂閱數據庫的LSN(MSreplication_subscriptions表的 transaction_timestamp)小於快照文件對應的LSN,這樣,所有大於訂閱LSN(也包含了快照)的數據都會被同步到訂閱。

       

    接下來就有個問題了,假設發布添加了一個新的訂閱數據庫,新的訂閱數據庫需要distribution agent來幫助其完成初始化快照的步驟。於是生成了一個新的快照,這些快照的xact_seqn肯定是大於已存在的訂閱的xact_seqno的。 但對於已經存在的訂閱數據庫,是不需要應用這些快照的.那么distribution agent是如何處理這種情況的呢?

    實際上sp_MSget_repl_commands除了會比較xact_seqno,還存在額外的判斷:訂閱對應的每個已發布項目在 MSsubscriptions 表中都會有一行記錄。MSsubscriptions 表的subscription_seqno 列表示快照事務序列號;publisher_seqno  列表示該訂閱在發布服務器上的事務序列號。如果@last_xact_seqno的值小於這兩個值中的任意一個,就表示訂閱需要應用快照,否則表示快照已經應用過了,只需要應用后續更新即可。

    當第一次快照生成后,這兩個列的值就不會再放生變化了(除非訂閱被標記為需要重新初始化),但是訂閱數據庫的MSreplication_subscriptions表的 transaction_timestamp是不斷增加的,所以即使生成新的快照,已存在的訂閱也不會受到影響。

       

    在應用快照過程中意外中斷怎么辦?

    假設一共有8個snapshot文件,distribution agent已經應用了3個文件,在應用第四個文件的時候OS重啟了。 那重啟后該如何繼續呢? 是否需要全部重新開始呢? 答案是否定的。 在應用snapshot文件的過程中,distribution agent會向subscription數據庫里的MSsnapshotdeliveryprogress系統表寫入數據,每當一個文件成功應用到訂閱,就會寫入一條數據。如果意外重啟,distribution agent會根據這張表來判斷哪些文件已經被應用過。當所有的snapshot文件都傳遞到訂閱后,distribution會清除表里的內容。  當下面是MSsnapshotdeliveryprogress的查詢截圖。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM