Rozwiązywanie problemów z rodzajem struktury synchronizacji między dwiema bazami danych SQL Server, na oddzielnych serwerach (obydwa SQL Server 2008 Enterprise 64 bity SP2 - 10.0.4000.0), poprzez połączone połączenia z serwerem, a my doszliśmy do punktu, w którym utknęliśmy.Wartość SQL MIN_ACTIVE_ROWVERSION() nie zmienia się przez długi czas
Logika określająca, które rekordy są "oczekujące na synchronizację", jest oczywiście oparta na wartościach ROWVERSION
, w tym z użyciem MIN_ACTIVE_ROWVERSION()
, aby uniknąć brudnych odczytów.
Wszystkie operacje SELECT
są enkapsulowane w SP po każdej stronie "źródła". Jest to schemat próbka jednego 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
podejście działa dobrze, zwykle zsynchronizować zapisy z oczekiwanym tempie 600k/h (Job każde 30 sekund, wielkość partii = 5k), ale w pewnym momencie , proces synchronizacji nie znajduje żadnego pojedynczego rekordu do przesłania, mimo że istnieje kilka tysięcy rekordów o wartości ROWVERSION
większej niż parametr @LastStamp
.
Sprawdzając przyczynę, stwierdziliśmy, że wartość parametru MIN_ACTIVE_ROWVERSION()
ma wartość mniejszą niż (lub nieco większą, tylko 5 lub 10) od przeszukania szukanego @LastStamp
. To oczywiście nie powinno być problemu, ponieważ podejście MIN_ACTIVE_ROWVERSION()
został wprowadzony w celu uniknięcia problemów brudny odczyt i tylne, BUT:
Problem widzimy w niektórych przypadkach, podczas wystąpienia powyższego scenariusza jest to, że wartość MIN_ACTIVE_ROWVERSION()
nie zmienia się podczas długiego (naprawdę długiego) okresu, np. 30/40 minut, czasem więcej niż jedną godzinę. Ta wartość jest znacznie mniejsza niż wartość @@DBTS
.
Po raz pierwszy pomyśleliśmy, że było to związane z oczekującą transakcją DB jeszcze nie zatwierdzoną. Zgodnie z MSDN definicji o MIN_ACTIVE_ROWVERSION()
(link):
Zwraca najniższą wartość rowversion aktywny w bieżącej bazie danych. Wartość rowversion jest aktywna, jeśli jest używana w transakcji, która nie została jeszcze zatwierdzona:.
Ale podczas sprawdzania sesji (sys.sysprocesses
) z open_tran > 0
podczas trwania tej kwestii, nie mogliśmy znaleźć żadnego sesja z waittime większej niż kilka sekund, tylko jeden lub dwa występujące +/- 5 minut waittime sesji.
W tym momencie staramy się zrozumieć sytuację: MIN_ACTIVE_ROWVERSION()
nie zmienia się w długim okresie czasu, a w tym okresie nie znaleziono niezatwierdzonych transakcji z długim czasem oczekiwania.
Nie jestem DBA i może być tak, że brakuje nam czegoś na zdjęciu, aby przeanalizować ten problem, a niektóre badania na forach i blogach nie mogą znaleźć żadnej innej wskazówki. Do tej pory open_tran> 0 było uzasadnionym powodem, ale w okolicznościach, które ujawniłem, jest jasne, że jest coś jeszcze i nie wiem dlaczego.
Wszelkie uwagi są mile widziane.
+1 za tak dobrze napisane pytanie. Zamiast dodawać rozwiązanie do pytania, dodaj je jako odpowiedź. – Kermit
@luiggig: Rozwiązania - nawet przez Ciebie - powinny być publikowane jako odpowiedzi. Możesz dodać tę część jako odpowiedź. A potem zaakceptuj to, jeśli nikt inny nie wymyśli lepszego. –