MSSQL Server Log Dosyasını Shrink Etmek

Bu makalede sql server log dosyasını shrink etmek konusunu ele alacağız. Bunun için ilk başta neden log dosyasını shrink ederiz bu konuyu ele alalım. Bazen log dosyamız bir transaction geldiğinde aşırı derecede büyüyebilir. İşletim sisteminden tahsis edilen disk alanını daha sonra tekrardan işletim sistemine iade edilmez. Örnek verecek olursak başlangıçta 100 GB’lık bir transaction geldiğinde ldf dosyasının boyutu 100 GB olur. Log backup alındıktan sonra ldf dosyası içinde veri olmasa bile boyutu 100 GB olarak kalmaya devam eder. Bu sebepten dolayı ldf dosyasında bulunan boş disk alanının işletim sistemine iade etmemiz gerekebilir. Disk konusunda herhangi bir sıkıntımız yoksa bu işleme gerek yoktur. Çünkü dosyamız o boyuta gelmişse tekrardan o boyuta gelme ihtimali çok yüksektir. Ama yok ben shrink’i çok seviyorum yapmak istiyorum derseniz aşağıdaki adımları uygulayarak deneyebilirsiniz. Ben gerçek sistem üzerinde shrink işlemi yapacağım ve resimlerle teyit etmek edeceğim.

Shrink Etmeden Önce Bilmen Gerekenler

  • Veri kaybı olmaz, ama log yedeği almadıysan büyümeye devam eder.
  • Her zaman yapılmaz – Sadece log kontrol altına alınmadan büyümüşse
  • Tekrar büyümesi log işlemi sırasında performans kaybı yaratabilir
  • Aktif transaction varsa shrink başarısız olur

Önceki makalemizde vlf sayılarının fazla olmasının database üzerinde oluşturacağı sıkıntılardan bahsetmiştik.(Sql Server Virtual Log File) Vlf sayısını düşürmek için log backup alınıp uygun bir auto growth değeri set edilmesi ve daha sonra log dosyamızın shrink edilmesi gerektiğinden  makalemizde belirtmiştik.

Aşağıdaki adımlarda shrink işlemini uygulamalı bir şekilde yapmaya çalışalım.

Bu yapıdan önce veritabanımızın shrink edilebilip edilmediğini aşağıdaki komut ile görebiliriz.

select name, log_reuse_wait_desc from sys.databases

Not: log_reuse_wait kolonu ise log_reuse_wait_desc kolonundaki değerlerin sayısal olarak karşılığıdır.

Bu komut konusunda NOTHING yazılması log dosyamızın shrink edilebilirliğini bize söylemiş oluyor.

Veritabanı üzerine sağ tıklayarak Task>Shrink>Files kısmına girilir.

Gelen ekranda File Type kısmında Log ifadesini seçmemiz gerekiyor. Yanlışlıkla data seçerseniz veritabanımızı suspend modu veya corruption olabilir. Bundan önce in-active vlf’lere bakıp shrink edeceğimiz veritabanını belirleyebiliriz. Bu işlemede aslında çok gerek olmadığını vlf makalesinde belirtmiştik. Aşağıdaki komutla In-active VLF ifadesiyle hangi database’in shrink edilebileceğini tahmin edebiliriz.

SELECT [name], s.database_id,
COUNT(l.database_id) AS 'VLF Count',
SUM(vlf_size_mb) AS 'VLF Size (MB)',
SUM(CAST(vlf_active AS INT)) AS 'Active VLF',
SUM(vlf_active*vlf_size_mb) AS 'Active VLF Size (MB)',
COUNT(l.database_id)-SUM(CAST(vlf_active AS INT)) AS 'In-active VLF',
SUM(vlf_size_mb)-SUM(vlf_active*vlf_size_mb) AS 'In-active VLF Size (MB)'
FROM sys.databases s
CROSS APPLY sys.dm_db_log_info(s.database_id) l
GROUP BY [name], s.database_id
ORDER BY 'VLF Count' DESC
GO

Yukarıdaki  komutun alternatifi olarak aşağıdaki resimde bulunan  komutla log dosyamızda ne kadar boş alan var görebiliriz.

Aşağıdaki resimde  Task>Shrink>Files kısmında Log ifadesini seçiyorum. File name kısmında shrink etmek istediğimiz log’u seçebiliriz.

Currently Allocated Space kısmında log dosyamızın maksimum büyüklüğünü görebiliriz.

Aşağıdaki resimde gelen ekranda Available free space kısımında log dosyasının %99 oranında  boş olduğu görünüyor. Zaten in_active vlf sayımızda fazla olduğunu görmüştük.

Shrink action kısmında 3 seçenek karşımıza çıkmaktadır.

  • Release unused space kullanılmayan alanların tamamını işletim sistemine iade etmek ister. Büyük databaselerde bu yapı kullanılmaz çünkü kullanılmayan alan büyükse hemen işletim sistemine iade edemez. Bu seçenek seçildiğinde komut aşağıdaki gibidir.
