リンクされたサーバー接続を介して、別々のサーバー(SQL Server 2008 Enterprise64ビットSP2-10.0.4000.0の両方)にある2つのSQLServerデータベース間の一種の同期フレームワークのトラブルシューティングを行っています。スタックの。
「同期が保留されている」レコードを識別するロジックは、もちろん、ダーティリードを回避するためROWVERSION
の使用を含め、値に基づいています。MIN_ACTIVE_ROWVERSION()
すべてのSELECT
操作は、各「ソース」側のSPにカプセル化されます。これは、1つの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分、場合によっては1時間以上などの長い(非常に長い)期間中に変化しないことです。そして、この値は値よりはるかに小さい@@DBTS
です。
これは、まだコミットされていない保留中のDBトランザクションに関連していると最初に考えました。MIN_ACTIVE_ROWVERSION()
(リンク)に関するMSDNの定義によると:
現在のデータベースで最も低いアクティブなrowversion値を返します。行バージョン値は、まだコミットされていないトランザクションで使用されている場合にアクティブになります。
しかし、この問題の期間中にセッション(sys.sysprocesses
)をチェックすると、待機時間が数秒を超えるopen_tran > 0
セッションは見つかりませんでした。+/-5分の待機時間セッションが1回または2回発生しただけです。
そのため、この時点で状況を理解するのに苦労しています。MIN_ACTIVE_ROWVERSION()
長期間にわたって変化することはなく、この時間枠内で待機時間が長いコミットされていないトランザクションは見つかりません。
私はDBAではないので、この問題を分析するための画像が欠落している可能性があります。フォーラムやブログで調査を行っても、他の手がかりは見つかりませんでした。これまでのところ、open_tran> 0が正当な理由でしたが、私が公開した状況では、他に何かがあることは明らかであり、その理由はわかりません。
フィードバックをいただければ幸いです。