分享方式:


當 SQL Server 在個別世代批次中處理子系和父代時,不會聚合

本文可協助您解決當 SQL Server 以個別世代批次處理子系和父代時所發生的非聚合問題。

原始產品版本: SQL S
原始 KB 編號: 308266

徵狀

在下列情況下,可能會在訂閱者端的子數據表中遺失 INSERT 命令:

  • 合併式復寫拓撲是階層式的,具有發行者、一或多個重新發行者,以及一或多個訂閱者。
  • 合併式復寫發行集中存在一或多個父發行項和子發行項,並在它們之間定義聯結篩選。
  • NOT FOR REPLICATION在重新發行者端和訂閱者端存在外鍵條件約束,以取得這兩篇文章之間的關聯性。
  • 子發行項中的 INSERT,會比合併代理程式參數中指定的值還多,在與其相關聯的父代產生區隔的 -DownloadGenerationsPerBatch 層代中發生。 因此,合併代理程式會在不同於其相關聯父代代的一批世代中處理子系產生。
  • 發行者與重新簽發者之間的合併處理中斷,以及子代和父代批次的處理之間發生中斷。

因應措施

合併式復寫架構不提供跨產生批次界限將父系和子系變更保持在一起的機制。 若要解決此問題,您可以:

  • -UploadGenerationsPerBatch將 和 -DownloadGenerationsPerBatch 合併代理程式 參數增加到其最大值 2000,這幾乎消除了在與父發行項產生不同的批次中處理子發行項產生的可能性。

-或-

  • NOT FOR REPLICATION在重新發行者端移除外鍵條件約束上的 屬性。 在此情況下,合併代理程式 無法將數據列插入子發行項,因為沒有相關聯的父發行項數據列。 不過,請記住,此變更可能會導致效能降低。 如果 合併代理程式 無法插入這些子數據列,則必須重試這些變更。 合併代理程式 重試程式的效率遠低於其一般批處理模式。

其他相關資訊

以下是可能發生此問題的更詳細事件序列。 和 合併代理程式 參數的預設值 -UploadGenerationsPerBatch-DownloadGenerationsPerBatch (重於此問題,) 為 100。 在下列範例中 -UploadGenerationsPerBatch ,假設 和 -DownloadGenerationsPerBatch 參數尚未改變。

  • INSERT 會在最上層發行者端進入子發行項和父發行項。 子發行項是發行集中任何對另一個數據表具有外鍵條件約束的發行項,稱為父發行項。 這兩篇文章與合併式復寫聯結篩選相關,而重新發行者和訂閱者上的實際伺服器端外鍵條件約束會標示 NOT FOR REPLICATION 屬性。 如果您不確定,您可以在數據表上執行 sp_help 預存程式,以判斷條件約束是否不適用於複寫。
  • 子數據表中的 INSERT 會發生 (例如層代 110 中的) 。 父數據表中的 INSERT 發生 (例如) 層代 250。 這些層代之間的分隔大於 -DownloadGenerationsPerBatch 參數。
  • publisher-republisher 合併代理程式 處理包含層代 101 到 200 的層代批次。 成功處理此批次,並將這些層代中相關聯的變更下載到重新發行者之後,publisher-republisher 合併代理程式 就會中斷。 中斷發生之前,合併代理程式 可以處理層代 201 到 300 (包含父發行項變更) 。 中斷的原因可能是網路連線中斷、查詢逾時等等。 合併代理程式 可以認可沒有父數據列的子發行項數據列,因為伺服器端外鍵條件約束會標示為 NOT FOR REPLICATION,因此會「暫停」條件約束的檢查。
  • 在 publisher-republisher 合併代理程式 再次開始處理之前,reublisher-subscriber 合併代理程式 開始合併會話。 它會開始從重新提交者下載變更的程式。
  • 當 reublisher-subscriber 合併代理程式 處理子發行項 INSERT) (層代 110 時,它會評估子發行項與父發行項之間的聯結篩選條件。 由於父發行項變更尚未送達重新發行者端,因此 合併代理程式 會判斷這些子系 INSERT 未「限定」聯結篩選條件。 合併代理程式 會下載代表層代 110 的MSmerge_genhistory列,但該世代中沒有任何變更。 此 合併代理程式 順利完成其會話。
  • 發行者與重新發行者之間的後續 合併代理程式 會成功處理包含父發行項 INSERT 的層代批次, (層代 201 到 300) ,並在重新發行者端認可這些變更。
  • 最後,重新發行者與訂閱者之間的後續 合併代理程式 會話會考慮第 250 代,並將父發行項 INSERT 下載至訂閱者。 不過,因為訂閱者也知道第110代 (子發行項的產生) ,所以 合併代理程式 不會重新評估子發行項的數據分割。

這會導致訂閱者端出現正確的父發行項數據列,並在重新發行者端包含 orphaned 子數據列。