sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server-transaktionsloggen, del 3:Grunderna i loggning

I den andra delen av denna serie beskrev jag transaktionsloggens strukturella hierarki. Eftersom det här inlägget främst handlar om de virtuella loggfilerna (VLF) som jag beskrev, rekommenderar jag att du läser den andra delen innan du fortsätter.

När allt är bra kommer transaktionsloggen oändligt att loopa och återanvända de befintliga VLF:erna. Detta beteende är vad jag kallar loggens cirkulära natur . Ibland händer det dock något för att förhindra detta, och transaktionsloggen växer och växer och lägger till fler och fler VLF:er. I det här inlägget kommer jag att förklara hur allt detta fungerar, eller ibland inte gör det.

VLF:er och loggavkortning

Alla VLF har en rubrikstruktur som innehåller metadata om VLF. Ett av de viktigaste fälten i strukturen är statusen för VLF, och värdena vi är intresserade av är noll, vilket betyder att VLF är inaktiv , och två, vilket betyder att VLF är aktiv . Det är viktigt eftersom en inaktiv VLF kan återanvändas, men en aktiv kan inte. Observera att en VLF är helt aktiv eller helt inaktiv.

En VLF förblir aktiv medan nödvändiga loggposter finns i den, så den kan inte återanvändas och skrivas över (jag kommer att täcka själva loggposterna nästa gång). Exempel på skäl till varför loggposter kan krävas är:

  • Det finns en långvarig transaktion som loggposterna är en del av, så de kan inte släppas förrän transaktionen har genomförts eller har återställts färdigt
  • En loggsäkerhetskopiering har ännu inte säkerhetskopierat dessa loggposter
  • Den delen av loggen har ännu inte bearbetats av Log Reader Agent för transaktionsreplikering eller Change Data Capture
  • Den delen av loggen har ännu inte skickats till en asynkron databasspegel eller tillgänglighetsgruppreplik

Det är viktigt att notera att om det inte finns några skäl för en VLF att förbli aktiv, kommer den inte att övergå till att vara inaktiv igen förrän en process som kallas loggavkortning inträffar – mer om detta nedan.

Genom att använda en enkel hypotetisk transaktionslogg med endast fem VLF:er och VLF-sekvensnummer som börjar på 1 (kom ihåg från förra gången att de i verkligheten aldrig gör det), när transaktionsloggen skapas, markeras VFL 1 omedelbart som aktiv, eftersom det alltid har gjorts. att vara minst en aktiv VLF i transaktionsloggen – den VLF dit loggblock för närvarande skrivs till. Vårt exempelscenario visas i figur 1 nedan.

Figur 1:Hypotetisk, helt ny transaktionslogg med 5 VLF:er, sekvensnummer 1 till 5.

När fler loggposter skapas och fler loggblock skrivs till transaktionsloggen, fylls VLF 1 upp, så VLF 2 måste bli aktiv för att fler loggblock ska kunna skrivas till, som visas i figur 2 nedan.

Figur 2:Aktiviteten flyttas genom transaktionsloggen.

SQL Server spårar starten av den äldsta oengagerade (aktiva) transaktionen, och denna LSN finns kvar på disken varje gång en kontrollpunktsoperation inträffar. LSN för den senaste loggposten som skrivits till transaktionsloggen spåras också, men den spåras bara i minnet eftersom det inte finns något sätt att bevara disken utan att råka ut för olika tävlingsförhållanden. Det spelar ingen roll eftersom det bara används under kraschåterställning, och SQL Server kan räkna ut LSN för "slutet" av transaktionsloggen under kraschåterställning. Kontrollpunkter och kraschåterställning är ämnen för framtida inlägg i serien.

Så småningom kommer VLF 2 att fyllas, och VLF 3 kommer att bli aktiv, och så vidare. Kärnan i transaktionsloggens cirkulära karaktär är att tidigare VLF:er i transaktionsloggen blir inaktiva så att de kan återanvändas. Detta görs genom en process som kallas loggavkortning , som också brukar kallas loggrensning . Tyvärr är båda dessa termer fruktansvärda felaktiga benämningar eftersom ingenting faktiskt är trunkerat eller rensat.

Loggtrunkering är helt enkelt processen att undersöka alla VLF:er i transaktionsloggen och bestämma vilka aktiva VLF:er som nu kan markeras som inaktiva igen, eftersom inget av deras innehåll fortfarande krävs av SQL Server. När loggavkortning utförs finns det ingen garanti för att aktiva VLF:er kan göras inaktiva – det beror helt på vad som händer med databasen.

Det finns två vanliga missuppfattningar om loggavkortning:

  1. Transaktionsloggen blir mindre (missuppfattningen "trunkering"). Nej, det gör det inte – det finns ingen storleksändring från stocktynkering. Det enda som kan göra transaktionsloggen mindre är en explicit DBCC SHRINKFILE.
  2. De inaktiva VLF:erna nollställs på något sätt (den "rensande" missuppfattningen). Nej – ingenting skrivs till VLF när den görs inaktiv förutom några få fält i VLF-huvudet.

