Database Snapshot Nedir ve Nasıl Alınır?
Database Snapshot, veritabanının o anki değiştirilemez bir görüntüsünün oluşturulmasıdır, o anki fotoğrafını çekmek gibi düşünebilirsiniz.
Bir örnek üzerinden anlatırsam daha net anlaşılacaktır.
Örneğin AdventureWorks2014 veritabanının snapshot’ını aldık. Bu snapshot üzerinden okuma yapıyoruz. Henüz AdventureWorks2014 veritabanında bir değişiklik olmadı. Yaptığımız select’ler orijinal veritabanında bir değişiklik olmadığı için orijinal veritabanına gider.
Orijinal veritabanında değişiklik olursa bu değişiklikler Snapshot için diskte ayrılmış bir alana yazılır(Sparse Files). Select çektiğimizde gelmesi gereken veriler orjinal veritabanında bir değişikliğe uğradıysa değişikliğe uğramadan önceki hali sparse file’a yazıldığı için buradan okunur. Bu şekilde snapshot alındığında çekilen fotoğraf bozulmamış olur.
Snapshot’ı aldığımız anda diskte yer kaplamasa da orijinal veritabanındaki değişiklikler arttıkça Sparse Files’ın boyutu büyüyecektir. Eğer sparse files’ın boyutu büyürse ve diskte yer kalmazsa snapshot suspect mode’a düşer ve silmeniz gerekir.
Daha çok Mirroring teknolojisi ile kullanılır.
“Database Mirroring Nedir ve Nasıl Yapılır? Mirroring Hataları ve Çözümleri..” isimli makalemi okumanızı tavsiye ederim. Mirroring’de secondary veritabanından read yapılamıyor. Secondary veritabanından read yapmak istediğimizde, secondary veritabanının snapshot’ını alarak bu snapshot üzerinde okuma yapabiliyoruz. Ve bu şekilde rapor sorgularımızı secondary veritabanından yaparak primary veritabanında rapor için bir yük oluşturmamış oluyoruz.
Ya da toplu bir update ya da delete işlemi yapmadan önce veritabanının snapshot’ını alabilirsiniz. Yanlış yapılan bir update ya da delete gibi işlemler snapshot kullanılarak geri alınabilir. Backup’tan restore yapmaktan çok daha hızlı bir dönüş olacaktır.
Snapshot, snapshot’ını aldığımız veritabanı ile aynı instance üzerinde olmalıdır.
İki örnek snapshot oluşturma işlemi ile devam edelim. İlk olarak Database Mirroring yapılmış bir veritabanının secondary veritabanından read yapabilmek için snapshot’ını alacağız. İkinci örneğimizde ise yanlış yapılmış bir update’i geri almak için snapshot alma işlemini gerçekleştireceğiz.
Örnek1:
Öncelikle mirror yapılmış veritabanının senkron olması gerekir. Yani secondary veritabanınızın görüntüsü aşağıdaki gibi olmalıdır.
Daha sonra aşağıdaki script yardımıyla Snapshot’ı oluşturuyoruz. Veritabanında ne kadar file varsa hepsini belirtmeniz gerekir. Bizde AdventureWorks2012_Data ve AdventureWorks2014_Deneme isimlerinde iki tane file vardı. Bu ikisi için snapshot’ı oluşturduk. FileGroup ve File’lar hakkında bilginiz yoksa “Veritabanı Oluşturmak Deyip Geçmeyin!” isimli makalemi okuyabilirsiniz.
CREATE DATABASE AdventureWorks2014_Snapshot ON ( NAME = AdventureWorks2012_Data, FILENAME = 'C:\DB\Data\AdventureWorks2012_Data.ss' ), ( NAME = AdventureWorks2014_Deneme, FILENAME = 'C:\DB\Data\AdventureWorks2014_Deneme.ss' ) AS SNAPSHOT OF AdventureWorks2014; GO
Msdn’den aldığım aşağıdaki script ile snapshot’ın diskte kapladığı alanı ve maksimum büyüyebileceği büyüklüğü bulabilirsiniz.
SELECT DB_NAME(sd.source_database_id) AS [SourceDatabase], sd.name AS [Snapshot], mf.name AS [Filename], size_on_disk_bytes/1024 AS [size_on_disk (KB)], mf2.size/128 AS [MaximumSize (MB)] FROM sys.master_files mf JOIN sys.databases sd ON mf.database_id = sd.database_id JOIN sys.master_files mf2 ON sd.source_database_id = mf2.database_id AND mf.file_id = mf2.file_id CROSS APPLY sys.dm_io_virtual_file_stats(sd.database_id, mf.file_id) WHERE mf.is_sparse = 1 AND mf2.is_sparse = 0 ORDER BY 1;
Script’i çalıştırdığımda aşağıdaki ekran görüntüsünü elde ettim. Bu iki data file’ın şu anki boyutunu 256 mb olarak set etmiştim. Bu yüzden snapshot’ın maksimum büyüyebileceği size 256 MB olarak geldi.
Snapshot’ımızı oluşturduk. SSMS üzerinde Databases->Database Snapshots kısmından sanki bir veritabanıymış gibi snapshot’ınızdan okuma yapabilirsiniz. Normalde Mirroring’de secondary’den okuma yapamazken snapshot’ını alarak bu şekilde okuma yapabilirsiniz.
Örnek2:
Aşağıdaki script’i bu sefer primary veritabanında çalıştıralım.
CREATE DATABASE AdventureWorks2014_Snapshot ON ( NAME = AdventureWorks2012_Data, FILENAME = 'C:\DB\Data\AdventureWorks2012_Data.ss' ), ( NAME = AdventureWorks2014_Deneme, FILENAME = 'C:\DB\Data\AdventureWorks2014_Deneme.ss' ) AS SNAPSHOT OF AdventureWorks2014; GO
Snapshot’ı aldıktan sonra herhangi bir tablodaki tüm kayıtları aşağıdaki script yardımıyla silin. Ben AdventureWorks2014 veritabanında daha önce oluşturmuş olduğum Snapshot_deneme isimli veritabanınındaki kayıtları siliyorum.
Delete From Snapshot_deneme
Silme işlemi gerçekleştikten sonra aşağıdaki script yardımıyla silinen kayıtlarınızı geri getirebilirsiniz. Ama snapshot aldıktan sonra başka bir işlem yaptıysanız o değişiklikler de gidecektir.
USE master GO RESTORE DATABASE AdventureWorks2014 FROM DATABASE_SNAPSHOT = 'AdventureWorks2014_Snapshot'