Det finns många anledningar till varför applikationer kan vara långsamma att svara, men om användare klagar på prestanda kan du ha att göra med ett dödläge i SQL Server. Lyckligtvis finns det sätt att identifiera och korrigera SQL Server-dödläge, och till och med förhindra att det påverkar applikationsprestanda negativt.
Dödläge för SQL Server är i grunden ett avstånd mellan två processer som konkurrerar om exklusiv åtkomst till samma resurs. Eftersom endast en process kan använda en resurs åt gången, saktar prestandan ner tills dödläget är löst.
Det finns två typer av SQL Server-låslägen att se upp för:konverteringslås och cykellås.
Deadlocks för konverteringslås uppstår när en tråd försöker konvertera ett lås från en exklusiv typ till en annan exklusiv typ men inte kan eftersom en annan tråd redan har ett delat lås på resursen som den första tråden försöker konvertera.
I SQL Server finns det tre typer av konverteringslås:
- Delat med avsikt exklusivt (SIX):Detta lås uppstår när en transaktion som har ett delat lås också har ett exklusivt lås på vissa sidor eller rader.
- Delad med avsiktsuppdatering (SIU):Detta lås uppstår när en transaktion som har ett delat lås också har några sidor eller rader låsta med ett uppdateringslås.
- Uppdatera med avsikt exklusiv (UIX):Detta lås uppstår när en transaktion som innehåller ett uppdateringslås också har ett exklusivt lås på vissa sidor eller rader.
Cykellås är SQL Server-låslägen som orsakas av två processer som tävlar om ett exklusivt lås på en resurs som är låst av den andra processen.
Till exempel håller process 1 ett lås på resurs 1 medan man väntar på att process 2 ska släppa sitt lås på resurs 2. Om process 2 håller ett lås på resurs 2 medan man väntar på att process 1 ska släppa resurs 1, har vi oss själva ett låst cykellås.
Hur diagnostiseras SQL Server dödläge
Dödläge för SQL Server är bara en av dussintals möjliga orsaker till att din applikation kan ha prestandaproblem. Om frågor som normalt körs snabbt plötsligt saktar ner, är det möjligt att du har ett dödläge. Men det är också möjligt att något annat är på gång.
Så, förutom att märka minskad frågehastighet, hur avgör du med säkerhet om dödläget är ansvarig för dina databasprestandaproblem?
Det enklaste och mest definitiva sättet att identifiera dödläge är närvaron av ett 1205-felmeddelande:
Transaktionen (Process ID %d) låstes på %.*ls resurser med en annan process och har valts som dödlägesoffer. Kör transaktionen igen.
1205-felmeddelandet berättar bokstavligen att det finns ett dödläge och hur man åtgärdar det. Men som Jeremiah Peschka påpekar, om du inte har åtgärdat orsaken till dödläget, kommer det förmodligen att misslyckas att köra transaktionen igen.
Ett annat alternativ för att hitta deadlocks är att dra en SQL Server-deadlock-graf från Extended Events. Genom att extrahera dödläget genom Extended Events kan du titta på deadlock-XML, som ger mer information än den grafiska representationen av en dödlägesgraf.
Deadlock XML organiseras av offerlistan, processlistan och resurslistan. Varje avsnitt ger detaljerade beskrivningar av offer, processer och resurser som är involverade i dödläget, vilket gör det lättare att felsöka och lösa problemet.
Hur man åtgärdar SQL Server-deadlock
Det enda sättet att lösa ett dödläge i SQL Server är att avsluta en av processerna och frigöra den låsta resursen så att processen kan slutföras. Detta sker automatiskt när SQL Server upptäcker ett dödläge och dödar en av de konkurrerande processerna (d.v.s. offret).
SQL Server väljer normalt vilken anslutning som ska dödas slumpmässigt, men det är möjligt att ställa in dödlägesprioriteter för att avgöra vilken anslutning som dödas under ett dödläge. När två anslutningar har olika prioritetsinställningar kommer SQL Server att döda transaktionen med lägst prioritet.
Hur man förhindrar att SQL Server låser sig
Dödläge för SQL Server är ett faktum när du hanterar en upptagen databas. Däremot kan DBA:er hjälpa till att minska förekomsten av dödlägen och minimera deras inverkan på databasens prestanda genom att vidta några förebyggande åtgärder:
- Skapa bättre index
- Justera transaktionsprioriteter
- Aktivera en försök/försök igen
- Ändra isoleringslägen
- Håll lås så kort tid som möjligt
- Åtkomst till resurser i samma ordning varje gång
- Skicka inte en transaktion förrän du har all information du behöver
- Begränsa låseskalering
Även om det inte är möjligt att helt förhindra SQL Server-dödläge, kan du implementera dessa bästa praxis och proaktivt kringgå några av de vanligaste källorna till dödläge för att hålla transaktionerna flytande och optimera databasprestanda.