Bu makalede join only yöntemiyle AlwaysOn ortamında database ekleme işlemine değineceğim. Eğer database’imiz büyükse veya secondary makinemiz uzak bir lokasyondaysa bu yöntemi kullanmakta fayda var. Çok büyük transactionlarımız varsa secondary sunucusuna database eklemede ilk iki seçenek log dosyamızın şişmesine sebep oluyor.
Auto Seeding sırasında, Auto Seeding, veriyi Transaction Log üzerinden “replay” ederek göndermez. Bunun yerine, veritabanının bir snapshot (anlık görüntü) kopyasını oluşturur ve veri sayfalarını (data pages) ağ üzerinden doğrudan stream eder. İşlem sırasında primary sunucuda devasa bir log kaydı oluşmaz. Ancak, seeding işlemi bitene kadar primary replikadaki log dosyası truncate edilemez. Çünkü SQL Server, seeding başladığı andaki LSN (Log Sequence Number) ile bittiği an arasındaki farkı secondary’ye göndermek için logu tutmak zorundadır. Yani log, 100GB büyümez ama mevcut loglar temizlenemediği için şişebilir.
Full database and log backup yönteminde , Secondary veritabanı NORECOVERY modunda kalsa bile Primary’den gelen logları işler. Ancak Primary üzerindeki log dosyasının boşalabilmesi (truncate) için; hem Primary’de log backup alınması hem de Secondary’nin bu logları başarıyla teslim almış olması gerekir. Eğer Secondary erişilemez durumdaysa, Primary’de alınan log backupları log dosyasını küçültmez/truncate etmez.”
Olay tam olarak şöyle işler:
- Secondary’nin LDF’i (Log Dosyası): Secondary sunucu, Primary’den gelen log kayıtlarını kendi LDF dosyasına yazar (Harden). Bu kayıtlar veritabanına işlendikten (Redo) ve bir Checkpoint gerçekleştikten sonra, Secondary kendi LDF dosyasındaki o alanları “tekrar kullanılabilir” (reusable) olarak işaretler. Yani evet, Secondary kendi log dosyasını yönetir ve şişmesini engeller.
- Primary’nin LDF’i: Primary sunucunun kendi LDF dosyasındaki alanı boşaltabilmesi (truncate) için, Secondary’den şu onayı alması gerekir: “Ben bu LSN (Log Sequence Number) değerine kadar olan her şeyi aldım ve diskime güvenle yazdım.” Primary tarafında logun gerçekten boşalması için Log Backup alınması şarttır. Ancak log backup alınsa bile, eğer Secondary “şu LSN’de kaldım, gerisini alamadım” derse, Primary o LSN’den sonrasını truncate edemez.
Özetle:
- Secondary tarafında: Gelen loglar işlendikçe (Redo) ve checkpoint oldukça LDF içindeki alanlar serbest kalır (truncate olur).
- Primary tarafında: LDF’in boşalması için hem Log Backup gerekir hem de Secondary’nin o logları teslim almış (harden) olması gerekir.

Önceden AlwaysOn’a eklemiş olduğum databaseleri AlwaysOn’dan çıkarıp tekrardan belirtilen AlwaysOn’a alma adımını yapmaya çalışacağım. Bu adımlada bir veritabanı AlwaysOn’dan nasıl çıkarılı ele almış olacağız.
Önceki database’i AlwaysOn’dan çıkaracağım zaman secondary sunucusundan kendisi otomatikmen çıkarmış oluyor. Secondary sunucusundan AlwaysOn’dan çıktıktan sonra veritabanı databases sekmesi altında restoring modda oluyor.

Primary sunucusunda Remove database.. dediğimizde secondary sunucusunda ilgili veritabanı restoring moduna düşüyor.

İkinci node’da restoring moda düşen database artık silinebilir.
Bu makalede join only işlemi yapacağımız için primary sunucumuzda Availability Groups’un altında Availability Databases sekmesine sağ tıklanır.

Gelen ekran next denilip bir sonraki adıma geçilir.

Gelen ekranda AdvantureWorks2012 veritabanımızın AlwaysOn için gerekli özellikleri karşıladığını söylüyor. Önceki makalelerde gerekli şartları karşılamadığında ne gibi senaryolar yapıldığından bahsetmiştik. Next deyip bir sonraki adıma geçiyoruz.

Gelen ekranda primary sunucumuzdan S2\TEST sunucumuza bağlanıyoruz.

Bağlantıyı sağladıktan sonra Next deyip bir sonraki aşamaya geçiyoruz.

