SSMS- und registrierte Serverergebnisse

8

Hintergrund :

Wir versuchen, ein AG-Testgeschirr für eines unserer Support-Teams zu erstellen. Da sie nicht wissen, welche Server zu einem bestimmten Zeitpunkt die primären Server sind, wurden sie angewiesen, die TSQL für eine registrierte Servergruppe auszuführen. Die registrierte Servergruppe besteht aus allen Servern in der AG. Ziel ist es, TSQL nur auf dem aktuellen Primärserver auszuführen:

Aktueller Prüfkabelbaum :

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

Problem :

Wenn der erste Server, der auf die Abfrage mit mehreren Servern antwortet, keine Ergebnisse zurückgibt, geht SSMS davon aus, dass die richtige Ergebnismenge keine Ergebnismenge ist, auch wenn andere Server später eine Ergebnismenge zurückgeben. In diesem Szenario werden also keine Ergebnisse zurückgegeben. Dies ist nicht korrekt und entspricht nicht der erwarteten Funktionalität.

Kann sich jemand eine Möglichkeit vorstellen, mit SSMS (dies ist das bekannteste Tool für das CS-Team) die Ausführung nur auf dem aktuellen Primärserver zu erzwingen?

Harry
quelle
Haben Sie darüber nachgedacht, sie mit dem AG-Listener zu verbinden und die Abfrage auf diese Weise auszuführen? Es wird sicherstellen, dass immer die primäre getroffen wird.
Nic
Das geht leider nicht. Wir haben eine Menge Mieter mit gleichnamigen Zuhörern. Funktioniert in diesem Fall einfach nicht.
Harry

Antworten:

10

Ich bin bereits auf dieses ** gestoßen, und wenn ich mich richtig erinnere, müssen Sie eine leere Ergebnismenge erzwingen, wenn sonst keine Zeilen zurückgegeben würden, um sicherzustellen, dass bei Abfragen mit mehreren Servern immer Ergebnisse erzielt werden. Das heißt, Sie brauchen einen ELSEZweig dazu IFund innerhalb des ELSEwürden Sie so etwas wie das Folgende tun:

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

Dies erzeugt eine leere Ergebnismenge mit den richtigen Namen und Datentypen.

ODER, und ich habe dies in der Vergangenheit nicht versucht (ich habe nur daran gedacht, als ich dies tippte), aber Sie können möglicherweise davonkommen, indem Sie einfach in diesem ELSEZweig pausieren, sodass der primäre / beabsichtigte Server immer seinen zurückgeben kann Ergebnismenge zuerst (was hier das eigentliche Problem ist: Der erste Server, der antwortet, definiert die Struktur, an die sich alle anderen Antworten halten müssen). Daher könnte das Folgende als das einzige in der Arbeit funktionieren ELSE:

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

Ich kann mich jedoch nicht erinnern, ob bei der Rückgabe anderer Ergebnisse durch andere Server eine Fehlermeldung auf der Registerkarte "Nachrichten" angezeigt wurde. In diesem Fall ist die leere Ergebnismenge definitiv der richtige Weg. Wenn dies jedoch funktioniert, funktioniert dies möglicherweise besser in einer allgemeinen Vorlage (wie es in Ihrem Fall der Fall zu sein scheint), da die erzwungene, leere Ergebnismenge nicht jedes Mal angepasst werden muss, wenn sie verwendet wird.

AKTUALISIEREN:

Das OP bestätigte Folgendes:

  • das WAITFOR DELAYhat ja funktioniert, und
  • Die Replikate meldeten zwar die Fehlermeldung, stellten jedoch kein Problem für die Verwendung des OP dar

** Die Situation, in die ich geriet, war ähnlich, hatte jedoch nichts mit Verfügbarkeitsgruppen zu tun oder mit dem Wunsch, Ergebnisse von nur einem Server zu erhalten. Unsere Situation war, dass wir 18 Server mit demselben Schema und unterschiedlichen Daten hatten und verschiedene Wartungsaufgaben ausführen mussten, Aggregationen über alle 18 Knoten. Es gab einige gespeicherte Prozeduren, die aus irgendeinem Grund gelegentlich keine Ergebnismenge zurückgaben, und aus welchem ​​Grund auch immer, sie konnten nicht innerhalb der gespeicherten Prozedur behoben werden. Abhängig davon, welcher Knoten zuerst zurückgegeben wurde, war die meiste Zeit alles in Ordnung, aber hin und wieder gab der Knoten, der manchmal keine Ergebnismenge zurückgab, zuerst zurück. Also musste ich so etwas wie die Ergebnisse in eine temporäre Tabelle kopieren und wenn @@ROWCOUNTdas INSERT...EXEC0 war, würde ich die erzwungene, leere Ergebnismenge auswählen.

Solomon Rutzky
quelle
2
Daran hätte ich nie gedacht !! Das Warten auf Verzögerung funktioniert wie ein Champion! Spart definitiv das Erstellen der leeren Ergebnismenge. Du machst Mann @srutzky Danke
Harry
@ Harry Du bist willkommen und danke :-). Ich habe gerade meine Antwort aktualisiert, um etwas klarer über den Nutzen des WAITFOR DELAYAnsatzes zu sein und um zu bestätigen, dass er funktioniert hat. Vielen Dank dafür!
Solomon Rutzky
1
Das ist das Coolste, was ich diese Woche gesehen habe.
Brent Ozar
Es wirft definitiv einen Fehler auf die Replikate, aber in diesem Fall ist dies völlig in Ordnung.
Harry
@ Harry Nochmals vielen Dank für dieses Feedback. Ich habe es meiner Antwort hinzugefügt, zusammen mit einer Erklärung am Ende der Situation, auf die ich gestoßen bin.
Solomon Rutzky
0

Ich habe immer eine temporäre Tabelle verwendet, um Ergebnisse zurückzugeben und konsistente Antworten von allen Servern in einer Gruppe zu erhalten. Abfragen mit mehreren Servern sind eine meiner Lieblingsbeschäftigungen bei SSMS.

Tony
quelle