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

SQL Server Transaction Log — Del 1

Hver SQL Server-database indeholder en eller flere transaktionslogfiler ud over datafiler. Logfiler registrerer alle transaktioner og databaseændringer foretaget af hver af dem.

Denne artikel fokuserer på transaktionsloggen, og hvordan SQL Server logger dataændringer for at bruge dataene til gendannelse af databasenedbrud.

Introduktion til SQL Server-transaktionslogfilen

Som vi husker, er hver transaktion "alt eller intet". Hvis en del af transaktionen mislykkes, mislykkes hele transaktionen, og databasetilstanden forbliver uændret.

SQL Server gemmer en registrering af hver transaktion udført på databasen i logfilen. Hvis en katastrofe medfører nedlukning af SQL Server, bruger den en transaktionslog til at gendanne databasen til en konsistent tilstand med dataintegritet.

Efter genstarten starter SQL Server nedbrudsgendannelsesprocessen. Den læser transaktionslogfilen for at sikre, at alle gyldige data er gemt i datafilerne, og ikke-forpligtede transaktioner rulles tilbage.

Under normal drift bruger SQL Server også transaktionsloggen. Oplysningerne i filen er nødvendige for at identificere, hvad SQL Server skal gøre, når en transaktion ruller tilbage på grund af enten en fejl eller en brugerspecificeret ROLLBACK-sætning.

Hvordan SQL Server bruger transaktionsloggen

Transaktionsloggen er en fysisk fil med udvidelsen LDF . SQL Server opretter den automatisk til enhver ny database sammen med den primære datafil (.MDF ) som gemmer databaseobjekterne og selve dataene.

Når T-SQL-koden ændrer et databaseobjekt eller de data, det indeholder, registreres detaljer om ændringen som en logpost i transaktionslogfilen.

Logposten indeholder oplysningerne om en specifik ændring, der er foretaget i databasen (f.eks. indsæt en enkelt række). Derfor vil vi have en række logposter til at beskrive virkningerne af en enkelt transaktion fuldt ud.

Transaktionslogarkitektur

Logsekvensnumre

En logpost har et unikt, automatisk stigende logsekvensnummer (LSN ), der giver os mulighed for at finde denne post i transaktionsloggen. LSN beskriver dataændringen og indeholder følgende information:

  • handlingen og den berørte række
  • den gamle og nye version af dataene
  • transaktionen, der udførte ændringen

LSN består af tre tal:

LSN =::

Hver datafilside har et LSN i sidehovedet, der identificerer den seneste logpost, hvis ændring afspejles på siden. Dette er afgørende for gendannelse af nedbrud.

Når nedbrudsgendannelsen kører, sammenligner den LSN'erne for logposter for forpligtede eller ikke-forpligtede transaktioner med LSN'er på datafilsider for at afgøre, om der skal gøres om eller fortryde på de pågældende logposter.

Når du opretter en database, er en god praksis at specificere størrelsen på transaktionsloggen . Hvis du ikke gør dette, vil SQL Server automatisk oprette transaktionsloggen med standardstørrelsen.

Standardstørrelsen af ​​transaktionsloggen af en ny database er den største af 0,5 MB eller 25 % af den samlede størrelse af alle datafiler, der er oprettet i den samme CREATE DATABASE-sætning.

Du skal være meget forsigtig, fordi nye dele af transaktionsloggen altid er nul-initialiseret . Hvis du har CREATE DATABASE-sætningen uden at angive logfilstørrelsen, og du f.eks. opretter en database på 1 TB, vil SQL Server oprette transaktionsloggen på 250 GB.

Da loggen skal nul-initialiseres, gør den ikke brug af den øjeblikkelige filinitialisering. Denne funktion blev tilføjet i SQL Server 2005 for at tillade, at datafilerne kan oprettes eller vokse næsten øjeblikkeligt.

