sql >> Databasteknik >  >> RDS >> Sqlserver

Hur rensar du SQL Server-transaktionsloggen?

Att göra en loggfil mindre bör verkligen vara reserverad för scenarier där den stötte på oväntad tillväxt som du inte förväntar dig ska hända igen. Om loggfilen kommer att växa till samma storlek igen, uppnås inte särskilt mycket genom att tillfälligt krympa den. Nu, beroende på återställningsmålen för din databas, är dessa åtgärder du bör vidta.

Ta först en fullständig säkerhetskopia

Gör aldrig några ändringar i din databas utan att se till att du kan återställa den om något skulle gå fel.

Om du bryr dig om punkt-i-tid återställning

(Och med punkt-i-tid återställning menar jag att du bryr dig om att kunna återställa till något annat än en fullständig eller differentiell säkerhetskopia.)

Förmodligen är din databas i FULL återställningsläge. Om inte, se till att det är:

ALTER DATABASE testdb SET RECOVERY FULL;

Även om du tar regelbundna fullständiga säkerhetskopior kommer loggfilen att växa och växa tills du utför en logg backup - detta är för ditt skydd, för att inte i onödan äta upp ditt diskutrymme. Du bör utföra dessa loggsäkerhetskopior ganska ofta, enligt dina återställningsmål. Om du till exempel har en affärsregel som säger att du inte har råd att förlora mer än 15 minuters data i händelse av en katastrof, bör du ha ett jobb som säkerhetskopierar loggen var 15:e minut. Här är ett skript som kommer att generera tidsstämplade filnamn baserat på den aktuella tiden (men du kan också göra detta med underhållsplaner etc., välj bara inte något av krympningsalternativen i underhållsplaner, de är hemska).

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;

Observera att \\backup_share\ bör vara på en annan dator som representerar en annan underliggande lagringsenhet. Att säkerhetskopiera dessa till samma maskin (eller till en annan maskin som använder samma underliggande diskar, eller en annan virtuell dator som finns på samma fysiska värd) hjälper dig inte riktigt, eftersom om maskinen sprängs har du förlorat din databas och dess säkerhetskopior. Beroende på din nätverksinfrastruktur kan det vara mer meningsfullt att säkerhetskopiera lokalt och sedan överföra dem till en annan plats bakom kulisserna; i båda fallen vill du ta bort dem från den primära databasmaskinen så snabbt som möjligt.

Nu, när du väl har kört regelbundna loggbackuper, borde det vara rimligt att krympa loggfilen till något mer rimligt än vad den har blåst upp till nu. Detta gör inte innebär att köra SHRINKFILE om och om igen tills loggfilen är 1 MB - även om du säkerhetskopierar loggen ofta, måste den fortfarande ta emot summan av eventuella samtidiga transaktioner som kan inträffa. Händelser för autotillväxt av loggfiler är dyra, eftersom SQL Server måste nollställa filerna (till skillnad från datafiler när omedelbar filinitiering är aktiverad), och användartransaktioner måste vänta medan detta händer. Du vill göra den här växa-krympa-växa-krympa-rutinen så lite som möjligt, och du vill absolut inte få dina användare att betala för det.

Observera att du kan behöva säkerhetskopiera loggen två gånger innan en krympning är möjlig (tack Robert).

Så du måste komma på en praktisk storlek för din loggfil. Ingen här kan berätta för dig vad det är utan att veta mycket mer om ditt system, men om du ofta har krympt loggfilen och den har vuxit igen, är en bra vattenstämpel förmodligen 10-50 % högre än den största den har varit . Låt oss säga att det kommer till 200 MB och du vill att eventuella efterföljande autotillväxthändelser ska vara 50 MB, då kan du justera loggfilens storlek på detta sätt:

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

Observera att om loggfilen för närvarande är> 200 MB, kan du behöva köra detta först:

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

Om du inte bryr dig om punkt-i-tid återställning

Om detta är en testdatabas och du inte bryr dig om punkt-i-tid återställning, bör du se till att din databas är i SIMPLE återställningsläge.

ALTER DATABASE testdb SET RECOVERY SIMPLE;

Lägger databasen i SIMPLE återställningsläget ser till att SQL Server återanvänder delar av loggfilen (i huvudsak fasar ut inaktiva transaktioner) istället för att växa för att hålla ett register över alla transaktioner (som FULL återställning gör tills du säkerhetskopierar loggen). CHECKPOINT händelser hjälper till att kontrollera loggen och se till att den inte behöver växa om du inte genererar mycket t-loggaktivitet mellan CHECKPOINT s.

Därefter bör du vara absolut säker på att denna stocktillväxt verkligen berodde på en onormal händelse (säg, en årlig vårstädning eller återuppbyggnad av dina största index), och inte på normal, vardaglig användning. Om du krymper loggfilen till en löjligt liten storlek och SQL Server bara måste växa igen för att tillgodose din normala aktivitet, vad fick du då? Kunde du använda det diskutrymme du frigjorde bara tillfälligt? Om du behöver en omedelbar åtgärd kan du köra följande:

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

