Makale Özeti

SQL Server' da bir veritabanı temel olarak iki dosyadan oluşur. Bunlardan birisi verileri tutulduğu veri dosyasıdır. Diğeri de veri dosyasına karşı yapılan işlemlerin kayıtlarının tutulduğu kayıt dosyası (Transaction Log). Kayıt dosyasının boyutu zaman zaman veritabanına karşı yapılan işlemlere göre çok şişebilir ve bu dosyanın boyutunu düşürmek isteyebilirsiniz. İşte bu yazımda size bu konuda bilgi vereceğim.

Makale

Merhaba arkadaşlar,


Giriş
SQL Server' da bir veritabanı temel olarak iki dosyadan oluşur. Bunlardan birisi verileri tutulduğu veri dosyasıdır. Diğeri de veri dosyasına karşı yapılan işlemlerin kayıtlarının tutulduğu kayıt dosyası (Transaction Log). Kayıt dosyasının boyutu zaman zaman veritabanına karşı yapılan işlemlere göre çok şişebilir ve bu dosyanın boyutunu düşürmek isteyebilirsiniz. İşte bu yazımda size bu konuda bilgi vereceğim.

Veri Dosyaları (Data Files)
İlk paragrafta sizlere veritabanının iki temel dosyadan oluştuğunu ve bunlardan birisinin de veri dosyası olduğunu söylemiştim. Veri dosyalarının uzantıları varsayılan olarak "*.mdf" tir. Fakat böyle olmak gibi bir zorunluluğu da yoktur. Bu sadece bir standarttır, fakat standartlara bağlı kalmak veya kendi standartlarınızı oluşturmak da çok önemli bir işlemdir.

Kayıt Dosyaları (Transaction Files)
Diğer temel olan dosya ve esas değinmek istediğim ise kayıt dosyasıdır. Kayıt dosyalarının da varsayılan uzantısı "*.ldf" tir. Gene veri dosyaları gibi bunların da dosya uzantılarının "*.ldf" olması zorunlu değildir.

Kayıt dosyasına birçok tip işlem kaydedilmektedir, aşağıdakiler bu işlemler arasındadır:

     - Tüm işlemlerin başlangıç ve bitişi,
     - INSERT, UPDATE ve DELETE gibi tüm veri değişiklikleri. Yani DML (Data Manipulation Language) işlemleri ve ayrıca DDL (Data Definition Language) işlemleri,
     - Tüm "extent" ve "sayfa (page)" ayırma ve kapatma işlemleri,
     - Bir tablo veya indeks oluşturma ve silme işlemleri...

Meselâ şöyle sorular geliyor: "Bir tablom var ve çok büyük. Tablonun iskeleti gerekiyor, ama içindeki verileri tamamen boşaltmak istiyorum. Fakat silmeye başlayınca kayıt dosyamın şiştiğini görüyorum. Acaba grup grup mu silsem ve sonra kayıt dosyamı küçültsem sonra aynı işlemleri sırasıyla tekrarlasam olur mu? Daha kolay bir yöntem yok mu?!" Var tabii, meselâ TRUNCATE TABLE ile bir tabloyu sildiğinizde, DELETE komutundan farklı olarak yaptığınız işlem kayıt dosyasına kaydedilmez.

Bazı arkadaşlar ise gerek habergruplarında gerekse de forumlarda şöyle sorular soruyorlar: "Veritabanımda indeksleme işlemi yapıyordum ve bir süre sonra 'kayıt dosyası doldu!' gibi bir hata alıyorum" diyorlar veya "İndeksleme işlemi yaparken kayıt dosyamın boyutunun çok arttığını fark ettim, bu dosyamın boyutu neden büyüyor? Kayıt dosyamı nasıl eski haline getirebilirim?" gibi gibi... Yukarıda da sıraladığım gibi, İndeksleme işlemi de kayıt dosyasında takip edilen bir işlemdir. Bu nedenle indeksleme işlemine dair tüm bilgiler kayıt dosyasına da saklanır. Yapacağınız indeksleme ne kadar geniş çaplıysa, kayıt dosyanız da ona eşit orantılı olarak büyüyecektir. Bu nedenle "kayıt dosyası doldu" hatası almamak için hem kayıt dosyanızın "dosya boyutu sınırı" ayarının düzgün yapılandırdığından, hem de kayıt dosyanızın bulunduğu diskte yeterli alan olduğundan emin olun.

Kayıt Dosyalarının Boyutlarını Küçültme
Kayıt dosyalarınızın boyutlarını küçültmek için ilk önce yedeklerini almanız gerekiyor veya doğrudan içlerindeki Pasif Sanal Kayıtları aşağıdaki örneklerde verdiğim gibi temizleyebilirsiniz:

BACKUP LOG veritabani_adi WITH TRUNCATE_ONLY

veya

BACKUP LOG veritabani_adi WITH NO_LOG

Bu komutlardan birini kullandıktan ve dolayısıyla kayıt dosyasının içerisindeki pasif sanal kayıtları temizledikten sonra, dosyanın fiziksel boyutunu küçültmek için DBCC SHRINKFILE komutunu kullanmalısınız. Aşağıdaki örnekte, Deneme_Log isimli kayıt dosyasının boyutu 1MB' a düşürülecektir. Bu komutu ise aşağıdaki örneğe göre kullanabilirsiniz:

