sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server-transaktionsloggen, del 1:Grunderna i loggning

Under hela min karriär som dataproffs, både inom Microsoft och som konsult, har jag funnit att en av de mest missförstådda delarna av en SQL Server-databas är transaktionsloggen. Bristande kunskap om hur transaktionsloggen fungerar och behöver hanteras, eller bara enkla missuppfattningar, kan leda till alla typer av produktionsproblem, inklusive:

  • Transaktionsloggen växer utom kontroll och kan ta slut på utrymme
  • Prestandaproblem från upprepad krympning av transaktionsloggen
  • Prestandaproblem från ett problem som kallas VLF-fragmentering , som jag diskuterade i det här inlägget
  • Oförmågan att återställa till en önskad tidpunkt med säkerhetskopior av transaktionsloggar
  • Oförmågan att utföra en säkerhetskopiering av tail-log under katastrofåterställning (se här för en förklaring av tail-log backups)
  • Olika problem kring failovers och återställning av prestanda

Med det här inlägget startar jag en och annan serie om transaktionsloggen och hur den fungerar och bör hanteras, och jag kommer att beröra alla problemen ovan under dess gång. I det här inlägget kommer jag att förklara vad loggning är och varför det krävs.

Grundläggande terminologi kring loggning

När jag pratar om vilken mekanism som helst i SQL Server, upptäcker jag att det finns ett kyckling-och-ägg-problem där jag måste använda ett ord eller en fras innan jag har förklarat det. För att undvika det problemet i den här serien ska jag börja med att förklara lite terminologi som måste användas när man diskuterar loggning, och jag kommer att utveckla många av dessa termer allt eftersom serien fortskrider.

Transaktion, åtagande och återställande

En transaktion omfattar en ändring eller en uppsättning ändringar i en databas. Den har en definierad början och ett definierat slut. Början är när en BEGIN TRANSACTION-sats används, eller när SQL Server automatiskt startar en transaktion åt dig. Slutet kan vara en av fyra saker:

  • Transaktionen commit när en COMMIT TRANSACTION-sats exekveras
  • Transaktionen commit när SQL Server automatiskt commit transaktionen i fallet med en autocommit transaktion
  • Transaktionen återställs efter att en ROLLBACK TRANSACTION-sats har körts
  • Transaktionen återställs efter att ett problem uppstod och SQL Server återställde automatiskt transaktionen

När en transaktion genomförs slutförs de ändringar som transaktionen gjorde i databasen och är varaktiga i SQL Server-transaktionsloggen på disken. Observera att jag sa "i transaktionsloggen." De faktiska ändringarna av datafilsidorna i minnet skrivs *inte* till disken när transaktionen genomförs. De behöver inte göras hållbara i datafilerna eftersom ändringarna redan är hållbara i transaktionsloggen. Så småningom kommer datafilsidorna att skrivas till disken genom en kontrollpunktsoperation.

Omvänt, när en transaktion rullar tillbaka, finns inte längre dataändringarna som transaktionen gjorde i databasen. Det kommer fortfarande att finnas några fysiska ändringar i databasen, eftersom en återställning av en transaktion innebär att utföra fler ändringar, men du kan tänka dig att en återställd transaktion inte har påverkat data i databasen.

Kontrollpunkter och återställningsoperationer är ämnen värda sina egna inlägg, så jag kommer att förklara dem senare i serien.

Jag diskuterar dessa tre termer mycket mer ingående i handledningen Introduktion till SQL Server-transaktioner på SentryOne-bloggen.

Loggning, loggposter och SQL Server-transaktionsloggen

Loggning innebär helt enkelt att skapa en hållbar beskrivning av en ändring i en databas, nästan alltid i samband med en transaktion. När en ändring görs beskrivs ändringen i en loggpost. En loggpost har vanligtvis tillräckligt med information för att ändringen ska kunna spelas upp i databasen eller rullas tillbaka i databasen om det behövs.

