“Database Mirroring”, bir server üzerindeki bir veritabanında olan değişikliklerin senkron veya asenkron olarak farklı bir server üzerindeki kopyasına yansımasını sağlamaktır. Tabir-i diğerle bir serverdaki mevcut vertabanının farklı bir serverda, işlem yapmaya kapalı online kopyasının sağlanmasıdır. Böylece disaster bir durumda veri kaybının önüne geçilmiş ve yüksek erişilebilirlik sağlanmış olur.

Mirroringde verinin alınacağı server Principal Server olarak adlandırılır. Principal serverdaki işlemlerin aktarılacağı server ise Mirror Server olarak adlandırılır. Optional olarak mirroringe dahil edilen, failoverları otomatik tespit eden ve principal server kullanım dışı olduğunda otomatik olarak mirror serverı principal server yapıp kullanıma alan server, Witness Server olarak adlandırılır. Aşağıda mirroring yapısı görülmektedir:

Mirroring Yapısı (MSDN)
Mirroring Yapısı (MSDN)

Mirroringde sadece bir tane principal/mirror server bulunabilir. Ancak birden fazla mirroring işlemi tek bir witness servera bağlanabilir. Tabir-i diğerle tek bir witness server ile birden fazla mirroring işlemi monitör edilebilir.

Mirroringde principal serverdan mirror servera aktarım işlemi, principal serverdaki transaction logların mirror servera aktarılması ile gerçekleşir. Mirror serverda ise transaction loglar okunarak değişiklikler data dosyasına aktarılır. Böylece principal server ve mirror server aynı yapı ve dataya sahip olur.

Mirroringde serverlar arasındaki iletişimin gerçekleşmesini endpointler sağlar. TCP ve HTTP olarak iki tür endpoint vardır. Mirroring için TCP, SOAP talepleri için HTTP endpointleri kullanılır. Endpointler, principal ve mirror serverlar için PARTNER, witness server için WITNESS ve her iki rolü de yüklenebilecek ALL olmak üzere üç rolde tanımlanabilirler.

Mirroring üç farklı modda çalışabilir:

High performance:

Principal serverdaki transactionlar commit edildikten sonra asenkron olarak mirror servera aktarılır. Asenkron iletişim olduğundan data kaybı söz konusu olabilir. Bu modda witness server kullanılmaz. Principal serverda Mirroring(Veritbanına sağ tıklayıp Tasks/Mirroring) ekranında Failover butonu tıklanarak manuel failover ile mirror server principal server rolüne getirilebilir. Yada aşağıdaki komut ile manuel failover gerçekleştirebilirsiniz:

ALTER DATABASE MIRROR SET PARTNER FAILOVER

Eğer principal server erişilmez durumda ise mirror serverı force ederek failover gerçekleştirip, mirror serverı principal server rolüne getirebilirsiniz:

ALTER DATABASE MIRROR SET PARTNER FORCE_SERVICE_ALLOW_DATA_LOSS

High safety without automatic failover:

Çalışma yöntemi aşağıdaki mod ile aynıdır. Farklı olarak witness server konfigrasyonu yapılamaz.

High safety with automatic failover:

Principal serverda transaction loga yazma olduğunda mirroring tetiklenir. Principal serverdaki transaction loglar mirror servera gönderilir. Transaction için commit gönderildiğinde transaction önce mirror servera sonra principal servera işlenir. Hem principal hem mirror serverda transaction log işlenmediği sürece transaction commit edilmediği için bu çalışma modunda performans düşük, veri güvenliği yüksektir.

Bu modda failoverları otomatik tespit etmek ve principal serverın erişilmez olduğu durumda mirror serverı devreye almak için witness server kullanılır.

Mirroring İçin Serverların Yapılandırılması

Mirroring için kullanacağım SQL Server Instance’lar aşağıdaki gibidir:

Principal Server: NINJA\NINJA

Mirror Server: NINJA\KEDI

Witness Server: NINJA\SQLEXPRESS

1-Principal serverda bir veritabanı oluşturalım.

2-Oluşturduğumuz veritabanına, sağ tıklayıp Properties’a girelim. Options tabında Recovery Model’in Full olduğunu kontrol edelim. Mirroring için full recovery modeli kullanmamız gerekir.

Full Recovery Model
Full Recovery Model

3-Oluşturduğumuz veritabanının full backupını alalım. Bu backupı NO RECOVERY olarak mirror servera restore edelim.

Restore With No Recovery
Restore With No Recovery

Restore işlemi sonrası mirror serverda veritabanı Restoring modunda olacaktır.

Mirror Server Restoring Mode
Mirror Server Restoring Mode

Restore işlemini mirror serverda var olan bir veritabanına overwrite ederek yapacaksanız, principal ve mirror serverdaki database isimlerinin aynı olmasına dikkat ediniz. Database isimleri farklı olursa aşağıdaki hatayı alırsınız:

Database “xxxx” does not exist on the mirror server instance. You must restore a backup of the principal database on the mirror server instance before starting mirroring.

4- Principal serverda mirroringde kullanacağımız veritabanına sağ tıklayıp, Properties’e girelim. Açılan pencerede Mirroring tabına gelelim. Mirroring konfigrasyonu için bu ekranda Configure Security butonunu tıklayalım.

Configure Security
Configure Security

Açılan pencerede Next butonunu tıklayalım. Mirroringde witness server kullanmak isteyip istemediğimizi soran ekran gelecektir. Witness server kullanacağımızdan bu ekranda Yes seçeneğini seçip Next butonuna tıklayalım. Yapılandıracağımız serverları listeleyen ekran gelecektir. Principal ve mirror server zorunlu olduğundan read only’dir. Witness server ise optional olduğundan unchecked yapılabilir. Next butonuna tıkladığımızda principal server yapılandırmasının yapılacağı ekran gelecektir.

Principal Server InstancePrincipal Server Instance
Principal Server Instance

Next butonuna tıkladığımızda mirror server ayarlarının yapılacağı ekran gelecektir. Mirror server instance bölümünden mirror serverı seçelim. Seçtiğimiz servera connection ekranı çıkacaktır. Authenticationı sağladıktan sonra görüntü aşağıdaki gibi olmalıdır:

Mirror Server Instance
Mirror Server Instance

Next butonuna tıkladığımızda witness server ayarlarının yapılacağı ekran gelecektir. Mirror server ayarlarında olduğu gibi witness server instance seçelim. Next butonuna tıkladığımızda service accounts ekranı gelecektir.

Service Accounts
Service Accounts

Principal, mirror ve witness SQL Server servisleri aynı accountu kullanıyor ise ekrandaki alanları doldurmanıza gerek yoktur. Ancak SQL Server servisler her serverda farklı accountlar kullanıyor ise bu durumda account bilgilerini girmeniz gerekecektir.

Next butonuna tıkladığımızda yaptığımız konfigrasyonun gösterildiği son ekran gelecektir.

Complete the Wizard
Complete the Wizard

Finish butonuna tıkladığımızda mirroring için serverlar yapılandırılmaya başlanacaktır.

Endpoint Yapılandırılması
Endpoint Yapılandırılması

Yapılandırma bittiğinde Close butonuna tıklayın. Mirroring konfigrasyon ayarlarının gösterildiği, mirroringi başlatma uyarı ekranı çıkacaktır.

Database Properties
Database Properties

Start Mirroring’i tıkladığımızda çıkan ekranda Yes butonunu tıklayarak mirroringi başlatıyoruz.

Database Properties

Böylece mirroring başlatılmış oldu. Principal ve mirror serverdaki database görüntüleri aşağıdaki gibi olacaktır.

Principal - Mirror
Principal – Mirror

Şimdi ufak bir test yapalım. Principal serverda, mirrored yaptığımız veritabanında bir tablo oluşturup, birkaç kayıt girelim ve sonra principal servera eklediğimiz tablo ve kayıtlar mirror servera yansımış mı kontrol edelim. Principal veritabanında Persons adında bir tablo oluşturup birkaç kayıt girdim. Mirror server işleme kapalı olduğundan değişikliklerin yansıyıp yansımadığını kontrol edebilmemiz için mirror serverdaki veritabanının snapshot’ını almamız gerekecektir. Principal serverda tablonuzu oluşturup, bir kaç kayıt girdiyseniz mirror serverda aşağıdaki gibi veritabanının snapshot’ını oluşturabilirsiniz:

