Gennem hele min karriere som dataprofessionel, både i Microsoft og som konsulent, har jeg fundet ud af, at en af de mest misforståede dele af en SQL Server-database er transaktionsloggen. Manglende viden om, hvordan transaktionsloggen fungerer og skal administreres, eller blot simple misforståelser, kan føre til alle slags produktionsproblemer, herunder:
- Transaktionsloggen vokser ude af kontrol og løber muligvis tør for plads
- Ydeevneproblemer fra gentagne formindskelser af transaktionsloggen
- Ydeevneproblemer fra et problem kendt som VLF-fragmentering , som jeg diskuterede i dette indlæg
- Den manglende evne til at gendanne til et ønsket tidspunkt ved hjælp af sikkerhedskopiering af transaktionslog
- Den manglende evne til at udføre en tail-log backup under katastrofegendannelse (se her for en forklaring af tail-log backups)
- Forskellige problemer omkring failovers og gendannelse af ydeevne
Med dette indlæg starter jeg en lejlighedsvis serie om transaktionsloggen, og hvordan den fungerer og skal administreres, og jeg vil komme ind på alle problemerne ovenfor i løbet af dets forløb. I dette indlæg vil jeg forklare, hvad logning er, og hvorfor det er påkrævet.
Grundlæggende terminologi omkring logning
Når jeg taler om enhver mekanisme i SQL Server, finder jeg ud af, at der er et kylling-og-æg-problem, hvor jeg skal bruge et ord eller en sætning, før jeg har forklaret det. For at undgå det problem i denne serie vil jeg starte med at forklare noget terminologi, der skal bruges, når man diskuterer logning, og jeg vil uddybe mange af disse udtryk, efterhånden som serien skrider frem.
Transaktion, Commit og Rollback
En transaktion omfatter en ændring eller et sæt ændringer af en database. Den har en defineret begyndelse og en defineret slutning. Begyndelsen er, når en BEGIN TRANSACTION-sætning bruges, eller SQL Server automatisk starter en transaktion for dig. Slutningen kan være en af fire ting:
- Transaktionen forpligtes, når en COMMIT TRANSACTION-sætning udføres
- Transaktionen commit, når SQL Server automatisk commit transaktionen i tilfælde af en autocommit transaktion
- Transaktionen afsluttes med at rulle tilbage, efter at en ROLLBACK TRANSACTION-sætning er udført
- Transaktionen afsluttes med at rulle tilbage efter et problem opstod, og SQL Server rullede automatisk transaktionen tilbage
Når en transaktion forpligtes, afsluttes de ændringer, som transaktionen har foretaget, i databasen og er holdbare i SQL Server-transaktionslog på disken. Bemærk, at jeg sagde "i transaktionsloggen." De faktiske ændringer af datafilsiderne i hukommelsen bliver *ikke* skrevet til disken, når transaktionen forpligtes. De behøver ikke at blive gjort holdbare i datafilerne, fordi ændringerne allerede er holdbare i transaktionsloggen. Til sidst vil datafilsiderne blive skrevet til disk ved en kontrolpunktoperation.
Omvendt, når en transaktion ruller tilbage, er de dataændringer, som transaktionen har foretaget, ikke længere til stede i databasen. Der vil stadig være nogle fysiske ændringer i databasen, da tilbagerulning af en transaktion betyder at udføre flere ændringer, men du kan tænke på, at en tilbageført transaktion ikke har påvirket dataene i databasen.
Kontrolpunkter og tilbagerulningsoperationer er emner, der fortjener deres egne indlæg, så jeg vil forklare dem senere i serien.
Jeg diskuterer disse tre udtryk meget mere i dybden i selvstudiet Introduktion til SQL Server-transaktioner på SentryOne-bloggen.
Logføring, logposter og SQL Server-transaktionsloggen
Logning betyder simpelthen at skabe en holdbar beskrivelse af en ændring i en database, næsten altid i forbindelse med en transaktion. Når der foretages en ændring, beskrives ændringen i en logpost. En logpost har normalt nok information til, at ændringen kan afspilles igen i databasen eller rulles tilbage i databasen, hvis det er nødvendigt.
Denne logpost vil i første omgang være i hukommelsen og kan skrives til disken, før transaktionen forpligtes, men skal absolut skrives til disken før transaktionen kan afslutte forpligtelsen, ellers ville transaktionen ikke være holdbar. En undtagelse fra denne regel er, når den forsinkede holdbarhed funktion er aktiveret, hvilket Aaron Bertrand diskuterer i dette indlæg.
Logposter gemmes i transaktionsloggen (en eller flere logfiler på disken), som har en noget kompleks intern arkitektur, og det vil jeg diskutere og meget mere på logposter i næste indlæg i serien.
Gendannelse af nedbrud
Et nedbrud er, hvor SQL Server lukker uventet ned, og de forskellige ændrede databaser ikke var i stand til at blive lukket korrekt ned (sørg for, at alle ændrede datafilsider er skrevet til disken, og databasen er markeret som renlukket).
Når SQL Server starter op, tjekker den alle databaser for at se, om nogen ikke er markeret som renlukket. Hvis den finder en, skal databasen gennemgå nedbrudsgendannelse. Dette sikrer følgende:
- For enhver transaktion, der blev begået før nedbruddet, skal du sikre dig, at alle ændringerne i transaktionen afspejles i databasen (dvs. genafspil transaktionen)
- For enhver transaktion, der ikke blev begået før nedbruddet, skal du sikre dig, at ingen af ændringerne i transaktionen afspejles i databasen (dvs. rulle transaktionen tilbage)
Med andre ord gør nedbrudsgendannelse en database transaktionelt konsistent på det tidspunkt, hvor styrtet indtraf. Gendannelse af nedbrud bruges:
- Når SQL Server starter og finder en database, der skal gendannes
- Under en failover til en sekundær kopi af en database
- I slutningen af en gendannelsessekvens, der involverer sikkerhedskopier (se her)
Gendannelse af nedbrud er en kompleks proces og kræver endnu et par indlæg i serien, før jeg kan forklare det i dybden.
Hvorfor er logning påkrævet?
Den mest grundlæggende årsag til logning er at tillade SQL Server-databasen at gøre transaktioner holdbare, så de kan gendannes under nedbrudsgendannelse eller rulles tilbage, hvis det er nødvendigt under normale databaseoperationer. Hvis der ikke var nogen logning, ville en database være transaktionsmæssigt inkonsekvent og muligvis strukturelt korrupt efter et nedbrud.
Uden logning ville et væld af andre funktioner i SQL Server dog ikke være mulige, herunder:
- Datasikkerhedskopier, der kan gendannes konsekvent
- SQL Server-transaktionslog-sikkerhedskopier, der kan bruges under en gendannelsesoperation og til at implementere logforsendelse
- Replikering, som er afhængig af at kunne høste transaktioner fra transaktionsloggen
- Change Data Capture, som bruger loglæseragenten for transaktionsreplikering til at hente ændringer fra transaktionsloggen
- Databasespejling og tilgængelighedsgrupper, som er afhængige af at sende logposter til sekundære kopier af databasen til genafspilning
SQL Server (og alle lignende databaseservere) bruger det, der kaldes fremskrivningslogning . Dette betyder, at beskrivelserne af ændringer skal skrives til disken før selve ændringerne for at garantere muligheden for korrekt at nedbryde en database. Hvis en ændring blev skrevet til en datafil, før logposterne, der beskriver den, og SQL Server gik ned, ville der ikke være nogen måde at vide, hvad der skulle rulles tilbage, og databasen ville være inkonsekvent. Denne bestilling er invariant, uanset hvilket isolationsniveau, transaktionstype, eller om funktionen for forsinket holdbarhed bruges. Log registrerer først, datasider senere.
Kun toppen af isbjerget
Som du kan se fra dette indledende indlæg, går et enormt beløb ind i transaktionsloggen og logningen i en SQL Server-database, og alt, hvad jeg har gjort indtil videre, er at definere en terminologi på højt niveau og forklare, hvorfor logning er påkrævet. Jeg håber, du vil slutte dig til mig, mens jeg forgrener mig og går dybere, efterhånden som serien skrider frem!