SQL Server’da Backup Seçenekleri, Transaction Log Yapısı ve Restore

SQL Server’da üç tür backup almak mümkündür. Full, Differantial ve Transaction Log backup. Alınan backup’ların history bilgisi MSDB veritabanında tutulur. Bununla ilgili şu sayfaya bakabilirsiniz.

Full Backup : İsminden tahmin edileceği üzere veritabanının tamamının kopyasının alınmasıdır. Kopyanın alındığı tarih ve saate, veritabanımızı başka bir dosyaya ihtiyaç duyulmadan restore yani geri yükleme yapabiliriz.

Full backup

Differantial Backup : Bir önceki full backup’tan bu yana veritabanında yapılmış olan değişikliklerin yedeğidir. Büyük boyutlu, yoğun işlem gören veritabanlarında sürekli full backup almak hem donanım kaynakları açısından hem de zaman yönetimi açısından maliyetli bir işlemdir. Bu maliyeti tolere edebilmek differantial backup alarak mümkündür. Bu backup türü bir full backup’ı temel alır ve temel aldığı full backup tan bu yana veritabanının uğradığı değişiklikleri tutar. Dikkat edilecek önemli nokta şudur ki; differential en son alınan full backup’tan bu yana yapılan değişikliklerin yedeğidir. Bir önceki differential backup’tan bu yana alınan değişikliklerin yedeği değildir.

Transaction Log Backup :  Transaction Log veritabanı üzerinde yapılan her bir değişikliğin kaydının tutulduğu log dosyasıdır. Bu logların yedeğinin alınması da üçüncü backup türümüzdür. Transaction Log backup veritabanımızın son full ya da differential yedekten sonra tutarlılığını sağlar. Bu yüzden yoğun işlem gören veritabanlarında olmazsa olmazdır.

Backup konusunun ve özellikle transaction log backup’ın anlaşılabilmesi için transaction log yapısının anlaşılması çok önemlidir. Transaction Log bir ya da daha fazla fiziksel dosyadan oluşabilir. Ancak Sql Server transaction log dosyalarını sequential yani sıralı olarak kullanır, eş zamanlı paralel olarak kullanmaz. Bu yüzden birden çok transaction log dosyasının log performansı anlamında bir katkısı yoktur. Diskte ayrılan tüm alana fiziksel log, bu fiziksel alan içerisindeki loga logical log (mantıksal log) adı verilir. Kavramsal olarak log kayıtlarından oluşan bir dizidir transaction log ve başında 8KB boyutunda header bulunur. Bu header tr log dosyasına ait boyut ve auto growth ayarları gibi bilgiler tutar.

Sql server motoru transaction log dosyasını, belirli parametrelere göre VLF olarak kısaltılan Virtual Log parçalarına böler. Bu parçalı yapı tr log’un yönetimini kolaylaştırır. VLF sayısını ya da boyutunu biz belirleyemeyiz. Şöyle ki;
Transaction Log dosyası boyutu 64 MB dan küçükse 4 VLF, 64MB ile 1GB arasındaysa 8VLF, 1GB’dan büyükse 16 VLF oluşur. Verdiğimiz autogrowth boyutuna göre vlf sayısı ve log boyutu bu parametrelere göre artmaya devam eder. Transaction Log sarmal (circular) bir yapıya sahiptir.

Eğer VLF içerisinde bir log kaydı var ise bu aktif bir VLF dir ve SQL server bu alanı kullanamaz. Yeni oluşturulan VLF inaktif ve kullanılmaz durumdadır. Yeni oluşturulmuş veritabanı hariç ilk VLF de her zaman kullanılır. Bir transaction log da en az bir tane VLF aktif ve kullanılıyor durumda olur. Bu VLF’lerin içerisinde de boyutları 512 byte ila 60 kb arasında değişen ve log kayıtlarını tutan log blokları bulunur. Log blok dolduğunda diske yazılmak zorundadur. Transaction Log Backup alındığında log truncate edilir yani commit olan kayıtlar diske yazılarak, bu kayıtları tutan VLF ler boş olarak işaretlenir ve unused statüsüne geçer yani kullanıma açılır. Truncate işleminin bu kayıtları sildiği bilgisi genelde yanlış algılanmış bir bilgidir. Kaydı içeren VLF kullanılabilir olarak işaretlernir. Ancak VLF açık bir transaction’a ait log kaydı barındırıyorsa istisnadır ve aktif durumda kalabilir. Log truncate etmenin tek yolu log backup’ı almaktır. Log dosyasının büyümesini engellemek için mümkün olduğunca sık transaction log backup alınır. Log’u truncate etmeden backup almanın yolu “Copy Only” backup seçeneğidir. Copy Only backup konusunda şu yazıdan detaylı bilgi alabilirsiniz. Aşağıdaki şekildeki MinLSN değeri log içerisindeki en eski ve açık transaction’a ait LSN değeridir. Sql Server peşi sıra gelen tüm kayıtları logical log’un sonuna yazar.

