Resultados do SSMS e do servidor registrado

8

Antecedentes :

Estamos tentando criar um equipamento de teste "básico" da AG para uma de nossas equipes de suporte. Não sabendo quais servidores, em um determinado momento, serão os principais instruídos para executar o TSQL em um grupo de servidores registrado. O grupo de servidores registrados consiste em todos os servidores no AG. O objetivo é executar apenas o TSQL no servidor principal atual:

Arnês de teste atual :

IF EXISTS (SELECT *
FROM sys.dm_hadr_availability_replica_states AS HARS 
INNER JOIN sys.dm_hadr_availability_replica_cluster_states AS HACS ON HACS.replica_id = HARS.replica_id 
    WHERE (HARS.role_desc = 'PRIMARY') AND (HACS.replica_server_name LIKE @@SERVERNAME))
BEGIN
<<SOME CODE TO EXECUTE>>
END

Problema :

Se o primeiro servidor que responder à consulta de vários servidores não retornar nenhum resultado, o SSMS assumirá que o conjunto de resultados correto não é um conjunto de resultados, mesmo que outros servidores posteriormente retornem com um conjunto de resultados. Portanto, nesse cenário, nenhum resultado é retornado ... isso não está correto e não é a funcionalidade esperada.

Alguém pode pensar em uma maneira, com o SSMS (essa é a ferramenta mais familiar para a equipe de CS), forçar a execução apenas no servidor principal atual?

atormentar
fonte
Você já pensou em conectá-los ao ouvinte AG, executando a consulta dessa maneira? Ele garantirá sempre atingir o primário.
Nic
Infelizmente, isto não é possível. Temos muitos inquilinos com ouvintes nomeados de forma idêntica. Só não vai funcionar neste caso.
Harry

Respostas:

10

Eu já deparei com isso ** antes, e se bem me lembro, para garantir sempre a obtenção de resultados com consultas de vários servidores, você precisa forçar um conjunto de resultados vazio quando nenhuma linha seria retornada. Ou seja, você precisa de uma ELSEramificação para isso IFe, dentro do ELSEdiretório, faria algo como o seguinte:

SELECT CONVERT(DATETIME, NULL) AS [Col1name],
       CONVERT(DECIMAL(12, 5), NULL) AS [Col2name],
       ...{additional fields}...
WHERE  1 = 0;

Isso produz um conjunto de resultados vazio que possui os nomes e tipos de dados adequados.

OU, e eu não tentei isso no passado (pensei nisso enquanto estava digitando isso), mas você pode simplesmente fazer uma pausa nesse ELSEramo, de modo que o servidor primário / pretendido sempre possa retornar seu primeiro conjunto de resultados (que é o problema real aqui: o primeiro servidor a responder define a estrutura que todas as outras respostas devem aderir). Portanto, o seguinte pode funcionar como a única coisa no ELSE:

WAITFOR DELAY '00:00:10'; -- 10 seconds (just needs to be longer than the real query takes)

Mas não me lembro se outros servidores retornaram nenhum resultado, causando a exibição de uma mensagem de erro na guia "Mensagens". Se isso acontecer, o conjunto de resultados vazio é definitivamente o caminho a percorrer. Mas se isso funcionar, poderá funcionar melhor em um modelo geral (como parece o seu caso), pois não exigiria o ajuste do conjunto de resultados vazio e forçado toda vez que for usado.

ATUALIZAR:

O OP verificou que:

  • o WAITFOR DELAYrealmente funcionou, e
  • as réplicas relataram a mensagem de erro, mas não apresentaram um problema para o uso do OP

** A situação em que me deparei era semelhante, mas não tinha nada a ver com os Grupos de Disponibilidade ou com os resultados de apenas um servidor. Nossa situação era que tínhamos 18 servidores com o mesmo esquema de dados diferentes e precisávamos executar várias tarefas de manutenção, agregações em todos os 18 nós. Havia alguns procedimentos armazenados que, por qualquer motivo, ocasionalmente não retornavam nenhum conjunto de resultados e, por qualquer motivo, não era possível corrigi-lo no procedimento armazenado. Portanto, dependendo de qual nó retornou primeiro, na maioria das vezes tudo estava bem, mas de vez em quando o nó que às vezes retornava nenhum conjunto de resultados retornava primeiro. Então, eu tinha que fazer algo como despejar os resultados em uma tabela temporária e se @@ROWCOUNTisso INSERT...EXECfoi de 0, então eu iria selecionar o forçado, conjunto de resultados vazio.

Solomon Rutzky
fonte
2
Nunca pensaria nisso !! A espera pelo atraso funciona como um campeão! Definitivamente, evita a criação do resultado vazio definido. Você trabalha man @srutzky Obrigado
Harry
@ Harry Você é bem-vindo, e obrigado :-). Acabei de atualizar minha resposta para ser um pouco mais clara sobre os benefícios da WAITFOR DELAYabordagem e que você confirmou que funcionou, então obrigado por isso!
Solomon Rutzky,
11
Essa é a coisa mais legal que eu já vi esta semana.
Brent Ozar
Definitivamente gera um erro nas réplicas, no entanto, neste caso, isso está completamente correto.
Harry
@ Harry Mais uma vez obrigado por fornecer esse feedback. Eu o adicionei à minha resposta, juntamente com uma explicação na parte inferior da situação que encontrei.
Solomon Rutzky
0

Eu sempre usei uma tabela temporária para retornar resultados e obter respostas consistentes de todos os servidores em um grupo. As consultas com vários servidores são uma das minhas coisas favoritas sobre o SSMS.

Tony
fonte