Estou procurando as melhores práticas para lidar com trabalhos agendados do SQL Server Agent em grupos de disponibilidade do SQL Server 2012. Talvez eu tenha perdido algo, no entanto, no estado atual, sinto que o SQL Server Agent não está realmente integrado com esse ótimo recurso do SQL2012.
Como posso informar um trabalho agendado do agente SQL sobre uma opção de nó? Por exemplo, tenho um trabalho em execução no nó principal que carrega dados a cada hora. Agora, se o primário cair, como posso ativar o trabalho no secundário, que agora se torna primário?
Se eu agendar o trabalho sempre no secundário, ele falhará porque o secundário será somente leitura.
Respostas:
Na tarefa do SQL Server Agent, tenha alguma lógica condicional para testar se a instância atual está cumprindo a função específica que você está procurando no seu grupo de disponibilidade:
Tudo o que isso faz é extrair a função atual da réplica local e, se ela estiver na
PRIMARY
função, você poderá fazer o que for necessário para o seu trabalho, se for a réplica primária. OELSE
bloco é opcional, mas é possível manipular a lógica possível se sua réplica local não for primária.Obviamente, altere
'YourAvailabilityGroupName'
a consulta acima para o nome do seu grupo de disponibilidade real.Não confunda grupos de disponibilidade com instâncias de cluster de failover. Se a instância é a réplica primária ou secundária de um determinado grupo de disponibilidade não afeta os objetos no nível do servidor, como os trabalhos do SQL Server Agent e assim por diante.
fonte
Em vez de fazer isso por tarefa (verificando todos os trabalhos para o estado do servidor antes de decidir continuar), criei um trabalho em execução nos dois servidores para verificar em que estado o servidor está.
Essa abordagem fornece várias coisas
o script verifica o banco de dados no campo abaixo
Este processo é executado a cada 15 minutos em cada servidor. (tem o bônus adicional de anexar um comentário para informar às pessoas por que o trabalho foi desativado)
Não é à prova de idiotas, mas para cargas noturnas e trabalhos por hora, ele faz o trabalho.
Ainda melhor do que executar esse procedimento em um agendamento, execute-o em resposta ao Alerta 1480 (alerta de alteração de função do AG).
fonte
Estou ciente de dois conceitos para fazer isso.
Pré-requisito: Com base na resposta de Thomas Stringer, criei duas funções no banco de dados mestre de nossos dois servidores:
Tornar um trabalho encerrado se não for executado na réplica primária
Nesse caso, todos os trabalhos nos dois servidores precisam de um dos dois trechos de código a seguir na Etapa 1:
Verifique pelo nome do grupo:
Verifique pelo nome do banco de dados:
Se você usar este segundo, tenha cuidado com os bancos de dados do sistema - por definição, eles não podem fazer parte de nenhum grupo de disponibilidade; portanto, eles sempre falham.
Ambos funcionam imediatamente para usuários administrativos. Para usuários não administradores, é necessário adicionar permissões extras, uma delas sugerida aqui :
Se você definir a ação de falha como Sair do relatório de trabalhos com êxito nesta primeira etapa, não receberá o registro de trabalhos cheio de sinais feios de cruz vermelha; para o trabalho principal, eles se transformarão em sinais de aviso amarelos.
De nossa experiência, isso não é o ideal. A princípio, adotamos essa abordagem, mas rapidamente perdemos o controle sobre a localização de tarefas que realmente tinham um problema, porque todas as tarefas de réplica secundária estavam repletas de logs de tarefas com mensagens de aviso.
O que procuramos então é:
Trabalhos de proxy
Se você adotar esse conceito, precisará criar dois trabalhos por tarefa que deseja executar. O primeiro é o "trabalho de proxy" que verifica se está sendo executado na réplica primária. Nesse caso, inicia o "trabalho do trabalhador"; caso contrário, termina normalmente sem desorganizar o log com mensagens de aviso ou erro.
Embora eu pessoalmente não goste da ideia de ter dois trabalhos por tarefa em todos os servidores, acho que é definitivamente mais sustentável, e você não precisa definir a ação de falha da etapa para Sair do sucesso do relatório de trabalhos , o que é um pouco desajeitado.
Para os trabalhos, adotamos um esquema de nomeação. O trabalho de proxy é apenas chamado
{put jobname here}
. O trabalho do trabalhador é chamado{put jobname here} worker
. Isso torna possível automatizar o início do trabalho do trabalhador a partir do proxy. Para fazer isso, adicionei o seguinte procedimento aos dois dbs principais:Isso utiliza a
svf_AgReplicaState
função mostrada acima, você pode facilmente mudar isso para verificar usando o nome do banco de dados, chamando a outra função.De dentro da única etapa do trabalho de proxy, você o chama assim:
Isso utiliza Tokens, como mostrado aqui e aqui, para obter o ID do trabalho atual. O procedimento obtém o nome do trabalho atual do msdb, anexa
worker
a ele e inicia o trabalho do trabalhador usandosp_start_job
.Embora isso ainda não seja o ideal, ele mantém os logs de tarefas mais organizados e com manutenção do que a opção anterior. Além disso, você sempre pode executar o trabalho de proxy com um usuário sysadmin, portanto, não é necessário adicionar permissões extras.
fonte
Se o processo de carregamento de dados for uma consulta simples ou chamada de procedimento, você poderá criar o trabalho nos dois nós e permitir que ele determine se é o nó principal com base na propriedade Updateability do banco de dados, antes de executar o processo de carregamento de dados:
fonte
É sempre melhor criar uma nova etapa da tarefa que verifique se é uma réplica primária e está tudo bem para continuar com a execução da tarefa; caso seja uma réplica secundária, interrompa a tarefa. Não falhe no trabalho, pois ele continuará enviando notificações desnecessárias. Em vez disso, pare o trabalho para que ele seja cancelado e nenhuma notificação seja enviada sempre que esses trabalhos forem executados na réplica secundária.
Abaixo está o script para adicionar uma primeira etapa para um trabalho específico.
Nota para executar o script:
Se houver vários Grupos de Disponibilidade, defina o nome do AG na variável @AGNameToCheck_IfMoreThanSingleAG sobre qual AG deve ser verificado quanto ao seu estado de réplica.
Observe também que esse script deve funcionar bem mesmo nos servidores que não possuem grupos de disponibilidade. Será executado apenas para versões do SQL Server 2012 e posteriores.
fonte
Outra maneira é inserir uma etapa em cada tarefa, que deve ser executada primeiro, com o seguinte código:
Defina esta etapa para continuar com a próxima etapa do sucesso e encerrar o trabalho que informa o sucesso em uma falha.
Acho mais limpo adicionar uma etapa extra em vez de adicionar lógica extra a uma etapa existente.
fonte
Outra opção mais recente é usar master.sys.fn_hadr_is_primary_replica ('DbName'). Eu achei isso super útil ao usar o SQL Agent para fazer a manutenção do banco de dados (juntamente com um cursor que eu usei há anos) e também ao executar uma ETL ou outra tarefa específica do banco de dados. O benefício é que ele seleciona o banco de dados em vez de examinar todo o Grupo de Disponibilidade ... se é isso que você precisa. Também torna muito mais improvável que um comando seja executado em um banco de dados que "estava" no primário, mas digamos que ocorreu um failover automático durante a execução do trabalho, e agora ele está em uma réplica secundária. Os métodos acima, que examinam a réplica primária, dão uma olhada e não são atualizados. Lembre-se de que essa é apenas uma maneira diferente de obter resultados muito semelhantes e fornecer um controle mais granular, se você precisar. Além disso, a razão pela qual esse método não foi discutido quando essa pergunta foi feita é porque a Microsoft não lançou essa função até o lançamento do SQL 2014. Abaixo estão alguns exemplos de como essa função pode ser usada:
Se você deseja usar isso para manutenção do banco de dados do usuário, é isso que eu uso:
Espero que seja uma dica útil!
fonte
Eu uso isso:
fonte