USE [Db_Name]
GO
DBCC SHRINKFILE (N'Db_Name_log', 0, TRUNCATEONLY)
GO
  • Release unused space seçeneğindeki sıkıntıdan dolayı ikinci seçenekte bulunan Reorganize pages before releasing unused space kısmı kullanarak kademeli kademeli disk alanını işletim sistemine iade etmek gerekir. Başlangıç olarak default olarak mevcut boyut gelmektedir.
  • Son seçenekte bulunan Empty file by migrating the data to other files in the same filegorup   ise  veritabanı altında ikinci bir log dosyası oluşturduktan sonra ilk log dosyasını shrink edip eski log dosyasının üzerine ikinci oluşturulan log dosyasını yazıp daha sonra log dosyamızı silebiliriz. Bununla ilgili karşılaşmış olduğum bir senaryoyla ilgili Empty file by migrating the data to other files in the same filegorup   makalesini okuyabilirsiniz.

Aşağıdaki resimde ldf dosyamızdaki boş alan %99 oranında olduğu için  log backup almıyorum. Log dosyam büyük olduğu için ikinci seçeneği seçip daha sonra script’ini alıyorum.

USE [Db_Name]
GO
DBCC SHRINKFILE (N'Db_Name_log',225319)
GO

Yukarıdaki ifadeye tıklayınca 225.319 şeklinde geliyor. Burayı 220000 yaparsak 5 gb lık bir shrink işlemi aslında yapılmaktadır. Yukarıdaki ifade MB cinsindendir. Tam 5 gb düşmese de 5 gb’a yakın düşmektedir.

Bu komuttan sonra ldf dosyamızın boyutunun düştüğünü Currently allocated space alanından bulabiliriz.

Shrink yaptıktan sonra  bir log backup alalım ve mevcut olan allocated space alanını düşürelim. Log backup alınırken restore ederken sıkıntı yaşamamak için aynı log dizini altına alınması gerekmektedir.

Backup’ı alıp tekrardan shrink işlemini yapalım. Şunu da belirtmek gerekirse backup alındıktan sonra shrink yapılamıyorsa  boş alan işletim sistemine iade edilemiyorsa tekrardan bir backup alınabilir.

Tekrar shrink işlemine tabi tutuğumuzda veritabanımızın düşebileceği maksimum seviyeye düştüğünü ve in-active vlf sayısının sıfır olduğunu görmüş oluyorum. Zaten aşağıdaki resimdeki VLF Size ile currently allocated space alanlarının  aynı olduğunu görmüş oluyoruz.

Sonuç olarak shrink işlemimiz başarılı bir şekilde gerçekleşmiş oldu. Başlangıçta 225 GB olan ldf dosyamız shrink işlemi ile birlikte 52 GB’ düşmüş oldu.

Not olarak şunu belirtmek gerekirse data file shrink edilebilir. Shrink edilince veritabanı bozulma ihtimali çok yüksek olur. Shrink edilen data dosyalarındaki indexs fragmantation çok yüksek oranda artacaktır. Bu yüzden önerilen yöntem yeni bir file group oluşturup shrink yapılacak file groupdaki tüm indexsleri ilgili file group altına koymamız tercih edilir. Ndf uzantılı filegroup shrink edildikten sonra silinebilir. fakat mdf uzantılı filegroup sadece shrink edilebilir.

Ne Zaman Shrink Yapmamalısın?

  • Sürekli büyüyen ve küçülen log dosyaları I/O’yu artırır, performansı bozar.
  • Eğer log dosyan büyük ama içeriği aktifse, shrink yapılamaz.
  • Eğer log dosyasının neden büyüdüğünü anlamadan sık sık shrink ediyorsan, bir yapısal sorun var demektir:
    • Log yedeği alınmıyor olabilir
    • Uzun süreli transaction olabilir
    • Replikasyon ya da Always On log işlemlerini bekletiyor olabilir

NOT: Alwayson yapısında bir sunucuda shrink işleminin yapılması diğer sunucuda bulunan aynı log dosyasınada yansımaktadır. Boyutları aynı olmaktadır. Stand alone veritabanlarında bu düşüş yaşanmaz. Sunucu bazlı işlem çalışmaktadır.

Bu makalede log dosyasının nasıl shrink edildiğini görmüş olduk.

Başka makalede görüşmek dileğiyle..

“De ki: ‘Ey kendilerinin aleyhine aşırı giden kullarım! Allah’ın rahmetinden ümidinizi kesmeyin. Şüphesiz Allah, bütün günahları affeder. Çünkü O, çok bağışlayandır, çok merhamet edendir.’ “ Zümer Suresi; 53. Ayet

Author: Yunus YÜCEL

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir