Stiamo risolvendo una sorta di Sync Framework tra due database di SQL Server, in server separati (entrambi SQL Server 2008 Enterprise 64 bit SP2 - 10.0.4000.0), tramite collegamento connessioni al server e abbiamo raggiunto un punto in cui siamo bloccati.SQL MIN_ACTIVE_ROWVERSION() valore non cambia per molto tempo
La logica per identificare quali sono i record "in sospeso da sincronizzare" è ovviamente basata sui valori ROWVERSION
, compreso l'uso di MIN_ACTIVE_ROWVERSION()
per evitare letture sporche.
Tutte le operazioni SELECT
sono incapsulate in SP su ciascun lato "sorgente". Questo è un esempio schematico di una 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
L'approccio funziona bene, di solito sincronizzeremo record con il tasso atteso di 600k/ora (lavoro ogni 30 secondi, dimensione del lotto = 5K), ma ad un certo punto , il processo di sincronizzazione non trova alcun singolo record da trasferire, anche se ci sono diverse migliaia di record con un valore ROWVERSION
superiore al parametro @LastStamp
.
Quando si verifica il motivo, abbiamo rilevato che lo MIN_ACTIVE_ROWVERSION()
ha un valore inferiore (o leggermente superiore, solo 5 o 10 incrementi) alla ricerca del . Questo, naturalmente, non dovrebbe essere un problema in quanto l'approccio MIN_ACTIVE_ROWVERSION()
è stato introdotto per evitare la legge sporco e le questioni posteriori, MA:
Il problema che vediamo in alcune occasioni, nel corso si verifica lo scenario di cui sopra, è che il valore per MIN_ACTIVE_ROWVERSION()
non cambia durante un lungo (molto lungo) periodo di tempo, come 30/40 minuti, a volte più di un'ora. E questo valore è di gran lunga inferiore al valore @@DBTS
.
Inizialmente pensavamo che questo fosse correlato a una transazione DB non ancora impegnata. Come da definizione MSDN sulla MIN_ACTIVE_ROWVERSION()
(link):
Restituisce il più basso valore di rowversion attiva nel database corrente. Un valore rowversion è attivo se è utilizzato in una transazione che non è stata ancora confermata.
Ma al momento del check sessioni (sys.sysprocesses
) con open_tran > 0
durante la durata di questo problema, ma non abbiamo trovato alcuna sessione con un waittime maggiore di un paio di secondi, solo uno o due occorrenze di +/- 5 minuti waittime sessioni.
Quindi, a questo punto, stiamo facendo fatica a capire la situazione: il MIN_ACTIVE_ROWVERSION()
non cambia durante un lungo periodo di tempo e in questo intervallo di tempo non vengono trovate transazioni non impegnate con lunghe attese.
Non sono un DBA e potrebbe essere il caso che ci manca qualcosa nell'immagine per analizzare questo problema, fare qualche ricerca su forum e blog non ha potuto trovare nessun altro indizio. Finora open_tran> 0 era la ragione valida, ma date le circostanze che ho esposto, è chiaro che c'è qualcos'altro e non so perché.
Qualsiasi feedback è apprezzato.
+1 per una domanda così ben scritta. Piuttosto che aggiungere la soluzione alla tua domanda, aggiungila come risposta. – Kermit
@luiggig: le soluzioni, anche da parte vostra, dovrebbero essere pubblicate come risposte. Sentiti libero di postare quella parte come risposta. E poi accettalo, se nessun altro ne esce con uno migliore. –