Figur 3 nedan visar vår transaktionslogg där VLF 3 och 4 är aktiva och loggavkortning kunde markera VLF 1 och 2 inaktiva.

Figur 3:Loggavkortning markerar tidigare VLF:er som inaktiva.

När loggavkortning inträffar beror på vilken återställningsmodell som används för databasen:

  • Enkel modell:loggavkortning inträffar när en kontrollpunktsoperation slutförs
  • Fullständig modell eller bulkloggad modell:loggavkortning inträffar när en loggsäkerhetskopiering slutförs (så länge det inte pågår en samtidig fullständig eller differentiell säkerhetskopiering, i vilket fall loggtrunkering skjuts upp tills säkerhetskopieringen av data är klar)

Det finns inga undantag från detta.

Loggens cirkulära karaktär

För att undvika att transaktionsloggen måste växa måste loggtrunkering kunna markera VLF:er inaktiva. Den första fysiska VLF i loggen måste vara inaktiv för att transaktionsloggen ska ha sin cirkulära karaktär.

Betrakta figur 4 nedan, som visar att VLF 4 och 5 används och loggavkortning har markerat VLF 1 till 3 som inaktiva. Fler loggposter genereras, fler loggblock skrivs in i VLF 5 och så småningom fylls den upp.

Figur 4:Aktiviteten fyller upp den högsta fysiska VLF i transaktionsloggen.

Vid det här laget tittar logghanteraren för databasen på statusen för den första fysiska VLF i transaktionsloggen, som i vårt exempel är VLF 1, med sekvensnummer 1. VLF 1 är inaktiv, så transaktionsloggen kan lindas runt och börja fylla igen från början. Logghanteraren ändrar den första VLF till aktiv och ökar dess sekvensnummer till ett högre än det nuvarande högsta VLF-sekvensnumret. Så det blir VLF 6, och loggning fortsätter med loggblock som skrivs in i den VLF. Detta är stockens cirkulära karaktär, som visas nedan i figur 5.

Figur 5:Transaktionsloggens cirkulära karaktär och VLF-återanvändning.

När det går fel

När den första fysiska VLF:en i transaktionsloggen inte är inaktiv kan transaktionsloggen inte lindas runt, så den kommer att växa (så länge den är konfigurerad för att göra det och det finns tillräckligt med diskutrymme). Detta händer ofta för att det finns något som hindrar loggtrunkering från att inaktivera VLF:er. Om du upptäcker att transaktionsloggen för en databas växer kan du fråga SQL Server för att ta reda på om det finns ett problem med loggavkortning med den här enkla koden nedan:

SELECT
      [log_reuse_wait_desc]
  FROM [master].[sys].[databases]
  WHERE [name] = N'MyDatabase';

Om loggtrunkering kunde inaktivera en eller flera VLF:er, blir resultatet INGENTING. Annars , får du en anledning till varför loggtrunkering inte kunde inaktivera några VLF:er. Det finns en lång lista med möjliga orsaker som beskrivs här i avsnittet Faktorer som kan fördröja trunkering av logg.

Det är viktigt att förstå semantiken för vad resultatet är:det är anledningen till att loggavkortning inte kunde göra någonting förra gången den försökte köras . Till exempel kan resultatet bli ACTIVE_BACKUP_OR_RESTORE, men du vet att den långvariga fullständiga säkerhetskopieringen är klar. Detta betyder bara att förra gången loggavkortning försökte köras backupen fortfarande.

Enligt min erfarenhet är den vanligaste orsaken till att loggavkortning förhindras LOG_BACKUP; d.v.s. gör en säkerhetskopiering av loggen! Men det finns också ett intressant, konstigt beteende med LOG_BACKUP . Om du kontinuerligt ser resultatet LOG_BACKUP men du vet att loggsäkerhetskopiering sker framgångsrikt, det beror på att det finns väldigt lite aktivitet i databasen och den aktuella VLF är densamma som den var förra gången en loggsäkerhetskopiering utfördes. Så, LOG_BACKUP betyder "gör en loggsäkerhetskopiering" eller "alla loggposter som säkerhetskopierats är från den aktuella VLF, så den kunde inte avaktiveras." När det senare händer kan det vara förvirrande.

Ring tillbaka...

Att bibehålla transaktionsloggens cirkulära karaktär är mycket viktigt för att undvika kostsamma stocktillväxter och behovet av att vidta korrigerande åtgärder. Vanligtvis innebär detta att man säkerställer att loggsäkerhetskopiering sker regelbundet för att underlätta trunkering av logg och storleksanpassa transaktionsloggen för att kunna hålla alla stora, långvariga operationer som indexombyggnader eller ETL-operationer utan att loggtillväxt inträffar.

I nästa del av serien kommer jag att täcka loggposter, hur de fungerar och några intressanta exempel.


  1. Vad är MySQL-radordning för SELECT * FROM table_name;?

  2. Hantering av frödata i R12.2 online patchning

  3. Korrekt användning av transaktioner i SQL Server

  4. pgadmin4 :postgresql applikationsserver kunde inte kontaktas.