sql >> Databasteknik >  >> RDS >> Database

Trimma mer transaktionsloggfett

I mitt tidigare inlägg om effektivisering av transaktionsloggen diskuterade jag två av de vanligaste orsakerna till att extra loggposter genereras:dödvikt från oanvända icke-klustrade index och siddelningsoperationer (som orsakar indexfragmentering). Förutsatt att du har läst det inlägget nämnde jag att det finns mer subtila problem som kan vara skadliga för transaktionsloggprestanda, och jag kommer att täcka dessa här.

Många, många små transaktioner

Då och då spolar SQL Server en del av transaktionsloggen till disken. En loggspolning inträffar närhelst:

  • En transaktionsbekräftelseloggpost genereras.
  • En transaktionsavbrottsloggpost genereras i slutet av en transaktionsåterställning.
  • 60 KB loggposter har genererats sedan föregående loggspolning.

Den minsta möjliga loggspolningen är ett enda 512-byte loggblock. Om alla transaktioner i en arbetsbelastning är mycket små (t.ex. att infoga en enda liten tabellrad) kommer det att förekomma massor av loggrensningar av minimal storlek. Loggspolningar utförs asynkront för att tillåta anständig transaktionslogggenomströmning, men det finns en fast gräns på 32 samtidiga log-flush I/O åt gången (höjt till 112 på SQL Server 2012).

Det finns två möjliga effekter som detta kan ha:

  1. På ett långsamt presterande I/O-undersystem kan volymen av små transaktionsloggskrivningar överväldiga I/O-undersystemet, vilket leder till skrivningar med hög latens och efterföljande försämring av transaktionsloggens genomströmning. Denna situation kan identifieras av högskrivna latenser för transaktionsloggfilen i utgången av sys.dm_io_virtual_file_stats (se demolänkarna överst i föregående inlägg)
  2. På ett högpresterande I/O-undersystem kan skrivningarna slutföras extremt snabbt, men gränsen på 32 samtidiga log-flush I/O skapar en flaskhals när man försöker göra loggposterna hållbara på disken. Denna situation kan identifieras av låga skrivfördröjningar och ett nästan konstant antal utestående transaktionsloggskrivningar nära 32 i den aggregerade utmatningen av sys.dm_io_pending_io_requests (se samma demolänkar).

I båda fallen kan att göra transaktioner längre (vilket är väldigt kontraintuitivt!) minska frekvensen av transaktionsloggspolningar och öka prestandan. Dessutom, i fall #1, kan flyttning till ett I/O-undersystem med högre prestanda hjälpa – men kan leda till fall #2. Med fall #2, om transaktionerna inte kan göras längre, är det enda alternativet att dela arbetsbelastningen över flera databaser för att komma runt den fasta gränsen på 32 samtidiga log-flush I/O eller uppgradera till SQL Server 2012 eller högre.

Automatisk tillväxt av transaktionslogg

Närhelst nytt utrymme läggs till i transaktionsloggen måste det nollinitieras (skriver ut nollor för att skriva över den tidigare användningen av den delen av disken), oavsett om funktionen för omedelbar filinitiering är aktiverad eller inte. Detta gäller skapande, manuell tillväxt och automatisk tillväxt av transaktionsloggen. Medan nollinitieringen äger rum, kan loggposter inte spolas till loggen, så automatisk tillväxt under en arbetsbelastning som ändrar data kan leda till en märkbar nedgång i genomströmningen, särskilt om storleken för automatisk tillväxt är inställd på att vara stor ( säg gigabyte, eller lämna på standardvärdet 10%).

Autotillväxt bör därför undvikas, om det alls är möjligt, genom att låta transaktionsloggen rensa så att det alltid finns ledigt utrymme som kan återanvändas för nya loggposter. Rensning av transaktionsloggar (även känd som trunkering av transaktionsloggar, inte att förväxla med transaktionsloggskrympning) utförs av säkerhetskopior av transaktionsloggar när du använder återställningslägena Full eller Bulk-loggad, och av kontrollpunkter när du använder det enkla återställningsläget.

