Microsoft SQL – Database in AAG – Abilitiamo o disabilitiamo servizi Windows sui nodi

Quella del cluster database di tipo AAG (Always-on Availability Group) è una delle configurazioni più resilienti di SQL e tramite una configurazione a nodo 1+N che se bilanciata bene permette una grossa resilienza ed un importante uptime.

Introduzione

Nell’AAG, uno dei nodi è sempre il primario, i “+N” (che potrebbe essere uno o molteplici) rimangono in standby con una replica puntuale dei DB. Una delle caratteristiche più interessanti della configurazione AAG è il failover automatico, che consiste nel cambio ruolo automatico a fronte di un problema tecnico. In questo scenario potrebbe essere necessario attivare dei servizi ancillari alla macchina, come ad esempio uno schedulatore esterno (es IWS), uno strumento di file transfer o un qualsiasi agent.

Esempio di TSQL per Avviare o Arrestare dinamicamente un servizio in base al nodo in cui sta girando l’istanza

di seguito, un piccolo POC con un esempio di TSQL per avviare o disabilitare un servizio a fronte di un cambio ruolo di SQL:

DECLARE @primreplica VARCHAR(100);
DECLARE @ServiceName VARCHAR(128) = 'NOMESERVIZIO';
DECLARE @Status VARCHAR(MAX);

    DECLARE @ServicesStatus TABLE
    (
        Status VARCHAR(50)
    );

SELECT @primreplica = s.primary_replica
FROM sys.dm_hadr_availability_group_states s
    JOIN sys.availability_groups ag
        ON ag.group_id = s.group_id;

-- se dove sto girando è primario
IF UPPER(@primreplica) = UPPER(@@SERVERNAME)
BEGIN

    INSERT @ServicesStatus
    EXEC xp_servicecontrol N'QUERYSTATE', @ServiceName;

    SELECT @Status = Status
    FROM @ServicesStatus;
    --select @Status

    IF @Status <> 'Running.'
    BEGIN
        EXEC xp_servicecontrol N'Start', @ServiceName;
    END;

END;

ELSE
BEGIN
    INSERT @ServicesStatus
    EXEC xp_servicecontrol N'QUERYSTATE', @ServiceName;

    SELECT @Status = Status
    FROM @ServicesStatus;
    --select @Status

    IF @Status = 'Running.'
    BEGIN
        EXEC xp_servicecontrol N'Stop', @ServiceName;
    END;

END;

Personalmente, l’ho schedulato in un job SQL sempre attivo su tutti i nodi (lo stesso JOB contiene lo statement per abilitare o disabilitare i JOB SQL).

Andiamo un poco più in drill-down:
Tramite la select di seguito riportata, stabilisco se sto girando sulla replica primaria o sul secondario, andando a confrontare il nome del server su cui sta girando l’istanza (tramite la funzione SQL @@SERVERNAME) ed il nome della replica primaria sulle tabelle di sistema che regolano l’AAG:

SELECT @primreplica = s.primary_replica
FROM sys.dm_hadr_availability_group_states s
    JOIN sys.availability_groups ag
        ON ag.group_id = s.group_id;

-- se dove sto girando è primario
IF UPPER(@primreplica) = UPPER(@@SERVERNAME)

Con un semplice ciclo IF/ELSE tramite una tabella di appoggio e la StoreProcedure EXEC xp_servicecontrol determino se il servizio sta girando o meno ed in base alla risposta ed al server, avvio o disabilito il servizio:

INSERT @ServicesStatus
    EXEC xp_servicecontrol N'QUERYSTATE', @ServiceName;

    SELECT @Status = Status
    FROM @ServicesStatus;
    --select @Status

    IF @Status <> 'Running.'
    BEGIN
        EXEC xp_servicecontrol N'Start', @ServiceName;
    END;

Sintassi di xp_servicecontrol

EXEC xp_servicecontrol ‘Querystat|Start|Stop’,’servicename’

La store in oggetto accetta due parametri, il primo è l’operazione da svolgere:

  • Querystat – Restituisce lo stato di un servizio.
  • Start – Avvia un servizio.
  • Stop  – Arresta un servizio.

Il secondo, il nome del servizio.

Enjoy!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *