在 Microsoft SQL Server 2005 中交易式複寫中,您可以使用
SubscriptionStreams 參數來啟用 「 散發代理程式 」 使用將套用變更到訂閱者的平行處理的批次的多重連線。在同一時間 「 散發代理程式 」 可以仍可維持許多相同的交易式特性為 「 散發代理程式 」 使用單一連線,以套用所做的變更時。
附註在下列各節中工作階段是指 「 散發代理程式 」 會開啟至 SQL Server 執行個體在訂閱者的連接。
「 散發代理程式 」 指定 SubscriptionStreams 參數之後的行為
「 散發代理程式 」 會維護在
SubscriptionStreams 參數中指定的工作階段數目。 「 散發代理程式 」 會使用這些工作階段,在訂閱者端套用變更。
不過,指定
SubscriptionStreams 參數和 「 散發代理程式 」 執行段時間之後,「 散發代理程式 」 可能會切換至使用只有一個工作階段,將變更套用至訂閱者。
讓 「 散發代理程式 」 去切換的理由使用只有一個工作階段
「 散發代理程式 」 可能會切換至因許多原因而使用只有一個工作階段。 以下是最常見的原因:
- 當 「 散發代理程式 」 會將變更套用時,工作階段的其中一個會引發錯誤。
比方說 「 散發代理程式 」 將資料列插入子資料表使用一個工作階段。 如果 「 散發代理程式 」 將對應的資料列插入父資料表藉由使用另一個工作階段之前,就會發生這個問題,外部索引鍵條件約束違規會引發錯誤訊息。 - 鎖定監視執行緒偵測到封鎖。下列原因可能會發生封鎖:
- 「 散發代理程式 」 會藉由使用不同的工作階段執行 INSERT 作業和在 「 訂閱者端資料表上的 UPDATE 作業。如果表格包含唯一的非叢集索引,封鎖兩個工作階段之間時,可能會發生 「 散發代理程式 」 會更新資料表的索引鍵。
- 在訂閱者端 「 散發代理程式 」 會執行 DML 陳述式上多個資料表。如果索引檢視表定義這些資料表上,封鎖兩個工作階段之間時,可能會發生索引檢視表更新共用的索引鍵。
- 「 散發代理程式 」 使用一個工作階段,針對在 「 訂閱者端的資料表執行 DML 陳述式。在此資料表上定義 DML 觸發程序。DML 觸發程序正在使用另一個工作階段來更新的另一個資料表上執行 DML 陳述式。在這種情況下兩個工作階段之間可能會發生封鎖。
我們強烈建議您不要在訂閱者資料庫使用下列的資料庫物件:
- 外部索引鍵條件約束
- 唯一的非叢集索引
- 索引檢視表
- DML 觸發程序可能會導致封鎖工作階段之間
如何判斷 「 散發代理程式 」 是否已切換至使用只有一個工作階段
如果要執行此動作使用其中一個下列的方法。
附註雖然您可以確認 「 散發代理程式 」 已不切換至使用一個工作階段使用方法 1,您必須使用方法 2 或 3 方法,以確認 「 散發代理程式 」 已切換至使用一個工作階段。
方法 1
查詢至訂閱資料庫的連線工作階段 sys.dm_exec_sessions 動態管理檢視 (DMV)。如果您看到 [只有一個連線工作階段 「 散發代理程式 」 可以切換到使用一個工作階段。如果您看到 [多個連線工作階段 「 散發代理程式 」 仍會使用指定的工作階段數。
若要確認 「 散發代理程式 」 已切換至使用一個工作階段,使用方法 2 」 或 「 方法 3。
方法 2
查詢散發資料庫中的 [msdistribution_history] 資料表的 [
註解] 資料行。如果查詢的結果中包含下列項目 「 散發代理程式 」 已切換至使用一個工作階段:
該處理無法完成在多重資料流模式中的最後一個批次,它已重設為單一連接模式,並目前正在重試這項作業。
方法 3
檢查 「 散發代理程式 」 的輸出檔。「 散發代理程式 」 已切換至使用只有一個工作階段,如果輸出檔包含相同的錯誤訊息,為方法 2。
下列的輸出檔是範例:
<Date><Time>已傳送 100 1181年命令與交易。
<Date><Time>已傳送 100 2672年命令與交易。
<Date><Time>桶 6 中止已經準備要認可的事件等候 spid 117 和 114 之間所找到的死結
<Date><Time>桶 1 中止已經準備要認可的事件等候 spid 117 和 114 之間所找到的死結
<Date><Time>桶 3 中止已經準備要認可的事件等候 spid 117 和 114 之間所找到的死結
<Date><Time>桶 0 中止已經準備要認可的事件等候 spid 117 和 114 之間所找到的死結
<Date><Time>桶 5 中止已經準備要認可的事件等候 spid 117 和 114 之間所找到的死結
<Date><Time>桶 2 中止已經準備要認可的事件等候 spid 117 和 114 之間所找到的死結
<Date><Time>桶 7 中止已經準備要認可的事件等候 spid 117 和 114 之間所找到的死結
<Date><Time>桶 4 中止已經準備要認可的事件,因為到執行緒關機事件等候
...
<Date><Time>訂閱資料流數目已重設從 8 為 1,狀態 4。
<Date><Time>正在中斷至訂閱者 <SQLinstance>
<Date><Time>正在中斷至訂閱者 <SQLinstance>
<Date><Time>正在中斷至訂閱者 <SQLinstance>
<Date><Time>正在中斷至訂閱者 <SQLinstance>
<Date><Time>正在中斷至訂閱者 <SQLinstance>
<Date><Time>正在中斷至訂閱者 <SQLinstance>
<Date><Time>正在中斷至訂閱者 <SQLinstance>
<Date><Time>正在中斷至訂閱者 <SQLinstance>
<Date><Time>連線到訂閱者 <SQLinstance>
<Date><Time>該處理無法完成在多重資料流模式中的最後一個批次,它已重設為單一連接模式,並目前正在重試這項作業。
<Date><Time>已傳遞 21 390 命令與交易。
如何疑難排解切換到使用只有一個工作階段的散發代理程式
- 在要擷取 封鎖處理序報告 事件和 例外狀況 事件訂閱者上執行 SQL Server 分析工具。這些事件記錄封鎖和 「 散發代理程式 」 套用變更時,會發生的錯誤。
附註例外狀況 事件的原因可能是任何種類的可能問題相關聯的錯誤。比方說,錯誤可能被因外部索引鍵條件約束違規。 - 使用其中一個方法來監視 「 散發代理程式 」 的 < 如何判斷 「 散發代理程式 」 是否已切換至使用只有一個工作階段 > 一節。
- 如果 「 散發代理程式 」 已切換至使用一個工作階段,停止追蹤。
- 從 「 散發代理程式 」 的輸出檔或 msdistribution_history 資料表 start_time 資料行,取得下列項目的時間戳記:
該處理無法完成在多重資料流模式中的最後一個批次,它已重設為單一連接模式,並目前正在重試這項作業。
- 開啟追蹤 (.trc) 檔從訂閱者。找出阻擋指令碼或其時間戳記是相同的作為或非常接近至您在步驟 4 中取得時間戳記的例外狀況事件。
- 如果您發現例外狀況時,請檢查以判斷原因例外狀況的詳細資料。例如外部索引鍵條件約束違規可能造成的例外狀況。如果是這種情況,我們建議您在訂閱者資料庫中移除外部索引鍵條件約束。
如果您注意到封鎖的指令碼,問題被因封鎖。 The following is a sample blocking script:<blocked-process-report monitorLoop="41589">
<blocked-process>
<process id="process3a6d438" taskpriority="0" logused="24592" waitresource="KEY: 6:72057594375700480 (0100e420fa5a)" waittime="9937" ownerId="568644832" transactionname="user_transaction" lasttranstarted="2008-05-05T04:55:04.430" XDES="0xa5619e370" lockMode="X" schedulerid="11" kpid="6104" status="suspended" spid="58" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2008-05-05T04:55:04.553" lastbatchcompleted="2008-05-05T04:55:04.430" clientapp=<DistributionAgentProgram> hostname=<servername> hostpid="3980" loginname=<SQLAgentAcct> isolationlevel="read committed (2)" xactid="568644832" currentdb="6" lockTimeout="4294967295" clientoption1="671090784" clientoption2="128056">
<executionStack>
<frame line="5" stmtstart="642" stmtend="1600" sqlhandle="0x0300060057a14477a8c6dd00609a00000100000000000000"/>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 2000986455] </inputbuf>
</process>
</blocked-process>
<blocking-process>
<process status="sleeping" spid="68" sbid="0" ecid="0" priority="0" transcount="1" lastbatchstarted="2008-05-05T04:55:04.570" lastbatchcompleted="2008-05-05T04:55:05.103" clientapp=<DistributionAgentProgram> hostname=<servername> hostpid="3980" loginname=<SQLAgentAcct> isolationlevel="read committed (2)" xactid="568644998" currentdb="6" lockTimeout="4294967295" clientoption1="671090784" clientoption2="128056">
<executionStack/>
<inputbuf>
Proc [Database Id = 6 Object Id = 1172459501] </inputbuf>
</process>
</blocking-process>
</blocked-process-report>
阻擋指令碼記錄封鎖的工作階段與封鎖的工作階段。已封鎖的工作階段啟動從 <blocked-process> 標籤。封鎖的工作階段啟動從 <blocking-process> 標籤。 - 找到 Proc 物件的物件識別碼已封鎖的工作階段中) 及封鎖的工作階段中)。
在範例封鎖指令碼,Proc 物件被封鎖的工作階段中的物件識別碼是 2000986455。Proc 物件所封鎖的工作階段中的物件 ID 是 1172459501。 - 訂閱] 資料庫中查詢 sys.objects 檢視藉由指定物件在步驟 7 中取得的 ID 等於 object_id 資料行。當您執行這項操作時,您可以決定物件名稱。
比方說的訂閱資料庫內容中執行下列查詢: USE <SubDBName>
GO
SELECT name FROM sys.objects
WHERE object_id = 1172459501 OR object_id = 2000986455
備忘稿- <SubDBName> 預留位置代表訂閱資料庫名稱。
- 通常,這些物件是在複寫中使用的預存程序。
- 判斷索引或索引檢視表,導致封鎖。要這麼做,請您執行下列步驟:
- 在 [封鎖指令碼尋找 waitresource 屬性的值。
在此範例中,封鎖指令碼,waitresource 屬性的值會是 72057594375700480。 - 查詢 [sys.partitions] 檢視中,以取得由指定 PARTITION_ID 行,等於您在步驟 9a 取得 waitresource 屬性的值的物件識別碼,以及索引識別碼。
比方說執行下列查詢: SELECT object_id, index_id FROM SYS.PARTITIONS WHERE PARTITION_ID=72057594375700480
- 訂閱] 資料庫中查詢 sys.indexes 檢視,以判斷索引藉由使用物件識別碼和您在步驟 9b 取得索引識別碼。
比方說執行下列查詢: USE <SubDBName>
GO
SELECT name, type_desc, is_unique FROM sys.indexes
WHERE object_id = <objID> and index_id = <idxID>
附註 的 <objID> 預留位置代表您在步驟 9b 取得的物件識別碼。<idxID> 預留位置代表您在步驟 9b 取得索引識別碼。
- 如果索引檢視表造成封鎖,我們建議您卸除索引檢視表。如果封鎖由唯一的非叢集索引所造成,我們建議您可以卸除該索引,並再重新建立非唯一索引。
鎖定監視執行緒的描述
「 散發代理程式 」 會維護封鎖的監視執行緒偵測到封鎖之工作階段之間的。如果鎖定監視執行緒偵測到封鎖之工作階段之間,「 散發代理程式 」 會切換至使用一個工作階段來重新套用目前的批次的 「 散發代理程式 」 無法套用先前的命令。
如鎖定監視執行緒的更多有關,按一下 [下面的文件編號,檢視 「 Microsoft 知識庫 」 中的發行項]:
956601?
(http://support.microsoft.com/kb/956601/
)
鎖定監視執行緒在 SQL Server 2005 中的描述
「 散發代理程式 」 會多個工作階段的繼續
「 散發代理程式 」 可以繼續多個工作階段之前 「 散發代理程式 」 必須執行
sp_MSget_repl_commands 預存程序,以重新查詢指令尚未套用在 「 訂閱者端的散發資料庫。然後,「 散發代理程式 」 必須套用在訂閱者的所有這些命令,「 散發代理程式 」 可以繼續多個工作階段之前。潛伏的複寫環境中 「 散發代理程式 」 無法繼續多個工作階段,因為 「 散發代理程式 」 可以繼續多個工作階段前,「 散發代理程式 」 必須套用在 「 訂閱者端的許多命令。
若要追蹤整個程序,檢查 「 散發代理程式 」 的輸出檔。
如需有關如何使用 SubscriptionStreams 參數以改善磁碟子系統輸送量的詳細資訊,按一下 [下列面的文件編號,檢視 「 Microsoft 知識庫 」 中的發行項]:
956600?
(http://support.microsoft.com/kb/956600/
)
如何使用 SubscriptionStreams 參數在 SQL Server 2005 中的改良的磁碟子系統輸送量的測試