Makalemizinde konu başlığı olan Join only kısmını seçip Next diyiyoruz. SQL Server Always On Availability Groups yapısında “Join Only” seçeneği, halihazırda Secondary sunucuya manuel olarak geri yüklenmiş (restore edilmiş) bir veritabanını Availability Group (AG) bünyesine katmak için kullanılır.
Bu yöntem, veritabanı dosyaları çok büyük olduğunda ve ağ üzerinden otomatik gönderim (Auto Seeding) yapmak istemediğinizde tercih edilen en güvenli yoldur.
Bu yöntemi kullanabilmeniz için ön hazırlık aşamalarını sizin tamamlamış olmanız gerekir:
- Hazırlık: Primary sunucuda veritabanının bir Full Backup‘ını ve ardından en az bir Transaction Log Backup‘ını alırsınız.
- Restore: Bu yedekleri Secondary sunucuya WITH NORECOVERY modunda geri yüklersiniz. (Veritabanı “Restoring…” durumunda görünmelidir).
- Join: AG kurulum sihirbazında (Wizard) veya T-SQL komutuyla “Join Only” seçeneğini seçersiniz.
SQL Server bu aşamada şunu yapar: “Ben veri taşımayacağım, sadece Secondary’deki veritabanı ile Primary’deki veritabanının LSN (Log Sequence Number) zincirinin uyumlu olup olmadığına bakacağım. Eğer uyumluysa aradaki bağları kurup veri senkronizasyonunu başlatacağım.”
Automatic seeding moda ve full database and log backup modu ile işlemlerimizi yaptığımız zaman transaction’larımız aşırı derecede büyüyor ldf’imizin bu şekilde dolmasına sebep olacaktır.

Join only işleminden önce secondary sunucusuna ekleyeceğimiz veritabanı için bir full backup’ını alıyorum. Bu işlem, yaptıktan sonra log backup alıyorum. Veritabanımıza aktif transaction geldiğini varsayarsak bu yöntem hızlı bir şekilde secondary makinesinin primary makinesiyle sekronizasyonu sağlıyor.
Şimdi Adventureworks2012 veritabanının backup’ını alıyorum.


Yukarıdaki işlemi yaptıktan sonra ilgili veritabanımın log backup’ını alıyorum.


Şimdi almış olduğum bu full ve log backup’ı secondary sunucuna restore işlemine alıyorum.
Bu backup’ları secondary sunucuma fiziksel olarak kopyalıyorum. Kopyalamayıp bu klasörü paylaşıma açsamda olur.(Sharing) Ama bu işlem network hızında gerçekleştiği için yavaş olacaktır.

Secondary sunucuma kopyaladıktan sonra şimdi ise SSMS arayüzünden restore işlemlerine geçelim.

Database’i seçtikten sonra option kısmından norecovery modu seçip veritabanını restoring modunda bırakıyorum. Veritabanını kullanıma açmıyorum.

Aşağıdaki resimde görüldüğü gibi ilgili bölümden norecovery mod seçilir.

Veritabanımız görüldüğü gibi restoring modunda üzerine diff veya log backup dönülebilir hale getirdik.

Restoring modda üzerine bir diff veya log backup bekliyor durumda. Şimdi secondary sunucusunda restoring modda olan database üzerine log backup’ı restore ediyorum. Buraya dikkat edilmesi gereken log backup restore edilirse primary sunucusunda log backup alınmaması lazım lsn değeri değişir buda backup’ımızı restore edemediğimize sebep olur. Log shipping yöntemiylede bu yapılabilir ama log’la ilgili job’ımız varsa kapatılması gerekmektedir. Yoksa ilgili log backup dosyamızında restore edilmesi gerekmektedir.
Bazen neden bağlantı gerçekleşir değinelim: Çünkü diff backup restore edilirken 2-3 log backup alınır ama secondary sunucusunda bulunan veritabanı join olmaktadır.
Eğer SQL Server “Join Only” dediğinde itiraz etmiyorsa, bunun sebebi “şanslı” bir zamanlama yakalamış olman veya SQL Server’ın o anki LSN eşleşmesini yeterli görmesidir.
Durumu netleştirelim:
SQL Server’da bir veritabanını başka bir sunucuya “Join” edebilmen için, Secondary üzerindeki veritabanının LSN (Log Sequence Number) değerinin, Primary’deki aktif log dizisiyle tam olarak örtüşmesi gerekir.
Teoride, Diff restore edildikten sonra Primary’de alınan 2-3 log backup varsa, Secondary geride kalmış demektir. Ancak şu iki durumdan biri gerçekleşmiş olabilir:
- Aktif Log Kesimi (Truncation) Henüz Gerçekleşmedi: Sen Diff restore ederken Primary’de log backupları alınsa bile, bu log kayıtları hala Primary’nin Transaction Log (.ldf) dosyası içinde “henüz ezilmemiş” şekilde duruyor olabilir. Sen Join komutunu verdiğinde, SQL Server aradaki farkın çok küçük olduğunu görüp, eksik olan log kayıtlarını backup dosyasından değil, direkt Primary’nin canlı .ldf dosyasından “re-scan” ederek çekmiş ve Secondary’e göndermiş olabilir.
- Checkpoint ve LSN Uyumu: Diff backup, alındığı ana kadarki değişiklikleri içerir. Eğer o 2-3 log backup çok küçükse veya veri değişikliği içermiyorsa (sadece sistem kayıtları vb.), LSN farkı bazen SQL Server’ın otomatik tolere edebileceği seviyede kalabilir.
Normal şartlarda, eğer Primary’de alınan o log backupları Transaction Log’u temizlediyse (truncate) ve o kayıtlar artık canlı .ldf içinde yoksa, Join işlemi şu hatayla patlar:
“The log scan number (LSN) (…) is too recent to apply to the secondary database.”
İşini şansa bırakmamak için izlemen gereken yol şudur:
- Full Restore (WITH NORECOVERY)
- Latest Diff Restore (WITH NORECOVERY)
- Eksik Tüm Log Backupları (Sırasıyla ve WITH NORECOVERY)
- Join Database
Özetle: SQL Server replica olduğunu anlayıp logu “kesmez”. Aksine, AlwaysOn mimarisi katı bir LSN takibi yapar. Senin durumunda muhtemelen eksik loglar hala Primary’nin canlı log dosyasında (buffer/ldf) mevcuttu ve SQL onları otomatik olarak kopyalayıp arayı kapattı.

