Bu makalede SQL Server 2016 versiyonu ile hayatımıza giren Distributed AlwaysOn(DAG) özelliğinden bahsedeceğiz.
• DAG Farklı Windows Failover Cluster (WSFC)’lar arası AlwaysON kurabilmemize olanak sağlamaktadır.
• DAG kullanabilmemiz aktifleştirebilemiz için ortamlarımızın fiziksel, sanal yada bulutta olması bu özelliği kullanmamıza engel değildir.ortamlarımızda WFSC ve 5022,1433 portlarımızın erişimi olması yeterlidir.
• SQL Sürümlerinin MS SQL 2016 ve üzeri sql sürümleri olmalıdır. SQL Özelliği olduğu için İşletim sisteminin farklılıkları engel değildir.
• DAG yapılandırması Klasik AG yapılandırmasından biraz farklıdır. Normalde her bir AG dahil olduğu replikaları Primary ve Secondary olarak beslerken burada Hem kendi AG’ sinde bulunan replikaları hemde DAG’a bağlı olan İletici(Forwarder) AG yi besler. İletici(Forwarder) ile birlikte farklı secondarylerde beslenebilir. Bu durumlarda Primary harici 2. WSFC lerde dahil sadece read-only olarak hizmet verebilir. Failover edilip Primary olmadığı sürece.
• Clusterless AlwaysON dan farkı, Clusterless AlwaysOn için yeni bir AG kurarken Cluster type=NONE olması gerekmektedir. Bu durumda mevcut clusterımıza dahil olan replikalarımızda Auto-Failover özelliği engellenir. DAG ile AG kurulumundaki Cluster Type=Windows Server Failover Cluster seçildiğinden aynı AG üzerinden hem clustera dahil olan replikalar otomatik Failover olabilecek hem de cluster dışı AG ler beslenebilecektir. Clusterless AlwaysOn Kurulumu için bknz:
• Sync yada Async olarak kullanılabilir.
• Auto-Failover özelliği bulunamamaktadır.
• Failoverlar’da FORCE_FAILOVER_ALLOW_DATA_LOSS seçeneği ile farklı WSFC’lerdeki AG lere Failover edilebilir.
• DAG’ı SSMS üzerinde izleyemiyoruz. DMV’ler yardımıyla Redo ve Commit zamanlarını kontrol edebiliriz.
Peki Neden Kullanmalıyız ?
1) Normal şartlarda Multi-Subnet AO ile aynı WSFC ye aldığımız farklı Subnetteki sunucuları AO ekleyerek tek bir primary node ile secondary nodeları besliyoruz. Bu yapıda Cluster ,witness ve vote bağımlılığımız oluyor. Bu şekilde Clusteri kaybettiğimizde tüm AG ler hizmet veremez durumlara geliyor. DAG ile bu senaryolarda Cluster, witness ve vote kendi cluster içinde olacağı için bağımlılık kalkmış oluyor. herhangi bir şekilde 1.Clusteri kaybettiğimiz senaryoda 2.Clusterımız hala ayakta kalıyor tabi manuel müdahale ile FORCE_FAILOVER_ALLOW_DATA_LOSS geçeneği ile data kaybı var ise kabul ederek failover yapılıp, ileticiyi primary olarak yapılandırabiliyoruz.
2) Farklı Clusterlar da bulunan bir çok prod ortamımız olduğunu düşünelim bu prod ortamların ise doğrulama yapmak için bir veri tabanına ihtiyacı var. Örneğin UserDB tüm prod-rapor ortamların UserDB içerisindeki User tablosunda sorgulama yapıyor. İşte tam bu noktada DAG ile farklı clusterlara UserDB veri tabanını Sync bir şekilde replikasyonunu sağlamana olanak tanır. Normal şartlarda UserDB veri tabanına sorguya gidip prod ortamda yük yaratacakken bu şekilde yükü yayarak erişilebilirlik daha da artırılabilir.
3) Sql Upgrade (Sql Server 2016 >>> Sql Server 2017) sunucu değişikliği çalışmalarında da DAG kullanılabilir. SQL 2016 ile gelen bir özellik olduğu için daha önce ki sürümler desteklenmemektedir.
4) Windows Server 2012 r2 işletim sistemine sahip bir ortama sahibiz ve bu ortamı Windows Server 2016 yada daha üst versiyona sahip bir WSFC ortama taşımak istiyoruz. Bu aşamada da DAG yapılandırarak Geçişleri hızlı bir şekilde sağlayıp failover sonrası yeni clusterda olan tüm replikaları hızlı bir şekilde besleyerek ayağa kaldırabiliriz.
DAG yapılandırmak;
Bu yapılandırma ile mevcut bir AG de bulunan dbleri mevcut ortamı bozmadan DAG yöntemi ile farklı bir WSFC ortamına da replikasyonunu sağlayacağız ve failover yapacağız.
AG_CL2 Mevcutta WindowsFailoverCluster AO;
Kurulum;
1) Eğer AG yok ve DAG yapılmak isteniyorsa bir endpoint oluşturmak gerekiyor;
1 2 3 4 5 6 7 8 9 |
CREATE ENDPOINT [Hadr_endpoint] STATE=STARTED AS TCP (LISTENER_PORT = 5022, LISTENER_IP = ALL) FOR DATA_MIRRORING ( ROLE = ALL, AUTHENTICATION = WINDOWS NEGOTIATE, ENCRYPTION = REQUIRED ALGORITHM AES ) GO |
2) Endpointlere servis hesaplarını çapraz yetkilendiriyoruz. (Primary instance’ın service hesabını Secondary instance’da, Secondary İnstance’in service hesabını Primary’de);
1 |
GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [testintra\tstsvcuser]; |
3) DAG’da bulunacak tüm AG lerde Çalıştırılır;
1 2 |
ALTER ENDPOINT Hadr_endpoint AS TCP (LISTENER_IP = ALL) GO |
4) Secondary instance’da yeni bir AG oluşturulur;
1 2 3 4 5 6 7 8 9 |
CREATE AVAILABILITY GROUP AG_RPT_TEST WITH (CLUSTER_TYPE = NONE) FOR REPLICA ON N'DRCTSTAODB02' WITH (ENDPOINT_URL = N'TCP://DRCTSTAODB02.test.testintra.com:5022', FAILOVER_MODE = MANUAL, AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SECONDARY_ROLE(ALLOW_CONNECTIONS = NO), SEEDING_MODE = AUTOMATIC) |
5) Primary İnstance’da DAG yaratılır;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
CREATE AVAILABILITY GROUP DAG_RPT_TEST WITH (DISTRIBUTED) AVAILABILITY GROUP ON 'AG_CL2' WITH ( LISTENER_URL = 'TCP://TSTAODBV11.test.testintra.com:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, SEEDING_MODE = AUTOMATIC ), 'AG_RPT_TEST' WITH ( LISTENER_URL = 'TCP://DRCTSTAODB02.test.testintra.com:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, SEEDING_MODE = AUTOMATIC ); GO |
6) Secondary instance’da JOIN edilir;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
ALTER AVAILABILITY GROUP DAG_RPT_TEST JOIN AVAILABILITY GROUP ON 'AG_CL2' WITH ( LISTENER_URL = 'TCP://TSTAODBV11.test.testintra.com:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, SEEDING_MODE = AUTOMATIC ), 'AG_RPT_TEST' WITH ( LISTENER_URL = 'TCP://DRCTSTAODB02.test.testintra.com:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, SEEDING_MODE = AUTOMATIC ); GO |
7)DAG kurulumu tamamlandı.Secondary instanceda bulunan DBler Kullanılacaksa Sadece Read-Only olarak açılabilir.
1 2 3 |
ALTER AVAILABILITY GROUP [AG_RPT_TEST] MODIFY REPLICA ON N'DRCTSTAODB02' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL)) GO |
DAG İzleme:
DAG özelinde Sync durumlarının Kontrolü İçin;
Script1;
1 2 3 4 5 6 7 8 9 10 11 12 13 |
SELECT ag.[name] AS [AG Name], ag.is_distributed, ar.replica_server_name AS [Underlying AG], ars.role_desc AS [Role], ars.synchronization_health_desc AS [Sync Status] FROM sys.availability_groups AS ag INNER JOIN sys.availability_replicas AS ar ON ag.group_id = ar.group_id INNER JOIN sys.dm_hadr_availability_replica_states AS ars ON ar.replica_id = ars.replica_id WHERE ag.is_distributed = 1; GO |
Script2;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
SELECT ag.name AS [AG Name], ag.is_distributed, ar.replica_server_name AS [AG], dbs.name AS [Database], ars.role_desc, drs.synchronization_health_desc, drs.log_send_queue_size, drs.log_send_rate, drs.redo_queue_size, drs.redo_rate, drs.suspend_reason_desc, drs.last_sent_time, drs.last_received_time, drs.last_hardened_time, drs.last_redone_time, drs.last_commit_time, drs.secondary_lag_seconds FROM sys.databases dbs INNER JOIN sys.dm_hadr_database_replica_states drs ON dbs.database_id = drs.database_id INNER JOIN sys.availability_groups ag ON drs.group_id = ag.group_id INNER JOIN sys.dm_hadr_availability_replica_states ars ON ars.replica_id = drs.replica_id INNER JOIN sys.availability_replicas ar ON ar.replica_id = ars.replica_id --WHERE ag.is_distributed = 1 GO |
DAG ile beslenen secondary’ye failover;
1) Primary ve secondary instancelarda AG statülerini synchronized yap
1 2 3 4 5 6 7 8 9 10 11 |
ALTER AVAILABILITY GROUP [DAG_RPT_TEST] MODIFY AVAILABILITY GROUP ON 'AG_CL2' WITH ( AVAILABILITY_MODE = SYNCHRONOUS_COMMIT ), 'AG_RPT_TEST' WITH ( AVAILABILITY_MODE = SYNCHRONOUS_COMMIT ); |
2) Kontrol için SYNCHRONIZED olmasını bekle!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
select ag.name , ag.is_distributed , ar.replica_server_name , ar.availability_mode_desc , ars.connected_state_desc , ars.role_desc , ars.operational_state_desc , ars.synchronization_health_desc from sys.availability_groups ag inner join sys.availability_replicas ar on ag.group_id=ar.group_id left join sys.dm_hadr_availability_replica_states ars on ars.replica_id=ar.replica_id where ag.is_distributed=1 GO |
3) LSN kontrolü yapılır;
1 2 3 4 5 6 7 8 9 |
SELECT ag.name , drs.database_id , db_name(drs.database_id) as database_name , drs.group_id , drs.replica_id , drs.synchronization_state_desc , drs.last_hardened_lsn FROM sys.dm_hadr_database_replica_states drs INNER JOIN sys.availability_groups ag on drs.group_id = ag.group_id; |
4) LSN’ler eşit ise primary instance da çalıştırılır.
1 |
ALTER AVAILABILITY GROUP [DAG_RPT_TEST] SET (ROLE = SECONDARY); |
5) Failover Yapılır
1 |
ALTER AVAILABILITY GROUP [DAG_RPT_TEST] FORCE_FAILOVER_ALLOW_DATA_LOSS; |
6) Failover oldu. Eski Primaryi kullanacaksak Async çekelim.
1 2 3 4 5 6 7 8 9 10 11 |
ALTER AVAILABILITY GROUP [DAG_RPT_TEST] MODIFY AVAILABILITY GROUP ON 'AG_CL2' WITH ( AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT ), 'AG_RPT_TEST' WITH ( AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT ); |
7) Read-only yapmak istiyorsak;
1 2 3 |
ALTER AVAILABILITY GROUP [AG_CL2] MODIFY REPLICA ON N'TSTAODBV11' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL)) GO |
İyi çalışmalar.