Vi kan se, hvad der foregår, når vi OPRETTER DATABASE – nul-initialiseringen sker af vores log ved hjælp af sporingsflag 3004 som udskriver beskeder om nul-initialisering og sporingsflag 3605 der gør det muligt at udskrive disse logmeddelelser ved hjælp af sporingsflaget 3004.

Den følgende demo viser, hvordan du kan se logfilen nulstilles.

1. Udfør følgende script for at sikre, at vi ikke har en database kaldet DBTest2014

USE master;
GO
 
IF DATABASEPROPERTY(N'DBTest2014', N'Version')>0
  BEGIN
    ALTER DATABASE DBTest2014 SET SINGLE_USER
      WITH ROLLBACK IMMEDIATE;
    DROP DATABASE DBTest2014;
  END
GO
 

2. Aktiver sporingsflag for at se nul-initialisering

DBCC TRACEON (3605, 3004, -1); GO 3. Flush the error log EXEC sp_cycle_errorlog; GO

3. Opret en database

CREATE DATABASE DBTest2014 ON PRIMARY (
  NAME = N'DBTest2014',
  FILENAME = N'D:\DBTest2014_data.mdf')
LOG ON (
  NAME= N'DBTest2014_log',
  FILENAME= N'D:\DBTest2014_log.ldf',
  SIZE = 10MB,
  FILEGROWTH = 10 MB);
GO
 

4. Læs fejllogfilen

EXEC sys.xp_readerrorlog;
GO
 

Virtuelle logfiler