Backup Zinciri && LSN Numaraları


SQL Server transaction log içerisindeki her kayıt için kendine ait bir sıra numarası verir. Bu sıra numarasına «Log Sequence Number, LSN» adı verilir. LSN numarası büyük olan kayıt log dosyasına LSN numarası küçük olan kayıttan sonra işlenmiştir. Log yedekleri LSN değeri üzerinden son Full backup ı referans alarak bir backup zinciri oluşturur. LSN üç parçadan oluşan decimal ya da hexadecimal formatta bir sayıdır
•VLF sıra numarası (Virtual Log File)
•Log Blok Numarası
•Log Kayıt Numarası

RESTORE HEADERONLY FROM DISK = 'fullyedek.bak'
Bu komut bize yedeğin niteliklerine dair birçok bilginin yanında dört tane LSN değeri döndürür
FirstLSN –Backup seti içerisindeki ilk transaction’a ait Log Sequence Number
LastLSN – Backup setinden sonraki ilk log kaydının LSN‘i
CheckpointLSN – Son checkpoint’e ait LSN
DatabaseBackupLSN – Son full backup’a ait LSN

CHECKPOINT işlemi memory’de veri üzerinde yapılan değişikliklerin diske kaydedilmesidir. Diskten buffer cache’e getirilen data değiştiğinde henüz diske yaılmadığı için dirty page olarak adlandırılır. Verideki bu değişime dair log buffer’da bir log record oluşur. Log Flush adı verilen işlemle Log buffer’daki bu kayıt transaction log dosyasına yazılır. Hemen akabinde de buffer cache’deki ilgili değişiklik diskteki mdf dosyasına yazılır. Yani önce transaction log dosyasına sonra mdf dosyasına yazılır. Bir felaket durumunda log dosyası ile verinin tutarlılığının korunması için gerçekleşen bu mekanizmaya write ahead logging denir.

Bir veritabanını restore ederken, LSN zincirine dikkat etmek gerekir. Aksi takdirde şu hata alınır “Unable to Create Restore Plan Due to Break in the LSN Chain”. LSN zincirini korumak için şu hususları bilmek faydalı olacaktır:

Alınan ilk full backup’da DatabaseBackupLSN değeri daima sıfırdır.
Alınan ilk full backup’da FirstLSN ve CheckpointLSN değerleri aynıdır.
Veritabanını geri yükleyeceğimiz zaman hangi differential backup bizim full backup’ımızla ilintiliyse anlamak için
DatabaseBackupLSN (differential backup) = CheckpointLSN (full backup)

Eğer differential backup’ımız yoksa, full backup ve transaction log yedeklerimiz varsa LSN zincirini korumak için şu konuya dikkat etmemiz gerekir:
FirstLSN(TransactionLog) < LastLSN (Full Backup) < LastLSN(TransactionLog)

Differential backup’tan sonra hangi transaction log’un geleceğini anlamak için:FirstLSN(TrLog) < LastLSN(Diff) < LastLSN(TrLog)

Transaction Log LSN zincirini de aşağıdaki şekildeki gibi kontrol edebiliriz.

Bütün bu bilgiler ışığında veritabanı restore işlemleri aşağıdaki ekrandan yapılır. LSN zinciri bozulmadığı sürece bir sorun çıkmayacaktır. Veritabanımızı elimizdeki yedeklerimizin elverdiği istenilen zamana geri döndürebiiriz.

Son olarak veritabanı simple recovery modeldeyken de bir transaction log dosyamız vardır. Ancak bu modda transaction’lar bu log dosyasında kısa bir süre için (aktif olduğu süre boyunca) tutulur. Transaction buffer’dan diske yazıldığında (checkpoint işlemiyle log flush işlemi yani log buffer’dan transaction log’a) log truncate edilir. Yani yukarıda bahsedildiği gibi, logdaki vlf’ler kullanılabilir(unused) statüsüne alınır. Full modda belirttiğimiz boyut dolduğunda, log dosyası döngüsünde yeni log dosyası oluşturulurken, burada varolan dosya üzerine dönüp dönüp tekrar yazar. Bu yüzden “point in time recovery” mümkün değildir