8. Effectuer une bascule d'urgence avec Slony-I

8.1. Avant-propos

Slony-I™ est un système de réplication asynchrone. À cause de cela, il est presque certain qu'au moment où le nœud origine d'un ensemble de réplication tombe en panne, la dernière transaction « validée » sur l'origine ne soit pas encore propagée aux abonnés. Les systèmes qui tombent en panne sont souvent soumis à une forte charge ; c'est un des corollaires de la loi de Murphy. Ainsi le but principal est d'éviter que le serveur principal tombe en panne. La meilleure façon d'éviter cela est d'effectuer une maintenance fréquente.

Ouvrir le capot d'un serveur à chaud n'est pas ce qu'on peut appeler une façon « professionelle » d'assurer la maintenance d'un système. En général, les utilisateurs qui ont besoin de réplication pour leur sauvegarde ou leur plan de reprise sur panne, ont également des critères très stricts en matière de « temps d'arrêt du système ». Pour répondre à ces critères, Slony-I™ ne se contente pas de fournir des méthodes de reprise sur panne, il intègre également la notion de transfert d'origine.

On suppose dans cette partie que le lecteur est familier avec l'utilitaire slonik(1) et qu'il sait comment mettre en place un système de réplication Slony-I™ composé de deux nœuds.

8.2. Bascule contrôlée

