För databasadministratörer (DBA:er) och DevOps-ingenjörer som hanterar Microsoft SQL Server är det få varningar som orsakar så mycket omedelbar ångest som fel 9002: Transaktionsloggen för databasen ’X’ är full. När transaktionsloggen fylls och inte kan växa blir databasen i praktiken skrivskyddad. Alla INSERT-, UPDATE– och DELETE-operationer avstannar, applikationstransaktioner misslyckas och produktionen stannar av helt.
Att förstå den underliggande arkitekturen i SQL Servers transaktionslogg, att korrekt diagnostisera grundorsaken och att utföra snabba återställningsprocedurer är kritiska färdigheter för att upprätthålla hög tillgänglighet. Denna omfattande guide utforskar transaktionsloggens mekanik, hur man löser en full logg i en nödsituation samt arkitektoniska bästa praxis för att förhindra att det händer igen.
Förståelse för SQL Servers transaktionsloggarkitektur
För att effektivt felsöka en full transaktionslogg måste du först förstå hur SQL Server skriver och hanterar data.
Write-Ahead Logging (WAL)
SQL Server använder ett Write-Ahead Logging (WAL)-protokoll. Varje gång en datamodifiering sker skrivs ändringen först till transaktionsloggen i minnet, och därefter töms den till den fysiska loggfilen på disken innan de faktiska datasidorna uppdateras i databasfilerna (MDF/NDF). Detta garanterar ACID-efterlevnad (Atomicity, Consistency, Isolation, Durability), vilket säkerställer att SQL Server vid en krasch kan spela upp (roll forward) eller ångra (roll back) transaktioner.
Virtuella loggfiler (VLF) och cirkulär loggning
Internt är den fysiska transaktionsloggfilen (LDF) uppdelad i mindre, logiska segment som kallas virtuella loggfiler (VLF). Transaktionsloggen fungerar cirkulärt. Allt eftersom loggposter skrivs fyller de en VLF och går vidare till nästa.
När loggen når slutet av den fysiska filen försöker den börja om från början. Den kan dock bara skriva över en VLF om den VLF:en är markerad som inaktiv. Om alla VLF:er är aktiva (vilket innebär att de innehåller loggposter som SQL Server fortfarande behöver) kan loggen inte börja om. Om automatisk tillväxt (auto-growth) är aktiverad och diskutrymme finns tillgängligt växer den fysiska filen. Om disken är full eller om automatisk tillväxt är begränsad stöter du på fel 9002.
Loggavkortning (Truncation) vs. Loggkrympning (Shrinking)
En vanlig missuppfattning är att avkortning av loggen minskar den fysiska filstorleken.
* Loggavkortning (Log Truncation): Processen att markera aktiva VLF:er som inaktiva, vilket gör utrymmet tillgängligt för återanvändning. Det minskar inte storleken på LDF-filen på disken.
* Loggkrympning (Log Shrinking): Processen att fysiskt minska LDF-filens storlek och återföra utrymme till operativsystemet.
I återställningsmodellen Full sker loggavkortning endast när en transaktionsloggsäkerhetskopia har slutförts (förutsatt att inga andra processer håller loggen aktiv).
Diagnostisering av felet ”Transaktionsloggen är full” (Fel 9002)
När loggen är full är ditt första steg inte att blint lägga till diskutrymme eller krympa filer. Du måste identifiera varför loggen inte kan avkortas. SQL Server tillhandahåller en inbyggd mekanism för att berätta exakt vad som förhindrar loggåteranvändning via katalogvyn sys.databases.
Kör följande T-SQL-kommando för att identifiera flaskhalsen:
SELECT
name AS DatabaseName,
recovery_model_desc AS RecoveryModel,
log_reuse_wait_desc AS LogReuseWaitReason
FROM sys.databases
WHERE name = 'YourDatabaseName';
Du kan också kontrollera den aktuella utrymmesanvändningen för dina transaktionsloggar med:
DBCC SQLPERF(LOGSPACE);
Vanliga log_reuse_wait_desc-tillstånd
- LOG_BACKUP: Databasen är i återställningsmodellen Full eller Bulk-Logged, och en transaktionsloggsäkerhetskopia har inte tagits nyligen. Detta är den vanligaste orsaken.
- ACTIVE_TRANSACTION: En långvarig transaktion (t.ex. en massiv indexombyggnad eller en glömd ej genomförd transaktion) håller loggen aktiv.
- REPLICATION / CDC: Transaktionell replikering eller Change Data Capture (CDC) är aktiverat, och Log Reader Agent har ännu inte bearbetat transaktionerna.
- AVAILABILITY_REPLICA: I en AlwaysOn Availability Group är en sekundär replika frånkopplad eller synkroniserar för långsamt, vilket tvingar den primära replikan att behålla loggposter tills de har skrivits till den sekundära.
Strategier för snabb återställning: Lösa problemet i produktion
Beroende på vilket log_reuse_wait_desc som returneras kommer din nödåtgärd att variera. Här är strategierna för snabb återställning för de vanligaste scenarierna.
Scenario 1: Saknade eller misslyckade loggsäkerhetskopior (LOG_BACKUP)
Om väntetypen är LOG_BACKUP är lösningen enkel: du måste säkerhetskopiera transaktionsloggen.
BACKUP LOG [YourDatabaseName]
TO DISK = 'N:BackupsYourDatabaseName_EmergencyLog.trn'
WITH COMPRESSION, STATS = 10;
När säkerhetskopieringen är klar kommer de inaktiva VLF:erna att avkortas och SQL Server återupptar normal drift. Om din säkerhetskopieringsdisk är full kan du behöva säkerhetskopiera till en temporär nätverksresurs eller en null-enhet (rekommenderas starkt inte om inte databasen är lätt att återskapa, eftersom det bryter loggkedjan):
-- VARNING: Detta bryter loggkedjan och äventyrar återställning till en viss tidpunkt.
-- Använd endast om absolut nödvändigt och följ omedelbart upp med en FULL säkerhetskopia.
BACKUP LOG [YourDatabaseName] TO DISK = 'NUL';
Scenario 2: Långvariga aktiva transaktioner (ACTIVE_TRANSACTION)
Om en enskild transaktion har körts i timmar förhindrar den loggavkortning under hela tiden. Identifiera först den felande transaktionen:
DBCC OPENTRAN('YourDatabaseName');
Detta kommando returnerar den äldsta aktiva transaktionen och dess Server Process ID (SPID). Du kan samla in mer information om vad SPID:et gör genom att fråga dynamiska hanteringsvyer (DMV:er):
SELECT
s.session_id,
s.login_name,
s.host_name,
r.start_time,
r.status,
r.command,
t.text AS QueryText
FROM sys.dm_exec_sessions s
JOIN sys.dm_exec_requests r ON s.session_id = r.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE s.session_id = <SPID_FROM_DBCC_OPENTRAN>;
Om transaktionen är en oönskad fråga eller en avstannad process kan du behöva avsluta den för att frigöra loggen.
KILL <SPID>;
Obs: Att avbryta en massiv transaktion utlöser en rollback, vilket kan ta avsevärd tid och tillfälligt generera ytterligare loggaktivitet. Starta inte om SQL Server-tjänsten under en rollback, annars kommer databasen att gå in i återställningsläge vid omstart.
Scenario 3: Nödtilldelning av utrymme (Disken är 100 % full)
Om LDF-filen har förbrukat hela disken kan du inte ens köra en säkerhetskopia eftersom SQL Server kräver en liten mängd loggutrymme för att registrera själva säkerhetskopieringshändelsen. I detta scenario måste du lägga till en sekundär loggfil på en annan disk med tillgängligt utrymme.
ALTER DATABASE [YourDatabaseName]
ADD LOG FILE
(
NAME = N'YourDatabaseName_Log2',
FILENAME = N'E:TempLogsYourDatabaseName_Log2.ldf',
SIZE = 5GB,
MAXSIZE = 50GB,
FILEGROWTH = 1GB
);
Detta ger omedelbart SQL Server andrum. När databasen är online, ta en transaktionsloggsäkerhetskopia, töm den sekundära loggfilen och ta bort den:
-- 1. Ta en loggsäkerhetskopia för att avkorta loggen
BACKUP LOG [YourDatabaseName] TO DISK = '...';
-- 2. Töm den temporära loggfilen
DBCC SHRINKFILE (N'YourDatabaseName_Log2', EMPTYFILE);
-- 3. Ta bort den temporära loggfilen
ALTER DATABASE [YourDatabaseName] REMOVE FILE [YourDatabaseName_Log2];
Bästa praxis för förebyggande och hantering av transaktionsloggar
Reaktiv felsökning är stressande och påverkar SLA:er. Att implementera proaktiva arkitektoniska och operativa bästa praxis är avgörande för stabiliteten i företagsdatabaser.
1. Implementera en robust, automatiserad säkerhetskopieringsstrategi
Om en databas är i återställningsmodellen Full är frekventa transaktionsloggsäkerhetskopior obligatoriska. Beroende på ditt mål för återställningspunkt (RPO) och transaktionsvolym bör loggsäkerhetskopior ske var 5:e till 15:e minut.
Företagslösningar för säkerhetskopiering som CloudSave förenklar denna process avsevärt. Genom att integrera direkt med SQL Server via VDI (Virtual Device Interface) tillåter CloudSave DBA:er att konfigurera policydrivna, högfrekventa transaktionsloggsäkerhetskopior. Detta säkerställer att loggar kontinuerligt avkortas, krypteras säkert och lagras utanför anläggningen eller i oföränderlig molnlagring, vilket förhindrar väntetillståndet LOG_BACKUP utan att kräva komplexa anpassade SQL Agent-jobb.
2. Rätt storlek på transaktionsloggen och hantering av VLF:er
Att förlita sig på automatisk tillväxt för att hantera storleken på din transaktionslogg är ett farligt anti-mönster. Operationer för automatisk tillväxt är resurskrävande och pausar transaktionsbearbetningen medan disken nollställs (såvida inte Instant File Initialization är aktiverat, vilket inte gäller loggfiler).
Dessutom leder frekvent, liten automatisk tillväxt (t.ex. att växa med 10 % eller 50 MB åt gången) till VLF-fragmentering. En transaktionslogg med tusentals små VLF:er kommer att kraftigt försämra databasens starttider, prestanda för säkerhetskopiering och replikeringslatens.
- Förinställ storleken på loggen: Analysera dina största underhållsoperationer (som indexombyggnader) och förinställ storleken på LDF-filen för att rymma dem utan att behöva växa.
- Ställ in fast automatisk tillväxt: Ändra automatisk tillväxt från en procentandel till en fast storlek (t.ex. 1 GB eller 5 GB) för att säkerställa att VLF:er skapas med en hälsosam storlek.
Du kan kontrollera ditt VLF-antal med följande fråga (för SQL Server 2017+):
SELECT
db_name(database_id) AS DatabaseName,
COUNT(vlf_sequence_number) AS VLF_Count
FROM sys.dm_db_log_info(DB_ID('YourDatabaseName'));
Om ditt VLF-antal är över 500, överväg att vänta på en lugn period, krympa loggen till en minimal storlek och manuellt växa tillbaka den till dess önskade storlek i stora block.
3. Optimera underhållsoperationer för index
Indexombyggnader är fullständigt loggade operationer, även i återställningsmodellen Bulk-Logged (beroende på indextyp). Att bygga om ett index på 500 GB genererar minst 500 GB transaktionsloggposter.
För att mildra loggsvällning under underhåll:
* Använd SORT_IN_TEMPDB = ON när du bygger om index. Detta avlastar sorteringsfasen till TempDB, vilket minskar belastningen på databasens transaktionslogg.
* Byt från indexombyggnader till indexomorganiseringar där det är möjligt, eftersom omorganiseringar är mer loggeffektiva och kan avbrytas utan att hela operationen rullas tillbaka.
* Batcha stora DELETE– eller UPDATE-operationer. Istället för att radera 10 miljoner rader i en transaktion, radera dem i batchar om 50 000, genomför (commit) och tillåt loggsäkerhetskopior att avkorta loggen mellan batcharna.
4. Övervaka hög tillgänglighet och replikeringstopologier
I AlwaysOn Availability Groups kan den primära replikan inte avkorta sin logg förrän loggposterna har skrivits till alla synkrona och asynkrona sekundära replikor.
Om en sekundär replika går offline, eller om nätverksbandbredden inte kan hålla jämna steg med den primära replikans transaktionsgenereringstakt, kommer den primära replikans sändningskö att växa och loggen kommer att fyllas (väntetyp AVAILABILITY_REPLICA).
Implementera robust övervakning för prestandaräknaren SQLServer:Replica > Log Send Queue. Om en sekundär replika går förlorad permanent måste du ta bort den från Availability Group eller pausa datatrafiken för att tillåta att den primära loggen avkortas.
Slutsats
Att stöta på en full transaktionslogg är ett elddop för databasadministratörer, men det behöver inte resultera i utdragen driftstopp. Genom att förstå mekaniken i Write-Ahead Logging och VLF:er kan du snabbt diagnostisera grundorsaken med hjälp av sys.databases och tillämpa rätt strategi för snabb återställning.
Långsiktig stabilitet bygger på att gå ifrån reaktiva fixar. Att förinställa storleken på dina loggfiler, optimera underhållsrutiner och använda säkerhetskopieringsplattformar i företagsklass som CloudSave för att upprätthålla strikta, automatiserade scheman för loggsäkerhetskopiering kommer att säkerställa att dina transaktionsloggar förblir hälsosamma, avkortade och redo att stödja produktionsarbetsbelastningar med hög genomströmning.