Distributed Availability Groups – SQL Server
Fala, Pessoal!
Após um tempo sem fazer post, venho trazer um assunto muito bacana sobre uma feature do SQL Server que não é tão comum.
Para quem não tem nenhum conhecimento sobre o alta disponibilidade e recuperação de desastres, recomendo que estude os principais conceitos sobre esses assuntos, pois serão os focos desse post.
Vou dividir o assunto nos seguintes tópicos, para facilitar a compreensão:
- Entendendo o que são grupos de disponibilidade distribuídos
- Quando devemos utilizar grupos de disponibilidade distribuídos
- Quanto custa?
- Criando e configurando um grupo de disponibilidade distribuído
- Pontos de atenção
Antes de partir para os conceitos e prática, devido a complexidade de montar as configurações que serão demonstradas, se fez necessário esconder algumas informações nas imagens, em razão de não ter realizado os procedimentos em ambiente de estudo. De qualquer forma, se houver alguma dúvida relacionada ao que vou apresentar, estou sempre a disposição para que entrem em contato comigo.
Distributed Availability Groups
Um grupo de disponibilidade distribuído nada mais é do que a combinação entre dois grupos de disponibilidade simples, que não precisam estar no mesmo local, nem possuir as configurações idênticas, contanto que haja comunicação entre eles.
Diferente de um grupo de disponibilidade simples, que é configurado utilizando o WSFC (Windows Server Failover Cluster), um grupo de disponibilidade distribuído utiliza recursos do próprio SQL Server para realizar a comunicação e propagação de dados entre os grupos de disponibilidades subjacentes que farão parte da arquitetura.
Essa é uma definição resumida, para que tenhamos uma noção do que se trata o assunto e facilitar o acompanhamento de todos os detalhes que serão expostos a seguir.
Mais detalhes podem ser encontrados acessando o seguinte link:
Utilização
Após vários estudos sobre casos de uso, enxergo como eficaz utilizar este recurso em dois cenários:
Migração de ambiente de alta disponibilidade
Ao configurar um grupo de disponibilidade distribuído entre dois grupos de disponibilidade simples, é possível realizar o failover de um ambiente pra o outro, com o mínimo de indisponibilidade.
Podemos realizar essa atividade para migrar ambientes pelos mais diversos motivos, inclusive, migração de versões e até mesmo realizar migração entre servidores que possuem sistemas operacionais diferentes. Isso é possível graças a independência de configurações que podem existir em um grupo de disponibilidade distribuído.
Recuperação de Desastres
Esse é o cenário que eu mais gosto.
Atualmente, os ataques a dados estão em alta. Temos observado diversos casos em que empresas estão sendo extremamente prejudicadas quando são invadidas, ficam com seus dados em jogo e nas mãos de pessoas mal-intencionadas.
Uma configuração de grupo de disponibilidade distribuído pode ser uma boa opção para que os dados tenham mais um nível de proteção e que o tempo de recuperação dos dados seja o melhor possível, evitando assim, maiores impactos em caso de invasão.
Custo
– Ah, Anderson! Parece muito legal mesmo, maaaaaas. Quanto custa?
O custo pode variar de acordo com o cenário de implementação. Se a ideia for implementar com a finalidade de migração, o custo ficará alto enquanto o ambiente de origem e o de destino estiverem em funcionamento para que a migração ocorra e possivelmente volte a ser o mesmo ou tenha uma variação menor após a conclusão do procedimento de migração, pois o ambiente antigo poderá ser descontinuado.
Já no cenário de utilizar a funcionalidade como estrutura de disaster recovery, o custo vai depender de como será configurado o ambiente secundário.
Por exemplo: se temos um grupo de disponibilidade primário de 3 nós e queremos implementar um grupo de disponibilidade secundário com a mesma configuração, o custo irá dobrar. Claro que isso depende das configurações dos servidores, mas vamos partir do princípio de que iremos criar servidores com a mesma configuração. Se a ideia for criar um segundo grupo de disponibilidade com apenas dois nós, o custo será um pouco menor e por aí vai.
De qualquer forma, precisamos ter em mente que, o custo para manter um grupo de disponibilidade distribuído ativo e sendo utilizado como estrutura de disaster recovery, será mais caro que montar essa estrutura para realizar uma migração.
Criando e Configurando um Grupo de Disponibilidade Distribuído
Agora que temos um entendimento sobre os cenários aplicáveis para a utilização dessa feature, vamos pra parte que é realmente interessante. Criar e configurar essa arquitetura.
Pré-Requisitos
- SQL Server 2016 ou superior (Enterprise).
- Os dois cluster que farão parte do grupo de disponibilidade distribuído devem possuir listener.
- Todos os servidores dos dois clusters que farão parte do grupo de disponibilidade distribuído, devem se comunicar nas portas que serão utilizadas para realizar a configuração. No nosso caso, 1433 e 5022.
- Os listeners dos grupos de disponibilidade que farão parte do grupo de disponibilidade distribuído devem escutar em todos os endereços IP.
OBS: Para o exemplo deste post, iremos configurar um grupo de disponibilidade distribuído entre dois clusters que possuem grupos de disponibilidade simples com 3 nós cada um.
Criando o Grupo de Disponibilidade Distribuído
Quando vamos configurar um grupo de disponibilidade distribuído, a configuração do failover só é permitida como manual. Isso para que sempre que for necessário realizar um failover de um cluster para outro, ele seja feito de forma controlada para evitar ou minimizar o risco de perda de dados.
O sincronismo pode ser configurado como síncrono ou assíncrono. Existe a recomendação de que seja configurado como assíncrono e só seja alterado para síncrono antes da realização de um failover.
Já com relação a propagação de dados , assim como em um grupo de disponibilidade simples, temos a opção de configurar como manual ou automático.
Como a opção de propagação automática é a mais simples, pois o próprio SQL Server se encarrega de realizar a “cópia” dos bancos de dados para o nó primário do cluster secundário, vamos trabalhar com a opção manual, mostrando como realizar essa configuração que é um pouco mais detalhada do que a configuração automática pelo fato da restauração dos bancos de dados nos outros servidores, ser realizada manualmente.
Então iremos considerar a configuração manual, como se estivéssemos trabalhando em um ambiente com um o volume dados muito grande, certo?!
Agora, vamos lá!
Hora de colocar a mão na massa, seguindo os passos a seguir:
- Executar o seguinte script para realizar a configuração no cluster que será o primário:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
CREATE AVAILABILITY GROUP TESTE_DAG WITH (DISTRIBUTED) AVAILABILITY GROUP ON 'AG1' WITH ( LISTENER_URL = 'TCP://ag1-listener.urlteste.com:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, SEEDING_MODE = MANUAL ), 'AG2' WITH ( LISTENER_URL = 'TCP://ag2-listener.urlteste.com:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, SEEDING_MODE = MANUAL ); GO |
- Executar o seguinte script para ingressar o cluster que será o secundário no grupo de disponibilidade distribuído:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
ALTER AVAILABILITY GROUP TESTE_DAG JOIN AVAILABILITY GROUP ON 'AG1' WITH ( LISTENER_URL = 'TCP://ag1-listener.urlteste.com:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, SEEDING_MODE = MANUAL ), 'AG2' WITH ( LISTENER_URL = 'TCP://ag2-listener.urlteste.com:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, SEEDING_MODE = MANUAL ); GO |
Observem que agora aparece um segundo grupo de disponibilidade (Distributed) no painel do Always On.
Ingressar o Banco de Dados no Grupo de Disponibilidade Distribuído
Se o modo de propagação de dados utilizado for o automático, basta ingressar o banco de dados no grupo de disponibilidade distribuído executando o script abaixo:
1 |
ALTER DATABASE BD_TESTE SET HADR AVAILABILITY GROUP = TESTE_DAG |
Como dito anteriormente, em alguns ambientes como os que possuem bancos de dados de volumetria muito alta, pode ser necessário utilizar o modo de propagação de dados manual. Nestes casos, é necessário realizar os backups dos bancos de dados na réplica primária do cluster primário e restaurá-los em todas as réplicas do cluster secundário com a opção NORECOVERY, conforme instruções abaixo:
- Backup Full na réplica primária do cluster primário
1 2 3 4 |
BACKUP DATABASE [BD_TESTE] TO DISK = N'D:\BACKUPS\BD_TESTE.bak' WITH NOFORMAT, NOINIT, NAME = N'BD_TESTE-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, COMPRESSION, STATS = 5 GO |
- Backup de Log na réplica primária do cluster primário
1 2 3 |
BACKUP LOG [BD_TESTE] TO DISK = N'D:\BACKUPS\LOG\BD_TESTE.ldf' WITH NOFORMAT, NOINIT, NAME = N'BD_TESTE-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 5 GO |
- Restore do backup full (Realizar essa operação para todos os nós do cluster secundário):
1 2 3 4 |
RESTORE DATABASE BD_TESTE FROM DISK = 'D:\BACKUPS\BD_TESTE.bak' WITH NORECOVERY, STATS = 5 GO |
- Restore do backup de log (Realizar essa operação para todos os nós do cluster secundário):
1 2 3 4 |
RESTORE LOG BD_TESTE FROM D:\BACKUPS\LOG\BD_TESTE.ldf WITH NORECOVERY, STATS = 5 GO |
Esse procedimento pode ser realizado executando a query abaixo nos dois clusters e comparando os LSN dos bancos de dados:
1 2 3 4 5 6 7 8 9 10 |
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 ORDER BY database_name |
Após essas etapas serem concluídas com sucesso, realizamos o procedimento para ingressar o banco de dados no grupo de disponibilidade distribuído, dessa vez executando o script no nó primário do cluster secundário:
1 |
ALTER DATABASE BD_TESTE SET HADR AVAILABILITY GROUP = TESTE_DAG |
É possível verificar se o banco de dados está sendo sincronizado com sucesso, executando o seguinte script no cluster primário:
1 2 3 4 5 6 |
SELECT ag.name , db_name(drs.database_id) as database_name , drs.synchronization_state_desc FROM sys.dm_hadr_database_replica_states drs INNER JOIN sys.availability_groups ag on drs.group_id = ag.group_id WHERE drs.database_id = 50 |
Realizar Failover em um Grupo de Disponibilidade Distribuído
Em um grupo de disponibilidade distribuído, só é possível realizar failover manual. O procedimento consiste nos seguintes passos:
- Definir o grupo de disponibilidade distribuído como síncrono
O grupo de disponibilidade distribuído deve ser configurado com o modo de propagação de dados síncrono executando o script abaixo:
1 2 3 4 5 6 7 8 9 10 11 |
ALTER AVAILABILITY GROUP TESTE_DAG MODIFY AVAILABILITY GROUP ON 'AG1' WITH ( AVAILABILITY_MODE = SYNCHRONOUS_COMMIT ), 'AG2' WITH ( AVAILABILITY_MODE = SYNCHRONOUS_COMMIT ); |
Após essa configuração, deve ser realizada a confirmação de que todos os servidores tenham o mesmo last_hardened_lsn por banco de dados.
Esse processo pode demorar alguns minutos, então é necessário aguardar até que os LSN estejam todos iguais.
É possível verificar o sincronismo utilizando o seguinte script:
1 2 3 4 5 6 |
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 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 |
Com a confirmação de que o sincronismo está corretamente configurado, deve ser averiguado se a sequência de logs entre o cluster primário e o secundário está igual, utilizando o script abaixo:
1 2 3 4 5 6 7 8 9 10 |
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 ORDER BY database_name |
- Definir o grupo de disponibilidade distribuído como secundário
Na réplica primária do cluster primário, executar o seguinte script para alterar a configuração da réplica:
1 |
ALTER AVAILABILITY GROUP AG1 SET (ROLE = SECONDARY); |
Observação: Neste momento o grupo de disponibilidade distribuído ficará indisponível.
- Verificar novamente a sequência de logs
Para garantir que o sincronismo entre todos os servidores esteja correto, deve ser executado o script abaixo e a verificação dos LSN:
1 2 3 4 5 6 7 8 9 10 |
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 ORDER BY database_name |
Observação: neste momento a consulta deve ser executada em todos os servidores dos dois clusters para garantir que não haverá nenhum problema relacionado a sincronismo dos logs.
- Realizar o failover do grupo de disponibilidade distribuído
Executar o seguinte script na réplica primária do cluster secundário:
1 |
ALTER AVAILABILITY GROUP TESTE_DAG FORCE_FAILOVER_ALLOW_DATA_LOSS; |
Após o failover, o cluster secundário irá assumir a posição de primário:
- Verificar sincronismo nos dois clusters
Após todo o processo ser realizado, é uma boa prática verificar o sincronismo nos dois cluster para garantir que não há nenhum problema relacionado a alta disponibilidade:
Realizar Failback em um Grupo de Disponibilidade Distribuído
O procedimento de failback consiste em realizar os mesmos passos do tópico de failover, porém invertendo a ordem dos clusters para que seja possível retornar o cluster que está como secundário para a função de primário.
Pontos de Atenção
- Devem ser levados em consideração pontos como a necessidade de sua criação, visto que os custos operacional e financeiro, aumentam de forma significativa.
- Ao utilizar o Change Data Capture (CDC), devem ser observadas as particularidades relacionadas a sua utilização junto com grupos de Disponibilidade. Mais detalhes podem ser encontrados no seguinte link:
- O monitoramento de um Grupo de Disponibilidade Distribuído é realizado via query, pois o SSMS não oferece suporte para visualizações gráficas relacionadas a essa feature.
Conclusão
É isso, galera!
Tentei trazer um pouco da experiência que venho tendo utilizando grupos de disponibilidade distribuídos e como foi o processo de criação desse ambiente, que pode ser muito útil para os cenários que citei no início do post.
Em breve, vou escrever um post relacionados ao monitoramento utilizando o Grafana, já que senti bastante falta da parte gráfica no SSMS.
Como será um assunto um pouco longo, vejo vocês no próximo post.
Espero que tenham gostado e até a próxima.
Deu aula!!! Show
Que post FODA!!! Muito bom e scripts valiosos ai para monitoramento também!
Obrigado por compartilhar!
Abraço,
Luiz Vitor
Excelente conteúdo !!
Vai me ajudar muito.
Parabéns e obrigado pela contribuição !