Imaginons un nœud « origine », appelé nœud1, avec un « abonné » appelé nœud2 (l'esclave). Une application web, placée sur un troisième serveur, accède à la base de données sur nœud1. Les deux bases sont actives et fonctionnelles, la réplication est est à peu près synchronisée. On contrôle la bascule avec la commande SLONIK MOVE SET(7).

  • Au moment où nous écrivons ces lignes, basculer vers un autre serveur nécessite que l'application se reconnecte à la nouvelle base de donnée. Donc, pour éviter toute complication, nous éteignons le serveur web. Les utilisateurs qui ont installé pgpool pour gérer les connexions peuvent simplement éteindre le pool.

    Les actions à mener dépendent beaucoup de la configuration des applications qui utilisent la base de données. En général, les applications qui étaient connectées à l'ancienne base doivent détruire leurs connexions et en établir de nouvelles vers la base qui vient d'être promue dans le rôle du « maître ». Il y a différentes façons de configurer cela, et donc différentes façon d'effectuer la bascule :

    • L'application stocke le nom de la base de donnée dans un fichier.

      Dans ce cas, la reconfiguration nécessite de changer la valeur dans ce fichier, d'arrêter puis de relancer l'application pour qu'elle pointe vers le nouvel emplacement des données.

    • Une utilisation pertinente de DNS consiste à créer des champs DNS CNAME qui permettent à l'application d'utiliser un nom pour référencer le nœud qui joue le rôle du nœud « maître ».

      Dans ce cas, la reconfiguration nécessite de changer le CNAME pour pointer vers le nouveau serveur. De plus, il faut probablement relancer l'application pour rafraîchir les connexions à la base.

    • Si vous utilisez pgpool ou un « gestionnaire de connexions » similaire, alors la reconfiguration implique de modifier le paramètrage de cet outil, à part cela la procédure est similaire à l'exemple DNS/CNAME ci-dessus.

    La nécessité de redémarrer l'application qui se connecte à la base dépend de la manière dont elle a été conçue et des mécanismes de gestion d'erreurs de connexion qui ont été implémentés ; si à la suite d'une erreur elle tente d'ouvrir à nouveau une connexion, alors il n'est pas nécessaire de la relancer.

  • Un petit script slonik(1) exécute les commandes suivantes :

    lock set (id = 1, origin = 1);
    wait for event (origin = 1, confirmed = 2);
    move set (id = 1, old origin = 1, new origin = 2);
    wait for event (origin = 1, confirmed = 2);
    

    Après ces commandes, l'origine (rôle du maître) de l'ensemble de réplication 1 est transféré sur le nœud 2. En fait, elle n'est pas simplement transférée ; le nœud1 devient un abonné parfaitement synchronisé et actif. Autrement dit, les deux nœuds ont échangé leurs rôles respectifs.

  • Après la reconfiguration de l'application web (ou de pgpool) pour qu'elle se connecte à la base du nœud 2, le serveur web est redémarré et reprend son activité normale.

    Lorsqu'on utilise un script shell, pour stopper l'application, lancer le script slonik, déplacer les fichiers de configuration et relancer l'ensemble, toute la procédure prend en général moins de 10 secondes.

Vous pouvez désormais éteindre le serveur qui héberge le nœud 1 et effectuer les opérations de maintenance requise. Lorsque le démon slon(1) du nœud 1 est redémarré, il reprend la réplication, et rattrape son retard. Une fois synchronisé, on peut exécuter la procédure à nouveau pour restaurer la configuration originale.

Ceci est la meilleure méthode pour ce genre d'opération de maintenance ; elle s'effectue rapidement, sous le contrôle d'un administrateur, et elle n'implique aucune perte de données.

Après avoir réalisé les modifications dans la configuration, vous devriez, comme Section 1, « Bonnes Pratiques avec Slony-I », exécuter les scripts Section 5.1, « test_slony_state » dans l'ordre pour valider que l'état du cluster reste bon.

8.3. Bascule d'urgence

Lorsque de graves problèmes apparaissent sur le serveur « origine », il est parfois nécessaire d'effectuer une bascule (SLONIK FAILOVER(7)) vers le serveur de sauvegarde. Ce cas de figure n'a rien de souhaitable car les transactions « validées » sur le serveur mais pas sur les abonnés, seront perdues. Certaines de ces transactions auront peut-être été annoncées à l'utilisateur final comme « validées ». En conséquence, les bascules d'urgence doivent être considérées comme un dernier recours. Si le serveur origine qui subit « l'avarie » peut être maintenu assez longtemps, il est nettement préférable d'effectuer une bascule contrôlée.

Slony-I™ ne fournit pas de moyen pour détecter les pannes du système. Abandonner des transactions « validées » est une décision commerciale qui ne peut pas être prise par un système de gestion de base de données. Si vous voulez placer les commandes ci-dessous dans un script exécuté automatiquement par un système de surveillance, ce sont vos données, et votre politique de bascule d'urgence.

  • La commande slonik(1)

    failover (id = 1, backup node = 2);
    

    ordonne au nœud 2 de se considérer comme le propriétaire (l'origine) de tous les ensembles que le nœud 1 possédait. S'il existe des nœuds supplémentaires dans le cluster Slony-I™, tous les nœuds abonnés au nœud 1 sont avertis du changement. Slonik va aussi envoyer une requête à chaque abonné pour déterminer le nœud de plus haut niveau de synchronisation (c'est-à-dire la dernière transaction « validée ») pour chaque ensemble de réplication. La configuration sera changée de façon à ce que le nœud 2 applique d'abord ces transactions finales, avant d'autoriser l'accès en écriture sur les tables.

    De plus, tous les nœuds qui étaient abonnés directement au nœud 1 considèreront désormais le nœud 2 comme leur fournisseur de données pour cet ensemble de replication. Cela signifie qu'une fois que la commande de bascule d'urgence est complétée, plus aucun nœud du cluster ne reçoit d'information de la part du nœud 1.

    [Note]

    Note

    Notez que, pour que le nœud 2 soit considéré comme un candidat pour la bascule, il doit avoir été configuré avec l'option forwarding = yes de SLONIK SUBSCRIBE SET(7), ce qui a pour effet que les données du log de réplication sont conservées dans sl_log_1/sl_log_2 du nœud 2. Si ces données ne sont pas conservées, alors la bascule vers ce nœud n'est pas possible.

  • Reconfigurer et relancer l'application (ou pgpool) pour qu'elle se reconnecte au nœud 2.

  • Purger le nœud abandonné.

    Vous découvrirez, après la bascule, qu'il existe encore beaucoup de références au nœud 1 dans la table sl_node, ainsi que ses tables associées telle que sl_confirm ; puisque des données sont toujours présentes dans sl_log_1/sl_log_2, Slony-I™ ne peut pas purger immédiatement le nœud.

    Une fois que la bascule est complète et que le nœud 2 accepte les opérations d'écriture sur les tables répliquées, il faut supprimer toutes les informations de configuration rémanentes avec la commande SLONIK DROP NODE(7) :

    drop node (id = 1, event node = 2);
    

    Supposons que la panne résulte d'un problème matériel catastrophique sur le nœud 1, il est possible qu'il ne « reste » plus rien sur le nœud 1. Si la panne n'est pas « totale », ce qui est souvent le cas lors d'une coupure réseau, vous découvrirez que le nœud 1 « imagine » toujours que rien n'a changé et qu'il est dans le même état qu'avant la panne. Reportez-vous à la section Section 8.6, « Après la bascule d'urgence, reconfiguration de l'ancienne origine » pour plus de détails sur ce que cela implique.

  • Après avoir réalisé les modifications dans la configuration, vous devriez, comme Section 1, « Bonnes Pratiques avec Slony-I », exécuter les scripts Section 5.1, « test_slony_state » dans l'ordre pour valider que l'état du cluster reste bon.

8.4. Bascule avec un ensemble de nœuds complexe

La bascule est assez « simple » s'il n'y a que deux nœuds ; si un cluster Slony-I™ comprends de nombreux nœuds, exécuter une bascule propre demande une planification et une exécution très attentives aux détails.

Considérez le diagramme suivant décrivant un ensemble de six nœuds sur deux sites. Multisites symétriques

Supposons que les nœuds 1, 2 et 3 résident à un point central et que nous ayons besoin d'effectuer une bascule à cause d'un problème sur ce site complet. Les causes peuvent aller d'une perte persistente de communications à la destruction physique de ce site. La cause n'a pas d'importance en soi car ce qui nous intéresse est de savoir comment réaluser une bascule propre de Slony-I™ vers le nouveau site.

Nous supposerons maintenant que le nœud 5 doit devenir la nouvelle origine après bascule.

La séquence de reconfiguration de Slony-I™ requiert d'exécuter les étapes suivantes pour une bascule propre de la configuration des nœuds :

  • Réabonner chaque nœud (en utilisant SLONIK SUBSCRIBE SET(7) nécessaire à la reformation d'un cluster qui n'est pas encore abonné au futur fournisseur de données.

    Dans notre cluster d'exemple, cela signifie que nous voulons réabonner les nœuds 4 et 6 , qui doivent tous les deux pointer vers 5.

    include </tmp/failover-preamble.slonik>;
    subscribe set (id = 1, provider = 5, receiver = 4);
    subscribe set (id = 1, provider = 5, receiver = 4);
    
  • Supprimer tous les nœuds inutiles, en commençant par les derniers esclaves.

    Comme les nœuds 1, 2 et 3 sont inaccessibles, nous devons indiquer EVENT NODE pour que chaque événement atteigne les portions toujours vivantes du cluster.

    include </tmp/failover-preamble.slonik>;
    drop node (id=2, event node = 4);
    drop node (id=3, event node = 4);
    
  • Maintenant exécuter la bascule avec FAILOVER.

    include </tmp/failover-preamble.slonik>;
    failover (id = 1, backup node = 5);
    
  • Enfin, supprimez l'ancienne origine du cluster.

    include </tmp/failover-preamble.slonik>;
    drop node (id=1, event node = 4);
    

8.5. Automatisation de la commande FAIL OVER

Si vous choisissez d'automatiser la commande FAIL OVER , il est important de le faire avec soin. Vous devez être sur que le nœud en panne est réellement en panne, et vous devez être capable de vous assurer que le nœud en panne ne redémarre pas, ce qui entraînerait un conflit entre deux nœuds capables de jouer le rôle du « maître ».

[Note]

Note

Le fait de « tirer une balle dans la tête du serveur en panne » ne pose pas directement de problème à la réplication ou à Slony-I™ ; Slony-I™ supporte cela de manière assez tranquillement car, une fois qu'un nœud est marqué comme étant en panne, les autres nœuds « l'oublient » et l'ignorent. Le problème se situe plutôt au niveau de votre application. Supposons que le nœud en panne soit capable de répondre aux requêtes de votre application, cela va certainement poser un problème qui n'a rien à voir avec Slony-I™. Le problème est que deux bases de données sont en mesure de répondre en tant que « maître ».

Lorsqu'une bascule d'urgence est effectuée, il faut un mécanisme pour dégager de force le nœud en panne hors du réseau afin d'éviter toute confusion au niveau des applications. Cela peut être fait via une interface SNMP qui effectue une partie des opérations suivantes :

  • Éteindre l'alimentation du serveur en panne.

    Si l'on ne fait pas attention, le serveur peut réapparaître dans le système de réplication si un administrateur le rallume.

  • Modifier les règles du pare-feu ou d'autres configurations pour exclure du réseau l'adresse IP du serveur en panne.

    Si le serveur a de multiples interfaces, et donc de multiple adresses IP, cette approche permet de supprimer/désactiver les adresses utilisées par l'application, tout en conservant les adresses « administratives » afin que le serveur reste accessible par les administrateurs systèmes.

8.6. Après la bascule d'urgence, reconfiguration de l'ancienne origine

Ce qui arrive au nœud en panne dépend beaucoup de la nature de la catastrophe qui a conduit à la bascule d'urgence vers un autre nœud. Si le nœud a été abandonné à cause de la destruction physique des disques de stockage, il n'y a plus grand-chose à faire. D'un autre coté, si un nœud a été abandonné à cause d'une coupure réseau, qui n'a pas perturbé le fonctionnement normal du nœud « fournisseur ». Toutefois, une fois que les communications sont restaurées, le fait est que la commande FAIL OVER rend obligatoire l'abandon du nœud qui était en panne.

Après ce genre de bascule d'urgence, les données stockées sur le nœud 1 seront rapidement et de plus en plus désynchronisées par rapport aux autres nœuds. Elles doivent être considérées comme corrompues. Ainsi le seul moyen pour que le nœud 1 retourne dans le cluster de réplication et qu'il redevienne le nœud origine est de le reconstruire à partir de zéro comme un abonné, de le laisser rattraper son retard, puis d'effectuer la procédure de bascule contrôlée.

Une bonne raison de ne pas faire cela automatiquement est que d'importantes mises à jour (d'un point de vue commercial) ont pu être « validées » sur le système en panne. Vous souhaiterez probablement analyser les dernières transactions que le nœud a réalisé avant de tomber en panne, afin de voir si certaines doivent être ré-appliquer sur le cluster « actif ». Par exemple, si quelqu'un réalisait des opérations bancaires impactant des comptes clients au moment de la panne, il est souhaitable de ne pas perdre cette information.

[Avertissement]

Avertissement

On a observé certains résultats étranges lorsqu'un nœud « tombe en panne » à cause d'une coupure réseau persistante, par opposition aux pannes du système de stockage. Dans de tels scénarios, le nœud « en panne » dispose d'une base de données en parfait état de marche ; le fait est qu'ayant été coupé des autres nœuds, il « crie en silence ».

Lorsque la connexion réseau est réparée, ce nœud peut réapparaître et conformément à sa configuration, il va communiquer avec les autres nœuds du cluster Slony-I™.

En fait, la confusion se trouve uniquement sur ce nœud. Les autres nœud du cluster ne sont pas du tout perturbés ; ils savent que ce nœud est « mort » et qu'ils doivent l'ignorer. Mais il est impossible de savoir cela en regardant le nœud qui était « en panne ».

Ceci nous ramène au fait que Slony-I™ n'est pas un outil de surveillance de réseau. Vous devez avoir des méthodes claires pour signaler aux applications et aux utilisateurs les bases de données à utiliser. En l'absence de telles méthodes, la réplication ne fera qu'empirer le potentiel de confusion, et les bascules d'urgence seront un énorme potentiel de confusion.

Si la base de données est très volumineuse, la construction du nœud 1 peut prendre plusieurs heures ; ceci est une autre raison de considérer les bascules d'urgence comme un « dernier recours » non souhaitable.