Abfragen des schreibgeschützten Replikats im Always On-Cluster

7

Wir haben einen Always On "Cluster", der aus 2 Servern besteht (es wird mehr geben), einer ist also PRIMARY und der andere ist (sind) SECONDARY . Die Idee war, SECONDARY als schreibgeschützte Replik zu widmen, damit es sich um einen Suchserver handelt.

Ich weiß, wie ConnectionString in C # festgelegt wird, damit das SECONDARY-Replikat verwendet wird - fügen Sie einfach hinzu ApplicationIntent=ReadOnly.

Ich verstehe jedoch nicht, wie ich die SECONDARY aus einer gespeicherten Prozedur adressieren soll, wenn ich eine verteilte Abfrage verwende. Gibt es eine Möglichkeit, einige Parameter für die Abfrage festzulegen (z. B. WITH-Anweisungen oder ähnliches), sodass für die Abfrage nur das Replikat und nicht der PRIMARY-Knoten verwendet wird?

Die Sache ist, offensichtlich ist Server1 von Anfang an PRIMARY und Server2 ist SECONDARY, aber wenn Server1 ausfällt, ist Server2 PRIMARY und Server1 ist SECONDARY, nachdem es repariert wurde. Ich kann also nicht einfach den Namen des statischen Servers2 verwenden.

Bisher habe ich es geschafft, den Servernamen des aktuellen Replikats als Variable abzurufen und in EXEC zu verwenden:

-- find first available replica
DECLARE @replicaServer nvarchar(50)

SELECT TOP 1
    @replicaServer = RCS.replica_server_name
FROM
    sys.availability_groups_cluster AS AGC
    INNER JOIN sys.dm_hadr_availability_replica_cluster_states AS RCS
          ON RCS.group_id = AGC.group_id
    INNER JOIN sys.dm_hadr_availability_replica_states AS ARS
          ON ARS.replica_id = RCS.replica_id
    INNER JOIN sys.availability_group_listeners AS AGL
          ON AGL.group_id = ARS.group_id
WHERE ARS.role_desc = 'SECONDARY'
      AND connected_state = 1

-- and query it
DECLARE @cmd nvarchar(MAX) = 'SELECT * FROM [' + @replicaServer + '].[somebase].[someschema].[sometable]'
EXEC (@cmd)

Aber das ist eine Schande, denke ich.

retif
quelle

Antworten:

7

Nach einigen Hilfe und Hinweisen (besonders dank Andriy M ) habe ich verstanden, was ich eigentlich will und wie es geht. Dieser Artikel von Microsoft hat ebenfalls geholfen: https://technet.microsoft.com/en-us/library/hh403414.aspx

Zuerst musste ich einen schreibgeschützten Listener erstellen . Und dann auf dem anderen Server einen solchen Verbindungsserver hinzufügen (ausgeliehen von: https://stackoverflow.com/a/19585304 ):

USE [master]
GEHEN
EXEC master.dbo.sp_addlinkedserver
    @server = N'cluster-readonly ', - nur ein Name
    @srvproduct = N'SQL ', - alles außer' SQL Server '
    @provider = N'SQLNCLI11 ',
    @datasrc = N'ClusterListener ', - Name des schreibgeschützten Listeners
    @provstr = N'ApplicationIntent = ReadOnly ',
    @catalog = N'AnyActualDataBase '- Systemdatenbank wie' master 'ist nicht gut
GEHEN

Wie überprüfe ich, wo ich bin:

SELECT * FROM OPENQUERY ([Cluster-Readonly], 'SELECT @@ SERVERNAME')

Hier ist ein Trick: Wenn ich nichts spezifiziere @catalog, wird die Verbindung aus bestimmten Gründen zum PRIMARY-Knoten hergestellt.

retif
quelle
Vielen Dank! Sie haben mir viel Zeit bei der Suche gespart.
Michael Cherevko
1
@retif Der Grund, warum Sie eine geeignete Datenbank angeben müssen, besteht darin, dass überprüft werden muss, ob die Zieldatenbank an der Verfügbarkeitsgruppe teilnimmt, bevor das Routing beginnt.> Eine Alternative dazu ist die in der Verbindung verwendete Anmeldung, bei der die Datenbank als Standarddatenbank konfiguriert ist. docs.microsoft.com/en-us/sql/database-engine/…
Janis Veinbergs
6

SQL Server Management Studio unterstützt das Hinzufügen von Elementen zur Verbindungszeichenfolge, wenn über das Dialogfeld "Mit Server verbinden" eine Verbindung zu einem Server hergestellt wird:

Geben Sie hier die Bildbeschreibung ein

Durch Hinzufügen ApplicationIntent=ReadOnly;zum Feld "Zusätzliche Verbindungsparameter" (wie im obigen Bild gezeigt) sollte das erreicht werden, was Sie benötigen.

Möglicherweise müssen Sie auch hinzufügen, Database='YourDatabase';wenn Ihre Standarddatenbank nicht Teil einer Verfügbarkeitsgruppe ist. Wenn Sie das Database='YourDatabase';Teil nicht hinzufügen , können Sie dennoch eine Verbindung zum primären Host herstellen, da die Standard-Masterdatenbank nicht Teil Ihrer Verfügbarkeitsgruppe ist.

Max Vernon
quelle
Nun, und was ist, wenn ich mit einem anderen Server verbunden bin, nicht in einem Cluster, und mich in einer gespeicherten Prozedur befinde, um eine Tabelle aus dem SECONDARY-Replikat des Clusters auszuwählen? Wie <code> SELECT * FROM [CLUSTERname]. [Somebase]. [Someschema]. [Sometable] </ code>. Gibt es eine Möglichkeit festzulegen, dass ich den SECONDARY-Server schreibgeschützt abfragen möchte?
Retif