Come riprodurre "Impossibile continuare la scansione con NOLOCK a causa del movimento dei dati"


10

Occasionalmente ricevo "Impossibile continuare la scansione a NOLOCKcausa dello spostamento dei dati" con alcuni lavori di grandi dimensioni, che hanno WITH (NOLOCK)sulle query selezionate.

Capisco che ciò abbia a che fare con il tentativo di selezionare i dati quando c'è stata una divisione della pagina che ha causato i dati non essere più dove avrebbero dovuto essere - presumo che sia ciò che sta accadendo nel mio ambiente.

Come lo riproduco?

Sto cercando di eseguire una soluzione temporanea per rilevare l'errore e riprovare quando ciò accade, ma non riesco a testarlo se non riesco a riprodurlo. C'è un modo ragionevolmente affidabile per causare questo?

Quando ciò accade, eseguire nuovamente la query ha esito positivo, quindi non ho alcuna preoccupazione sul fatto che i dati effettivi o il database siano permanentemente danneggiati. Alcune delle tabelle nella query (insieme ai loro indici) vengono eliminate, ricreate e ripopolate spesso, quindi presumo sia qualcosa correlato a questo.

La rimozione NOLOCKè il mio problema a lungo termine da affrontare. Il motivo è NOLOCKstato messo lì in primo luogo è che le query sono così brutte che si sono bloccati con le transazioni quotidiane, quindi è NOLOCKstato un aiuto di fascia per fermare i deadlock (che ha funzionato). Quindi ho bisogno di un cerotto su un cerotto finché non possiamo fare una soluzione permanente.

Se potessi riprodurlo con un Hello World, probabilmente pianificherei di schiacciare il cerotto nel lavoro in meno di un'ora. Non riesco a eseguire la rimozione di ricerca e sostituzione NOLOCK, perché ricomincerei a ottenere nuovamente i deadlock delle app, che sono peggio per me di un lavoro occasionale non riuscito.

L'uso dell'isolamento dell'istantanea con commit della lettura è una buona possibilità: dovrò lavorare con il nostro team di database per ottenere maggiori dettagli a riguardo. Parte del nostro problema è che non abbiamo un esperto di SQL Server che si occupi di quel tipo di cose, e non capisco i livelli di isolamento abbastanza bene da apportare quel cambiamento in questo momento.


1
Hai considerato semplicemente la rimozione NOLOCKda questi lavori? 601 dovrebbe essere l'ultima delle tue preoccupazioni se i risultati di queste domande dovrebbero essere accurati . Paul White mostra un esempio particolarmente terribile di lettura dei dati che non dovrebbe essere possibile qui .
Aaron Bertrand

3
È possibile impostare DEADLOCK_PRIORITYsu LOWnei lavori, in modo che se ci sono deadlock, i lavori falliranno e non le applicazioni. Successivamente, è possibile ricercare i deadlock e scoprire perché stanno accadendo e risolvere il problema. Potrebbe essere una soluzione molto semplice, come scambiare l'ordine di due istruzioni. Qualunque sia il problema, nonNOLOCK è la soluzione , quindi smetti di provare a forzarlo perché è il più semplice.
Aaron Bertrand

@AaronBertrand Grazie, non sapevo di DEADLOCK_PRIORITY - Lo esaminerò. Abbiamo provato a rintracciare i deadlock, ma quelli si sono verificati in momenti apparentemente casuali, e solo una o due volte al giorno, e non sono mai riproducibili su richiesta: i nostri processi pianificati eseguono decine di migliaia di query ogni ora e la nostra app esegue centinaia di query ogni volta che carica una pagina o salva qualcosa e non abbiamo individuato quale query su entrambi i lati è coinvolta nel deadlock. Non avevo intenzione di lasciare NOLOCK lì per sempre, motivo per cui stiamo cercando soluzioni migliori a lungo termine.
wookie23,

1
Hai detto che stavi facendo fatica a rintracciare i deadlock. Dato che sei nel 2008 R2, potresti guardare qui: sqlservercentral.com/articles/deadlock/65658 Jonathan Kehayias ripercorre l'estrazione delle informazioni di deadlock dal buffer dell'anello.
Kenneth Fisher,

Le risposte e i commenti affrontano bene il problema di fondo, ma sei ancora interessato a trovare un modo per riprodurlo come esercizio intellettuale?
James L

Risposte:


8

Poiché un potenziale "aiuto di banda" ai problemi di NOLOCK è smettere di usare NOLOCK e iniziare a utilizzare l'isolamento READ_COMMITTED_SNAPSHOT, desidero indicarti il ​​post sul blog all'indirizzo http://www.brentozar.com di Kendra Little: Implementing Snapshot o Read Committed Isolamento dello snapshot in SQL Server: una guida .

Kendra fornisce una discreta quantità di dettagli su benefici e rischi con l'utilizzo del livello di isolamento READ_COMMITTED_SNAPSHOT.

  1. Questo livello di isolamento diventa il livello di isolamento predefinito per il codice del database.
  2. È necessario disporre di un solo utente nel database per apportare la modifica al livello di isolamento READ_COMMITTED_SNAPSHOT.
  3. Anche se si utilizza l'isolamento READ_COMMITTED_SNAPSHOT , sarà comunque necessario rimuovere i suggerimenti NOLOCK poiché sostituiscono quelli predefiniti.
  4. Alcuni dei tuoi codici potrebbero avere problemi che devono essere curati.

Alcuni anni fa abbiamo implementato l'isolamento READ_COMMITTED_SNAPSHOT su un database che soffriva gravemente di blocco . Ma una volta modificato il livello di isolamento, abbiamo iniziato a ottenere deadlock in un paio di aree critiche.

Perché è successo? Poiché il precedente livello di isolamento causava blocchi pesanti, il codice non poteva "mai" raggiungere il punto di blocco. Tuttavia, con l'isolamento READ_COMMITTED_SNAPSHOT, le query potrebbero continuare ad andare avanti. Tuttavia, una percentuale delle transazioni non più in attesa ha iniziato il deadlock.

Fortunatamente il nostro caso è stato risolto rapidamente determinando i punti di deadlock e regolando gli indici su un paio di tabelle per avere un ordine di colonna più razionale. Ciò ha notevolmente ridotto i nostri problemi di blocco.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.