Bedingte Verbindung in SSIS basierend auf dem Status der Verfügbarkeitsgruppe

7

Ich arbeite an einem SSIS-Paket, das Entwicklungsdatenbanken aus Produktionssicherungen aktualisiert. Das Paket ist seit Jahren vorhanden, aber wir stellen Verfügbarkeitsgruppen auf der Entwicklungsinstanz bereit, sodass die Aufgaben geändert werden müssen, um sowohl mit den primären als auch mit den sekundären Replikaten zu arbeiten. Hintergrund: Alle Instanzen sind SQL Server 2014 SP2. Eine Produktionsinstanz (PD1), zwei Entwicklungsinstanzen (DV3 & DV7) und eine Dienstprogramminstanz (DV1), in denen das SSIS-Paket in SSISDB bereitgestellt wird und in der der SQL Agent-Job ausgeführt wird. Nachdem im SSIS-Paket die vollständigen Sicherungen abgerufen und eine Netzwerkfreigabe aus der Produktion bereitgestellt wurden, müssen die nächsten Aufgaben (in einem separaten SSIS-Paket) herausfinden, auf welchem ​​Knoten sich das primäre Replikat befindet. Ich folge den hier aufgeführten Schrittenum diese Arbeit zu erledigen, und alles funktioniert großartig, wenn es fest codiert ist (was natürlich nicht funktioniert, wenn / wenn ein Failover auftritt). Die einzige Möglichkeit, darüber nachzudenken, besteht darin, zur Laufzeit zu bewerten, welche Instanz primär ist, und dann mit den Aufgaben fortzufahren (die übrigens alle "Execute SQL Task" -Objekte sind - für die eine eigene Verbindungsdefinition erforderlich ist ). Ich habe einige Beispiele für die Verwendung von Ausdrücken in ConnectionStrings und Variablen gesehen, kann jedoch nicht herausfinden, wie der von der folgenden Abfrage in SQL Server zurückgegebene Wert festgelegt wird, um die richtige Instanz zum Festlegen der Verbindungszeichenfolge im Paket zurückzugeben.

    select cs.replica_server_name
from sys.dm_hadr_availability_replica_states rs
join sys.dm_hadr_availability_replica_cluster_states cs
    on rs.replica_id = cs.replica_id
join sys.dm_hadr_name_id_map n
    on rs.group_id = n.ag_id
where rs.role = 2
and n.ag_name = 'DVAG001'

Im Idealfall gibt es zwei dieser Verbindungsmanager, einen für den primären und einen für den sekundären, die ich dann in den Objekten "SQL-Task ausführen" verwenden kann. Dann würde alles perfekt funktionieren. Es gibt vielleicht auch andere Möglichkeiten, dies zu tun, aber ich bin nicht sehr erfahren in SSIS oder der Entwicklung außerhalb von TSQL.

UPDATE: Der obige Vorgang wird jeden Tag ausgeführt. Deshalb verwende ich ein SSIS-Paket und einen SQL-Agenten. Daher muss der gesamte Prozess automatisiert werden und alle erforderlichen Werte - insbesondere die Bestimmung der Replikationszustände (primär und sekundär) - im Paket enthalten sein, damit kein manueller Eingriff erforderlich ist.

SQL_Hacker
quelle

Antworten:

8

Nehmen wir an, Sie haben eine Verfügbarkeitsgruppe mit nur einem sekundären Replikat (Sie können dieses Beispiel problemlos für weitere Replikate erweitern).

1. Verbindungen

Sie benötigen 3 Verbindungen:

  • AG-Listener (um die Abfrage auszuführen, die zurückgibt, welcher Server den primären und den sekundären Server hält)
  • Primär (mit dem Primärserver zu parametrieren)
  • Sekundär (mit dem Sekundärserver zu parametrieren)

2. Variablen

Erstellen Sie 2 Variablen mit dem Datentyp String

  • ServernamePrimary
  • ServernameSecondary

Geben Sie hier die Bildbeschreibung ein

3. Abfrage

Um eine Abfrageergebnismenge mithilfe von Execute SQL Task einer Variablen zuzuordnen, muss Ihre Abfrage nur eine Zeile zurückgeben. Sie ordnen jede Spalte der gewünschten Variablen zu. Da ich das weiß, habe ich Ihre Abfrage wie folgt geändert:

WITH CTE_AGStatus as (
    select cs.replica_server_name, rs.role
    from sys.dm_hadr_availability_replica_states rs
    join sys.dm_hadr_availability_replica_cluster_states cs
        on rs.replica_id = cs.replica_id
    join sys.dm_hadr_name_id_map n
        on rs.group_id = n.ag_id
    where n.ag_name = 'DVAG001'
)