Annars, ställ in en lämplig storlek och tillväxthastighet. Som i exemplet i punkt-i-tidsåterställningsfallet kan du använda samma kod och logik för att bestämma vilken filstorlek som är lämplig och ställa in rimliga parametrar för autotillväxt.

Vissa saker du inte vill göra

  • Säkerhetskopiera loggen med TRUNCATE_ONLY alternativet och sedan SHRINKFILE . För en, denna TRUNCATE_ONLY alternativet har fasats ut och är inte längre tillgängligt i nuvarande versioner av SQL Server. För det andra, om du är i FULL återställningsmodell kommer detta att förstöra din loggkedja och kräver en ny, fullständig säkerhetskopia.

  • Koppla loss databasen, ta bort loggfilen och bifoga igen . Jag kan inte betona hur farligt det här kan vara. Din databas kanske inte kommer upp igen, den kan komma upp som misstänkt, du kanske måste återgå till en säkerhetskopia (om du har en), etc. etc.

  • Använd alternativet "krympa databas" . DBCC SHRINKDATABASE och alternativet för underhållsplanen att göra detsamma är dåliga idéer, speciellt om du egentligen bara behöver lösa ett loggproblem. Rikta in filen du vill justera och justera den oberoende av varandra med DBCC SHRINKFILE eller ALTER DATABASE ... MODIFY FILE (exempel ovan).

  • Förminska loggfilen till 1 MB . Det här ser lockande ut eftersom SQL Server låter mig göra det i vissa scenarier och titta på allt utrymme det frigör! Om inte din databas är skrivskyddad (och det är den, bör du markera den som sådan med ALTER DATABASE ), kommer detta absolut bara att leda till många onödiga tillväxthändelser, eftersom loggen måste ta emot aktuella transaktioner oavsett återställningsmodell. Vad är poängen med att frigöra det utrymmet tillfälligt, bara så att SQL Server kan ta tillbaka det långsamt och smärtsamt?

  • Skapa en andra loggfil . Detta kommer att ge tillfällig lättnad för enheten som har fyllt din disk, men det är som att försöka fixa en punkterad lunga med ett plåster. Du bör ta itu med den problematiska loggfilen direkt istället för att bara lägga till ytterligare ett potentiellt problem. Förutom att omdirigera viss transaktionsloggaktivitet till en annan enhet, gör en andra loggfil verkligen ingenting för dig (till skillnad från en andra datafil), eftersom endast en av filerna någonsin kan användas åt gången. Paul Randal förklarar också varför flera loggfiler kan bita dig senare.

Var proaktiv

Istället för att krympa din loggfil till ett litet belopp och låta den ständigt växa automatiskt i en liten takt på egen hand, ställ in den på en ganska stor storlek (en som kommer att rymma summan av din största uppsättning samtidiga transaktioner) och ställ in en rimlig autotillväxt inställning som en reserv, så att den inte behöver växa flera gånger för att uppfylla enskilda transaktioner och så att det kommer att vara relativt sällsynt att den någonsin behöver växa under normal affärsverksamhet.

De sämsta möjliga inställningarna här är 1 MB tillväxt eller 10 % tillväxt. Lustigt nog är det här standardinställningarna för SQL Server (som jag har klagat på och bett om ändringar utan resultat) - 1 MB för datafiler och 10% för loggfiler. Den förra är alldeles för liten i våra dagar och den senare leder till längre och längre händelser varje gång (säg, din loggfil är 500 MB, första tillväxten är 50 MB, nästa tillväxt är 55 MB, nästa tillväxt är 60,5 MB , etc. etc. - och på långsam I/O, tro mig, du kommer verkligen att märka denna kurva).

Mer läsning

Snälla sluta inte här; Även om många av de råd du ser där ute om krympande loggfiler är dåliga och till och med potentiellt katastrofala, finns det vissa människor som bryr sig mer om dataintegritet än att frigöra diskutrymme.

Ett blogginlägg jag skrev 2009, när jag såg några "här är hur du krymper loggfilen"-inlägg dyker upp.

Ett blogginlägg Brent Ozar skrev för fyra år sedan och pekade på flera resurser, som svar på en SQL Server Magazine-artikel som inte borde har publicerats.

Ett blogginlägg av Paul Randal som förklarar varför underhåll av t-loggar är viktigt och varför du inte heller bör krympa dina datafiler.

Mike Walsh har ett bra svar som täcker några av dessa aspekter också, inklusive orsaker till varför du kanske inte kan krympa din loggfil omedelbart.



  1. Kommaseparerade resultat i SQL

  2. Få områden med förbättringar i PostgreSQL 9.4

  3. Quickbooks ODBC-drivrutin

  4. MIN() Funktion i MariaDB