Denna loggpost kommer initialt att finnas i minnet och kan skrivas till disk innan transaktionen genomförs, men måste definitivt skrivas till disk innan transaktionen kan slutföras, annars skulle transaktionen inte vara varaktig. Ett undantag från denna regel är när fördröjd hållbarhet funktionen är aktiverad, vilket Aaron Bertrand diskuterar i det här inlägget.

Loggposter lagras i transaktionsloggen (en eller flera loggfiler på disken), som har en något komplex intern arkitektur, och jag kommer att diskutera det och mycket mer på loggposter i nästa inlägg i serien.

Krashåterställning

En krasch är där SQL Server stängdes av oväntat och de olika ändrade databaserna inte kunde stängas av korrekt (se till att alla ändrade datafilsidor skrivs till disken och att databasen markeras som rent avstängd).

När SQL Server startar kontrollerar den alla databaser för att se om några inte har markerats som rent avstängda. Om den hittar en måste databasen gå igenom kraschåterställning. Detta säkerställer följande:

  • För alla transaktioner som utfördes före kraschen, se till att alla ändringar i transaktionen återspeglas i databasen (d.v.s. spela om transaktionen)
  • För alla transaktioner som inte begicks före kraschen, se till att inga av ändringarna i transaktionen återspeglas i databasen (d.v.s. återställ transaktionen)

Med andra ord, kraschåterställning gör en databas transaktionellt konsekvent när kraschen inträffade. Kraschåterställning används:

  • När SQL Server startar och hittar en databas som behöver återställas
  • Under en failover till en sekundär kopia av en databas
  • I slutet av en återställningssekvens som involverar säkerhetskopior (se här)

Kraschåterställning är en komplex process och kräver ytterligare några inlägg i serien innan jag kan förklara det på djupet.

Varför krävs loggning?

Det mest grundläggande skälet till loggning är att tillåta SQL Server-databasen att göra transaktioner hållbara, så att de kan återställas under kraschåterställning eller rullas tillbaka om det behövs under normala databasoperationer. Om det inte fanns någon loggning skulle en databas vara transaktionsmässigt inkonsekvent och möjligen strukturellt korrupt efter en krasch.

Utan loggning skulle en mängd andra funktioner i SQL Server dock inte vara möjliga, inklusive:

  • Datasäkerhetskopior som kan återställas konsekvent
  • SQL Server transaktionsloggsäkerhetskopior som kan användas under en återställningsoperation och för att implementera loggsändning
  • Replikering, som är beroende av att kunna hämta transaktioner från transaktionsloggen
  • Change Data Capture, som använder logläsaragenten för transaktionsreplikering för att hämta ändringar från transaktionsloggen
  • Databasspegling och tillgänglighetsgrupper, som är beroende av att skicka loggposter till sekundära kopior av databasen för uppspelning

SQL Server (och alla liknande databasservrar) använder vad som kallas skrivförut-loggning . Detta innebär att beskrivningarna av ändringar måste skrivas till disken innan själva ändringarna för att garantera möjligheten att krascha återställa en databas. Om en ändring skrevs till en datafil innan loggposterna som beskriver den, och SQL Server kraschade, skulle det inte finnas något sätt att veta vad som skulle återställas, och databasen skulle vara inkonsekvent. Denna beställning är oföränderlig, oavsett vilken isoleringsnivå, typ av transaktion eller om funktionen för fördröjd hållbarhet används. Logga poster först, datasidor senare.

Bara toppen av isberget

Som du kan se från det här inledande inlägget går en enorm mängd in i transaktionsloggen och loggning i en SQL Server-databas, och allt jag har gjort hittills är att definiera en terminologi på hög nivå och förklara varför loggning krävs. Jag hoppas att du vill följa med mig när jag förgrenar mig och går djupare när serien fortskrider!


  1. Gå med fyra bord som involverar LEFT JOIN utan dubbletter

  2. Anropa en lagrad procedur med parameter i c#

  3. Skillnaden mellan Inner join och Outer join i SQL

  4. indatafilen verkar vara en textformatdump. Använd psql