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

Hvordan rydder du SQL Server-transaktionsloggen?

At gøre en logfil mindre bør virkelig være forbeholdt scenarier, hvor den stødte på uventet vækst, som du ikke forventer vil ske igen. Hvis logfilen vokser til samme størrelse igen, opnås der ikke ret meget ved at krympe den midlertidigt. Nu, afhængigt af gendannelsesmålene for din database, er disse handlinger, du skal tage.

Tag først en fuld sikkerhedskopi

Foretag aldrig ændringer i din database uden at sikre, at du kan gendanne den, hvis noget skulle gå galt.

Hvis du bekymrer dig om gendannelse på tidspunktet

(Og med punkt-i-tidsgendannelse mener jeg, at du bekymrer dig om at kunne gendanne til alt andet end en fuld eller differentiel sikkerhedskopi.)

Formentlig er din database i FULL Gendannelsestilstand. Hvis ikke, så sørg for at det er:

ALTER DATABASE testdb SET RECOVERY FULL;

Selvom du tager regelmæssige fuld backup, vil logfilen vokse og vokse, indtil du udfører en log backup - dette er for din beskyttelse, for ikke at unødigt tære på din diskplads. Du bør udføre disse log backups ret ofte i henhold til dine gendannelsesmål. For eksempel, hvis du har en forretningsregel, der siger, at du ikke har råd til at miste mere end 15 minutters data i tilfælde af en katastrofe, bør du have et job, der sikkerhedskopierer loggen hvert 15. minut. Her er et script, der vil generere tidsstemplede filnavne baseret på det aktuelle tidspunkt (men du kan også gøre dette med vedligeholdelsesplaner osv., vælg bare ikke nogen af ​​krympemulighederne i vedligeholdelsesplaner, de er forfærdelige).

DECLARE @path NVARCHAR(255) = N'\\backup_share\log\testdb_' 
  + CONVERT(CHAR(8), GETDATE(), 112) + '_'
  + REPLACE(CONVERT(CHAR(8), GETDATE(), 108),':','')
  + '.trn';

BACKUP LOG foo TO DISK = @path WITH INIT, COMPRESSION;

Bemærk, at \\backup_share\ skal være på en anden maskine, der repræsenterer en anden underliggende lagerenhed. At sikkerhedskopiere disse til den samme maskine (eller til en anden maskine, der bruger de samme underliggende diske, eller en anden VM, der er på den samme fysiske vært) hjælper dig ikke rigtigt, da hvis maskinen sprænger, har du mistet din database og dens sikkerhedskopier. Afhængigt af din netværksinfrastruktur kan det være mere fornuftigt at tage backup lokalt og derefter overføre dem til en anden placering bag kulisserne; i begge tilfælde ønsker du at få dem væk fra den primære databasemaskine så hurtigt som muligt.

Nu, når du har regelmæssige log-backups kørende, burde det være rimeligt at formindske logfilen til noget mere fornuftigt end hvad den er blæst op til nu. Dette gør ikke betyder at køre SHRINKFILE igen og igen, indtil logfilen er 1 MB - selvom du sikkerhedskopierer loggen ofte, skal den stadig rumme summen af ​​eventuelle samtidige transaktioner, der kan forekomme. Logfil autogrow hændelser er dyre, da SQL Server skal nulstille filerne (i modsætning til datafiler, når øjeblikkelig filinitialisering er aktiveret), og brugertransaktioner skal vente, mens dette sker. Du ønsker at gøre denne vækst-krymp-voks-krymp rutine så lidt som muligt, og du ønsker bestemt ikke at få dine brugere til at betale for det.

Bemærk, at du muligvis skal sikkerhedskopiere loggen to gange, før en shrink er mulig (tak Robert).

Så du skal finde på en praktisk størrelse til din logfil. Ingen her kan fortælle dig, hvad det er uden at vide meget mere om dit system, men hvis du ofte har formindsket logfilen, og den er vokset igen, er et godt vandmærke sandsynligvis 10-50 % højere end det største, det har været . Lad os sige, at det kommer til 200 MB, og du ønsker at eventuelle efterfølgende autovæksthændelser skal være 50 MB, så kan du justere logfilstørrelsen på denne måde:

USE [master];
GO
ALTER DATABASE Test1 
  MODIFY FILE
  (NAME = yourdb_log, SIZE = 200MB, FILEGROWTH = 50MB);
GO

Bemærk, at hvis logfilen i øjeblikket er> 200 MB, skal du muligvis køre denne først:

USE yourdb;
GO
DBCC SHRINKFILE(yourdb_log, 200);
GO

Hvis du er ligeglad med gendannelse på tidspunktet

Hvis dette er en testdatabase, og du er ligeglad med gendannelse på tidspunkter, så skal du sørge for, at din database er i SIMPLE gendannelsestilstand.

ALTER DATABASE testdb SET RECOVERY SIMPLE;

Sætter databasen i SIMPLE gendannelsestilstand sørger for, at SQL Server genbruger dele af logfilen (i det væsentlige udfaser inaktive transaktioner) i stedet for at vokse til at holde et register over alle transaktioner (som FULL gendannelse gør, indtil du sikkerhedskopierer loggen). CHECKPOINT hændelser hjælper med at kontrollere loggen og sørge for, at den ikke behøver at vokse, medmindre du genererer en masse t-log aktivitet mellem CHECKPOINT s.