select  ServernamePrimary = MAX(case when role = 1 then replica_server_name end)
,       ServernameSecondary = MAX(case when role = 2 then replica_server_name end)
from CTE_AGStatus

(Sie können es jederzeit ändern. Denken Sie jedoch daran, nur eine Zeile zurückzugeben.)

4. Zuordnung der Ergebnismenge zu Variablen

Fügen Sie im SQL Task-Editor zum Ausführen die obige Abfrage ein, setzen Sie die OLEDB-Verbindung 'AG Listener' und ändern Sie die Ergebnismenge in 'Einzelne Zeile'. SQL Task Editor ausführen - Registerkarte Allgemein

Gehen Sie dann zur Registerkarte 'Ergebnismenge' und ordnen Sie die Spalten den Variablen zu Ergebnis Map auf Variable setzen

5. Ändern Sie die Verbindungszeichenfolgen

Klicken Sie auf den Verbindungsmanager "Primär" und wechseln Sie zur Registerkarte "Eigenschaften". Klicken Sie dann auf "Ausdrücke", wählen Sie die Eigenschaft "Servername" aus und fügen Sie Ihre Variable zum Ausdruck hinzu.

Geben Sie hier die Bildbeschreibung ein

Wiederholen Sie den Vorgang für den Verbindungsmanager "Sekundär"

6. Überprüfen Sie den Prozess

Zur Validierung können Sie weitere Schritte hinzufügen und mithilfe von Haltepunkten überprüfen, wie Ihre Variablen ausgeführt werden. Die nächsten Schritte liegen bei Ihnen. Jetzt haben Sie eine Verbindung, die auf jeden Server Ihrer AG verweist. Geben Sie hier die Bildbeschreibung ein

Evandro
quelle
Das ist fantastisch! Ich werde das ausprobieren und sehen, ob es das tut, was ich brauche. Vielen Dank!
SQL_Hacker
Bitte schön! Ich bin froh, dass ich hilfreich sein konnte
Evandro
1
Das ist eine gute Antwort. Willkommen auf der Website
Tom V - versuchen Sie topanswers.xyz
0

Als alternative Strategie könnte ich in Betracht ziehen, Dinge zu vereinfachen, ohne dass SSIS-Parameter mithilfe der T-SQL-Ausführung erforderlich sind (keine Parameter erforderlich). SSIS, insbesondere Legacy-Pakete, scheinen immer so fehleranfällig und fehlerhaft zu sein, dass ich sie einfach nicht berühren möchte, wenn sie nicht benötigt werden:

A Ziehen Sie zunächst in Betracht, Ihren "Primary AG Check" auf den Produktionsservern selbst und nicht auf den Entwicklungsservern auszuführen.

B. Importieren Sie dann Ihre SSIS-Pakete in die Produktion, falls sie noch nicht vorhanden sind - um dort ausgeführt zu werden. Man könnte Entwickler-Wiederherstellungen von Prod sowieso eher als Produktionsprozess betrachten.

C. Und schließlich sollten Sie vermeiden, Ihre alten SSIS-Pakete so weit wie möglich zu ändern, indem Sie einen T-SQL Agent-Job ausführen, der die Ausführung des SSIS-Pakets (Datenbankwiederherstellung) von jeder "potenziellen" primären AG mit dem folgenden Code - oder ähnlichem - aufruft. - wie in Listing A gezeigt.

Listing A: Führen Sie das SSIS-Paket (Datenbankwiederherstellung) nur aus, wenn der SQL Server der primäre ist - über einen SQL Agent-Job.

--If current server is the primary AG then run the legacy package

if (select a.role_desc FROM sys.dm_hadr_availability_replica_states AS a JOIN sys.availability_replicas AS b  ON b.replica_id = a.replica_id WHERE b.replica_server_name like @@Servername) like 'Primary' 
begin
            Declare @execution_id bigint  
            EXEC [SSISDB].[catalog].[create_execution] @package_name=N'Package.dtsx', @execution_id=@execution_id OUTPUT, @folder_name=N'AlwaysOn', @project_name=N'MyTestPackage', @use32bitruntime=False, @reference_id=Null  
                exec ssisdb.catalog.start_execution @execution_id 
end

Hinweis:

Wenn ich Sie richtig verstehe, werden die Entwicklungsserver immer gleich benannt. Es sind nur die Namen der Produktionsserver, die sich ändern können. Angesichts dessen glaube ich, dass Sie mit der in Listing A gezeigten Code-Ausführung mit etwas weniger Zeit und Aufwand das erreichen können, was Sie benötigen. Sie können diese Ausführung sogar am Ende Ihrer SQL-Sicherungen huckepack nehmen, um eine schnellere Aktualisierung der Entwicklungsumgebungen zu erhalten.

Stachel
quelle