Veritabanı Yedekleme Stratejileri - 2
Bir önceki makalemde yedekleme tiplerinden ve yedekleme stratejilerini geliştirirken nelere dikkat edilmesi gerektiğinden bahsetmiştim. Bu makelemde ise veritabanı yedekleme işlemini örneklerle detaylandırmaya çalışacağım.
Veritabanı ve veritabanı loglarının yedeklenmesi “BACKUP” komutu temelinde gerçekleşir. Backup komutunun en temel kullanım notasyonu aşağıdaki gibidir.
--BOŞLUKLARI DOLDURMAK İÇİN CTRL+SHIFT+M TUŞ KOMBİNASYONUNA BASINIZ
BACKUP DATABASE <VERİTABANI ADI,VARCHAR,> TO DISK='<YEDEKLENECEK YERİ BELİRTİNİZ,VARCHAR,>'
Yukarıdaki komutun çalışması durumunda belirtilen veritabanının yedeği diskte belirtilen lokasyona yedeklenir. Bu komut ile alınan yedek full yedek tipinde bir yedektir.
Şimdi örneklerimiz için bir veritabanı oluşturalım ve log yedek alabilmek için bu veritabanının recovery durumunu full olarak set edelim.
CREATE DATABASE BACKUPTESTDB
GO
ALTER DATABASE BACKUPTESTDB SET RECOVERY FULL
Differential(fark) yedekleri veritabanındaki değişiklikleri LSN (Log Sequence Number - Log Sıra Numarası) ile takip eder ve bu bilgi de her full yedekten sonra ilgili sistem tablolarına yazılır. Bu bilgiye aşağıdaki information schemaya sorgu çekerek ulaşabiliriz.
SELECT differential_base_lsn,*
FROM sys.master_files
where database_id=DB_ID('BACKUPTESTDB')
Henüz yedek almadığımız için yukarıdaki sorgunun sonucu null olarak gelecektir.
İlk full yedeğimizi alalım ve alınan full yedek hakkında bazı incelemeler yapalım.
BACKUP DATABASE BACKUPTESTDB TO DISK='BACKUPTESTFULL_FULL1.BAK'
Yukarıdaki komutun çalışması ile beraber aşağıdaki şekilde sonuçlar alınır. Peki bize bu sonuçlar neler ifade etmektedir?
Processed 1288 pages for database 'BACKUPTESTDB', file 'BACKUPTESTDB' on file 2.
Processed 2 pages for database 'BACKUPTESTDB', file 'BACKUPTESTDB_log' on file 2.
BACKUP DATABASE successfully processed 1290 pages in 0.978 seconds (10.297 MB/sec).
Yukarıdaki istatistiksel çıktı yedek işlemi esnasında ne kadarlık bir iş yapıldığını (1290 veritabanı sayfası işlenmiş) , işlemin ne kadar sürdüğünü (0.978 saniyede yedekleme süreci tamamlanmış) ve yedek dosyasının diske yazılma hızı (saniyede 10.297 MB) hakkında bilgi verir.
İlk yedeğimizin tamamlanması ile birlikte aşağıdaki sorguyu çekmemiz durumunda veritabanımız için bir değişim tabanlı log sıra numarası üretildiğini görürüz.
SELECT differential_base_lsn,*
FROM sys.master_files
where database_id=DB_ID('BACKUPTESTDB')

SQL Server bu LSN (Log Sequence Number - Log Sıra Numarası) değerini daha sonra alınan differential(fark) yedekleri için kullanacak. Şimdi bir differential yedek alalım ve bu durumu gözlemleyelim. Differential (fark) yedeği veritabanı yedekleme işleminin bir özelliği olduğundan dolayı özel bir komut seti bulunmaz. Differential yedek almak için gerekli örnek komutumuz aşağıdaki gibidir.
--BOŞLUKLARI DOLDURMAK İÇİN CTRL+SHIFT+M TUŞ KOMBİNASYONUNA BASINIZ
BACKUP DATABASE <VERİTABANI ADI,VARCHAR,> TO DISK='<YEDEKLENECEK YERİ BELİRTİNİZ,VARCHAR,>' WITH DIFFERENTIAL
Bu bilgiyi de verdikten sonra veritabanı üzerinde bazı işlemler yapıp fark yedeğimizi alalım,
USE BACKUPTESTDB
GO
CREATE TABLE TEST ( KOLON1 UNIQUEIDENTIFIER,KOLON2 UNIQUEIDENTIFIER,KOLON3 UNIQUEIDENTIFIER)
--10000 adet kayıtla dolduruyoruz
INSERT INTO TEST(KOLON1,KOLON2,KOLON3)
SELECT TOP 10000 NEWID(),NEWID(),NEWID()
FROM sys.all_columns A CROSS JOIN sys.all_columns B
GO
BACKUP DATABASE BACKUPTESTDB TO DISK='BACKUPTESTFULL_DIFF1.BAK' WITH DIFFERENTIAL
Processed 248 pages for database 'BACKUPTESTDB', file 'BACKUPTESTDB' on file 1.
Processed 5 pages for database 'BACKUPTESTDB', file 'BACKUPTESTDB_log' on file 1.
BACKUP DATABASE WITH DIFFERENTIAL successfully processed 253 pages in 0.234 seconds (3.692 MB/sec).
Sonuçları full yedekle karşılaştırırsak ikinci alınan yedeğin fark yedek olduğu çok daha net olarak anlaşılacaktır.
|
Full
|
Differential
|
İşlenen Sayfa Sayısı
|
1290
|
253
|
Süre
|
0.978
|
0.234
|
Şimdi de restore headeronly komutu ile differential(fark) yedeğin başlık bilgilerini görelim, burdaki amacım differential(fark) yedeğin log sıra numarasının full yedeği takip edip etmediğini görebilmek.

Bir önceki makalemde full yedekten sonra alınan differential(fark) yedeklerin kendinden önceki differential(fark) yedeklerini kapsadığını söylemiştim. Şimdi yeni bir differential(fark) yedeği alıp ikinci differential(fark) yedeğin birinci differential(fark) yedeği kapsadığını görelim. Yedeği almadan önce veritabanı üzerinde biraz daha işlem yaratalım.
INSERT INTO TEST(KOLON1,KOLON2,KOLON3)
SELECT TOP 10000 NEWID(),NEWID(),NEWID()
FROM sys.all_columns A CROSS JOIN sys.all_columns B
GO
BACKUP DATABASE BACKUPTESTDB TO DISK='BACKUPTESTFULL_DIFF2.BAK'
WITH DIFFERENTIAL
(10000 row(s) affected)
Processed 320 pages for database 'BACKUPTESTDB', file 'BACKUPTESTDB' on file 1.
Processed 1 pages for database 'BACKUPTESTDB', file 'BACKUPTESTDB_log' on file 1.
BACKUP DATABASE WITH DIFFERENTIAL successfully processed 321 pages in 0.327 seconds (7.651 MB/sec).
10000 adet kayıt girildikten sonra differential(fark) yedek alındı, bu iki differential yedeği ve full yedeği karşılaştıralım
|
Full
|
Differential1
|
Differential2
|
İşlenen Sayfa Sayısı
|
1290
|
253
|
321
|
Süre
|
0.978
|
0.234
|
0.327
|
Doğal olarak full yedekten sonra veritabanı sayfalarının sayısı arttıkça differential(fark) yedek almak için işlenen veritabanı sayfa sayısı artıyor ve süre uzuyor. Bir de bu iki differential(fark) yedeği restore headeronly komutu ile inceleyelim.

Buradan anlaşılan bu iki yedek dosyası aynı full yedekten sonra alınan differential(fark) yedekleridir.
Şimdiki örneğimizde yeni bir full yedek aldıktan sonra fark yedeğinin DatabaseBackupLSN değerinin değiştiğini görelim.
--FULL YEDEK ALINIYOR
BACKUP DATABASE BACKUPTESTDB TO DISK='BACKUPTESTFULL_FULL2.BAK'
Processed 1432 pages for database 'BACKUPTESTDB', file 'BACKUPTESTDB' on file 1.
Processed 1 pages for database 'BACKUPTESTDB', file 'BACKUPTESTDB_log' on file 1.
BACKUP DATABASE successfully processed 1433 pages in 1.041 seconds (10.754 MB/sec).
--VERİTABANI ÜZERİNDE İŞLEM YAPILIYOR
INSERT INTO TEST(KOLON1,KOLON2,KOLON3)
SELECT TOP 10000 NEWID(),NEWID(),NEWID()
FROM sys.all_columns A CROSS JOIN sys.all_columns B
GO
--DİFFERENTİAL(FARK) YEDEK ALINIYOR
BACKUP DATABASE BACKUPTESTDB TO DISK='BACKUPTESTFULL_DIFF3.BAK' WITH DIFFERENTIAL
Processed 144 pages for database 'BACKUPTESTDB', file 'BACKUPTESTDB' on file 1.
Processed 1 pages for database 'BACKUPTESTDB', file 'BACKUPTESTDB_log' on file 1.
BACKUP DATABASE WITH DIFFERENTIAL successfully processed 145 pages in 0.245 seconds (4.595 MB/sec).
Sonuçtanda görüldüğü gibi full yedekten sonra differential(fark) yedeği daha az sayfanın işlenmesine neden oldu, şimdi differential(yedekteki) DatabaseBackupLSN değerlerinin değiştiğini görelim

