14. Ajouter des objets à la réplication

Vous découvrirez peut-être que vous avez oubliez des choses que vous vouliez répliquer.

En général, on peut très aisément y remédier. Cette section propose un « tour d'horizon » des moyens pour répondre à la question « Comment réaliser la tache X avec Slony-I™ ? », pour différente valeur de X.

On ne peut pas utiliser directement les commandes SLONIK SET ADD TABLE(7) ou SLONIK SET ADD SEQUENCE(7) de slonik(1) pour ajouter des tables et des séquences à un ensemble de réplication en cours de fonctionnement ; on doit au contraire créer un nouvel ensemble de réplication. Une fois que ce nouvel ensemble est répliqué à l'identique (c'est-à-dire les fournisseurs et abonnés sont entièrement identiques à ceux de l'ensemble que l'on veut compléter), les deux ensembles peuvent être fusionnés avec la commande SLONIK MERGE SET(7).

Jusqu'à la version 1.0.2 (incluse), il existait des risques potentiels si SLONIK MERGE SET(7) était lancée alors que d'autres événements de type abonnement étaient en attente ; des confusions pouvaient se produire sur les nœuds ayant ces événements en attente. Ce problème fut résolu avec la version 1.0.5. Jusqu'à la version 1.2.1, il existait toujours un problème avec SLONIK MERGE SET(7) si la commande était lancée avant que tous les abonnements soient complets, des « perturbations » pouvaient apparaître sur les nœuds où l'activité d'abonnement n'était pas terminée.

Notez que si vous ajoutez des nœuds, vous devez également ajouter les déclarations SLONIK STORE PATH(7) pour indiquer comment les nœuds communiquent entre eux, et les déclarations SLONIK STORE LISTEN(7) pour configurer le « réseau de communications » correspondant. Voir le chapitre Section 9, « Voix d'écoute » pour plus de détails.

Il est conseillé d'être très prudent lorsqu'on ajoute des nœuds et des voies de communications. Par exemple, soumettre de multiples demandes d'abonnements à un ensemble donné dans un script slonik(1) finit mal, en général. S'il est vraiment nécessaire d'automatiser cette étape, il est préférable de soumettre des requêtes SLONIK WAIT FOR EVENT(7) entre chaque requête d'abonnement pour que le script slonik(1) attende qu'un abonnement soit complet avant de lancer le suivant.

Mais en général, il est plus facile de gérer les reconfigurations complexes en s'assurant qu'un changement a été parfaitement réussi avant de passer au suivant. Il est beaucoup plus simple de corriger un problème unique que de réparer les dégâts provoqués par l'interaction erronée de cinq commandes successives.

Voici un ensemble de « recettes » pour réaliser différentes modifications sur la configuration de la réplication.

14.1. Ajouter une table dans le cluster de réplication

Slony-I™ ne vous permet pas d'ajouter une table dans un ensemble qui est déjà en cours de réplication. En principe, c'est certainement possible ; mais cela implique que l'événement SET_ADD_TABLE produise le code adéquat à partir de l'événement SUBSCRIBE_SET invoqué pour analyser la table. Cela compliquerait de manière significative et regrettable la logique de tous ces composants, donc ce n'est pas permis.

