2013-02-28 60 views
15

我們正在解決兩個SQL Server數據庫之間的一種Sync Framework,這些Sync Server在不同的服務器(包括SQL Server 2008 Enterprise 64位SP2 - 10.0.4000.0)中,通過鏈接服務器連接,並且我們達到了我們被困住的地步。SQL MIN_ACTIVE_ROWVERSION()值長時間不會更改

確定哪些是「待同步」待處理記錄的邏輯當然是基於ROWVERSION的值,包括使用MIN_ACTIVE_ROWVERSION()來避免髒讀。

全部SELECT操作封裝在每個「源」端的SP中。這是一個SP的示意圖樣本:

PROCEDURE LoaderRetrieve(@LastStamp bigint, @Rows int) 
    BEGIN 
    ... 
    (vars handling) 
    ... 

    SET TRANSACTION ISOLATION LEVEL SNAPSHOT 

    Select TOP (@Rows) Field1, Field2, Field3 
    FROM Table 
    WHERE [RowVersion] > @LastStampAsRowVersionDataType  
    AND [RowVersion] < @MinActiveVersion 
    Order by [RowVersion] 

    END 

這種方法工作得很好,我們通常會同步到600K /小時(工作每30秒,批量大小= 5K)的預期收益率的記錄,但在某些時候,即使有幾千條記錄的ROWVERSION值大於@LastStamp參數,同步過程也不會找到要傳輸的任何單個記錄。

檢查原因時,我們發現MIN_ACTIVE_ROWVERSION()的值小於(或稍大於5或10個增量)正在搜索的@LastStamp。這當然因爲MIN_ACTIVE_ROWVERSION()辦法,是爲了避免髒讀,後的問題,但應該不會是一個問題:

我們在一些場合看到,在上述情況下出現的問題是,對於價值MIN_ACTIVE_ROWVERSION()在很長(很長時間)內不會改變,如30/40分鐘,有時超過一小時。而這個值遠遠小於@@DBTS的值。

我們首先認爲這與尚未提交的未決數據庫事務有關。按照有關MIN_ACTIVE_ROWVERSION()link)MSDN定義:

返回當前數據庫中的最低活性rowversion值。如果在尚未提交的事務中使用rowversion值,則該值是活動的

但這個問題的持續期間檢查與open_tran > 0會議(sys.sysprocesses)的時候,我們無法找到一個WAITTIME大於幾秒任何會話,只有一個或兩個事件+的/ - 5分鐘等待時間會話。

所以在這一點上,我們正在努力瞭解情況:MIN_ACTIVE_ROWVERSION()在一段時期巨大不改變,並與長時間的等待沒有未提交的事務這個時間框架內找到。

我不是DBA,可能是我們錯過了圖片中的某些內容來分析此問題,在論壇和博客上做了一些調查,結果找不到任何其他線索。到目前爲止,open_tran> 0是有效的原因,但在我暴露的情況下,顯然還有其他的東西,不知道爲什麼。

任何反饋意見。

+3

+1這樣寫得很好的問題。不要將您的解決方案添加到您的問題中,而是將其添加爲答案。 – Kermit 2013-02-28 21:37:11

+6

@luiggig:解決方案 - 即使是你 - 也應該發佈爲答案。隨意發佈該部分作爲答案。然後接受它,如果沒有人提出更好的。 – 2013-02-28 21:38:29

回答

6

好吧,我終於找到了更多的挖掘後的解決方案。

的問題是,我們有很長的WAITTIME尋找會話,但真正的交易是要找到其中有一個活躍的一批因爲同時會話。

如果有一個會話open_tran = 1,爲了準確獲得該事務處於打開狀態(當然仍然活動,尚未提交),必須檢查sys.sysprocesses的last_batch字段。

使用此查詢:

select 
    batchDurationMin= DATEDIFF(second,last_batch,getutcdate())/60.0, 
    batchDurationSecs= DATEDIFF(second,last_batch,getutcdate()), 
    hostname,open_tran,* from sys.sysprocesses a 
    where spid > 50 
    and a.open_tran >0 
    order by last_batch asc 

,我們可以找出一個開放TRAN活躍30+分鐘的會話。通過主機名值和Web服務中的更多檢查(並使用dbcc inputbuffer),我們找到了負責任的流程。

因此,最後一個問題實際上是「確實存在未提交事務的活動會話」,因此MIN_ACTIVE_ROWVERSION()不會更改。我們只是用錯誤的標準來看過程。

現在我們知道哪個進程的行爲如此,下一步就是改進它。

希望這個結果對其他人有用。