Önceki makalemde de bahsettiğim gibi plansız alınan full yedeklerin yedekleme zincirini bozmaması için COPY_ONLY özelliği ile alınması gerekmektedir. Bunu gözlemlemek için aşağıdaki kodu çalıştırabiliriz.
--VERİTABANI ÜZERİNDE İŞLEM YAPILIYOR
INSERT INTO TEST(KOLON1,KOLON2,KOLON3)
SELECT TOP 10000 NEWID(),NEWID(),NEWID()
FROM sys.all_columns A CROSS JOIN sys.all_columns B
--DEĞİŞİM TABANLI LSN NUMARASI KONTROL EDİLİYOR
SELECT differential_base_lsn,*
FROM sys.master_files
where database_id=DB_ID('BACKUPTESTDB')
--COPY_ONLY ÖZELLİĞİ İLE YEDEK ALINIYOR
BACKUP DATABASE BACKUPTESTDB TO DISK='BACKUPTESTFULL_FULL3.BAK'
WITH COPY_ONLY
--DEĞİŞİM TABANLI LSN NUMARASI KONTROL EDİLİYOR
SELECT differential_base_lsn,*
FROM sys.master_files
where database_id=DB_ID('BACKUPTESTDB')

Log yedeklerinde ise durum differential(fark) yedeklerinden farklıdır. Log yedekleri veritabanı log dosyaları içinde barınan işlenmiş log kayıtlarının yedeklenmesini sağlayacağını ve log yedeğinden sonra varsayılan olarak işlenmiş log kayıtlarını sileceğinden bahsetmiştik. Bu bahsedilenleri örneklerimizle görelim.
Log yedekleme komutunun en temel kullanım notasyonu aşağıdaki gibidir.
--BOŞLUKLARI DOLDURMAK İÇİN CTRL+SHIFT+M TUŞ KOMBİNASYONUNA BASINIZ
BACKUP LOG <VERİTABANI ADI,VARCHAR,>
TO DISK='<YEDEKLENECEK YERİ BELİRTİNİZ,VARCHAR,>'
Şimdi örnek veritabanımızın log yedeklerini alalım ve log yedek dosyasını inceleyelim.
BACKUP LOG BACKUPTESTDB TO DISK='BACKUPTESTLOG_LOG1.TRN'
RESTORE HEADERONLY FROM DISK='BACKUPTESTLOG_LOG1.TRN'
Processed 193 pages for database 'BACKUPTESTDB', file 'BACKUPTESTDB_log' on file 1.
BACKUP LOG successfully processed 193 pages in 0.183 seconds (8.210 MB/sec).

Log yedek dosyasını incelediğimizde yedeklenen işlenmiş log kayıtlarının belirli aralıkta olduğunu görüyoruz. Log yedekleri tamamen sıralı yedeklerdir. Bir sonraki seferde alınacak log yedeği bu yedekteki Last LSN den başlayacaktır. Bunu gözlemlemek için aşağıdaki komutu kullanılarak sonucunu görelim.
RESTORE HEADERONLY FROM DISK='BACKUPTESTLOG_LOG1.TRN'
INSERT INTO TEST(KOLON1,KOLON2,KOLON3)
SELECT TOP 10000 NEWID(),NEWID(),NEWID()
FROM sys.all_columns A CROSS JOIN sys.all_columns B
BACKUP LOG BACKUPTESTDB TO DISK='BACKUPTESTLOG_LOG2.TRN'
RESTORE HEADERONLY FROM DISK='BACKUPTESTLOG_LOG2.TRN'

Şimdide log yedeği sonrasında işlenmiş log kayıtlarının silindiğini ve veritabanı log kullanımlarının azaldığı görelim. İlk olarak log dosyalarının büyümesine neden olan komutlar çalıştıralım ve sonrasında veritabanı log kullanım oranlarını görelim.
--VERİTABANINA 60000 KAYIT INSERT EDELIM VE LOG DOSYASI KULLANIM ORANLARINA BAKALIM
INSERT INTO TEST(KOLON1,KOLON2,KOLON3) SELECT TOP 20000 NEWID(),NEWID(),NEWID() FROM sys.all_columns A CROSS JOIN sys.all_columns B
INSERT INTO TEST(KOLON1,KOLON2,KOLON3) SELECT TOP 20000 NEWID(),NEWID(),NEWID() FROM sys.all_columns A CROSS JOIN sys.all_columns B
INSERT INTO TEST(KOLON1,KOLON2,KOLON3) SELECT TOP 20000 NEWID(),NEWID(),NEWID() FROM sys.all_columns A CROSS JOIN sys.all_columns B
--LOG KULLANIM YÜZDELERİNE BAKILIYOR
DBCC SQLPERF(LOGSPACE)

Log yedeği alındıktan sonra işlenmiş log kayıtları silineceğinden dolayı bu kullanım oranı düşecektir.
BACKUP LOG BACKUPTESTDB TO DISK='BACKUPTESTLOG_LOG3.TRN'
DBCC SQLPERF(LOGSPACE)

COPY_ONLY özelliği log yedeği alırken de kullanılabilir. Bu özellik ile alınan yedekler sonrasında işlenmiş log kayıtları silinmezler. Yukarıdaki komutları tekrarlayarak bu durumu gözlemleyebilirsiniz.
Bugünkü makalemde size üç temel yedekleme tipini örneklerle anlatmaya çalıştım. İleriki makalelerimde sizlere yedekten dönme işlemlerinden örneklerle derinlemesine bahsediyor olacağım.