Za administratore baza podataka (DBA) i DevOps inženjere koji upravljaju Microsoft SQL Serverom, malo upozorenja izaziva toliko trenutne anksioznosti kao Greška 9002: The transaction log for database ‘X’ is full (Transakcioni log za bazu podataka ‘X’ je pun). Kada se transakcioni log popuni i ne može da se proširi, baza podataka efektivno postaje samo za čitanje (read-only). Sve INSERT, UPDATE i DELETE operacije se zaustavljaju, transakcije aplikacije ne uspevaju, a produkcija staje.
Razumevanje osnovne arhitekture transakcionog loga SQL Servera, precizno dijagnostikovanje osnovnog uzroka i sprovođenje brzih procedura oporavka su kritične veštine za održavanje visoke dostupnosti. Ovaj sveobuhvatni vodič istražuje mehaniku transakcionog loga, kako rešiti pun log u hitnim slučajevima i arhitektonske najbolje prakse kako se to ne bi ponovilo.
Razumevanje arhitekture transakcionog loga SQL Servera
Da biste efikasno rešili problem punog transakcionog loga, prvo morate razumeti kako SQL Server upisuje i upravlja podacima.
Write-Ahead Logging (WAL)
SQL Server koristi protokol Write-Ahead Logging (WAL). Kad god dođe do modifikacije podataka, promena se prvo upisuje u transakcioni log u memoriji, a zatim se ispire (flush) u fizičku log datoteku na disku pre nego što se stvarne stranice podataka ažuriraju u datotekama baze podataka (MDF/NDF). Ovo garantuje ACID (Atomicity, Consistency, Isolation, Durability) usklađenost, osiguravajući da u slučaju pada, SQL Server može ponovo da izvrši (roll forward) ili poništi (roll back) transakcije.
Virtuelne log datoteke (VLF) i kružno logovanje
Interno, fizička datoteka transakcionog loga (LDF) je podeljena na manje, logičke segmente koji se nazivaju virtuelne log datoteke (VLF). Transakcioni log radi kružno. Kako se zapisi loga upisuju, oni popunjavaju jedan VLF i prelaze na sledeći.
Kada log stigne do kraja fizičke datoteke, pokušava da se vrati na početak. Međutim, on može da prepiše VLF samo ako je taj VLF označen kao neaktivan. Ako su svi VLF-ovi aktivni (što znači da sadrže zapise loga koji su SQL Serveru i dalje potrebni), log ne može da se „omotava“. Ako je omogućeno automatsko povećanje (auto-growth) i ima slobodnog prostora na disku, fizička datoteka raste. Ako je disk pun ili je automatsko povećanje ograničeno, nailazite na Grešku 9002.
Skraćivanje loga (Truncation) naspram smanjivanja loga (Shrinking)
Česta zabluda je da skraćivanje loga smanjuje veličinu fizičke datoteke.
* Skraćivanje loga (Log Truncation): Proces označavanja aktivnih VLF-ova kao neaktivnih, čime se prostor čini dostupnim za ponovnu upotrebu. To ne smanjuje veličinu LDF datoteke na disku.
* Smanjivanje loga (Log Shrinking): Proces fizičkog smanjivanja veličine LDF datoteke i vraćanja prostora operativnom sistemu.
U modelu potpunog oporavka (Full Recovery model), skraćivanje loga se dešava samo kada se uspešno završi rezervna kopija (backup) transakcionog loga (pod pretpostavkom da nijedan drugi proces ne drži log aktivnim).
Dijagnostikovanje greške „Transakcioni log pun“ (Greška 9002)
Kada je log pun, vaš prvi korak nije da slepo dodajete prostor na disku ili smanjujete datoteke. Morate identifikovati zašto log ne može da se skrati. SQL Server pruža ugrađeni mehanizam da vam tačno kaže šta sprečava ponovnu upotrebu loga putem sys.databases kataloškog prikaza.
Pokrenite sledeću T-SQL komandu da identifikujete usko grlo:
SELECT
name AS DatabaseName,
recovery_model_desc AS RecoveryModel,
log_reuse_wait_desc AS LogReuseWaitReason
FROM sys.databases
WHERE name = 'YourDatabaseName';
Takođe možete proveriti trenutnu upotrebu prostora vaših transakcionih logova koristeći:
DBCC SQLPERF(LOGSPACE);
Uobičajena log_reuse_wait_desc stanja
- LOG_BACKUP: Baza podataka je u modelu potpunog (Full) ili Bulk-Logged oporavka, a rezervna kopija transakcionog loga nije skoro napravljena. Ovo je najčešći uzrok.
- ACTIVE_TRANSACTION: Transakcija koja dugo traje (npr. masovno ponovno indeksiranje ili zaboravljena nepotvrđena transakcija) drži log aktivnim.
- REPLICATION / CDC: Omogućena je transakciona replikacija ili Change Data Capture (CDC), a Log Reader Agent još nije obradio transakcije.
- AVAILABILITY_REPLICA: U AlwaysOn grupi dostupnosti, sekundarna replika je isključena ili se presporo sinhronizuje, primoravajući primarnu repliku da zadrži zapise loga dok se ne potvrde na sekundarnoj.
Strategije brzog oporavka: Rešavanje problema u produkciji
U zavisnosti od vraćenog log_reuse_wait_desc, vaš odgovor na hitan slučaj će varirati. Evo strategija brzog oporavka za najčešće scenarije.
Scenario 1: Nedostajuće ili neuspele rezervne kopije loga (LOG_BACKUP)
Ako je tip čekanja LOG_BACKUP, rešenje je jednostavno: morate napraviti rezervnu kopiju transakcionog loga.
BACKUP LOG [YourDatabaseName]
TO DISK = 'N:BackupsYourDatabaseName_EmergencyLog.trn'
WITH COMPRESSION, STATS = 10;
Kada se backup završi, neaktivni VLF-ovi će biti skraćeni i SQL Server će nastaviti normalan rad. Ako je vaš backup disk pun, možda ćete morati da napravite backup na privremenu mrežnu deljenu lokaciju ili null uređaj (veoma se ne preporučuje osim ako se baza podataka lako može reprodukovati, jer to prekida lanac loga):
-- UPOZORENJE: Ovo prekida lanac loga i ugrožava oporavak do određene tačke u vremenu (point-in-time recovery).
-- Koristite samo ako je apsolutno neophodno i odmah nakon toga uradite FULL backup.
BACKUP LOG [YourDatabaseName] TO DISK = 'NUL';
Scenario 2: Aktivne transakcije koje dugo traju (ACTIVE_TRANSACTION)
Ako jedna transakcija traje satima, ona sprečava skraćivanje loga tokom celog trajanja. Prvo, identifikujte problematičnu transakciju:
DBCC OPENTRAN('YourDatabaseName');
Ova komanda vraća najstariju aktivnu transakciju i njen ID procesa servera (SPID). Možete prikupiti više detalja o tome šta SPID radi upitom na dinamičke prikaze upravljanja (DMV):
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>;
Ako je transakcija neispravan upit ili zaglavljen proces, možda ćete morati da ga prekinete da biste oslobodili log.
KILL <SPID>;
Napomena: Prekidanje masivne transakcije će pokrenuti poništavanje (rollback), što može potrajati značajno vreme i privremeno će generisati dodatnu aktivnost loga. Nemojte ponovo pokretati SQL Server servis tokom poništavanja, inače će baza podataka ući u režim oporavka nakon ponovnog pokretanja.
Scenario 3: Hitna dodela prostora (Disk je 100% pun)
Ako je LDF datoteka potrošila ceo disk, ne možete čak ni da pokrenete backup jer SQL Server zahteva malu količinu prostora u logu da bi zabeležio sam događaj backup-a. U ovom scenariju, morate dodati sekundarnu log datoteku na drugom disku sa dostupnim prostorom.
ALTER DATABASE [YourDatabaseName]
ADD LOG FILE
(
NAME = N'YourDatabaseName_Log2',
FILENAME = N'E:TempLogsYourDatabaseName_Log2.ldf',
SIZE = 5GB,
MAXSIZE = 50GB,
FILEGROWTH = 1GB
);
Ovo odmah pruža SQL Serveru prostor za rad. Kada baza podataka bude na mreži, napravite rezervnu kopiju transakcionog loga, ispraznite sekundarnu log datoteku i uklonite je:
-- 1. Napravite log backup da skratite log
BACKUP LOG [YourDatabaseName] TO DISK = '...';
-- 2. Ispraznite privremenu log datoteku
DBCC SHRINKFILE (N'YourDatabaseName_Log2', EMPTYFILE);
-- 3. Uklonite privremenu log datoteku
ALTER DATABASE [YourDatabaseName] REMOVE FILE [YourDatabaseName_Log2];
Najbolje prakse za prevenciju i upravljanje transakcionim logom
Reaktivno rešavanje problema je stresno i utiče na SLA. Implementacija proaktivnih arhitektonskih i operativnih najboljih praksi je ključna za stabilnost baze podataka u preduzeću.
1. Implementirajte robusnu, automatizovanu strategiju backup-a
Ako je baza podataka u modelu potpunog (Full) oporavka, česte rezervne kopije transakcionog loga su obavezne. U zavisnosti od vašeg cilja tačke oporavka (RPO) i obima transakcija, backup loga treba da se dešava svakih 5 do 15 minuta.
Enterprise rešenja za backup kao što je CloudSave značajno pojednostavljuju ovaj proces. Integracijom direktno sa SQL Serverom putem VDI (Virtual Device Interface), CloudSave omogućava DBA-ovima da konfigurišu backup transakcionog loga visoke frekvencije vođen politikama. Ovo osigurava da se logovi kontinuirano skraćuju, bezbedno šifruju i skladište van lokacije ili u nepromenljivom cloud skladištu, sprečavajući stanje čekanja LOG_BACKUP bez potrebe za složenim prilagođenim SQL Agent poslovima.
2. Pravilno dimenzionišite transakcioni log i upravljajte VLF-ovima
Oslanjanje na automatsko povećanje (auto-growth) za upravljanje veličinom transakcionog loga je opasan anti-obrazac. Operacije automatskog povećanja su skupe i pauziraju obradu transakcija dok se disk ne inicijalizuje nulama (osim ako je omogućena Instant File Initialization, koja se ne primenjuje na log datoteke).
Štaviše, česta, mala automatska povećanja (npr. povećanje za 10% ili 50MB odjednom) dovode do VLF fragmentacije. Transakcioni log sa hiljadama malih VLF-ova će ozbiljno degradirati vreme pokretanja baze podataka, performanse backup-a i latenciju replikacije.
- Prethodno dimenzionišite log: Analizirajte svoje najveće operacije održavanja (poput ponovnog indeksiranja) i prethodno dimenzionišite LDF datoteku da ih prihvati bez rasta.
- Postavite fiksno automatsko povećanje: Promenite automatsko povećanje sa procenta na fiksnu veličinu (npr. 1GB ili 5GB) kako biste osigurali da se VLF-ovi kreiraju u zdravoj veličini.
Možete proveriti svoj broj VLF-ova koristeći sledeći upit (za 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'));
Ako je vaš broj VLF-ova preko 500, razmislite o čekanju na miran period, smanjivanju loga na minimalnu veličinu i ručnom povećanju nazad na potrebnu veličinu u velikim komadima.
3. Optimizujte operacije održavanja indeksa
Ponovno indeksiranje (Index rebuilds) su operacije koje se u potpunosti loguju, čak i u modelu Bulk-Logged oporavka (u zavisnosti od tipa indeksa). Ponovna izgradnja indeksa od 500GB će generisati najmanje 500GB zapisa transakcionog loga.
Da biste ublažili pretrpanost loga tokom održavanja:
* Koristite SORT_IN_TEMPDB = ON prilikom ponovne izgradnje indeksa. Ovo prebacuje fazu sortiranja u TempDB, smanjujući opterećenje na transakcioni log korisničke baze podataka.
* Prebacite se sa ponovne izgradnje indeksa na reorganizaciju indeksa gde je to moguće, jer su reorganizacije efikasnije u pogledu loga i mogu se prekinuti bez poništavanja cele operacije.
* Grupisano izvršavajte velike DELETE ili UPDATE operacije. Umesto brisanja 10 miliona redova u jednoj transakciji, brišite ih u grupama od 50.000, potvrđujući (committing) i omogućavajući backup-u loga da skrati log između grupa.
4. Nadgledajte visoku dostupnost i topologije replikacije
U AlwaysOn grupama dostupnosti, primarna replika ne može da skrati svoj log dok se zapisi loga ne potvrde na svim sinhronim i asinhronim sekundarnim replikama.
Ako sekundarna replika ode van mreže, ili ako propusni opseg mreže ne može da prati brzinu generisanja transakcija primarne replike, red za slanje primarne replike će rasti, a log će se popuniti (tip čekanja AVAILABILITY_REPLICA).
Implementirajte robusno nadgledanje za brojač performansi SQLServer:Replica > Log Send Queue. Ako je sekundarna replika trajno izgubljena, morate je ukloniti iz grupe dostupnosti ili suspendovati kretanje podataka kako biste omogućili skraćivanje primarnog loga.
Zaključak
Nailazak na pun transakcioni log je vatreno krštenje za administratore baza podataka, ali ne mora da rezultira produženim zastojem. Razumevanjem mehanike Write-Ahead Logging-a i VLF-ova, možete brzo dijagnostikovati osnovni uzrok koristeći sys.databases i primeniti ispravnu strategiju brzog oporavka.
Dugoročna stabilnost se oslanja na udaljavanje od reaktivnih popravki. Prethodno dimenzionisanje vaših log datoteka, optimizacija rutina održavanja i korišćenje platformi za backup na nivou preduzeća kao što je CloudSave za sprovođenje strogih, automatizovanih rasporeda backup-a loga osiguraće da vaši transakcioni logovi ostanu zdravi, skraćeni i spremni da podrže produkciona opterećenja visokog propusnog opsega.