CREATE DATABASE MIRROR_SNAPSHOT

ON (

NAME = ‘MIRROR’,

FILENAME = ‘C:\Program Files\Microsoft SQL Server\MSSQL10.KEDI\MSSQL\DATA\MIRROR_SNAPSHOT.snp’)

AS SNAPSHOT OF MIRROR

Mirror serverda aşağıdaki gibi snapshottan sorgulama yaparak, principal serverdaki değişikliklerin yansıdığını görebilirsiniz:

select * from MIRROR_SNAPSHOT.dbo.Persons

T-SQL İle Database Mirroring

1-Principal serverda full recovery modelde veritabanı oluşturuyoruz.

USE master
IF EXISTS
(SELECT name FROM sys.databases WHEREname = N’MIRROR’)
DROP DATABASE MIRROR
CREATE DATABASE MIRROR ON PRIMARY
(
NAME = N’MIRROR’,
FILENAME = N’C:\Program Files\Microsoft SQL Server\MSSQL10.NINJA\MSSQL\DATA\MIRROR.mdf’ ,
SIZE = 1280,
MAXSIZE = UNLIMITED,
FILEGROWTH = 1024
)
LOG ON
(
NAME = N’MIRROR_log’,

FILENAME = N’C:\Program Files\Microsoft SQL Server\MSSQL10.NINJA\MSSQL\DATA\MIRROR_log.LDF’,
SIZE = 500,
MAXSIZE = 2048,
FILEGROWTH = 10%
)
GO
ALTER DATABASE
MIRROR SET RECOVERY FULL

2- Oluşturduğumuz veritabanının full ve transaction log backuplarını alıyoruz.

BACKUP DATABASE MIRROR TO
DISK = ‘C:\Program Files\Microsoft SQL Server\MSSQL10.NINJA\MSSQL\Backup\MIRROR.bak’
WITH INIT
GO
BACKUP
LOG MIRROR TO
DISK
= ‘C:\Program Files\Microsoft SQL Server\MSSQL10.NINJA\MSSQL\Backup\MIRROR_LOG.bak’
WITH INIT

3-Aldığımız backupları mirror server’a no recovery olarak restore ediyoruz.

RESTORE DATABASE MIRROR FROM
DISK =’C:\Program Files\Microsoft SQL Server\MSSQL10.NINJA\MSSQL\Backup\MIRROR.bak’
WITH NORECOVERY,
MOVE ‘MIRROR’ TO
‘C:\Program Files\Microsoft SQL Server\MSSQL10.KEDI\MSSQL\DATA\MIRROR.mdf’,
MOVE ‘MIRROR_log’ TO
‘C:\Program Files\Microsoft SQL Server\MSSQL10.KEDI\MSSQL\DATA\MIRROR_log.ldf’
GO
RESTORE DATABASE
MIRROR FROM
DISK =’C:\Program Files\Microsoft SQL Server\MSSQL10.NINJA\MSSQL\Backup\MIRROR_LOG.bak’
WITH NORECOVERY

4-Serverlar arasındaki iletişim için her serverda endpointleri oluşturuyoruz. Her serverda database mirroring için sadece bir tane endpoint oluşturulabilir. Daha önce endpoint oluşturulmuş ise mirroring için zaten endpoint tanımlanmış olduğunu bildiren bir hata alırız. Var olan endpointi silmek için (DROP ENDPOINT Endpoint Adi) komutunu kullanabilirsiniz. Principal, mirror ve witness serverda endpoint tanımlarını yapmak için aşağıda belirtilen serverde verilen komutları çalıştırmalısınız:

Principal Server:

CREATE ENDPOINT PEndpoint
STATE = STARTED AS TCP (LISTENER_PORT = 6022)
FOR Database_Mirroring (ROLE = PARTNER)

Mirror Server:

CREATE ENDPOINT MEndpoint
STATE = STARTED AS TCP (LISTENER_PORT = 6023)
FOR Database_Mirroring (ROLE = PARTNER)

Witness Server:

CREATE ENDPOINT WEndpoint
STATE = STARTED AS TCP (LISTENER_PORT = 6024)
FOR Database_Mirroring (ROLE = WITNESS)

