sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server-transaktionsloggen, del 3:Grundlæggende logføring

I anden del af denne serie beskrev jeg det strukturelle hierarki i transaktionsloggen. Da dette indlæg hovedsageligt handler om de virtuelle logfiler (VLF'er), jeg beskrev, anbefaler jeg, at du læser anden del, før du fortsætter.

Når alt er godt, vil transaktionsloggen uendeligt løkke og genbruge de eksisterende VLF'er. Denne adfærd er, hvad jeg kalder loggens cirkulære natur . Nogle gange vil der dog ske noget for at forhindre dette, og transaktionsloggen vokser og vokser og tilføjer flere og flere VLF'er. I dette indlæg vil jeg forklare, hvordan alt dette fungerer, eller nogle gange ikke gør.

VLF'er og logafkortning

Alle VLF'er har en overskriftsstruktur, der indeholder metadata om VLF'en. Et af de vigtigste felter i strukturen er status for VLF, og de værdier, vi er interesserede i, er nul, hvilket betyder, at VLF er inaktiv , og to, hvilket betyder, at VLF er aktiv . Det er vigtigt, fordi en inaktiv VLF kan genbruges, men en aktiv kan ikke. Bemærk, at en VLF er helt aktiv eller helt inaktiv.

En VLF forbliver aktiv, mens de nødvendige logposter er i den, så den kan ikke genbruges og overskrives (jeg dækker selv logposter næste gang). Eksempler på årsager til, at logposter kan være påkrævet, omfatter:

  • Der er en langvarig transaktion, logposterne er en del af, så de kan ikke frigives, før transaktionen er forpligtet eller er færdig med at rulle tilbage
  • En logbackup har endnu ikke sikkerhedskopieret disse logposter
  • Den del af loggen er endnu ikke blevet behandlet af Log Reader Agent til transaktionsreplikering eller Change Data Capture
  • Den del af loggen er endnu ikke blevet sendt til et asynkront databasespejl eller en tilgængelighedsgruppereplik

Det er vigtigt at bemærke, at hvis der ikke er nogen grunde til, at en VLF forbliver aktiv, vil den ikke skifte til at være inaktiv igen, før en proces kaldet log trunkering forekommer – mere om dette nedenfor.

Ved at bruge en simpel hypotetisk transaktionslog med kun fem VLF'er og VLF-sekvensnumre, der starter ved 1 (husk fra sidste gang, at det i virkeligheden aldrig gør), når transaktionsloggen er oprettet, markeres VFL 1 med det samme som aktiv, da der altid har at være mindst én aktiv VLF i transaktionsloggen - den VLF, hvor der i øjeblikket skrives logblokke til. Vores eksempelscenarie er vist i figur 1 nedenfor.

Figur 1:Hypotetisk, helt ny transaktionslog med 5 VLF'er, sekvensnumre 1 til 5.

Efterhånden som der oprettes flere logposter, og flere logblokke skrives til transaktionsloggen, fyldes VLF 1, så VLF 2 skal blive aktiv for at der kan skrives flere logblokke til, som vist i figur 2 nedenfor.

Figur 2:Aktivitet bevæger sig gennem transaktionsloggen.

SQL Server sporer starten på den ældste ikke-forpligtede (aktive) transaktion, og denne LSN bevares på disken, hver gang en kontrolpunktsoperation finder sted. LSN for den seneste logpost, der er skrevet til transaktionsloggen, spores også, men den spores kun i hukommelsen, da der ikke er nogen måde at fortsætte på disken uden at løbe ind i forskellige raceforhold. Det betyder ikke noget, da det kun bruges under gendannelse af nedbrud, og SQL Server kan beregne LSN'et for "slutningen" af transaktionsloggen under gendannelse af nedbrud. Kontrolpunkter og gendannelse af nedbrud er emner for fremtidige indlæg i serien.

Til sidst vil VLF 2 blive fyldt op, og VLF 3 bliver aktiv, og så videre. Kernen i transaktionsloggens cirkulære karakter er, at tidligere VLF'er i transaktionsloggen bliver inaktive, så de kan genbruges. Dette gøres ved en proces kaldet log trunkering , som også almindeligvis kaldes log clearing . Desværre er begge disse udtryk forfærdelige fejlbetegnelser, fordi intet faktisk er afkortet eller slettet.

Logtrunkering er simpelthen processen med at undersøge alle VLF'er i transaktionsloggen og bestemme, hvilke aktive VLF'er nu kan markeres som inaktive igen, da intet af deres indhold stadig kræves af SQL Server. Når logtrunkering udføres, er der ingen garanti for, at aktive VLF'er kan gøres inaktive - det afhænger helt af, hvad der sker med databasen.

Der er to almindelige misforståelser om log-trunkering:

  1. Transaktionsloggen bliver mindre (fejlopfattelsen af ​​"trunkering"). Nej, det gør det ikke - der er ingen størrelsesændring fra logafskæring. Det eneste, der kan gøre transaktionsloggen mindre, er en eksplicit DBCC SHRINKFILE.
  2. De inaktive VLF'er nulstilles på en eller anden måde (den "rydde" misforståelse). Nej – intet skrives til VLF, når det gøres inaktivt bortset fra nogle få felter i VLF-headeren.

Figur 3 nedenfor viser vores transaktionslog, hvor VLF'er 3 og 4 er aktive, og log-trunkering var i stand til at markere VLF'er 1 og 2 inaktive.

Figur 3:Logafkortning markerer tidligere VLF'er som inaktive.

Hvornår logafkortning finder sted afhænger af, hvilken gendannelsesmodel der er i brug for databasen:

  • Simpel model:logafkortning forekommer, når en kontrolpunktsoperation er fuldført
  • Fuld model eller bulk-logget model:logafkortning opstår, når en logsikkerhedskopiering fuldføres (så længe der ikke kører en samtidig fuld eller differentiel sikkerhedskopiering, i hvilket tilfælde logafkortning udskydes, indtil sikkerhedskopieringen af ​​data er fuldført)

Der er ingen undtagelser fra dette.

Loftens cirkulære natur

For at undgå at transaktionsloggen skal vokse, skal logafkortning kunne markere VLF'er inaktive. Den første fysiske VLF i loggen skal være inaktiv, for at transaktionsloggen har sin cirkulære karakter.

Overvej figur 4 nedenfor, som viser, at VLF'er 4 og 5 er i brug, og log-trunkering har markeret VLF'er 1 til 3 som inaktive. Flere logposter genereres, flere logblokke skrives ind i VLF 5, og til sidst fyldes den op.

Figur 4:Aktivitet fylder den højeste fysiske VLF i transaktionsloggen.

På dette tidspunkt ser logmanageren for databasen på status for den første fysiske VLF i transaktionsloggen, som i vores eksempel er VLF 1, med sekvensnummer 1. VLF 1 er inaktiv, så transaktionsloggen kan ombrydes og begynde at fylde igen fra starten. Logmanageren ændrer den første VLF til aktiv og øger dens sekvensnummer til at være én højere end det nuværende højeste VLF-sekvensnummer. Så det bliver til VLF 6, og logningen fortsætter med, at logblok bliver skrevet ind i den VLF. Dette er loggens cirkulære karakter, som vist nedenfor i figur 5.

Figur 5:Den cirkulære karakter af transaktionsloggen og VLF-genbrug.

Når det går galt

Når den første fysiske VLF i transaktionsloggen ikke er inaktiv, kan transaktionsloggen ikke ombrydes, så den vil vokse (så længe den er konfigureret til at gøre det, og der er tilstrækkelig diskplads). Dette sker ofte, fordi der er noget, der forhindrer logtrunkering i at deaktivere VLF'er. Hvis du opdager, at transaktionsloggen for en database vokser, kan du forespørge SQL Server for at finde ud af, om der er et logafkortningsproblem ved at bruge denne enkle kode nedenfor:

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

Hvis logtrunkering var i stand til at deaktivere en eller flere VLF'er, så vil resultatet være INGENTING. Ellers , får du en grund til, hvorfor logafkortning ikke kunne deaktivere nogen VLF'er. Der er en lang liste af mulige årsager beskrevet her i afsnittet Faktorer, der kan forsinke logafkortning.

Det er vigtigt at forstå semantikken for, hvad resultatet er:det er årsagen til, at logafkortning ikke kunne gøre noget sidste gang den forsøgte at køre . For eksempel kan resultatet være ACTIVE_BACKUP_OR_RESTORE, men du ved, at den langvarige fuld backup er afsluttet. Dette betyder blot, at sidste gang logtrunkering blev forsøgt, kørte sikkerhedskopien stadig.

Efter min erfaring er den mest almindelige årsag til, at logtrunkering forhindres, LOG_BACKUP; dvs. udfør en log backup! Men der er også en interessant, mærkelig adfærd med LOG_BACKUP . Hvis du konstant ser resultatet LOG_BACKUP men du ved, at log backups sker med succes, det er fordi der er meget lidt aktivitet i databasen, og den aktuelle VLF er den samme, som den var sidste gang en log backup blev udført. Så LOG_BACKUP betyder "udfør en logbackup" eller "alle de sikkerhedskopierede logposter er fra den aktuelle VLF, så den kunne ikke deaktiveres." Når det sidste sker, kan det være forvirrende.

Runder tilbage...

Det er meget vigtigt at opretholde den cirkulære karakter af transaktionsloggen for at undgå dyre logvækster og behovet for at træffe korrigerende handlinger. Normalt betyder det, at der skal sikres log backups regelmæssigt for at lette logafkortning og dimensionere transaktionsloggen, så den er i stand til at holde store, langvarige operationer som indeksgenopbygninger eller ETL-operationer uden logvækst.

I den næste del af serien vil jeg dække logposter, hvordan de fungerer og nogle interessante eksempler.


  1. Kører ProxySQL som Kubernetes Service

  2. Sådan fungerer TO_SECONDS() i MariaDB

  3. PostgreSQL-mod:Hvad er "resjunk"?

  4. Hybrid OLTP/Analytics Database Workloads i Galera Cluster ved hjælp af asynkrone slaver