Dernæst skal du være helt sikker på, at denne trævækst virkelig skyldtes en unormal begivenhed (f.eks. en årlig forårsrengøring eller genopbygning af dine største indekser), og ikke på grund af normal daglig brug. Hvis du formindsker logfilen til en latterlig lille størrelse, og SQL Server bare skal vokse den igen for at imødekomme din normale aktivitet, hvad fik du så? Var du i stand til at bruge den diskplads, du kun frigjorde midlertidigt? Hvis du har brug for en øjeblikkelig løsning, kan du køre følgende:

USE yourdb;
GO
CHECKPOINT;
GO
CHECKPOINT; -- run twice to ensure file wrap-around
GO
DBCC SHRINKFILE(yourdb_log, 200); -- unit is set in MBs
GO

Ellers skal du indstille en passende størrelse og væksthastighed. Som i eksemplet i punkt-i-tidsgendannelsessagen kan du bruge den samme kode og logik til at bestemme hvilken filstørrelse der er passende og indstille rimelige autovækstparametre.

Nogle ting, du ikke vil gøre

  • Sikkerhedskopier loggen med TRUNCATE_ONLY option og derefter SHRINKFILE . For det første denne TRUNCATE_ONLY optionen er blevet forældet og er ikke længere tilgængelig i aktuelle versioner af SQL Server. For det andet, hvis du er i FULL gendannelsesmodel, vil dette ødelægge din log-kæde og kræve en ny, fuld backup.

  • Fjern databasen, slet logfilen, og vedhæft igen . Jeg kan ikke understrege, hvor farligt det kan være. Din database kommer muligvis ikke op igen, den kan opstå som mistænkelig, du skal muligvis vende tilbage til en sikkerhedskopi (hvis du har en), osv. osv.

  • Brug muligheden "formindsk database" . DBCC SHRINKDATABASE og vedligeholdelsesplanen mulighed for at gøre det samme er dårlige ideer, især hvis du virkelig kun skal løse et logproblem. Målret den fil, du vil justere, og juster den uafhængigt ved hjælp af DBCC SHRINKFILE eller ALTER DATABASE ... MODIFY FILE (eksempler ovenfor).

  • Formindsk logfilen til 1 MB . Dette ser fristende ud, for hej, SQL Server vil lade mig gøre det i visse scenarier og se på al den plads, det frigiver! Medmindre din database er skrivebeskyttet (og det er den, bør du markere den som sådan med ALTER DATABASE ), vil dette absolut bare føre til mange unødvendige væksthændelser, da loggen skal rumme aktuelle transaktioner uanset genopretningsmodellen. Hvad er meningen med at frigøre den plads midlertidigt, bare så SQL Server kan tage den langsomt og smertefuldt tilbage?

  • Opret en anden logfil . Dette vil give midlertidig lindring for det drev, der har fyldt din disk, men det er som at prøve at reparere en punkteret lunge med et plaster. Du bør håndtere den problematiske logfil direkte i stedet for blot at tilføje et andet potentielt problem. Bortset fra at omdirigere noget transaktionslogaktivitet til et andet drev, gør en anden logfil virkelig intet for dig (i modsætning til en anden datafil), da kun én af filerne nogensinde kan bruges ad gangen. Paul Randal forklarer også, hvorfor flere logfiler kan bide dig senere.

Vær proaktiv

I stedet for at formindske din logfil til en lille mængde og lade den konstant autovokse med en lille hastighed af sig selv, skal du indstille den til en rimelig stor størrelse (en, der vil rumme summen af ​​dit største sæt af samtidige transaktioner) og indstille en rimelig autogrow indstilling som en fallback, så den ikke behøver at vokse flere gange for at tilfredsstille enkelte transaktioner, og så det vil være relativt sjælden, at den nogensinde skal vokse under normal forretningsdrift.

De værst tænkelige indstillinger her er 1 MB vækst eller 10 % vækst. Sjovt nok er disse standarder for SQL Server (som jeg har klaget over og bedt om ændringer uden nytte) - 1 MB for datafiler og 10% for logfiler. Førstnævnte er alt for lille i dag og alder, og sidstnævnte fører til længere og længere begivenheder hver gang (f.eks. din logfil er 500 MB, første vækst er 50 MB, næste vækst er 55 MB, næste vækst er 60,5 MB , osv. osv. - og på langsom I/O, tro mig, du vil virkelig bemærke denne kurve).

Yderligere læsning

Venligst stop ikke her; Mens mange af de råd, du ser derude om at krympe logfiler, i sagens natur er dårlige og endda potentielt katastrofale, er der nogle mennesker, der bekymrer sig mere om dataintegritet end at frigøre diskplads.

Et blogindlæg, jeg skrev i 2009, da jeg så et par "her er, hvordan du formindsker logfilen"-indlæg dukker op.

Et blogindlæg Brent Ozar skrev for fire år siden, der pegede på flere ressourcer, som svar på en SQL Server Magazine-artikel, der ikke burde er blevet offentliggjort.

Et blogindlæg af Paul Randal, der forklarer, hvorfor t-log vedligeholdelse er vigtigt, og hvorfor du heller ikke bør formindske dine datafiler.

Mike Walsh har et godt svar, der også dækker nogle af disse aspekter, inklusive årsager til, hvorfor du måske ikke er i stand til at formindske din logfil med det samme.



  1. Hvordan kan jeg se SQL-udførelsesplanen i Oracle?

  2. Microsoft Access DevCon i Wien Østrig 1. – 2. april 2017

  3. Hvordan opretter man dummy-variable kolonner for tusindvis af kategorier i Google BigQuery?

  4. Skift adgangskoden til et SQL Server-login