DBCC SHRINKFILE (Deneme_Log, 1);

Not:
Burada göz önünde bulundurmanız gereken şey, kayıt dosyasının içerisindeki sanal kayıtların, en son aktif sanal kayda kadar silinebileceğidir. En son aktif sanal kayıttan daha sonrası silinemez, ta ki o aktif kayıt pasifleşinceye kadar. Aktif ve Pasif Sanal Kayıtlardan aşağıda söz edeceğim.

Ayrıca, bu konu hakkında SQL Server 2008' de bazı değişiklikler var. Bununla ilgili olan ve aşağıda adresini verdiğim makalemi de okuyabilirsiniz:
SQL Server 2008' de 'TRUNCATE_ONLY' ve 'NO_LOG' BACKUP Seçenekleri

Bununla birlikte, "Recovery Models" konusu da doğrudan kayıt dosyasının büyümesiyle alâkalı bir konudur. Meselâ bir kayıt dosyasının içini SIMPLE RECOVERY modelini kullanarak da belli aralıklarla temizleyebilirsiniz. Bu konuda da daha fazla bilgi almak için aşağıdaki makalemi okuyabilirsiniz:
Recovery Models: FULL, BULK LOGGED, SIMPLE

Kayıt dosyalarının dosya boyutlarını sürekli düşük bir değerde tutmak da marifet değildir. Aslında Veritabanı Yöneticisi olmayıp, ama kaynak olmadığı için de bu konuda bir uzmanla çalışamayan kişilerin sürekli bu tür hatalar yaptıklarını gözlemliyorum.

Aşağıdaki paragrafa geçmeden önce hemen kısaca Aktif Sanal Kayıt ve Pasif Sanal Kayıtlardan da bahsetmek istiyorum. Kayıt dosyası içerisindeki kayıtlar Aktif ve Pasif Sanal Kayıtlar olarak sınıflandırılır. Aktif Sanal Kayıtlar, "Rollback" işlemi için açılmış ve başarıyla devam eden işlemler silsilesindeki kayıtlardır. Bu kayıtlar ne kayıt dosyasının yedeği alınarak, ne de başka bir şekilde kesinlikle temizlenemezler. Pasif Kayıt Dosyaları ise, kayıt dosyasının yedeği alınarak temizlenebilir.

Peki neden kayıt dosyalarının boyutları çok düşük olmamalı ve ortamınıza özel belli bir değerde olmalı? Çünkü yukarıda da anlattığım gibi veritabanınızda işlemler gerçekleştirildikçe, bu işlemler kayıt dosyasına işlenirler. Metin dizeleri gibidir kayıt dosyaları da yani belli bir sıraya göre düzenlenir ve yeni işlemler hep sona eklenirler. Her işlemin bir LSN (Kayıt Sırası Numarası) i vardır. Siz işlem yaptıkça dosya büyür de büyür. Ve her büyüme esnasında Veritabanı Motoru işlemleri durdurup, kayıt dosyasının boyutunu büyütür ve işlemlere devam eder.

Şöyle bir örnek vereyim: Veri dosyası boyutu 80GB olan ve her gün veri girişi yapılan ve yoğun kullanılan bir veritabanınız olsun. Bunun kayıt dosyasının boyutunu ise her gün kayıt dosyası yedeğinin alınması işleminin ardından "DBCC SHRINKFILE\SHRINKDATABASE" gibi komutlar kullanarak veya "Maintanence Task" lar kullanarak küçülttüğünüzü varsayalım. Dosya büyüme oranı da 10MB olsun. Bunun anlamı şu dur, kayıt dosyasının yedeğini alma işlemiyle kayıt dosyanızın içindeki Pasif Sanal Kayıtları temizlersiniz, DBCC SHRINK işlemi ile de dosyanın fiziksel boyutunu küçültürsünüz; yani yeni işlemler için kayıt dosyasının içerisinde boşluk kalmaz. Bu nedenle, yeni işlemler için kayıt dosyasının fiziksel boyutunun büyütülmesi gerekir. Zaten yoğun kullanılan bir veritabanı ve büyüme değeri de sadece 10MB. Veritabanı Motorunun sürekli bu dosyanın boyutunu büyütmesi gerekeceği zaman nasıl bir sorunun oluşabileceğini görüyorsunuz değil mi? İşte bu, performans sorunlarına katkıda bulunabilecek önemli bir etkendir.

Sonuç
Gerekli gereksiz kayıt dosyasının küçültülmesi işleminin yapılmamasını tavsiye ederim. Kayıt dosyanızı belli bir büyüklük değerinde bırakın, sürekli büyüyüp küçülmesi gerekmesin. SHRINK işlemlerini gerektiğinde siz yapın, otomatikleştirmeyin. Ayrıca otomatik dosya büyüme değeri için de küçük değerler kullanmayın. Eğer yeriniz varsa bırakın rahatça büyüsün. Ama 80GB' lık veritabanında da 50GB kayıt dosyası olsun demiyorum tabi, yazımın belli yerlerinde de dediğim gibi, her ortamın kendine has özellikleri ve ihtiyaçları vardır. Siz de ayarlarınızı kendi durumunuza uygun yapın.


 

Ekrem Önsoy