SQL MIN_ACTIVE_ROWVERSION()值长时间不会更改

前端之家收集整理的这篇文章主要介绍了SQL MIN_ACTIVE_ROWVERSION()值长时间不会更改前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们正在通过链接的服务器连接在不同的服务器(sql Server 2008 Enterprise 64位SP2 – 10.0.4000.0)中的两个sql Server数据库之间排除一种Sync Framework的异常,我们达到了我们排序卡住了

识别哪些记录“等待同步”的逻辑当然是基于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()的值正在被搜索的@LastStamp值小于(或稍大于5或10增量).这当然不应该是一个问题,因为引入了MIN_ACTIVE_ROWVERSION()方法以避免脏读和后期问​​题,但是:

在上述情况发生的情况下,我们在某些情况下看到的问题是,MIN_ACTIVE_ROWVERSION()的值在长(很长)的时间段内不会改变,例如30/40分钟,有时超过一小时.这个值远远小于@@ DBTS值.

我们首先认为这与尚未提交的待处理数据库事务有关.根据MSDN关于MIN_ACTIVE_ROWVERSION()(link)的定义:

Returns the lowest active rowversion value in the current database. A rowversion value is active if it is used in a transaction that has not yet been committed.

但是当使用open_tran>检查会话(sys.sysprocesses)时在这个问题的持续时间内,我们找不到任何等待时间超过几秒的会话,只有一到两次/ 5分钟的等待时间会话.

所以在这一点上,我们正在努力去理解这种情况:MIN_ACTIVE_ROWVERSION()在很长一段时间内没有改变,在这段时间内没有找到长时间等待的未提交的事务.

我不是DBA,可能是我们在图片中缺少一些东西来分析这个问题,在论坛和博客上进行一些研究找不到任何其他线索.到目前为止,open_tran> 0是有效的理由,但在我暴露的情况下,很明显有其他的东西,不知道为什么.

任何反馈都不胜感激.

解决方法

嗯,我终于找到解决方案,再挖一点.

问题是我们正在寻找一个漫长的等待时间的会话,但真正的交易是找到一段时间以来有活动的会话.

如果有一个会话,其中open_tran = 1,从这个事务打开(当然仍然是活动,尚未提交)开始就准确地获得,那么应该检查sys.sysprocesses中的last_batch字段.

使用此查询

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

我们可以识别一个开放的活动的活动30分钟.并且通过主机名值和一些更多的Web服务检查(以及使用dbcc inputbuffer),我们发现了负责的过程.

所以,最后一个问题实际上是“确实有一个未提交事务的活动会话”,因此MIN_ACTIVE_ROWVERSION()不会改变.我们只是看错了标准的进程.

现在我们知道哪个进程的行为是这样的,下一步将是改进它.

希望这个结果对别人有用.

猜你在找的MsSQL相关文章