Transaksjonsloggen: Hvorfor vokser .ldf-filen, og hva gjør du?
«Loggfilen er på 200 GB, men databasen er bare 5 GB – hva skjer?» Det er kanskje det vanligste spørsmålet fra folk som drifter SQL Server uten å være databaseadministratorer. Transaksjonsloggen (.ldf-filen) er SQL Servers sikkerhetsnett, men den må forvaltes. Denne guiden forklarer hva loggen gjør, hvorfor den vokser, hvordan du finner årsaken, og hvordan du får den ned i en fornuftig størrelse – uten å ødelegge muligheten til å gjenopprette.
- Den vanligste årsaken er gjenopprettingsmodellen Full uten loggbackuper.
- Spør SQL Server hvorfor loggen ikke kan gjenbrukes:
log_reuse_wait_descisys.databases. - Rett opp årsaken først. Krymp deretter loggen én gang til en fornuftig størrelse – ikke som en fast jobb.
- Slett aldri .ldf-filen. Databasen kan bli ubrukelig.
Hva er transaksjonsloggen?
Alle endringer i en database skrives først til transaksjonsloggen, og først senere til datafilene. Dette kalles write-ahead logging. Når en transaksjon er bekreftet (COMMIT), er den garantert lagret i loggen, selv om datasidene i minnet ennå ikke er skrevet til disk. Krasjer serveren, bruker SQL Server loggen ved oppstart til å:
- gjøre om (redo) bekreftede transaksjoner som ikke rakk å bli skrevet til datafilene, og
- angre (undo) transaksjoner som ikke var fullført.
Det er slik SQL Server oppfyller kravet til varighet (durability, D-en i ACID). Loggen brukes også til loggbackuper, availability groups, replikering og Change Data Capture.
Virtuelle loggfiler og sirkulær bruk
Loggfilen er internt delt i mange virtuelle loggfiler (VLF-er). SQL Server skriver til dem i rekkefølge og bruker dem om igjen sirkulært når innholdet ikke lenger trengs. Loggen vokser bare når SQL Server kommer rundt til en VLF som fortsatt er i bruk. Spørsmålet er derfor aldri «hvorfor vokser loggen?», men «hvorfor kan ikke loggen gjenbrukes?».
Når kan en VLF gjenbrukes? Det avhenger av gjenopprettingsmodellen:
- Simple: Etter neste checkpoint, så lenge ingen aktiv transaksjon eller annen prosess trenger den.
- Full og Bulk-logged: Først når innholdet er tatt med i en loggbackup.
Finn årsaken
SQL Server forteller deg selv hva den venter på:
SELECT name, recovery_model_desc, log_reuse_wait_desc
FROM sys.databases
ORDER BY name;
-- Hvor stor er loggen, og hvor mye er i bruk?
SELECT DB_NAME(database_id) AS DatabaseNavn,
total_log_size_in_bytes / 1048576.0 AS StørrelseMB,
used_log_space_in_bytes / 1048576.0 AS BruktMB,
used_log_space_in_percent AS BruktProsent
FROM sys.dm_db_log_space_usage; -- kjøres i databasen du vil sjekke
De vanligste verdiene i log_reuse_wait_desc og hva du gjør med dem:
| Verdi | Betydning | Tiltak |
|---|---|---|
| NOTHING | Loggen kan gjenbrukes nå. | Ingenting. Loggen er stor fordi den har vokst tidligere. |
| CHECKPOINT | Venter på neste checkpoint. | Forbigående. Kjør eventuelt CHECKPOINT. |
| LOG_BACKUP | Full-modell, og loggen er ikke tatt backup av. | Sett opp jevnlige loggbackuper, eller bytt til Simple hvis du ikke trenger gjenoppretting til tidspunkt. |
| ACTIVE_TRANSACTION | En transaksjon har stått åpen lenge. | Finn og avslutt den (se under). |
| ACTIVE_BACKUP_OR_RESTORE | En backup pågår. | Vent, eller undersøk om backupen henger. |
| REPLICATION | Transaksjonsreplikering eller CDC har ikke lest loggen. | Sjekk at Log Reader Agent eller CDC-jobbene kjører. |
| AVAILABILITY_REPLICA | En sekundær replika i en availability group henger etter. | Sjekk nettverk, ytelse og tilstand på sekundæren. |
Finn en langvarig transaksjon
SELECT s.session_id,
s.login_name,
s.host_name,
s.program_name,
at.transaction_begin_time,
DATEDIFF(MINUTE, at.transaction_begin_time, SYSDATETIME()) AS MinutterÅpen
FROM sys.dm_tran_active_transactions AS at
JOIN sys.dm_tran_session_transactions AS st ON st.transaction_id = at.transaction_id
JOIN sys.dm_exec_sessions AS s ON s.session_id = st.session_id
ORDER BY at.transaction_begin_time;
En klassiker er et vindu i SSMS der noen har kjørt BEGIN TRAN og gått hjem for dagen. Ofte er det også en applikasjon som åpner en transaksjon og så venter på brukeren eller på et eksternt API.
Løs problemet riktig
Trenger du gjenoppretting til et tidspunkt?
Hvis ja: behold Full og sett opp loggbackup, typisk hvert 5.–15. minutt. Den første loggbackupen kan ta tid fordi den må ta med alt som har samlet seg opp.
Hvis nei – for eksempel en test- eller utviklingsdatabase – bytt til Simple:
ALTER DATABASE Test SET RECOVERY SIMPLE;
Krymp loggen – én gang
Når årsaken er rettet og loggen kan gjenbrukes, kan du krympe filen til en fornuftig størrelse:
USE Salg;
-- Finn det logiske filnavnet på loggfilen
SELECT name, type_desc, size / 128 AS StørrelseMB
FROM sys.database_files;
-- Krymp til 8 GB (målstørrelsen angis i MB)
DBCC SHRINKFILE (N'Salg_log', 8192);
Hvis loggen ikke krymper, ligger den aktive delen av loggen sannsynligvis på slutten av filen. Ta en ny loggbackup (eller vent på en checkpoint i Simple) og prøv igjen.
Ikke legg inn krymping som en fast jobb. Loggen vokser bare tilbake til den størrelsen arbeidsmengden faktisk trenger, og hver vekst koster: SQL Server må nullstille nytt loggområde før det kan brukes, og mens det skjer venter alle transaksjoner.
Hvor stor bør loggen være?
Stor nok til å romme den største aktiviteten mellom to loggbackuper – eller den største enkelttransaksjonen, ofte en indeksombygging eller en stor import. Et grovt utgangspunkt er 10–25 prosent av datastørrelsen, men mål heller: se hvor stor loggen blir etter en uke med normal drift og vedlikehold, og sett den der med litt margin.
Vekstinnstillinger og antall VLF-er
Prosentvis vekst (standard i eldre versjoner) gir små vekster i starten og enorme vekster senere. Sett fast vekst i MB. Svært mange VLF-er – flere tusen – gjør oppstart, gjenoppretting og availability groups tregere.
-- Antall VLF-er i gjeldende database
SELECT COUNT(*) AS AntallVLF
FROM sys.dm_db_log_info(DB_ID());
-- Fast vekst i stedet for prosent
ALTER DATABASE Salg
MODIFY FILE (NAME = N'Salg_log', FILEGROWTH = 1024MB);
Har en database tusenvis av VLF-er, kan du krympe loggen så langt det går og deretter øke den igjen i noen få, store steg til ønsket størrelse. Det gir færre og større VLF-er.
Feil 9002: loggen er full
«The transaction log for database 'X' is full due to 'LOG_BACKUP'» betyr at loggen ikke kan vokse mer – enten fordi disken er full eller fordi filen har nådd maks størrelse. Databasen kan da bare leses. Akutt:
- Les årsaken i feilmeldingen eller i
log_reuse_wait_desc. - Er årsaken
LOG_BACKUP: ta en loggbackup til en disk med plass. - Er disken full: frigjør plass, utvid disken, eller legg til en ekstra loggfil midlertidig på en annen disk (og fjern den etterpå).
- Rett den underliggende årsaken, slik at det ikke skjer igjen.
Vanlige spørsmål
Kan jeg bare slette .ldf-filen?
Nei. Transaksjonsloggen er en del av databasen. Slettes den mens databasen har ufullførte transaksjoner eller endringer som ikke er skrevet til datafilene, kan databasen bli inkonsistent og ikke la seg åpne. Det finnes nødprosedyrer for å bygge en ny logg, men de kan føre til tap av data og skal bare brukes når alt annet har feilet.
Hjelper det med flere loggfiler?
Nei, ikke for ytelse. SQL Server skriver til loggen sekvensielt, én fil om gangen. En ekstra loggfil er bare nyttig som nødløsning når disken er full.
Krymper loggen av seg selv etter en loggbackup?
Nei. Loggbackupen gjør plassen inne i filen tilgjengelig for gjenbruk, men filen beholder størrelsen. Det er tilsiktet: den er allerede klar til neste topp.
Hvorfor vokser loggen kraftig under indeksvedlikehold?
Indeksombygging er fullt logget i Full-modell, så en ombygging av en indeks på 50 GB kan generere tilsvarende mengde logg. Ta gjerne loggbackup oftere i vedlikeholdsvinduet, og bygg om bare indeksene som trenger det. Se guiden om vedlikehold.