Procédure de mise en veille (mode quiesced) de Sybase Replication Server

Introduction

Cet article propose un guide pratique pour mettre en veille un moteur Replication Server, la mise en veille s'appelle aussi le mode "quiesced". La mise en veille s'avère parfois nécessaire pour réaliser des opérations d'administration : suppression massive des exceptions, déplacement des partitions etc...

Un script shell est proposé en annexe pour une mise en veille automatique (mode quiesced) d'un moteur Replication Server.

Le contexte du schéma de réplication de l'article est le suivant :

contexte réplication image
La mise en veille doit être utilisée dans des cas très particuliers pour lesquels le système de réplication doit être inactif. Elle est proscrite pour récupérer l'état d'un système de réplication à intervalles réguliers.

La procédure de mise en veille d'un moteur Replication Server est disponible dans le guide pratique Sybase Replication Server : Guide pratique et astuces Sybase Replication Server

Étapes de mise en veille d'un moteur Replication Server

Déconnexions des agents de réplication ou LTM (Log Transfer Manager) avec suspend log transfer

Pour mettre en veille un système de réplication, dans un premier temps tous les agents de réplication ou les LTM (Log Transfer Manager) sources sont déconnectés du moteur Replication Server avec la commande suspend log transfer dans Replication Server :

suspend log transfer from {data_server.database | all}
DEC_D1_REP > suspend log transfer from all
Suspending LogTransfer for DEC_D1_ASE.idee

Lorsque la commande suspend log transfer est exécutée, non seulement les agents de réplication ou LTM sont déconnectés, mais la reconnexion automatique est interdite par Replication Server, reconnexion automatique qui est définie avec le paramètre "retry timeout" en secondes pour un agent de réplication :

DEC_D1_ASE > exec sp_config_rep_agent 'idee','retry timeout'
Parameter Name  Default  Config Value Run Value
--------------  -------  ------------ ---------
retry timeout   60       60           60 

La commande suspend log transfer tolère le redémarrage de Replication Server, cette information est enregistrée dans la base RSSD.

Lorsque la suspension est réalisée :

La commande admin who_is_down doit montrer l(es) Agent(s) de réplication dans un statut suspendu
DEC_D1_REP > admin who_is_down
DEC_D1_REP > go

 Spid Name       State         Info
 ---- ---------- ------------- ----------------
      REP AGENT  Suspended     DEC_D1_ASE.idee 
L'état suspendu est notifié dans le fichier de log du moteur de réplication
%> tail -f DEC_D1_REP.log
I. 2009/12/14 18:10:01. Replication Agent
for DEC_D1_ASE.idee has been Suspended.
Disconnecting Replication Agent.
Le message 14040 apparaît dans le fichier de log du serveur ASE hébergeant l'agent de réplication
%> tail -f DEC_D1_ASE.log
server  RepAgent(4): Received the following error
message from the Replication Server: 
Msg 14040. Replication Agent for DEC_D1_ASE.idee
has been Suspended. 
Disconnecting Replication Agent..

Mise en veille des threads RSI (Replication Server Interface) avec admin quiesce_force_rsi

La commande Replication Server admin quiesce_force_rsi est ensuite exécutée. Elle vérifie si Replication Server est en mode veille et dans le cas contraire force les threads RSI (Replication Server Interface) dans Replication Server à envoyer les messages en sortie en demandant un acquittement.

admin quiesce_force_rsi
DEC_D1_REP > admin quiesce_force_rsi

Cette commande ne suspend pas de process Replication Server, elle force l'envoi des messages RSI et DSI avec acquittement.

Vérification de la mise en veille avec la commande admin quiesce_check

La commande admin quiesce_check vérifie la mise en veille du système de réplication.

admin quiesce_check
DEC_D1_REP > admin quiesce_check
Replication Server DEC_D1_REP is Quiesced

La réponse de mise en veille effective doit être : Replication Server <RS_Name> is quiesced. Dans le cas contraire, un message indique la raison :

Can't Quiesce. Queue 103:1 has not been read out. Write=32.1 Read=30.2

Il s'avère parfois nécessaire d'exécuter plusieurs fois la commande admin quiesce_check, le système de réplication pouvant mettre un certain temps avant de rentrer en mode veille.

