Causa di un processo che è vittima di un deadlock


105

Ho un processo con una selezione che richiede molto tempo per terminare, nell'ordine da 5 a 10 minuti.
Al momento non sto utilizzando NOLOCK come suggerimento per il motore di database MS SQL.
Allo stesso tempo abbiamo un altro processo che esegue aggiornamenti e inserimenti nello stesso database e nelle stesse tabelle.
Il primo processo è iniziato, recentemente terminato prematuramente con un messaggio

SQLEXCEPTION: la transazione è stata bloccata sulle risorse di blocco con un altro processo ed è stata scelta come vittima del deadlock.

Questo primo processo è in esecuzione su altri siti in condizioni identiche ma con database più piccoli e quindi l'istruzione select in questione richiede un periodo di tempo molto più breve (dell'ordine di 30 secondi circa). In questi altri siti, non ricevo il messaggio di deadlock in questi altri siti. Inoltre, non ho ricevuto questo messaggio sul sito che presenta il problema inizialmente, ma, presumo, poiché il database è cresciuto, credo di aver superato una certa soglia. Ecco le mie domande:

  1. Il tempo necessario per l'esecuzione di una transazione potrebbe aumentare le probabilità che il processo associato venga contrassegnato come vittima di deadlock.
  2. Se eseguo la selezione con un suggerimento NOLOCK, questo rimuoverà il problema?
  3. Sospetto che un campo datetime controllato come parte della clausola WHERE nell'istruzione select stia causando il tempo di ricerca lento. Posso creare un indice basato su questo campo? È consigliabile?

Risposta parziale al punto 1: non confondere un deadlock con un timeout. Se stavi subendo un timeout, il tempo necessario per concludere una transazione potrebbe essere responsabile dell'arresto anomalo dell'altra. Inoltre, sarebbe utile sapere su quale risorsa stai bloccando (è un indice o una tabella?).
NealB

1
SET DEADLOCK_PRIORITY HIGH ALTER DATABASE dbname SET MULTI_USER;
gstackoverflow

Risposte:


128

D1: Il tempo necessario per l'esecuzione di una transazione potrebbe aumentare le probabilità che il processo associato venga contrassegnato come vittima di deadlock.

No. Il SELECT è la vittima perché aveva solo i dati letti, quindi la transazione ha un costo inferiore ad essa associato quindi viene scelta come vittima:

Per impostazione predefinita, il Motore di database sceglie come vittima del deadlock la sessione che esegue la transazione meno costosa da ripristinare . In alternativa, un utente può specificare la priorità delle sessioni in una situazione di deadlock utilizzando l' SET DEADLOCK_PRIORITYistruzione. DEADLOCK_PRIORITY può essere impostato su LOW, NORMAL o HIGH o, in alternativa, può essere impostato su qualsiasi valore intero compreso nell'intervallo (da -10 a 10).

Q2. Se eseguo la selezione con un suggerimento NOLOCK, questo rimuoverà il problema?

No. Per diversi motivi:

Q3. Sospetto che un campo datetime controllato come parte della clausola WHERE nell'istruzione select stia causando il tempo di ricerca lento. Posso creare un indice basato su questo campo? È consigliabile?

Probabilmente. La causa del deadlock è quasi molto probabile che sia un database scarsamente indicizzato. Le query di 10 minuti sono accettabili in condizioni così ristrette, che sono sicuro al 100% nel tuo caso non sono accettabili.

Con una sicurezza del 99% dichiaro che il tuo deadlock è causato da una grande scansione della tabella in conflitto con gli aggiornamenti. Inizia catturando il grafico del deadlock per analizzare la causa. Molto probabilmente dovrai ottimizzare lo schema del tuo database. Prima di apportare qualsiasi modifica, leggere questo argomento Progettazione di indici e sotto-articoli.


Grazie per la tua risposta esauriente. Credo di avere ancora una domanda però. Perché dovrei ottenere la situazione di stallo solo in un ambiente e non in un altro. Anche se il software è lo stesso. La tua risposta suggerisce che il tempo necessario per eseguire la query di selezione non fa differenza ed è il fatto che è una query di selezione di per sé a causare il fallimento del processo. Ma allora, perché solo quando l'esecuzione della query di selezione richiede molto tempo?
Elliott

4
La lunghezza della query non fa differenza nella scelta della vittima del deadlock . Fa la differenza nel causare il deadlock da almeno due fattori: 1) probabilità semplici. Più lunga è la query, più è probabile che si sovrappongano aggiornamenti simultanei e si verifichino deadlock. 2) una tabella più grande può utilizzare un piano di query completamente diverso, suscettibile di deadlock.
Remus Rusanu

12

Ecco come si è verificato effettivamente questo particolare problema di deadlock e come è stato effettivamente risolto. Questo è un database abbastanza attivo con 130.000 transazioni che si verificano ogni giorno. Gli indici nelle tabelle di questo database erano originariamente raggruppati. Il cliente ci ha chiesto di rendere gli indici non cluster. Non appena lo abbiamo fatto, è iniziato il deadlock. Quando abbiamo ristabilito gli indici come cluster, il deadlock si è interrotto.


34
Qualcuno può spiegare perché? (Le soluzioni magiche non sono molto utili)
OGrandeDiEnne

1
Questo ragazzo lo spiega nel suo post: mssqltips.com/sqlservertip/2517/…
siga0984

6

Vale la pena provare le risposte qui, ma dovresti anche rivedere il tuo codice. In particolare, leggi la risposta di Polyfun qui: Come sbarazzarsi del deadlock in un'applicazione SQL Server 2005 e C #?

Spiega il problema della concorrenza e come l'uso di "with (updlock)" nelle tue query potrebbe correggere la tua situazione di deadlock, a seconda di ciò che sta facendo il tuo codice. Se il tuo codice segue questo schema, questa è probabilmente una soluzione migliore da fare, prima di ricorrere a letture sporche, ecc.


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.