En contrepartie, vous devez procéder de la manière suivante :

  • Ajouter la nouvelle table sur chaque nœud.

    En principe, le script SLONIK EXECUTE SCRIPT(7) peut être utilisé pour cela, mais en réalité cela provoque des problèmes d'inter-blocages et cela nécessite la modification de toutes les tables dans l'ensemble de réplication existant, sur tous les nœuds, ce qui fait que SLONIK EXECUTE SCRIPT(7) est une approche peu attrayante sur un serveur chargé. Ceci brise la règle de Slony-I™ qui dit qu'« il n'est pas nécessaire d'interrompre l'activité normale pour ajouter la réplication ».

    À contrario, vous pouvez ajouter la table via psql sur chaque nœud.

  • Créer un nouvel ensemble de réplication avec SLONIK CREATE SET(7).

  • Ajouter la table dans le nouvel ensemble avec SLONIK SET ADD TABLE(7)

  • Demander l'abonnement de ce nouvel ensemble avec SLONIK SUBSCRIBE SET(7). S'il existe plusieurs nœuds, vous devez utiliser SLONIK SUBSCRIBE SET(7) une fois pour chaque nœud que vous voulez abonner.

  • Si vous voulez savoir de manière déterministe si un abonnement est complet, vous devez soumettre pour chaque abonnement un script slonik qui ressemble à cela :

    SUBSCRIBE SET (ID=1, PROVIDER=1, RECEIVER=2);
    WAIT FOR EVENT (ORIGIN=2, CONFIRMED = 1);
    SYNC(ID = 1);
    WAIT FOR EVENT (ORIGIN=1, CONFIRMED=2);
    
  • Une fois que les abonnements sont configurés de manière à ce que les abonnements du nouvel ensemble soient identiques à ceux de l'ancien ensemble, vous pouvez fusionner le nouveau et l'ancien avec la commande SLONIK MERGE SET(7).

14.2. Comment ajouter une colonne dans une table répliquée

Cette réponse est la même que pour la question « Comment renommer des colonnes dans une table répliquée ? », et plus généralement aux autres questions du type « Comment modifier la définition de tables répliquées ? »

Si vous changez la « forme » d'une table répliquée, vous devez le faire au même instant dans le « flux de transaction » sur tous les nœuds qui sont abonnés à l'ensemble qui contient la table.

Ainsi, la méthode consiste à construire un script SQL composé des changements DDL et de le soumettre à tous les nœuds via la commande Slonik SLONIK EXECUTE SCRIPT(7).

Il existe une alternative si vous avec installé les scripts altperl. Vous pouvez utiliser slonik_execute_script pour cela :

slonik_execute_script [options] numero_de_l_ensemble full_path_to_sql_script_file

Tapez la commande slonik_execute_script -h pour plus d'informations ; notez que ce script utilise SLONIK EXECUTE SCRIPT(7).

Il y a de nombreux « points délicats » à noter...

  • Vous ne devez absolument jamais inclure des commandes de contrôle de transaction, notamment BEGIN et COMMIT, à l'intérieur de ces scripts. Slony-I™ encapsule les scripts DDL avec une paire BEGIN/COMMIT ; ajouter des opérateurs de contrôle de transaction supplémentaires implique que des parties des ordres DDL seront « validées » en dehors du contrôle de Slony-I™.

  • Avant la version 1.2, il était nécessaire d'être extrêmement restrictif sur ce qu'on envoyait au script SLONIK EXECUTE SCRIPT(7).

    Il était interdit de placer du texte entre guillemets simples dans le script car cela l'empêchait d'être stocké et transmis correctement. À partir de la version 1.2, les guillemets simples sont correctement prises en compte.

    Si vous soumettez une séries d'ordre DDL, les derniers ne peuvent pas faire référence aux objets créés par les premiers car tous les ordres sont soumis dans une requête unique, dont le plan d'exécution est basé sur l'état de la base de données au début, avant que les modifications ne soient effectuées. À partir de la version 1.2, il y a 12 ordres SQL, chacun est soumis individuellement ainsi la commande ALTER TABLE x ADD COLUMN c1 integer; peut désormais être suivie par ALTER TABLE x ALTER COLUMN c1 SET NOT NULL;.

14.3. Comment supprimer la réplication sur un nœud

Vous devez supprimer les différents composants Slony-I™ connectés à la base.

Considérons, un instant, que nous faisons cela pour un nœud. Si vous avez de multiples nœuds, vous devrez répéter ces étapes autant de fois que nécessaire.

Les composants à retirer :

  • Triggers de logs / Triggers de blocage de mises à jour

  • Le schéma « cluster » contenant les tables Slony-I™ indiquant l'état du nœud et diverses procédures stockées

  • Le processus slon(1) qui gère le nœud

  • Accessoirement, les scripts SQL, les scripts pl/pgsql et les binaires Slony-I™ qui font partie de la compilation de PostgreSQL™. (Bien sûr, cela complique la tache si vous souhaitez redémarrer la réplication ; il est peu probable que vous ayez besoin de supprimer ces fichiers...)