Transaktionsloggen er opdelt internt i en række bidder kaldet virtuelle logfiler (VLF'er ) for at forenkle styringen.

Når en transaktionslog oprettes, giver den et vist antal VLF'er. Nyoprettede VLF'er er inaktive og ubrugte. En aktiv VLF kan ikke genbruges, før den er gjort inaktiv ved logrydning.

Der er dog én undtagelse – den første VLF i en ny database er altid aktiv, fordi enhver transaktionslog skal have mindst én aktiv VLF.

Hver logfil har også en filoverskriftside hvilket tager 8KB i starten af ​​transaktionslogfilen. Filhovedsiden gemmer metadata om filen, såsom størrelse og indstillinger for automatisk vækst.

Antallet og størrelsen af ​​VLF'er i en ny del af transaktionsloggen bestemmes af SQL Server. Det er umuligt at konfigurere det.

Hvis den nyligt tilføjede størrelse er:

  • <1 MB er irrelevant for diskussion
  • <64 MB vil der være 4 nye VLF'er (hver 1/4 af vækststørrelsen)
  • 64 MB til 1 GB vil der være 8 nye VLF'er (hver 1/8 af vækststørrelsen)
  • > 1 GB vil der være 16 nye VLF'er (hver 1/16 af vækststørrelsen)

Dette gælder for den oprindeligt oprettede transaktionslog og for hver manuel eller automatisk vækst, der opstår. Når du kender formlen for det potentielle antal VLF'er og deres potentielle størrelse, hjælper det at styre loggen. For få eller for mange VLF'er kan forårsage ydeevneproblemer med transaktionslogoperationer.

VLF-sekvensnummer

Hver VLF har et sekvensnummer til entydigt at identificere VLF i transaktionsloggen. Sekvensnummeret stiger med én, hver gang logstyringssystemet aktiverer den næste VLF. Kæden af ​​sekvensnumrene giver det aktuelt aktive sæt af VLF'er.

Starten af ​​den aktive del af transaktionsloggen begynder med en VLF, der har det laveste sekvensnummer og stadig er aktiv. Inaktive VLF'er har sekvensnumre, men de er ikke en del af den aktive logdel.

Den aktive del af loggen har logposter, der af en eller anden grund kræves af SQL Server.

Når du først opretter en ny database, starter VLF-sekvensnumrene ikke ved 1. De starter med det højeste VLF-sekvensnummer, der er i modeldatabasens transaktionslog plus 1 . Det er umuligt at løbe tør for VLF-sekvensnumre. SQL Server har kode, der vil tvinge instansen til at lukke ned, hvis et VLF-sekvensnummer nogensinde ombrydes til nul (hvis det næste VLF-sekvensnummer er mindre end det forrige).

VLF og logblokke

Inden for VLF'er er der logblokke af varierende størrelse. Logblokkens minimumstørrelse er 512 bytes og logblokke vokser op til en maksimal størrelse på 60 KB . Størrelsen indstilles, når et af følgende tilfælde opstår:

  • En transaktion genererer en logpost for at afslutte afbrydelse af en transaktion
  • Logblokstørrelsen når 60 KB uden en transaktion, der begår eller afbryde

Der er logposter inde i en logblok (farvet på diagrammet). Logposter har også varierende størrelse. Diagrammet viser, at logposter fra flere samtidige transaktioner kan eksistere inden for samme logblok. Logposterne gemmes i den rækkefølge, der er skrevet på samme måde som en datasidefil.

Hver VLF indeholder en VLF-header med følgende information:

  • Om VLF er aktiv eller ej.
  • Logsekvensnummeret, da VLF blev oprettet.
  • De aktuelle paritetsbits for alle 512-byte blokke i VLF.

Paritetsbittene starter ved 64 for første gang i brug VLF. Hvis VLF bliver inaktivt, men yderligere genaktiveret, bliver paritetsbittene 128. Disse bruges under gendannelse af nedbrud.

Undersøgelse af transaktionslogoplysninger – DBCC LOGINFO

Den eneste måde at se på transaktionslogstrukturen er at bruge den udokumenterede DBCC LOGINFO kommando. Syntaksen for kommandoen er:

DBCC LOGINFO [({'dbname | dbid'})] 

Hvis du ikke angiver dbname og dbid , vil det dumpe dig logindholdet for den aktuelle database.

Resultatet er én række for hver VLF, der er i transaktionsloggen for den pågældende database. De returnerede felter er:

  • RecoveryUnitId — tilføjet i SQL Server 2012, men i øjeblikket ubrugt
  • FileId — transaktionslogfil-id i en database.
  • Filstørrelse — VLF-størrelse i bytes.
  • StartOffset — startforskydning af VLF i transaktionslogfilen, i bytes
  • FSeqNo — VLF-sekvensnummeret
  • Status — Om VLF er aktiv eller ej (0 =inaktiv, 2 =aktiv, 1 – bruges ikke)
  • Paritet — aktuelle paritetsbit (64 eller 128 eller 0, hvis VLF aldrig har været aktiv)
  • CreateLSN — LSN, da VLF blev oprettet (0 =VLF blev oprettet, da transaktionslogfilen oprindeligt blev oprettet). Alle andre VLF'er, der tilføjes efter den første oprettelse af transaktionslogfilen, vil have CreateLSN, der ikke er nul.

Vi kan udføre følgende kommando for DBTest2014 database, som vi har oprettet tidligere:

DBCC LOGINFO (N'DBTest2014');
GO
 

Se resultatet:

DBCC SQLPERF (LOGSPACE)

Den eneste måde i Transact-SQL at undersøge mængden af ​​den anvendte log er DBCC SQLPERF. Syntaksen for kommandoen er:

DBCC SQLPERF
(
     [ LOGSPACE ]
     |
          [ "sys.dm_os_latch_stats" , CLEAR ]
     |
     [ "sys.dm_os_wait_stats" , CLEAR ]
)
     [WITH NO_INFOMSGS ]
 

Kommandoen returnerer et resultatsæt med én række pr. database:

  • Databasenavn
  • Logstørrelse (MB)
  • Logplads brugt (%)
  • Status:altid sat til nul

I mit miljø er følgende kommando:

DBCC SQLPERF (LOGSPACE);
GO
 

Returnerer følgende resultat:

I den næste artikel skal vi undersøge logposter.


  1. SLET VS DROP i SQL

  2. Kører Total-Order By Date i SQLite

  3. mySQL længde- og breddegradsforespørgsel for andre rækker inden for x mile radius

  4. Kortlæg et PostGIS-geometripunktfelt med Hibernate on Spring Boot