5-Mirror serverda, principal server endpoint tanımı yapıyoruz.

ALTER DATABASE MIRROR SET PARTNER = N’TCP://NINJA:6022′

6-Principal serverda, mirror server ve witnes server endpoint tanımı yapıyoruz.

ALTER DATABASE MIRROR SET PARTNER = N’TCP://NINJA:6023′
ALTER DATABASE MIRROR SET WITNESS = N’TCP://NINJA:6024′

Mirroring yapılandırmamız tamamlanmış oldu.

Mirroring işlemini duraklatmak, duraklatılmış mirroringi başlatmak veya silmek için principal serverda ilgili veritabanına sağ tıklayıp Tasks/Mirroring ekranındaki Pause, Resume, Remove Mirroring butonlarını kullanabilir veya aşağıdaki T-SQL komutlarını execute ederek bunları gerçekleştirebilirsiniz:

Pause: ALTER DATABASE MIRROR SET PARTNER SUSPEND
Resume: ALTER DATABASE MIRROR SET PARTNER RESUME
Remove Mirroring: ALTER DATABASE MIRROR SET PARTNER OFF

Mirroring Monitoring

Mirroring işlemini monitör edebilmek için principal serverda ilgili veritabanına sağ tıklayıp, Tasks/Launch Database Mirroring Monitoring’e tıklayın. Monitoring ekranı açılacaktır. Go menüsünden Database Mirroring Monitoring seçeneğini seçin. Database Mirroring Monitoring ekranı açılacaktır.

Mirroring Monitoring
Mirroring Monitoring

Register mirrored database linkine tıklayarak mirror edilmiş principal serverımızı ekleyelim. Ekledikten sonra monitoring ekranında görüntü aşağıdaki gibi olacaktır:

Registered Mirrored Database
Registered Mirrored Database

Mirroring işlemi monitor edilmeye başlanacaktır. History altındaki üç noktalı butona tıkladığımızda principal ve mirror server’ın mirroring history’sini görebiliriz. Principal serverın historysine bakalım:

Principal Server Mirroring History
Principal Server Mirroring History

Person adında bir tablo oluşturmuş ve birkaç kayıt girmiştim. Mirror servera 2 KB bir transaction log iletilmiş. Mirror serverın historysine baktığımızda gönderilen 2 KB’lık transaction logun alınıp, restore edildiğini görürüz:

Mirror Server Mirroring History
Mirror Server Mirroring History

Şu ana kadar hep server tarafını inceledik. Peki client tarafında mirroring aktif bir yapıyı nasıl kullanabiliriz? Ufak bir konsol uygulama ile bunu test edelim.

Yeni bir konsol uygulama oluşturup, bir connection nesnesi tanımlayıp, bağlantıyı open etmeye çalışalım. Connection nesnesini “server=NINJA\NINJA; Database=MIRROR; Integrated Security=true” şeklinde bir connection string ile tanımlıyoruz. Principal server erişilebilir olduğu için hata alınmayacaktır. Şimdi principal serverı(NINJA\NINJA) stop edelim. Mirroringden beklentimiz principal server erişilemez olduğunda mirror serverı devreye alması ve principal serverın erişilemez durumundan kaynaklanacak kesintilerin önüne geçilmesiydi. Şu anda principal server stop durumda olduğuna göre connectionı open yapmaya çalıştığımızda mirror servera gitmesi gerekmektedir. Ancak mevcut connection string ile bağlanmaya çalıştığınız serverın bulunamadığına dair bir hata mesajı alırsınız. Clienttan gelen talebin principal server erişilmez olduğunda mirror servera yönlenebilmesi için connection stringe mirror server tanımını eklememiz gerekmektedir. Yani connection string aşağıdaki gibi olmalıdır:

server=NINJA\NINJA;Failover Partner=NINJA\KEDI; Database=MIRROR; Integrated Security=true

Şimdi clienttan servera bir talep geldiğinde principal server erişilmez durumda ise mirror server devreye alınır ve principal serverın erişilmez olması client tarafına yansımamış olur. SQL Server Management Studio’dan baktığınızda principal serverın mirror server rolünü alıp Restoring moduna geçtiğini, mirror serverın ise principal server rolünü alıp Synchronized moduna geçtiğini göreceksiniz.