La commande admin quiesce_check vérifie les conditions ci-dessous :

  • Des files de matérialisation n'existent pas (souscriptions par matérialisation).
  • Toutes les files ont été lues.
  • Les files d'entrées (inbound queues) ne contiennent pas des transactions validées non délivrées.
  • Tous les messages dans les files des RSI (Replication Server Interface) ont été envoyés et un acquittement reçu.
  • Tous les messages dans les files des DSI distributeurs (Data Server Interface) ont été appliqués et un acquittement reçu.

Suppression du mode veille (quiesced) d'un moteur Replication Server

Le système de réplication est remis en route avec la commande resume log transfer de Replication Server, commande qui autorise les agents de réplication ou LTM (Log Transfer Manager) à se reconnecter au moteur Replication Server.

resume log transfer from {data_server.database | all }
DEC_D1_REP > resume log transfer from all
Resuming LogTransfer for DEC_D1_ASE.idee

La commande resume log transfer ne redémarre pas les agents de réplication si ceux-ci ont été stoppés avec la commande sp_stop_rep_agent par exemple.

Lorsque la suppression du mode veille est réalisée

La commande admin who_is_down doit montrer aucun état suspendu
DEC_D1_REP > admin who_is_down
DEC_D1_REP > go
 Spid Name       State         Info
 ---- ---------- ------------- ----------------
La reconnexion de l'agent de réplication est notifiée dan le fichier de log de Replication Server
%> tail -f DEC_D1_REP.log
I. 2009/12/14 19:37:00. Replication Agent for
DEC_D1_ASE.idee connected in passthru mode.
        

Script rsquiesce.ksh de mise en veille d'un moteur Replication Server

Le script rsquiesce.ksh proposé ci-dessous active ou désactive le mode veille (mode quiesced) d'un moteur Replication Server.

%> rsquiesce.ksh <RepServer> "quiesce|unquiesce"

Les codes retour suivants sont retournés pour une éventuelle utilisation au sein d'un autre script :

0 Application du mode quiesce réussie.
%> rsquiesce.ksh DEC_D1_REP quiesce
Suspend log transfer for Replication Server DEC_D1_REP...
Suspending LogTransfer for DEC_D1_ASE.idee
Running admin quiesce_force_rsi for Replication Server DEC_D1_REP...
DEC_D1_REP is quiesced, return code 0

%>echo $?
0
1 Suppression du mode quiesce réussie.
%> rsquiesce.ksh DEC_D1_REP unquiesce
Resume log transfer for Replication Server DEC_D1_REP...
Resuming LogTransfer for DEC_D1_ASE.idee
Running admin who_is_down...
Resume log transfer successfull, return code 1

%> echo $?
1
2 Application du mode quiesce en échec après 3 vérifications (10 secondes entre chaque vérification).
%> rsquiesce.ksh DEC_D1_REP quiesce
Suspend log transfer for Replication Server DEC_D1_REP...
Suspending LogTransfer for DEC_D1_ASE.idee
Running admin quiesce_force_rsi for Replication Server DEC_D1_REP...
Checking DEC_D1_REP is quiesced, try # 1
Sleep 10 seconds before next attempt
Checking DEC_D1_REP is quiesced, try # 2
Sleep 10 seconds before next attempt
Checking DEC_D1_REP is quiesced, try # 3
Sleep 10 seconds before next attempt
Resuming log transfer for Replication Server DEC_D1_REP...
Resuming LogTransfer for DEC_D1_ASE.idee
Unable to quiesce DEC_D1_REP after 3 attempts, return code 2

%>echo $?
2
3 Erreur de syntaxe dans l'appel du programme (nombre de paramètres, nom du serveur de réplication, mode quiesce ou unquiesce).
%> rsquiesce.ksh DEC_D1_REP unquiesce  
Usage : rsquiesce.ksh REPSERVER, quiesce|unquiesce

%> echo $?
3
4 Suppression du mode quiesce en échec, des agents de réplication sont toujours à l'état suspendu.
%> rsquiesce.ksh DEC_D1_REP unquiesce
Resume log transfer for Replication Server DEC_D1_REP...
Resuming LogTransfer for DEC_D1_ASE.idee
Running admin who_is_down...
Replication agent(s) still in suspended state, investigate as soon as possible, return code 4

%> echo $?
4

Ce script s'appuie sur une normalisation : l'environnement est pris à partir du fichier $DBA/etc/<RepServer>.rep, $DBA étant le répertoire /Software/sybase/dba.

