dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Runbook #27
sqlserver
AvailabilitySEV1 · KRİTİK KESİNTİ15-30 dakika / 15-30 minssysadmin / CONTROL SERVER / VIEW SERVER STATE

SQL Server Transaction Log Doldu (Error 9002): Nedeni Bulma ve Güvenli Çözüm

log_reuse_wait_desc ile logun neden temizlenemediğini bulur ve nedene göre çözer: log yedeği, açık transaction, replika veya replikasyon. Yanlış "SIMPLE'a geç ve shrink et" hatasını önler.

İlişkili Metrik:M30M33
İlişkili Script:S59S49S46
#transaction-log#error-9002#log-reuse#backup

Operasyonel Güvenlik ve Risk Uyarısı

Bu runbook müdahale adımları içerir; birçok adım yazma etkilidir (KILL, terminate, DROP, RESIZE). Önce test ortamında deneyin, üretimde adımları sırayla ve doğrulayarak uygulayın.

🟢 Salt Okunur (Read-Only)·🟡 Geri Alınabilir (Reversible)·🔴 Yüksek Etkili / Geri Alınamaz (High Impact)

1. Belirti / Symptom

- `Error 9002: The transaction log for database 'X' is full due to 'LOG_BACKUP'` (veya başka neden).

- Yazma işlemleri başarısız; M30 %90 üzeri.

2. Etki / Impact

İlgili veritabanında **yazmalar durur**, okumalar sürer. Uygulama yazma hataları verir.

3. Teşhis / Diagnosis

🟢 Salt Okunur1. **Neden nedir?** (S59):
sql
SELECT name, recovery_model_desc, log_reuse_wait_desc FROM sys.databases WHERE name = 'X';
SELECT used_log_space_in_percent, total_log_size_in_bytes/1048576 AS log_mb
FROM sys.dm_db_log_space_usage;   -- ilgili veritabanı bağlamında
🟢 Salt Okunur2. `log_reuse_wait_desc` değerine göre:
DeğerAnlamıÇözüm
`LOG_BACKUP`FULL recovery'de log yedeği alınmıyorLog yedeği alın
`ACTIVE_TRANSACTION`Uzun/açık transactionTransaction'ı bulun (S49)
`AVAILABILITY_REPLICA`Always On replika gerideReplikayı kontrol edin
`REPLICATION`Log reader agent geride/durmuşReplikasyon agent'ını düzeltin
`DATABASE_MIRRORING`Mirror gerideMirror durumunu kontrol edin
`CHECKPOINT`Henüz checkpoint olmamış`CHECKPOINT;`
`NOTHING`Sorun yok / alan başka nedenle doluDisk dolu mu kontrol edin
🟢 Salt Okunur3. Disk dolu mu? Log dosyası otomatik büyüyemiyor olabilir (disk yok veya `MAXSIZE`).
🟢 Salt Okunur4. Son log yedeği ne zaman alındı (S46)? Yedek job'ı sessizce mi başarısız oldu?

4. Müdahale / Response

1. **`LOG_BACKUP` ise (en sık):** Log yedeği alın. Disk için yer gerekiyorsa yedeği başka bir sürücüye alın:

sql
BACKUP LOG [X] TO DISK = N'E:\Yedek\X_log.trn';

Yedek sonrası log kullanımı boşalır (dosya boyutu küçülmez, sadece içi boşalır).

2. **`ACTIVE_TRANSACTION` ise:** Transaction'ı bulun ve sonlandırın (rollback uzun sürebilir):

sql
DBCC OPENTRAN('X');
KILL <spid>;

3. **`AVAILABILITY_REPLICA` ise:** Replika bağlantısını/erişilebilirliğini düzeltin. Replika çok uzun süre kopuksa log şişer; dayanılmaz hale gelirse replikayı AG'den çıkarmayı değerlendirin.

🔴 YÜKSEK RİSK / GERİ ALINAMAZ4. **Disk tamamen dolduysa:** Logu başka bir sürücüye geçici ek dosya olarak ekleyin:
sql
ALTER DATABASE [X] ADD LOG FILE
 (NAME = X_log2, FILENAME = N'F:\Log\X_log2.ldf', SIZE = 8GB, FILEGROWTH = 1GB);
🔴 YÜKSEK RİSK / GERİ ALINAMAZ5. **Yapmayın (FULL recovery'de):** `SIMPLE` recovery'ye geçip `DBCC SHRINKFILE` yapmak **log zincirini kırar**, point-in-time recovery imkanını kaybettirir. Yalnızca veri kaybını göze alıyor ve yeni full yedek alacaksanız düşünün.

6. **Kalıcı çözüm:**

- Log yedek job'ını sık çalıştırın (RPO'ya göre 5-15 dk) ve başarısızlığını izleyin (M33).

- Log dosyasını doğru boyutlayın, sabit MB cinsinden `FILEGROWTH` verin (yüzde değil), VLF sayısını kontrol edin.

- Toplu işleri küçük batch'lere bölün.

5. Doğrulama / Verification

- `log_reuse_wait_desc = NOTHING` ve `used_log_space_in_percent` normal.

- Yazmalar başarılı, uygulama hataları durdu.

- Log yedek zinciri sağlam (`msdb.dbo.backupset` ardışık LSN).

6. Geri Alma / Rollback

- Geçici ek log dosyasını işiniz bitince kaldırın: önce `DBCC SHRINKFILE (X_log2, EMPTYFILE)` sonra `ALTER DATABASE ... REMOVE FILE X_log2`.

- `KILL` ve `SIMPLE` geçişi geri alınamaz (zincir kopar).

Diğer SQLSERVER Runbook'ları