SSMS et résultats des serveurs enregistrés

8

Contexte :

Nous essayons de créer un faisceau de test AG «principal» pour l'une de nos équipes d'assistance. Ne sachant pas quels serveurs à un moment donné seront les principaux auxquels ils ont été chargés d'exécuter le TSQL sur un groupe de serveurs enregistré. Le groupe de serveurs enregistrés comprend tous les serveurs de l'AG. L'objectif est d'exécuter TSQL uniquement sur le serveur principal actuel:

Harnais de test actuel :

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

Problème :

Si le premier serveur qui répond à la requête multi-serveur ne renvoie aucun résultat, SSMS supposera que le bon jeu de résultats n'est pas un jeu de résultats, même si d'autres serveurs reviennent plus tard avec un jeu de résultats. Donc, dans ce scénario, aucun résultat n'est renvoyé ... ce n'est pas correct et ce n'est pas la fonctionnalité attendue.

Quelqu'un peut-il penser à un moyen, avec SSMS (c'est l'outil le plus familier pour l'équipe CS), de forcer l'exécution uniquement sur le serveur principal actuel?

Harry
la source
Avez-vous envisagé de les connecter à l'écouteur AG, exécutant ainsi la requête de cette façon? Il assurera toujours de frapper le primaire.
Nic
Malheureusement, ce n'est pas possible. Nous avons une tonne de locataires avec des auditeurs nommés de manière identique. Ne fonctionnera tout simplement pas dans ce cas.
Harry

Réponses:

10

J'ai déjà rencontré ce ** avant, et si je me souviens bien, pour vous assurer d'obtenir toujours des résultats avec des requêtes multi-serveurs, vous devez forcer un ensemble de résultats vide lorsqu'aucune ligne ne serait retournée autrement. ELSECela signifie que vous avez besoin d'une branche à ce sujet IFet que ELSEvous feriez quelque chose comme ceci:

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

Cela produit un jeu de résultats vide qui a les noms et les types de données appropriés.

OU, et je n'ai pas essayé cela dans le passé (je l'ai juste pensé en tapant ceci), mais vous pourriez peut- être vous en sortir simplement en faisant une pause dans cette ELSEbranche de telle sorte que le serveur principal / prévu soit toujours autorisé à renvoyer son résultat défini en premier (ce qui est le vrai problème ici: le premier serveur à répondre définit la structure à laquelle toutes les autres réponses doivent adhérer). Par conséquent, ce qui suit pourrait fonctionner comme la seule chose dans le ELSE:

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

Mais je ne me souviens pas si le fait que d'autres serveurs ne retournent aucun résultat provoquait l'affichage d'un message d'erreur dans l'onglet "Messages". Si cela se produit, le jeu de résultats vide est définitivement la voie à suivre. Mais si cela fonctionne, cela pourrait mieux fonctionner dans un modèle général (comme votre cas semble l'être) car cela ne nécessiterait pas d'ajuster le jeu de résultats forcé et vide chaque fois qu'il est utilisé.

MISE À JOUR:

Le PO a vérifié que:

  • l' WAITFOR DELAYavez fait travailler, et
  • les répliques ont signalé le message d'erreur, mais cela n'a pas posé de problème pour l'utilisation de l'OP

** La situation que j'ai rencontrée était similaire, mais n'avait rien à voir avec les groupes de disponibilité ou le fait de vouloir des résultats provenant d'un seul serveur. Notre situation était que nous avions 18 serveurs de données de schéma différent et que nous devions effectuer diverses tâches de maintenance, agrégations sur les 18 nœuds. Il y avait des procédures stockées qui, pour une raison quelconque, ne retournaient parfois aucun ensemble de résultats, et quelle que soit la raison, il ne pouvait pas être corrigé dans la procédure stockée. Ainsi, en fonction du nœud renvoyé en premier, la plupart du temps tout allait bien, mais de temps en temps le nœud qui ne renvoyait parfois aucun jeu de résultats revenait en premier. Donc, je devais faire quelque chose comme vider les résultats dans une table temporaire et si @@ROWCOUNTcela INSERT...EXECétait 0, alors je choisirais le résultat forcé, ensemble vide.

Solomon Rutzky
la source
2
N'aurais jamais pensé à ça !! L'attente du retard fonctionne comme un champion! Sauve définitivement de la construction du résultat vide défini. You do man @srutzky Merci
Harry
@Harry Vous êtes les bienvenus et merci :-). Je viens de mettre à jour ma réponse pour être un peu plus clair sur les avantages de l' WAITFOR DELAYapproche et que vous avez confirmé qu'elle fonctionnait, alors merci pour ça!
Solomon Rutzky
1
C'est la chose la plus cool que j'ai vue cette semaine.
Brent Ozar
Cela jette définitivement une erreur sur les répliques, mais dans ce cas, c'est très bien.
Harry
@Harry Merci encore d'avoir fourni ces commentaires. Je l'ai ajouté à ma réponse, accompagné d'une explication au bas de la situation que j'ai rencontrée.
Solomon Rutzky
0

J'ai toujours utilisé une table temporaire pour renvoyer des résultats afin d'obtenir des réponses cohérentes de tous les serveurs d'un groupe. Les requêtes multi-serveurs sont l'une de mes choses préférées sur SSMS.

Tony
la source