2013-02-28 83 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()不会更改。我们只是用错误的标准来看过程。

现在我们知道哪个进程的行为如此,下一步就是改进它。

希望这个结果对其他人有用。