Loggrensning kan endast ske om ingenting kräver att loggposterna i avsnittet i transaktionsloggen rensas. Ett vanligt problem som förhindrar loggrensning är att ha långa transaktioner. Tills en transaktion genomförs eller rullas tillbaka, krävs alla loggposter från början av transaktionen och framåt ifall transaktionen rullar tillbaka – inklusive alla loggposter från andra transaktioner som varvas med dem från den långvariga transaktionen. Långvariga transaktioner kan till exempel bero på dålig design, kod som väntar på mänsklig input eller felaktig användning av kapslade transaktioner. Alla dessa kan undvikas när de identifieras som ett problem.

Du kan läsa mer om detta här och här.

Högtillgänglighetsfunktioner

Vissa funktioner med hög tillgänglighet kan också fördröja rensningen av transaktionsloggen:

  • Databasspegling och tillgänglighetsgrupper när de körs asynkront kan bygga upp en kö av loggposter som ännu inte har skickats till den redundanta databaskopian. Dessa loggposter måste förvaras tills de skickas, vilket försenar rensningen av transaktionsloggen.
  • Transaktionsreplikering (och även Change Data Capture) är beroende av ett Log Reader Agent-jobb för att regelbundet skanna transaktionsloggen efter transaktioner som ändrar en tabell i en replikeringspublikation. Om Log Reader Agent hamnar på efterkälken av någon anledning, eller avsiktligt görs att köras sällan, måste alla loggposter som inte har skannats av jobbet hållas runt, vilket försenar rensningen av transaktionsloggen.

När du kör i synkront läge kan databasspegling och tillgänglighetsgrupper orsaka andra problem med loggningsmekanismen. Genom att använda synkron databasspegling som ett exempel kan alla transaktioner som genomförs på huvudmannen faktiskt inte återvända till användaren eller applikationen förrän alla loggposter som den genererade har skickats till spegelservern, vilket lägger till en fördröjning av uppdraget på huvudmannen. Om den genomsnittliga transaktionsstorleken är lång, och fördröjningen är kort, kanske detta inte märks, men om den genomsnittliga transaktionen är mycket kort, och förseningen är ganska lång, kan detta ha en märkbar effekt på arbetsbelastningen. I så fall måste antingen prestationsmålen för arbetsbelastningen ändras, högtillgänglighetstekniken ändras till asynkront läge, eller så måste nätverkets bandbredd och hastighet mellan de huvudsakliga och redundanta databaserna ökas.

För övrigt kan samma typ av problem uppstå om själva I/O-undersystemet speglas synkront – med en potentiell fördröjning för alla skrivningar som SQL Server utför.

Sammanfattning

Som du kan se handlar transaktionsloggprestanda inte bara om att extra transaktionsloggposter genereras – det finns många miljöfaktorer som också kan ha en djupgående effekt.

Summan av kardemumman är att transaktionsloggens hälsa och prestanda är av största vikt för att upprätthålla övergripande arbetsbelastningsprestanda. I dessa två inlägg har jag beskrivit de viktigaste orsakerna till problem med transaktionsloggprestanda så förhoppningsvis kommer du att kunna identifiera och åtgärda alla som du har.

Om du vill lära dig mycket mer om transaktionsloggoperationer och prestandajustering rekommenderar jag att du kollar in min 7,5 timmars onlinekurs om loggning, återställning och transaktionsloggen, tillgänglig via Pluralsight.


  1. Konfigurera AlwaysOn Availability Groups på SQL Server

  2. Varför misslyckas min ODBC-anslutning när jag kör en SSIS-laddning i Visual Studio men inte när jag kör samma paket med Execute Package Utility

  3. 2 sätt att se om föråldrade funktioner fortfarande används i en SQL Server-instans

  4. Introduktion till specialfrågor