Het kleiner maken van een logbestand zou eigenlijk gereserveerd moeten worden voor scenario's waarin het onverwachte groei tegenkwam waarvan u niet verwacht dat dit nog een keer zal gebeuren. Als het logbestand weer dezelfde grootte krijgt, wordt er niet veel bereikt door het tijdelijk te verkleinen. Nu, afhankelijk van de hersteldoelen van uw database, zijn dit de acties die u moet ondernemen.
Maak eerst een volledige back-up
Breng nooit wijzigingen aan in uw database zonder ervoor te zorgen dat u deze kunt herstellen als er iets misgaat.
Als u herstel op een bepaald tijdstip belangrijk vindt
(En met herstel op een bepaald tijdstip bedoel ik dat u het belangrijk vindt dat u iets anders kunt herstellen dan een volledige of differentiële back-up.)
Vermoedelijk is uw database in FULL
herstelmodus. Zo niet, controleer dan of het:
ALTER DATABASE testdb SET RECOVERY FULL;
Zelfs als u regelmatig volledige back-ups maakt, zal het logbestand groeien en groeien totdat u een log uitvoert back-up - dit is voor uw bescherming, niet om onnodig uw schijfruimte op te vreten. U zou deze logboekback-ups vrij vaak moeten uitvoeren, afhankelijk van uw hersteldoelstellingen. Als u bijvoorbeeld een bedrijfsregel hebt die stelt dat u het zich kunt veroorloven om niet meer dan 15 minuten aan gegevens te verliezen in het geval van een ramp, moet u een taak hebben die elke 15 minuten een back-up van het logboek maakt. Hier is een script dat bestandsnamen met tijdstempel zal genereren op basis van de huidige tijd (maar je kunt dit ook doen met onderhoudsplannen enz., kies gewoon geen van de krimpopties in onderhoudsplannen, ze zijn verschrikkelijk).
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;
Merk op dat \\backup_share\
moet zich op een andere machine bevinden die een ander onderliggend opslagapparaat vertegenwoordigt. Een back-up maken van deze naar dezelfde machine (of naar een andere machine die dezelfde onderliggende schijven gebruikt, of een andere VM die zich op dezelfde fysieke host bevindt) helpt je niet echt, want als de machine ontploft, ben je je database kwijt en zijn back-ups. Afhankelijk van uw netwerkinfrastructuur kan het logischer zijn om lokaal een back-up te maken en deze vervolgens achter de schermen naar een andere locatie over te brengen; in beide gevallen wilt u ze zo snel mogelijk van de primaire databasemachine halen.
Nu, als je eenmaal regelmatig logback-ups hebt gemaakt, zou het redelijk moeten zijn om het logbestand te verkleinen tot iets redelijkers dan wat het tot nu toe is opgeblazen. Dit doet niet bedoel het uitvoeren van SHRINKFILE
keer op keer totdat het logbestand 1 MB is - zelfs als u regelmatig een back-up van het logbestand maakt, moet het nog steeds de som van alle gelijktijdige transacties die kunnen plaatsvinden, opvangen. Autogrow-gebeurtenissen van logbestanden zijn duur, omdat SQL Server de bestanden op nul moet zetten (in tegenstelling tot gegevensbestanden wanneer directe bestandsinitialisatie is ingeschakeld), en gebruikerstransacties moeten wachten terwijl dit gebeurt. Je wilt deze groei-krimp-groei-krimp-routine zo min mogelijk doen, en je wilt zeker niet dat je gebruikers ervoor betalen.
Houd er rekening mee dat u mogelijk twee keer een back-up van het logboek moet maken voordat een derving mogelijk is (bedankt Robert).
Je moet dus een praktisch formaat voor je logbestand bedenken. Niemand hier kan je vertellen wat dat is zonder veel meer over je systeem te weten, maar als je het logbestand vaak hebt verkleind en het weer is gegroeid, is een goed watermerk waarschijnlijk 10-50% hoger dan het grootste dat het is geweest . Laten we zeggen dat dit 200 MB is, en u wilt dat eventuele volgende autogrowth-gebeurtenissen 50 MB zijn, dan kunt u de grootte van het logbestand als volgt aanpassen:
USE [master];
GO
ALTER DATABASE Test1
MODIFY FILE
(NAME = yourdb_log, SIZE = 200MB, FILEGROWTH = 50MB);
GO
Merk op dat als het logbestand momenteel> 200 MB is, u dit mogelijk eerst moet uitvoeren:
USE yourdb;
GO
DBCC SHRINKFILE(yourdb_log, 200);
GO
Als u niets geeft om herstel op een bepaald tijdstip
Als dit een testdatabase is en u niet geïnteresseerd bent in herstel op een bepaald moment, moet u ervoor zorgen dat uw database zich in SIMPLE
bevindt herstelmodus.
ALTER DATABASE testdb SET RECOVERY SIMPLE;
De database in SIMPLE
zetten herstelmodus zorgt ervoor dat SQL Server delen van het logbestand hergebruikt (in wezen geleidelijk uitfaseren van inactieve transacties) in plaats van te groeien om een record van alle bij te houden transacties (zoals FULL
herstel doet totdat u een back-up van het logboek maakt). CHECKPOINT
gebeurtenissen helpen het logboek te controleren en ervoor te zorgen dat het niet hoeft te groeien, tenzij u veel t-log-activiteit genereert tussen CHECKPOINT
v.
Vervolgens moet u er absoluut zeker van zijn dat deze logboekgroei echt te wijten was aan een abnormale gebeurtenis (bijvoorbeeld een jaarlijkse voorjaarsschoonmaak of het opnieuw opbouwen van uw grootste indexen), en niet aan normaal, alledaags gebruik. Als u het logbestand tot een belachelijk klein formaat verkleint en SQL Server het gewoon opnieuw moet laten groeien om uw normale activiteit te accommoderen, wat hebt u dan gewonnen? Kon u die schijfruimte die u vrijmaakte slechts tijdelijk gebruiken? Als u een onmiddellijke oplossing nodig heeft, kunt u het volgende uitvoeren:
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
Stel anders een geschikte grootte en groeisnelheid in. Zoals in het voorbeeld in het geval van herstel op een bepaald moment, kunt u dezelfde code en logica gebruiken om te bepalen welke bestandsgrootte geschikt is en om redelijke autogrowth-parameters in te stellen.
Sommige dingen die je niet wilt doen
-
Maak een back-up van het logboek met
TRUNCATE_ONLY
optie en danSHRINKFILE
. Ten eerste dezeTRUNCATE_ONLY
optie is verouderd en is niet langer beschikbaar in de huidige versies van SQL Server. Ten tweede, als je inFULL
. bent herstelmodel, dit vernietigt uw logketen en vereist een nieuwe, volledige back-up. -
De database loskoppelen, het logbestand verwijderen en opnieuw toevoegen . Ik kan niet benadrukken hoe gevaarlijk dit kan zijn. Uw database komt mogelijk niet terug, deze kan als verdacht worden weergegeven, u moet mogelijk terugkeren naar een back-up (als u die heeft), enz. enz.
-
Gebruik de optie "database verkleinen" .
DBCC SHRINKDATABASE
en de optie voor een onderhoudsplan om hetzelfde te doen, zijn slechte ideeën, vooral als u echt alleen een probleem met een logprobleem hoeft op te lossen. Target het bestand dat u wilt aanpassen en pas het onafhankelijk aan, met behulp vanDBCC SHRINKFILE
ofALTER DATABASE ... MODIFY FILE
(voorbeelden hierboven). -
Verklein het logbestand tot 1 MB . Dit ziet er verleidelijk uit, want, hé, SQL Server zal me het in bepaalde scenario's laten doen, en kijken naar alle ruimte die het vrijmaakt! Tenzij uw database alleen-lezen is (en dat is het, moet u deze als zodanig markeren met
ALTER DATABASE
), zal dit absoluut alleen maar leiden tot veel onnodige groeigebeurtenissen, omdat het logboek de huidige transacties moet accommoderen, ongeacht het herstelmodel. Wat heeft het voor zin om die ruimte tijdelijk vrij te maken, zodat SQL Server het langzaam en pijnlijk kan terugnemen? -
Maak een tweede logbestand . Dit zal tijdelijk verlichting bieden voor de schijf die uw schijf heeft gevuld, maar dit is als proberen een lekke long te repareren met een pleister. U moet het problematische logbestand rechtstreeks aanpakken in plaats van alleen een ander potentieel probleem toe te voegen. Behalve het omleiden van een transactielogactiviteit naar een andere schijf, doet een tweede logbestand echt niets voor u (in tegenstelling tot een tweede gegevensbestand), aangezien slechts één van de bestanden ooit tegelijk kan worden gebruikt. Paul Randal legt ook uit waarom meerdere logbestanden je later kunnen bijten.
Wees proactief
In plaats van uw logbestand tot een klein aantal te verkleinen en het constant op zichzelf te laten groeien met een kleine snelheid, stelt u het in op een redelijk groot formaat (een dat geschikt is voor de som van uw grootste reeks gelijktijdige transacties) en stelt u een redelijke autogrow in instelling als een fallback, zodat het niet meerdere keren hoeft te groeien om aan enkele transacties te voldoen en zodat het relatief zeldzaam zal zijn om ooit te groeien tijdens normale bedrijfsvoering.
De slechtst mogelijke instellingen hier zijn 1 MB groei of 10% groei. Grappig genoeg zijn dit de standaardwaarden voor SQL Server (waarover ik heb geklaagd en tevergeefs om wijzigingen heb gevraagd) - 1 MB voor gegevensbestanden en 10% voor logbestanden. De eerste is veel te klein in deze tijd, en de laatste leidt elke keer tot langere en langere gebeurtenissen (zeg, je logbestand is 500 MB, de eerste groei is 50 MB, de volgende groei is 55 MB, de volgende groei is 60,5 MB , etc. etc. - en op langzame I/O, geloof me, je zult deze curve echt opmerken).
Verder lezen
Stop hier alsjeblieft niet; Hoewel veel van het advies dat je ziet over het verkleinen van logbestanden inherent slecht en zelfs potentieel rampzalig is, zijn er sommige mensen die meer geven om gegevensintegriteit dan om schijfruimte vrij te maken.
Een blogpost die ik in 2009 schreef, toen ik een paar "hier is hoe je het logbestand kunt verkleinen" berichten zag verschijnen.
Een blogpost die Brent Ozar vier jaar geleden schreef, wijzend op meerdere bronnen, als reactie op een artikel in SQL Server Magazine dat niet zou moeten zijn gepubliceerd.
Een blogpost van Paul Randal waarin hij uitlegt waarom onderhoud van t-log belangrijk is en waarom je je gegevensbestanden ook niet moet verkleinen.
Mike Walsh heeft ook een geweldig antwoord op een aantal van deze aspecten, waaronder redenen waarom je je logbestand misschien niet onmiddellijk kunt verkleinen.