Comment effectuer facilement la suppression

  • Vous pouvez utiliser la commande Slonik SLONIK DROP NODE(7) pour supprimer un nœud du cluster. Ceci provoquera la suppression des triggers et tout ce qui se trouve dans schéma cluster. Le processus slon(1) va mourir automatiquement.

  • Dans le cas d'un nœud en échec (lorsque vous avez utilisé la commande SLONIK FAILOVER(7) pour basculer sur un autre nœud), vous devrez peut-être utiliser SLONIK UNINSTALL NODE(7) pour supprimer les triggers, le schéma et les fonctions.

    Si le nœud est en échec à cause d'une panne matérielle dramatique (par exemple si vos disques ont pris feu), il est possible qu'il n'y ait plus de traces de la base de données sur le nœud ; en général, la base ne survit que lorsque la panne matérielle est un problème de réseau qui n'endommage pas les données mais qui vous oblige à supprimer le nœud à cause de coupures réseau persistantes.

  • Si les opérations ci-dessus se sont particulièrement mal passée, vous pouvez lancer la commande SQL DROP SCHEMA "Nom_du_cluster" CASCADE; qui supprime toutes les fonctions, les tables et les triggers de Slony-I™. En général, c'est une opération moins pratique que SLONIK UNINSTALL NODE(7) car cette commande ne se contente pas de supprimer le schéma et son contenu, elle supprime également toutes les colonnes ajoutées avec la commande SLONIK TABLE ADD KEY(7).

    [Note]

    Note

    Dans Slony-I™ 2.0, SLONIK TABLE ADD KEY(7) n'est plus supporté et, du coup, SLONIK UNINSTALL NODE(7) consiste très simplement en des commandes DROP SCHEMA "Nom_du_cluster" CASCADE;.

14.4. Ajouter un nœud dans le cluster de réplication

Les choses ne sont pas fondamentalement différentes entre l'ajout d'un nœud flambant neuf et la restauration d'un nœud qu'on supprime puis reconstruit. Dans les deux cas, vous ajoutez un nœud dans le cluster de réplication.

Les étapes nécessaires sont...

  • Déterminer le numéro du nœud et les DSN adéquats pour le nœud. Utilisez la commande PostgreSQLcreatedb pour créer la base ; ajoutez les définitions des tables que vous voulez répliquer car Slony-I™ ne propage pas automatiquement cette information.

    Si vous ne disposez pas d'un script SQL parfaitement propre pour ajouter les tables, alors vous pouvez utiliser l'outil slony1_extract_schema.sh situé dans le répertoire tools afin d'obtenir le schéma utilisateur sans les « morceaux » de Slony-I™.

  • Si le nœud était un nœud en échec, vous devez lancer la commande SLONIK DROP NODE(7) de slonik(1) afin de vous débarrasser de ses vestiges dans le cluster et de supprimer le schéma que Slony-I™ a créé.

  • Lancer la commande SLONIK STORE NODE(7) de slonik pour établir le nouveau nœud.

  • À cet instant, vous pouvez lancer le démon slon(1) sur le nouveau nœud. Il ne connaîtra rien des autres nœuds, donc les logs de ce nœud seront particulièrement calmes.

  • Lancer la commande slonik SLONIK STORE PATH(7) pour indiquer comment les processus slon(1) doivent communiquer avec le nouveau nœud. Dans la version 1.1 et suivante, cette commande génère automatiquement des lignes de la table des voies d'écoute. Dans les versions précédentes, vous devez utiliser SLONIK STORE LISTEN(7) pour les générer manuellement.

  • À cet instant, lancer le script Section 5.1, « test_slony_state » est une excellente idée. Ce script parcourt le cluster tout entier et pointe les anomalies qu'il trouve. Il peut notamment identifier une grande variété de problèmes de communication.

  • Lancer commande slonik SLONIK SUBSCRIBE SET(7) pour abonner le nœud à l'ensemble de réplication.

14.5. Comment remanier les abonnements ?

Par exemple, on souhaite que le nœud 3 reçoive les données en provenance du nœud 1, alors qu'actuellement il reçoit les données du nœud 2.

Il ne s'agit pas d'un cas d'utilisation de la commande SLONIK MOVE SET(7) car on ne souhaite pas déplacer l'origine, mais simplement remanier les abonnés.

Pour cela, on peut simplement soumettre des requêtes SLONIK SUBSCRIBE SET(7) pour modifier les abonnements. Ces abonnements ne seront pas redémarrés à partir de zéro, mais simplement reconfigurés.

14.6. Comment utiliser le Log Shipping ?

Cette question est largement débattue dans la section Log Shipping...

14.7. Comment savoir si la réplication fonctionne ?

La preuve ultime est le fait que les données ajoutées sur l'origine soient présentes sur les abonnés. Il suffit « simplement de lancer une requête » pour le savoir.

Cependant, il existe quelques autres méthode pour examiner l'état de la réplication :

  • Regarder les logs des processus slon(1).

    Ils ne vous diront pas grand chose, même à un niveau de débogage élevé sur le nœud origine. Au niveau 2 de débogage, vous devriez voir sur les abonnés les événements SYNCs qui sont en cours de traitement. À partir de la version 1.2, les informations sur le traitement des SYNC incluent le nombre de tables traitées, ainsi que le nombre de lignes insérées, supprimées et mises à jour.

  • Regarder dans la vue sl_status sur le nœud origine.

    Cette vue indique quel est le retard des différents nœuds abonnés. Cette information n'est pertinente que sur un nœud origine.

  • Lancer le script Section 5.1, « test_slony_state » qui se trouve dans le répertoire tools. Ce script parcourt le cluster tout entier et pointe les anomalies qu'il détecte, ainsi que des informations sur le statut de chaque nœud.

14.8. Comment mettre à jour la version de Slony-I ?

La réponse se trouve ici.

14.9. Que se passe-t-il lors d'une bascule d'urgence ?

Une partie de la réponse se trouve dans la section Section 8, « Effectuer une bascule d'urgence avec Slony-I » mais il reste beaucoup de choses à écrire sur le sujet...

14.10. Comment déplacer le maître vers un autre nœud ?

Tout d'abord il faut choisir un nœud qui est connecté à l'ancienne origine (sinon il n'est pas évident de conserver les connexions lors du changement).

Deuxièmement, vous devez lancer un script slonik(1) avec la commande SLONIK LOCK SET(7) pour verrouiller l'ensemble de réplication sur le nœud origine. Notez qu'à cet instant votre application risque de ne plus fonctionner car cette opération pose des triggers sur l'origine qui rejetent toutes les mises à jour.

Maintenant, lancez la requête slonik(1) SLONIK MOVE SET(7). Il est parfaitement raisonnable de soumettre les deux requêtes à l'intérieur d'un même script slonik(1). Désormais, l'origine est basculée vers le nouveau nœud origine. Si le nouveau nœud a quelques événement de retard, il faudra un peu de temps pour que tout se mette en place.

14.11. Comment réaliser une synchronisation complète sur une table ?

Pour Slony-I™, la notion de SYNC est toujours quelque chose d'incrémental ; un SYNC représente un ensemble de mises à jour qui furent « validées » pendant la durée d'un événement SYNC donné sur le nœud origine. Si des mises à jour qui ont altéré l'ensemble du contenu d'une table sont « validées » au cours d'un SYNC unique, alors cela affectera l'ensemble du contenu de la table. Mais du point de vue de Slony-I™, ce changement est « incrémental » même si la modification concerne « la table toute entière ».

La seule fois où Slony-I™ « synchronise » le contenu d'une table est lors de la mise en place de l'abonnement. À ce moment-là, il utilise la commande COPY pour rapatrier la totalité du contenu de la table à partir du nœud fournisseur.

Puisque les tables abonnées sont protégées contre les modifications réalisées par un autre utilisateur que Slony-I™, il est impossible (mis à part d'horribles bogues) que les tables soient désynchronisées. Si c'est le cas, alors il y a vraiment un gros problème dans Slony-I™.

Si une corruption très grave se produit, la solution est de retirer la table de la réplication, puis de créer un nouvel ensemble de réplication et de l'ajouter à nouveau.