Le mot de passe sa du serveur de Réplication est localisé dans le répertoire $CFG/script/mdp/mdp_sa, $CFG provenant de la normalisation (/Software/sybase/dba/<RepServer>/cfg/<RepServer>.cfg)

#!/bin/ksh
#

PROG=$0

Usage() {
   echo "Usage : ${PROG} REPSERVER, quiesce|unquiesce"
   exit 3
}

RsSuspend() {
        isql -U${SYB_USER} -S${REPSERVER} <<-EOF |grep -v '^Password:'
        ${SYB_PASSWD}
        suspend log transfer from all
        go
        EOF
}

RsQuiesceForceRsi() {
        isql -U${SYB_USER} -S${REPSERVER} -o ${LOG_FILE} <<-EOF |grep -v '^Password
:'
        ${SYB_PASSWD}
        admin quiesce_force_rsi
        go
        EOF
}
RsQuiesceCheck() {
        isql -U${SYB_USER} -S${REPSERVER} -o ${LOG_FILE} <<-EOF |grep -v '^Password
:'
        ${SYB_PASSWD}
        admin quiesce_check
        go
        EOF
}
RsAdminWhoIsDown() {

        isql -U${SYB_USER} -S${REPSERVER} -o ${LOG_FILE} <<-EOF |grep -v '^Password
:'
        ${SYB_PASSWD}
        admin who_is_down
        go
        EOF
}

RsResume() {
        isql -U${SYB_USER} -S${REPSERVER} <<-EOF |grep -v '^Password:'
        ${SYB_PASSWD}
        resume log transfer from all
        go
        EOF
}

if [ $# -lt 2 ]
then
  Usage
fi

REPSERVER=$1
MODE=$2

export REPSERVER
export MODE

LOG_FILE=/tmp/tmp_quiesce.${REPSERVER}.$$.log

# Verification du mode
if [[ "${MODE}" != "quiesce" && "${MODE}" != "unquiesce" ]]
then
   Usage
fi
# Verification de l'existence du fichier d'initialisation pour REPSERVER

if [ ! -f $DBA/etc/${REPSERVER}.rep ]
then
   echo "The file $DBA/etc/${REPSERVER}.rep does not exist"
   Usage
fi

# Prise de l'environnement
 . ~sybase/.profile
 . $DBA/etc/${REPSERVER}.rep

SYB_USER="sa"
SYB_PASSWD=$(cat $DBA/$REPSERVER/cfg/script/mdp/mdp_sa)

export SYB_USER
export SYB_PASSWD

# Mise en mode quiesce
if [[ "${MODE}" == "quiesce" ]]
then
        echo "Suspend log transfer for Replication Server ${REPSERVER}..."
        RsSuspend
        echo "Running admin quiesce_force_rsi for Replication Server ${REPSERVER}..."
        RsQuiesceForceRsi

        if [[ $(cat ${LOG_FILE} | grep -i "Replication Server ${REPSERVER} is Quiesced" | wc -l ) -gt 0 ]]
        then
                echo "${REPSERVER} is quiesced, return code 0"
                exit 0
        else
                RTY=0
                while [[ ${RTY} -lt 3 ]]
                do
                        let RTY=RTY+1


                        echo "Checking ${REPSERVER} is quiesced, try # ${RTY}"
                        RsQuiesceCheck
                        if [[ $(cat ${LOG_FILE} | grep -i "Replication Server ${REPSERVER} is Quiesced" | wc -l ) -gt 0 ]]
                        then
                                echo "${REPSERVER} is quiesced, return code 0"
                                exit 0

                        fi
                        echo "Sleep 10 seconds before next attempt"
                        sleep 10
                done
                echo "Resuming log transfer for Replication Server ${REPSERVER}..."
                RsResume
                echo "Unable to quiesce ${REPSERVER} after 3 attempts, return code 2"
                exit 2
        fi
fi

# Suppression du mode quiesce
if [[ "${MODE}" == "unquiesce" ]]
then
        echo "Resume log transfer for Replication Server ${REPSERVER}..."
        RsResume
        echo "Running admin who_is_down..."
        RsAdminWhoIsDown
        if [[ $(cat ${LOG_FILE} | grep -i "Suspended" | grep -i "REP AGENT" | wc -l) -gt 0 ]]
        then
                echo "Replication agent(s) still in suspended state, investigate as soon as possible, return code 4"
                exit 4
        fi
        echo "Resume log transfer successfull, return code 1"
        exit 1
fi