Restore edeceğimiz log dosyasını seçtikten sonra tekrar options bölümünden norecovery modunda log backup’ımızı restore ettiğimiz full backup’ın üzerine dönüyoruz.


Veritabanımızı yine restoring modda bırakıyoruz.

Benim elimde canlı veri olmadığı için gerçek sistemlerde durum aynen yukarıdaki gibi olmaktadır. Tek fark ben secondary sunucusunda restore işlemleri yaparken primary sunucusunda veriler birikmiş olabilir. Yukarıdaki gibi restore işlemini tamamlamadan önce primary sunucusunda son log backup alınır. Yukarıdaki gibi log backup no recovery modda restore edilir ve daha sonra aşağıdaki yöntemlerdeki gibi always ona dahil edilir.
Kısacası secondary sunucu ile primary sunucusu arasımdaki farkı minimize etmek için kullanılır.
Tekrardan primary sunucusuna geliriz always on database senkronizayon ekranına kaldığımız yerden devam ederiz. İkinci node’a restore işlemi yapıldıktan sonra AG üzerinde database aşağıdaki şekilde eklenebilir.

Next deyip bir sonraki aşamaya geçeriz. Kurulumuzun başarılı bir şekilde yapıldığını görmüş oluyoruz.

Not: Alwayson yapısında bir secondary replica üzerinde bir veritabanı join aşamasına geliyorsa bu durum history kısmında görünür. Alwayson a dahil etmezsek bile, bunun temel nedeni veritabanının synchronize sürecinde geçici olarak bu durumda olmasıdır. Diff backup restore edildikten sonra veritabanı lsn zinciri kopmadığı için alwayson mekanizması otomatik olarak devreye girer ve secondary sunucusunda veritabanı join olarak görünür. Log backup’ı restore etmeden senkron olabileceğini alwayson içerisideki log mekanizmasıyla öğrenmiş oldu. Bu durumu genellikle Skip initial data synchronization bölümünü seçip veritabanı manuel ekleyeceğimiz zaman görülmektedir.

History dediğimiz kavram aşağıdan veya Show dasboard ekranından gözleyebiliriz.
SELECT
ag.name AS AvailabilityGroupName,
db.name AS DatabaseName,
drs.synchronization_state_desc AS SynchronizationState,
drs.synchronization_health_desc AS SynchronizationHealth,
r.replica_server_name AS ReplicaServerName
FROM
sys.dm_hadr_database_replica_states AS drs
JOIN
sys.availability_groups AS ag
ON drs.group_id = ag.group_id
JOIN
sys.databases AS db
ON drs.database_id = db.database_id
JOIN
sys.availability_replicas AS r
ON drs.replica_id = r.replica_id
ORDER BY
ag.name, db.name;
Kurulum işlemlerinden sonra secondary sunucumuzda database’imiz AG’ye dahil olmuş mu kontrol ediyoruz.

Secondary sunucusunda synchronized durumunda olduğunu görmüş oluyoruz. Join only yöntemiyle secondary sunucusunda veritabanımız hemen AG altına dahil olmaktadır.

Başka bir makalede görüşmek dileğiyle..
“Şüphesiz, inkar edenlere, ne malları, ne de evlatları Allah’a karşı hiçbir fayda sağlamaz. Onlar ateşin yakıtıdırlar.”Âl-i İmrân-10
