Last modified: Sun Jan 30 09:14:28 JST 2011
Bienvenue sur la page de pgpool-II


pgpool-II

pgpool-II est un middleware qui se place entre les serveurs PostgreSQL et les clients de ces derniers. Voici ses différentes fonctionalités:

  • Pooling de connexions
  • pgpool-II maintient les connexions établies aux serveurs PostgreSQL et les réutilise dès qu'une nouvelle connexion partageant les mêmes propriétés (c'est-à-dire même utilisateur, même base de données et même version de protocole) arrive. Il réduit ainsi le coût de la connexion et améliore les performances générales du système.

  • Réplication
  • pgpool-II peut gérer plusieurs serveurs PostgreSQL. En activant le mode réplication, il devient possible de créer une sauvegarde continue sur d'autres instances PostgreSQL, afin que le service puisse continuer sans interruption si l'une de ces instances était défaillante.

  • Répartition de charge
  • Si une base de données est répliquée, exécuter une requête en SELECT sur n'importe lequel de ceux-ci retournera le même résultat. pgpool-II profite ainsi avantageusement de la réplication pour réduire la charge sur chacun des serveurs PostgreSQL. Il parvient à cela en distribuant les requêtes SELECT entre tous les serveurs disponibles, ce qui qui améliore les performances générales du système. Dans un scénario idéal, les performances en lecture s'améliorent proportionnellement au nombre de serveurs PostgreSQL. La répartition de charge avec pgpool-II fonctionne au mieux dans un scénario où il y a beaucoup d'utilisateurs qui exécutent beaucoup de requêtes en lecture au même moment.

  • Limitation des connexions excédentaires
  • Dans PostgreSQL, il y a une limite maximum du nombre de connexions concurrentes au serveur (NDT: paramètre max_connections), et toutes les nouvelles connexions sont rejettées une fois que ce nombre est atteint. Augmenter ce nombre est possible mais accroît la consommation de ressources par le serveur et a un impact négatif sur les performances générales du système. Bien que pgpool-II ait aussi une limite sur le nombre de connexions maximum, il va mettre toute connexion excédentaire dans une file d'attente au lieu de retourner immédiatement une erreur.

  • Requêtes parallèlisées
  • En utilisant la fonctionalité des requêtes parallèlisées, les données peuvent être réparties sur plusieurs serveurs afin que les requêtes puissent être exécutées sur tous les serveurs à la fois, en réduisant ainsi le temps d'exécution global de la requête. Cette fonctionalité donne les meilleurs résultats lorsqu'on cherche à extraire un très grand ensemble de données.

pgpool-II utilise le même protocole que le serveur et les clients PostgreSQL, et relaie les messages entre les deux. Ainsi, une application cliente va prendre pgpool-II pour le serveur, et ce dernier va voir pgpool-II comme une application cliente. Puisque pgpool-II est complètement transparent, il peut-être utilisé pour une application sans pratiquement rien changer de son code source.

Il y a cependant quelques restrictions à l'utilisation du SQL via pgpool-II. Veuillez vous reporter à la section Restrictions pour plus de détails.

Plates-formes supportées

pgpool-II fonctionne sous Linux, Solaris, FreeBSD et la plupart des architectures UNIX. Windows n'est pas supporté. Les versions 6.4 et ultérieures de PostgreSQL sont supportées. Cependant, pour utiliser la fonctionalité de requêtage en parallèle, vous devez avoir un serveur en version 7.4 ou supérieure.

Si vous utilisez PostgreSQL en version 7.3 ou inférieure, certaines fonctionnalités de pgpool-II ne seront pas disponibles. Cependant, vous ne devriez pas utiliser une si vieille version de toute façons.

Vous devez aussi être certain que vos serveurs PostgreSQL sont tous dans la même version majeure. De plus, les architectures matérielles et logicielles (systèmes d'exploitation) doivent-être identiques si vous voulez utiliser la technologie « online recovery ».

Installation de pgpool-II

pgpool-II est téléchargeable sur la page de développement de pgpool. Plusieurs packages sont aussi fournis pour diverses plates-formes incluant CentOS, RedHat Enterprise Linux, Fedora et Debian.

Le code source de pgpool-II est téléchargeable sur la page de développement de pgpool.

Pour installer pgpool-II depuis son code source, vous aurez besoin de gcc, en version 2.9 ou supérieure, et de GNU make. pgpool-II utilisant la bibliothèque libpq de PostgreSQL, celle-ci doit aussi être installée ainsi que les fichiers d'en-tête sur la machine utilisée pour compiler pgpool-II. Si vous souhaitez activer le support d'OpenSSL dans pgpool-II, il vous faudra aussi avoir cette bibliothèque ainsi que les fichiers d'en-tête relatifs installés sur la machine de compilation.

Configuration

Après avoir extrait les sources depuis l'archive, exécutez le script de configuration comme suit.

./configure
Plusieurs options de configuration ont des valeurs par défaut, mais vous pouvez cependant les surcharger comme suit :
  • --prefix=path
    Les binaires de pgpool-II ainsi que sa documentation seront installés dans ce répertoire. La valeur par défaut est /usr/local.
  • --with-pgsql=path
    Répertoire sous lequel les bibliothèques de PostgreSQL sont installées. La valeur par défaut est fournie par l'utilitaire pg_config.
  • --with-openssl
    Avec cette option, les binaires de pgpool-II seront compilés avec le support d'OpenSSL. Par défaut, le support d'OpenSSL est désactivé.

Compilation

make
make install
Ces deux commandes suffisent pour compiler et installer pgpool-II. Si vous utilisez Solaris ou FreeBSD, remplacez make par gmake.

Installation de pgpool_regclass

Si vous utilisez PostgreSQL 8.0 ou supérieur, l'installation des fonctions pgpool_regclass, utiles à pgpool-II, est fortement recommandée. Sans celles-ci, le support de tables homonymes mais figurant dans des schémas différents pourrait ne pas fonctionner correctement (pour les tables temporaires, il n'y a aucun problème).

cd pgpool-II-x.x.x/sql/pgpool-regclass
make
make install
psql -f pgpool-regclass.sql template1

L'exécution du script pgpool-regclass.sql doit être faite sur toutes les bases qui sont accédées via pgpool-II. Vous n'avez pas besoin de le faire pour toutes les bases de données créées après l'exécution des commandes ci-dessus car la base template1 est la base utilisée comme modèle par défaut pour les nouvelles bases de données sous PostgreSQL.

Installation de pgpool_walrecrunning

Si vous utilisez PostgreSQL 9.0 ou supérieur avec le « streaming replication », vous aurez besoin d'installer la fonction pgpool_walrecrunning sur tous les serveurs PostgreSQL accedées par pgpool-II.

cd pgpool-II-x.x.x/sql/pgpool-walrecrunning
make
make install
psql -f pgpool-walrecrunning.sql template1

L'exécution du script pgpool-walrecrunning.sql doit-être faite sur toutes les bases de données accedées par pgpool-II. Comme précedemment, vous n'avez pas besoin de le faire pour toutes les bases de données créées après l'exécution des commandes ci-dessus car la base template1 est la base utilisée comme modèle par défaut pour les nouvelles bases de données sous PostgreSQL.

Configuration de pgpool-II

Les fichiers de configuration par défaut de pgpool-II sont /usr/local/etc/pgpool.conf et /usr/local/etc/pcp.conf. Plusieurs modes de fonctionnement sont disponibles sous pgpool-II. Chaque mode a des fonctionnalités associées qui peuvent être activées ou désactivées, mais aussi configurées pour contrôler leur comportement.

Fonction/Mode Raw Mode (*3) Mode réplication Mode maître/esclave Mode de requêtage en parallèle
Pooling de connexions X O O O
Réplication X O X (*1)
Répartition de charge X O O (*1)
Failover O O O X
Online recovery X 0 (*2) X
Requêtage en parallèle X X X O
Nombre de serveurs requis 1 ou plus 2 ou plus 2 ou plus 2 ou plus
Base de donnée système requise? non non non oui

  • 0 signifie 'disponible' et X 'indisponible'
  • (*1) Le mode de requêtage en parallèle nécessite que la réplication et la répartition de charge soient activés, cependant la réplication et la répartition de charge ne peuvent pas être utilisés pour les tables distribuées en mode de requêtage parallèlisé.
  • (*2) Le online recovery peut-être utilisé en mode maître/esclave avec la « Streaming Replication ».
  • (*3) Les clients se connectent simplement aux serveurs PostgreSQL via pgpool-II. Ce mode est utile pour limiter simplement les connexions excédentaires aux serveurs, ou activer le failover avec de multiples serveurs.

Configuration de pcp.conf

Une interface de contrôle est fournie avec pgpool-II et permet à l'administrateur de vérifier l'état de pgpool-II et d'arrêter les processus de pgpool-II à distance. pcp.conf est le fichier contenant la définition des utilisateurs et de leurs mots de passe pour accéder à cette interface. Tous les modes d'utilisation de pgpool-II nécessitent que le fichier pcp.conf soit renseigné. Un fichier d'exemple $prefix/etc/pcp.conf.sample est créé lors de l'installation de pgpool-II. Renommez ce fichier en pcp.conf, ajoutez-y votre nom d'utilisateur ainsi que votre mot de passe.

cp $prefix/etc/pcp.conf.sample $prefix/etc/pcp.conf

Une ligne vide ou commençant par un dièse (#) est traitée comme un commentaire et sera ignorée. Un nom d'utilisateur et son mot de passe doivent être écrits sur une seule ligne et respecter le format suivant :

nom_d_utilisateur:[mot de passe crypté en md5]

Le [mot de passe crypté en md5] peut être obtenu avec la commande $prefix/bin/pg_md5.

pg_md5 -p
password: <votre mot de passe>

ou

./pg_md5 foo
acbd18db4cc2f85cedef654fccc4a4d8

Le fichier pcp.conf doit être lisible par l'utilisateur qui exécute pgpool-II.

Configuration de pgpool.conf

Comme cela a déjà été expliqué, chaque mode de pgpool-II a ses propres paramètres de configuration dans le fichier pgpool.conf. Un fichier d'exemple $prefix/etc/pgpool.conf.sample est créé lors de l'installation de pgpool-II. Renommez ce fichier en pgpool.conf et éditez son contenu.

cp $prefix/etc/pgpool.conf.sample $prefix/etc/pgpool.conf

Toute ligne vide ou commençant par "#" sera traitée comme un commentaire et sera donc ignorée.

Paramètres communs

listen_addresses

Spécifie le nom de la machine ou son adresse IP, sur laquelle pgpool-II acceptera les connexions TCP/IP. '*' accepte toutes les connexions. '' empêchera toute connexion TCP/IP. La valeur par défaut est 'localhost'. Les connexions via les sockets UNIX sont toujours acceptées. Ce paramètre ne peut être modifié qu'au démarrage du serveur.

port

Spécifie le numéro de port sur lequel pgpool-II écoute les connexions. La valeur par défaut est 9999. Ce paramètre ne peut être modifié qu'au démarrage du serveur.

socket_dir

Répertoire dans lequel sera créé le socket UNIX de pgpool-II pour les connexions entrantes. La valeur par défaut est '/tmp'. Faites attention au fait que ce socket pourrait être effacé par une tâche programmée en cron. Aussi, nous vous recommandons de configurer cette valeur à '/var/run' ou un répertoire de ce type. Ce paramètre ne peut être modifié qu'au démarrage du serveur.

pcp_port

Numéro de port sur lequel le processus PCP accepte les connexions. La valeur par défaut est 9898. Ce paramètre ne peut être modifié qu'au démarrage du serveur.

pcp_socket_dir

Chemin du répertoire UNIX où le socket UNIX acceptant les connexions pour les commandes PCP est créé. La valeur par défaut est '/tmp'. Faites attention au fait que cet socket pourrait être effacé par une tâche programmée en cron. Aussi, nous vous recommandons de configurer cette valeur à '/var/run' ou un répertoire de ce type. Ce paramètre ne peut être modifié qu'au démarrage du serveur.

backend_socket_dir

À NE PLUS UTILISER Ce paramètre n'est présent que pour garantir la cohérence avec la politique par défaut de la bibliothèque libpq. Reportez-vous à la définition du paramètre backend_hostname pour adapter votre configuration.

Ce paramètre permettait de définir le répertoire UNIX servant au serveur PostgreSQL.

pcp_timeout

Délai maximum en secondes pour l'établissement d'une connexion PCP. Si un client ne répond plus au bout de cette valeur en secondes, le processus PCP ferme la connexion avec le client. La valeur par défaut est de 10 secondes. 0 signifie que la vérification du délai est désactivée. Ce paramètre est pris en compte lors du rechargement des fichiers de configuration.

num_init_children

Nombre de processus pré-forkés de pgpool-II. La valeur par défaut est de 32. num_init_children est aussi la limite du nombre de connexions clientes concurrentes à pgpool-II. Si plus de num_init_children clients essaient de se connecter à pgpool-II, ceux-ci sont bloqués (mais pas rejettés), jusqu'à ce qu'une connexion à l'un des processus de pgpool-II soit fermé. On peut avoir ansi jusqu'à deux fois num_init_children clients dans la queue de connexion.

Quelques précisions et astuces :

  • L'annulation d'une requête crée une autre connexion au processus serveur PostgreSQL ; ainsi, une requête ne peut pas être annulée si toutes les connexions sont utilisées. Si vous voulez vous assurer que les requêtes puissent être annulées, positionnez cette valeur au double des connexions attendues.
  • PostgreSQL permet un certain nombre de connexions pour les utilisateurs qui ne sont pas superutilisateurs. On le calcule ainsi :max_connections - superuser_reserved_connections

Pour résumer, max_pool,num_init_children, max_connections et superuser_reserved_connections doivent satisfaire la formule suivante :

  • Si on n'a pas besoin de l'annulation de requêtes :
    max_pool*num_init_children <= (max_connections - superuser_reserved_connections)
  • Si on a besoin de l'annulation de requêtes :
    max_pool*num_init_children*2 <= (max_connections - superuser_reserved_connections)
Ce paramètre ne peut être modifié qu'au démarrage du serveur.

child_life_time

Durée de vie en secondes d'un processus fils de pgpool-II. Lorsqu'un processus fils est sans activité depuis ce nombre de secondes, il se termine et un nouveau processus fils est créé. Ce paramètre est une mesure pour prévenir tout problème de mémoire et autres erreurs inattendues. La valeur par défaut est 300 (5 minutes). Cette fonctionalité est désactivée si cette option a une valeur de 0. Notez que cela ne s'applique qu'aux processus qui n'ont pas encore été utilisés ou qui n'ont pas encore accepté de connexions. Vous devez recharger le fichier de configuration pgpool.conf si vous changez cette valeur.

child_max_connections

Un processus fils de pgpool-II sera terminé après avoir accepté ce nombre de connexions clientes. Ce paramètre est utile sur un serveur à ce point chargé que ni child_life_time, ni connection_life_time ne sont déclenchés. Vous devez recharger pgpool-II si vous changez cette valeur.

client_idle_limit

Déconnecte un client s'il est resté inactif pendant ce nombre de secondes après que la dernière requête ne se soit terminée. Ceci est utile pour empêcher qu'un processus fils de pgpool-II ne soit occupé par un client inactif ou une connexion TCP/IP rompue entre le client et pgpool-II. La valeur par défaut de client_idle_limit est de 0, ce qui signifie que cette fonctionalité est désactivée. Ce paramètre est ignoré dans la seconde phase d'un online recovery. Vous aurez besoin de recharger pgpool-II si vous modifiez client_idle_limit.

authentication_timeout

Spécifie le délai maximum en secondes pour terminer une authentification. 0 désactive cette fonctionnalité. Vous aurez besoin de redémarrer pgpool-II si vous changez cette valeur.

logdir

Répertoire utilisé pour les logs. pgpool_status est écrit dans ce répertoire.

log_destination

pgpool-II utilise plusieurs méthodes pour écrire les messages du serveur. Cela inclut stderr et syslog. La valeur par défaut est d'envoyer les messages à stderr.

Note: vous aurez besoin de modifier la configuration du serveur syslog de votre système pour que l'écriture des messages vers syslog fonctionne. pgpool-II peut envoyer les traces à syslog en utilisant les niveaux LOCAL0 à LOCAL7 (voir la documentation de syslog), mais la valeur par défaut de syslog sur la plupart des plates-formes ignorera de tels messages. Vous aurez donc besoin d'ajouter quelque-chose comme

	local0.*    /var/log/pgpool.log
	

au fichier de configuration de votre démon syslog pour le faire fonctionner.

syslog_facility

Lorsque la sortie des messages vers syslog est configurée, ce paramètre détermine le niveau syslog à utiliser. Vous pouvez choisir toute valeur entre LOCAL0 et LOCAL7. La valeur par défaut est LOCAL0. Veillez à vous reporter à la documentation système au sujet de syslog.

syslog_ident

Lorsque la sortie vers syslog est configurée, ce paramètre permet de déterminer le nom du programme utilisé pour identifier les messages de pgpool-II dans les traces enregistrées par syslog. La valeur par défaut est pgpool.

pid_file_name

Chemin complet vers le fichier qui contient le numéro d'identifiant du processus pgpool. La valeur par défaut est "/var/run/pgpool/pgpool.pid". Vous aurez besoin de redémarrer pgpool-II pour changer cette valeur.

print_timestamp

Ajoute un horodatage dans les traces lorsque cette valeur est à true. La valeur par défaut est true. Vous aurez besoin de recharger pgpool-II si vous changez cette valeur afin qu'elle soit prise en compte.

connection_cache

Cache les connexions à PostgreSQL lorsque cette valeur est configurée à true. La valeur par défaut est true.

health_check_timeout

pgpool-II essaie périodiquement de se connecter à PostgreSQL afin de détecter toute erreur sur les serveurs ou sur le réseau. Cette procédure de vérification d'erreurs est appelée « health check ». Si une erreur est détectée, pgpool-II essaie d'exécuter un failover ou une dégénération. Ce paramètre permet d'empêcher qu'un "health check" n'attende trop longtemps dans les cas où un câble réseau est débranché par exemple. La valeur du paramètre est en secondes. La valeur par défaut est de 20 secondes. 0 désactive cette fonctionnalité (dans ce cas, pgpool-II attend jusqu'à la fin du délai maximum configuré au niveau TCP/IP). Cette vérification nécessite une connexion supplémentaire à chacun des serveurs PostgreSQL. Du coup, il faut le prendre en compte dans la configuration du paramètre max_connections de chaque serveur PostgreSQL. Vous aurez besoin de recharger pgpool-II après toute modification de ce paramètre.

health_check_period

Ce paramètre précise l'intervalle de temps entre deux vérifications en secondes. La valeur par défaut est de 0, ce qui a pour effet de désactiver la vérification. Vous aurez besoin de recharger pgpool-II après tout changement de ce paramétrage.

health_check_user

Nom de l'utilisateur PostgreSQL utilisé pour exécuter la vérification. Cet utilisateur doit exister dans tous les serveurs PostgreSQL. Vous aurez besoin de recharger pgpool-II après tout changement de la valeur de ce paramètre.

failover_command

Ce paramètre spécifie la commande à exécuter lorsqu'un nœud est détaché. pgpool-II remplace les caractères spéciaux suivants avec les informations associées.

Caractère spécialDescription
%dID du processus serveur correspondant au nœud détaché
%hNom d'hôte du nœud détaché
%pNuméro de port du nœud détaché
%DRépertoire de l'instance PostgreSQL du nœud détaché
%MID du nœud de l'ancien maître
%mID du nœud du nouveau maître
%HNom d'hôte du nouveau nœud maître
%PID de l'ancien nœud primaire
%%Caractère '%'

Vous devez recharger pgpool.conf si vous changez la valeur de failover_command.

Lorsqu'une commande failover est exécutée, pgpool tue tous ses processus fils, ce qui fermera toutes les sessions actives à pgpool. Alors, pgpool invoque la commande failover_command et attend son exécution complète. Après cela, pgpool démarre de nouveaux processus fils et est alors à nouveau disponible pour accepter des connexions depuis les clients.

failback_command

Ce paramètre contient une commande à exécuter lors qu'un nœud est attaché. pgpool-II remplace les caractères spéciaux suivants avec les informations associées.

Caractère spécialDescription
%dID du processus serveur d'un nœud attaché
%hNom d'hôte d'un nœud attaché
%pNuméro de port d'un nœud attaché
%DRépertoire de l'instance PostgreSQL d'un nœud attaché
%MAncien nœud maître
%mNouveau nœud maître
%HNom d'hôte du nouveau nœud maître
%PID de l'ancien nœud primaire
%%Caractère '%'

Vous devez recharger pgpool.conf si vous changez le contenu de la commande failback_command.

fail_over_on_backend_error

Si ce paramètre est à true et qu'une erreur apparaît lors d'une écriture sur le canal de communication d'un processus serveur, pgpool-II déclenchera une procédure de failover. C'est le même comportement qu'avec les versions 2.2.x ou précédentes de pgpool-II. Si ce paramètre est à false, pgpool reportera une erreur dans ses fichiers de traces et déconnectera la session. Notez cependant que si ce paramètre est activé, pgpool effectuera aussi un failover lorsque la connexion à un processus serveur échoue ou lorsqu'il détecte l'arrêt du serveur PostgreSQL par un administrateur. Vous devez recharger pgpool.conf si vous changez cette valeur.

ignore_leading_white_space

Si ce paramètre est activé, pgpool-II ignorera les espaces en début de requête SQL lorsqu'il est dans le mode de répartition de charge. C'est particulièrement intéressant lorsqu'il est utilisé avec des API comme DBI/DBD::Pg qui ajoutent des espaces sans que l'utilisateur le demande. Vous aurez besoin de demander à pgpool-II de recharger sa configuration pour que ce paramètre soit pris en compte.

log_statement

Lorsque ce paramètre est activé, pgpool-II tracera les requêtes SQL qu'il reçoit dans son fichier de traces. Cela va produire des traces même si l'option debug n'est pas passée à pgpool-II au démarrage. Vous aurez besoin de recharger pgpool.conf pour que ce paramètre soit pris en compte.

log_per_node_statement

Similaire à log_statement, à l'exception qu'il écrit les traces de manière séparée par nœud. Cela peut se révéler très utile si vous voulez vous assurer, par exemple, que votre réplication fonctionne. Vous aurez besoin de recharger pgpool.conf pour que ce paramètre soit pris en compte.

log_hostname

Si ce paramètre est positionné à true, le nom de la commande affichée dans la sortie de ps sera le nom de l'hôte plutôt que son IP. De même, si log_connections est activé, le nom de l'hôte sera écrit dans les fichiers de trace plutôt que son IP. Ce paramètre est pris en compte au rechargement de pgpool.conf.

log_connections

Si ce paramètre est à true, toutes les connexions entrantes seront tracées dans les journaux applicatifs. Ce paramètre est pris en compte au rechargement de pgpool.conf.

enable_pool_hba

Si ce paramètre est à vrai, on utilisera le fichier pool_hba.conf pour l'authentification des clients. Voir la configuration de pool_hba.conf pour l'authentification des clients. Ce paramètre est pris en compte au rechargement de pgpool-II.

backend_hostname

Permet de spécifier à quel serveur PostgreSQL on se connecte. C'est utilisé par pgpool-II pour communiquer avec le serveur. Ce paramètre n'est lu qu'au démarrage du serveur pgpool-II.

Pour les communications TCP/IP, ce paramètre accepte soit un nom d'hôte, soit une adresse IP. Si ce dernier commence avec un slash, il spécifie un socket Unix plutôt qu'une adresse IP ; la valeur est alors le nom du répertoire dans lequel le fichier de socket UNIX est stocké. Si ce paramètre est vide (''), le comportement par défaut de pgpool-II est de se connecter à un socket UNIX stocké dans le répertoire /tmp.

On peut spécifier ici plusieurs serveurs en ajoutant un nombre à la fin du nom du paramète (par exemple backend_hostname0). Ce nombre est l'identifiant du nœud au sein de pgpool-II. Le premier nœud est toujours le nœud 0. Le serveur PostgreSQL qui se voit attribuer l'identifiant 0 sera appelé le serveur maître. Lorsque plusieurs serveurs sont définis et seulement pour certains modes, le service peut continuer même si le serveur maître est arrêté. Dans ce cas, c'est toujours le serveur qui a le plus petit identifiant de nœud et qui est encore disponible qui est alors promu serveur maître.

Si vous pensez n'utiliser qu'un seul serveur PostgreSQL, spécifiez-le avec backend_hostname0.

De nouveaux serveurs PostgreSQL peuvent être ajoutés grâce à ce paramètre mais Vous devez recharger le fichier de configuration. Par contre, les valeurs de ces paramètres ne pouvant être mises à jour, si vous les changez, vous devrez alors redémarrer pgpool-II.

backend_port

Spécifie le numéro de port des serveurs. Comme précédemment, on peut spécifier le port de plusieurs serveurs en ajoutant à la fin du nom du paramètre l'identifiant du nœud (par exemple backend_port0). Si vous n'utilisez qu'un seul serveur, vous devrez le spécifier par backend_port0.

Comme précédemment, vous pouvez ajouter de nouveaux paramètres concernant de nouveaux nœuds, et alors, un rechargement de la configuration suffira. Cependant, si vous mettez à jour des valeurs de paramètres existant, vous devrez redémarrer le serveur pgpool-II.

backend_weight

Spécifie le poids des serveurs pour la répartition de charge. On peut indiquer une valeur pour chacun des serveurs. Il suffit pour cela d'ajouter le numéro du serveur à la fin du nom du paramètre (par exemple backend_weight0). Si vous n'utilisez qu'un seul serveur PostgreSQL, utilisez le paramètre backend_weight0. Si vous êtes dans le mode RAW de pgpool-II, mettez toujours cette valeur à 1.

De nouveaux poids pour les backends peuvent être ajoutés pour de nouveaux nœuds. Cependant, si vous mettez à jour des valeurs de paramètres existant, vous devrez redémarrer le serveur pgpool-II.

À partir de pgpool-II 2.2.6/2.3, vous pouvez changer cette valeur par rechargement du fichier de configuration. Le nouveau paramétrage prendra alors effet uniquement pour les nouvelles sessions clientes. C'est très pratique si vous voulez empêcher toute requête envoyée aux serveurs esclaves de réaliser des tâches administratives en mode maître/esclave.

backend_data_directory

Précise le répertoire des données des serveurs PostgreSQL. Plusieurs serveurs peuvent être spécifiés en ajoutant un nombre à la fin du nom de paramètre (par exemple backend_data_directory0). Si vous ne pensez pas utiliser « online recovery », vous n'avez pas besoin de spécifier ce paramètre.

Des spécifications de répertoires de données PostgreSQL additionnels peuvent être ajoutés par rechargement du fichier de configuration. En revanche, leur valeur ne peut pas être mise à jour de cette façon. Du coup, vous devrez redémarrer pgpool-II si vous modifiez la valeur d'un paramètre déjà configuré.

ssl

Si ce paramètre est à "true", le support de SSL est activé à la fois pour les connexions clientes et les connexions aux serveurs PostgreSQL. Notez que ssl_key et ssl_cert doivent être renseignés pour que les connexions clientes puissent fonctionner en SSL.

SSL est désactivé par défaut. Notez que le support d'OpenSSL doit aussi avoir été configuré au moment de la compilation, comme c'est mentionné dans la section installation.

Le démon de pgpool-II doit être redémarré lorsqu'on met à jour les paramètres relatifs à SSL.

ssl_key

Chemin du fichier de clé privée pour les connexions clientes entrantes.

Il n'y a aucune valeur par défaut pour ce paramètre. S'il n'est pas modifié, le support de SSL sera désactivé pour les connexions clientes entrantes.

ssl_cert

Chemin complet vers le certificat public x509 à utiliser pour les connexions clientes entrantes.

Il n'y a aucune valeur par défaut pour ce paramètre. S'il n'est pas modifié, le support de SSL sera désactivé pour les connexions clientes entrantes.

debug_level

Niveau de verbosité des messages de débogage. 0 signifie aucun message, plus grand que 1 engendre des messages plus verbeux. La valeur par défaut est 0.

relcache_expire

Durée de vie en secondes d'une relation en cache. 0 signifie qu'il n'y a pas d'expiration (valeur par défaut). Ce cache de relations est utilisé pour cacher le résultat de requêtes effectuées sur le catalogue système de PostgreSQL pour obtenir diverses informations comme la structure des tables ou pour savoir si telle ou telle table est temporaire. Ce cache est maintenu dans une mémoire locale au processus fils de pgpool et est gardé aussi longtemps que le processus est en vie. Si un utilisateur modifie une table avec un ALTER TABLE, par exemple, ce cache n'est alors plus cohérent. À cet effet, le paramète relcache_expiration contrôle la durée de vie du cache.

Génération de certificats SSL

La manipulation des certificats n'est pas couvert dans ce document. La page Secure TCP/IP Connections with SSL (en anglais) sur le site PostgreSQL.org référence des documents qui expliquent en détail les commandes à taper pour engendrer des certificats auto-signés.

Failover dans le mode Raw

Le failover peut être accompli dans le mode Raw si plusieurs serveurs sont définis. pgpool-II accède en général au serveur spécifié par backend_hostname0 pendant son fonctionnement normal. Si le backend_hostname0 est en échec, quel que soit la raison, pgpool-II essaie d'accéder au serveur spécifié par backend_hostname1. En cas d'échec, pgpool-II essaie alors backend_hostname2, et ainsi de suite.

Mode pooling de connexions

Dans le mode pooling de connexions, toutes les fonctions du mode raw et du mode pooling de connexions peuvent être utilisées. Pour activer ce mode, configurez les paramètres du mode raw ainsi que les autres paramètres ci-après.

max_pool

Nombre maximum de connexions en cache dans les processus fils de pgpool-II. pgpool-II réutilise les connexions en cache si une connexion entrante se connecte à la même base de données avec le même nom d'utilisateur. Sinon, pgpool-II crée une nouvelle connexion au serveur PostgreSQL. Si le nombre de connexions en cache dépasse max_pool, la plus vieille des connexions sera supprimée et on utilisera cet emplacement ainsi libéré pour la nouvelle connexion. La valeur par défaut est 4. Faites bien attention au fait que le nombre total de connexions des processus pgpool-II aux serveurs PostgreSQL pourraient atteindre ainsi : num_init_children * max_pool. Ce paramètre n'est pris en compte qu'au démarrage du serveur pgpool-II.

connection_life_time

Durée de vie en seconde d'une connexion en cache. Une connexion en cache dont la durée de vie expire sera alors déconnectée. La valeur par défaut est 0, ce qui signifie que les connexions en cache ne seront jamais déconnectées.

reset_query_list

Spécifie les requêtes SQL envoyées à la connexion au serveur PostgreSQL lorsqu'une session se termine, côté client de pgpool-II. Plusieurs commandes peuvent être spécifiées en les séparant par un point-virgule. La valeur ci-dessous est la valeur par défault, mais elle peut être adaptée pour satisfaire vos besoins.

      reset_query_list = 'ABORT; DISCARD ALL'
      

Les commandes diffèrent dans chaque version de PostgreSQL. Voici les paramètres recommandés par version.

Version de PostgreSQLreset_query_list value
7.1 ou précédentesABORT
7.2 à 8.2ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT
8.3 et suivantesABORT; DISCARD ALL

  • "ABORT" n'est pas envoyé en dehors d'un bloc de transactions à partir de la 7.4.

Vous aurez besoin de recharger pgpool.conf après toute modification de ce paramètre pour que sa nouvelle valeur soit prise en compte.

Le failover dans le mode pooling de connexions

Le failover dans le mode pooling de connexions est identique à celui du mode raw.

Mode réplication

Ce mode permet la réplication des données entre les serveurs PostgreSQL. Les paramètres de configuration ci-dessous doivent être renseignés, en plus de tout ce qui a été vu plus haut.

replication_mode

Mettre ce paramètre à true active le mode de réplication. La valeur par défaut est false.

load_balance_mode

Lorsque ce paramètre est à true, les requêtes de type SELECT sont distribuées à chaque serveur PostgreSQL pour obtenir une répartition de la charge entre les serveurs. La valeur par défaut est false.

failover_if_affected_tuples_mismatch

Lorsque ce paramètre est positionné à true, si les serveurs PostgreSQL ne retournent pas le même nombre de lignes affectées lors d'un INSERT, UPDATE ou DELETE, les serveurs qui diffèrent de la valeur la plus fréquente sont « dégénérés » (NDT: ils ne sont alors plus jamais utilisés par pgpool-II, qui les considère comme incohérents). Si ce paramètre est à false, la session est terminée et les serveurs PostgreSQL ne sont pas « dégénérés ». La valeur par défaut est à false.

replication_stop_on_mismatch

Si ce paramètre est à true et si tous les serveurs PostgreSQL ne retournent pas le même type de paquet, les serveurs dont la valeur diffère du résultat le plus fréquent sont « dégénérés ». Un cas d'utilisation typique est une requête SELECT dans une transaction, avec replicate_select à true, qui retournerait un nombre d'enregistrements différent suivant les serveurs PostgreSQL. Les requêtes qui ne sont pas en SELECT pourraient aussi déclencher cette action. Par exemple, si un serveur PostgreSQL réussit un UPDATE alors que les autres échouent. Notez que pgpool-II n'examine pas le contenu des enregistrements retournés par un SELECT. Si ce paramètre est à false, la session est terminée et les serveurs PostgreSQL ne sont pas « dégénérés ». La valeur par défaut est false.

white_function_list

Permet de spécifier une liste de noms de fonctions, séparées par des virgules, qui ne font pas d'écritures dans la base de données. Tous les SELECTs qui font appel à des fonctions qui ne sont pas spécifiées dans cette liste ne seront ainsi jamais répartis entre les serveurs PostgreSQL, ni même répliqués dans le mode réplication. Dans le mode maître/esclave, de tels SELECTs sont envoyés au maître (ou primaire) uniquement.

Vous pouvez utiliser des expressions régulières dans la liste pour établir une correspondance à une famille de fonctions. Par exemple, si vous avez eu la bonne idée de préfixer toutes les fonctions de votre base qui ne font que des lectures avec 'get_' ou 'select_' par exemple, vous pourrez ainsi vous limiter à n'écrire que les deux expressions régulières dans ce paramètre :

white_function_list = 'get_.*,select_.*'
black_function_list

Permet de spécifier une liste de noms de fonctions, séparées par des virgules, qui font des écritures dans la base de données. Les SELECT qui utilisent les fonctions spécifiées dans cette liste ne seront jamais répartis entre les serveurs PostgreSQL, ni répliqués dans le mode de réplication. Dans le mode maître/esclave, de tels SELECT sont envoyés uniquement au maître.

Vous pouvez utiliser des expressions régulières dans la liste pour établir une correspondance avec une famille de fonctions. Par exemple, si vous avez eu la bonne idée de préfixer toutes les fonctions de votre base qui font des écritures avec 'set_','update_','delete_' ou 'insert_' par exemple, vous pourrez ainsi vous limiter à n'écrire que les expressions régulières suivantes dans ce paramètre :

black_function_list = 'nextval,setval,set_.*,update_.*,delete_.*,insert_.*'

Attention, une seule de ces deux listes ne peut être renseignée dans la configuration de pgpool-II. Autrement dit, vous devez opter pour l'un ou l'autre des paramètres : autoriser de manière explicite, ou interdire de manière explicite. De préférence, optez pour la sécurité d'autoriser explicitement, c'est-à-dire utiliser le paramètre white_function_list. En effet, en cas d'oubli d'une fonction en écriture dans le paramètre black_function_list, vous risquez de demander l'exécution d'une fonction en écriture sur un serveur en lecture seule, dans le mode maître/esclave par exemple.

Avant la version 3.0 de pgpool-II, les fonctions nextval() et setval() étaient connues pour leurs écritures dans la base de données. Vous pouvez émuler ce comportement en utilisant les deux paramètres vus précédemment de la façon suivante :

white_function_list = ''
black_function_list = 'nextval,setval,lastval,currval'

Notez que l'on a lastval() et currval() en plus des nextval() et setval(). Bien que lastval() et currval() ne soient pas des fonctions qui provoquent des écritures, il vaux mieux les ajouter pour éviter toute erreur dans le cas où ces fonctions seraient accidentellement réparties entre les différents nœuds. Ainsi, les ajouter à la black_function_list permettra d'éviter qu'elles soient réparties.

replicate_select

Lorsque ce paramètre est à true, pgpool-II va répliquer les SELECT dans le mode de réplication. Si c'est à false, pgpool-II va les envoyer uniquement au serveur maître (primaire). La valeur par défaut est false.

Si une requête SELECT est à l'intérieur d'un bloc de transaction explicite, replicate_select et load_balance_mode auront un effet sur le fonctionnement de la réplication. Les détails sont expliqués ci-dessous.

Le SELECT est à l'intérieur d'un bloc de transaction O O O N N N O N
replicate_select = true O O N N O O N N
load_balance_mode = true O N N N O N O O
resultats (R:réplication, M:envoyé au maître uniquement, L:réparti) R R M M R R M L

insert_lock

Si on réplique une table qui utilise le type de données SERIAL, la valeur du SERIAL pourrait être différente entre les serveurs PostgreSQL. On peut éviter ce problème en verrouillant la table de manière explicite (bien que le parallélisme des transactions sera alors sévèrement dégradé). Pour arriver à cela, les changements suivants doivent être faits :

      INSERT INTO ...
      

à

      BEGIN;
      LOCK TABLE ...
      INSERT INTO ...
      COMMIT;
      

Lorsque insert_lock est à true, pgpool-II ajoute automatiquement les requêtes ci-dessus à chaque fois qu'un INSERT est exécuté. Si on est alors déjà dans une transaction, il ajoute alors simplement un LOCK TABLE.

À partir de pgpool-II 2.2, la détection des tables qui ont un SERIAL ou non est automatique. Ainsi, seules les tables qui ont un SERIAL sont verrouillées de manière exclusive.

pgpool-II 3.0 utilise désormais un verrou de ligne sur la relation de la séquence, plutôt qu'un verrou de table exclusif. Cela minimise les conflits sur les verrous, comme par exemple VACUUM (direct ou via autovacuum).

Si vous souhaitez un contrôle plus fin (par requête) :

  1. positionnez insert_lock à true, et ajoutez /*NO INSERT LOCK*/ au début d'une requête INSERT pour laquelle vous ne voulez pas qu'un verrou exclusif de table ne soit ajouté.
  2. positionnez insert_lock à false, et ajoutez /*INSERT LOCK*/ au début d'une requête INSERT pour laquelle vous voulez provoquer un verrouillage exclusif de la table.

La valeur par défaut est false. Si insert_lock est activé, les tests de régression pour PostgreSQL 8.0 échoueront dans les transactions, droits, règles (rules) et ALTER TABLE. La raison en est que pgpool-II essaie de verrouiller une vue pour le test sur les règles, ce qui a pour conséquence l'erreur suivante :

      ! ERROR: current transaction is aborted, commands ignored until
      end of transaction block
      

Par exemple, le test sur les transactions essaie un INSERT dans une table qui n'existe pas, et pgpool-II essaie d'acquérir un verrou exclusif avant cela. La transaction sera alors interrompue et la requête d'INSERT qui suit produira le message ci-dessus.

recovery_user

Ce paramètre permet de spécifier l'utilisateur PostgreSQL à utiliser pour le « online recovery ». Il peut être changé sans avoir besoin de redémarrer pgpool-II.

recovery_password

Ce paramètre permet de spécifier le mot de passe de l'utilisateur spécifié dans le paramètre ci-dessus, à savoir recovery_user, qui est utilisé lors du « online recovery ». Comme le paramètre précédent, il peut être changé sans avoir à redémarrer le serveur pgpool-II.

recovery_1st_stage_command

Ce paramètre permet de préciser une commande à exécuter pour la première phase du « online recovery ». Le fichier de commandes spécifié ici doit être placé à la racine du répertoire des données de l'instance PostgreSQL, pour des raisons de sécurité. Par exemple, si recovery_1st_stage_command = 'sync-command', alors pgpool-II exécute $PGDATA/sync-command. Notez que pgpool-II accepte les connexions et les requêtes alors que recovery_1st_stage command est en cours d'exécution. On peut ainsi lire et écrire dans la base de données pendant cette première phase du « online recovery ».

Ce paramètre peut être changé sans avoir à redémarrer pgpool-II.

recovery_2nd_stage_command

Ce paramètre spécifie une commande à exécuter lors de la deuxième phase du « online recovery ». Ce fichier de commandes doit être placé à la racine du répertoire des données de l'instance PostgreSQL pour des raisons de sécurité. Par exemple, si recovery_2nd_stage_command = 'sync-command', alors pgpool-II exécute $PGDATA/sync-command. Notez que pgpool-II n'accepte pas de connexions ou d'exécution de requêtes pendant que recovery_2nd_stage_command est en cours d'exécution. Ainsi, si un client reste connecté pendant une longue période, rien ne sera exécuté. En effet, pgpool-II attends que tous les clients aient fermé leurs connexions pour exécuter cette seconde phase du « online recovery ». La commande n'est donc exécutée que lorsqu'il n'y a plus aucun client de connecté.

Ce paramètre peut être changé sans redémarrer pgpool-II.

recovery_timeout

pgpool n'accepte plus de nouvelle connexion pendant la seconde phase du « online recovery ». Si un client essaie de se connecter à pgpool-II pendant un « online recovery », il devra attendre la fin de ce dernier.

Ce paramètre spécifie un délai au terme duquel le « online recovery » sera annulé s'il n'est pas terminé. Après l'annulation, pgpool-II acceptera alors de nouveau les connexions. La valeur 0 désactive cette fonctionnalité.

Ce paramètre peut être changé sans avoir à redémarrer pgpool-II.

client_idle_limit_in_recovery

Similaire à client_idle_limit. Cependant, il n'agit que lors de la seconde phase du « online recovery ». Un client qui aura été inactif pendant client_idle_limit_in_recovery secondes depuis sa dernière requête sera déconnecté. Ce paramètre permet d'éviter que le « online recovery » ne soit perturbé par un client inactif, ou si la connexion TCP/IP entre le client et pgpool tombe de manière accidentelle (un câble réseau défectueux par exemple). Si ce paramètre est à -1, le client est déconnecté immédiatement. La valeur par défaut de ce paramètre est 0, ce qui signifie que cette fonctionalité est désactivée.

Si vos clients sont très actifs, pgpool-II ne pourra jamais entrer dans la seconde phase du « online recovery », quelle que soit la valeur de client_idle_limit_in_recovery que vous aurez choisie. Dans ce cas, vous pouvez paramétrer client_idle_limit_in_recovery à -1 afin que pgpool-II puisse déconnecter immédiatement des clients aussi actifs avant de passer à la seconde phase du « online recovery ».

Vous devez recharger la configuration de pgpool-II si vous changer la valeur de client_idle_limit_in_recovery.

lobj_lock_table

Ce paramètre spécifie un nom de table utilisé pour le contrôle de la réplication des « large objects ». Si elle est spécifiée, pgpool-II verrouillera cette table, et génèrera un identifiant de « large object » en regardant dans la table pg_largeobject du catalogue système, et enfin, appellera lo_create pour créer le « large object ». Cette procédure garantie que pgpool-II obtiendra le même identifiant de « large object » sur tous les serveurs PostgreSQL lorsque pgpool-II est dans le mode réplication. Notez que PostgreSQL 8.0 et ultérieur n'a plus de fonction lo_create. Du coup, cette fonctionalité est pas utilisable pour ces versions.

Un appel à la fonction de la libpq lo_creat() utilisera cette fonctionalité. De même, la création de « large objects » via l'API Java (driver JDBC) devrait fonctionner, tout comme l'API PHP (pg_lo_create, ou API similaire dans la bibliothèque de PHP, comme PDO), et ce genre d'API similaires dans plusieurs langages de programmation qui sont réputées pour utiliser un protocole similaire.

Les opérations suivantes de création d'un « large object » ne fonctionneront pas :

  • lo_create de la libpq
  • l'API d'un langage qui utilise lo_create
  • la fonction lo_import dans le serveur PostgreSQL
  • SELECT lo_creat

Peu importe le schéma où est stockée la table lobj_lock_table, celle-ci doit en revanche être accessible en écriture à tous les utilisateurs. Voici un exemple de création d'une telle table :

CREATE TABLE public.my_lock_table ();
GRANT ALL ON public.my_lock_table TO PUBLIC;

La table spécifiée par lobj_lock_table doit être créée à l'avance. Vous pouvez par exemple la créer dans la base template1 afin que toute base de données créée par la suite en dispose.

Si lobj_lock_table contient une chaîne vide (''), la fonctionalité est désactivée. Du coup, la réplication des « large objects » ne fonctionnera pas. La valeur par défaut de ce paramètre est justement la chaîne vide ('').

Pré-requis pour la répartition de charge

Pour qu'une requête soit répartie, les pré-requis suivants doivent être respectés :

  • Version 7.4 ou ultérieure de PostgreSQL
  • La requête ne doit pas être déclarée explicitement (c'est-à-dire qu'on ne doit pas être dans un bloc BEGIN ~ END)
  • Il ne s'agit pas d'un SELECT nextval ou d'un SELECT setval
  • Il ne s'agit pas d'un SELECT INTO
  • Il ne s'agit pas d'un SELECT FOR UPDATE ou FOR SHARE
  • La requête commence par un SELECT ou COPY TO STDOUT, EXPLAIN, EXPLAIN ANALYZE SELECT... le paramètre ignore_leading_white_space = true permettra d'ignorer tous les éventuels espaces présents avant la requête.

Notez que vous pouvez interdire de manière explicite la répartition d'une charge sur une requête SELECT en ajoutant un commentaire au début de la requête SELECT (quel que ce soit ce commentaire). Par exemple :

  /*REPLICATION*/ SELECT ...

Merci de lire attentivement la page replicate_select au sujet de la réplication. De même, étudiez attentivement ce schéma qui explique comment pgpool-II détermine à quel serveur PostgreSQL envoyer telle ou telle requête.

Attention : le connecteur JDBC a une option autocommit. Si autocommit est à false, le connecteur JDBC envoie un BEGIN et un COMMIT lui-même. Ainsi, pgpool-II ne pourra faire aucune répartition de charge. Vous devez alors appeler setAutoCommit(true) pour activer l'autocommit.

Failover dans le mode Réplication

pgpool-II désactive un serveur « mort » et le service continue, à condition qu'il y ait au moins un serveur PostgreSQL en vie.

Mode Maître-Esclave

Ce mode est utilisé lorsque pgpool-II est couplé avec un autre outil de réplication de type maître/esclave(s) (comme Slony-I ou le Streaming Réplication intégré à PostgreSQL). Cet outil est alors responsable de la réplication des données. L'information sur les serveurs PostgreSQL doit être renseignée (les paramètres backend_hostname, backend_port, backend_weight et backend_data_directory), de la même façon que dans le mode réplication. De plus, il faut paramétrer master_slave_mode et load_balance_mode à true. pgpool-II enverra alors les requêtes qui doivent être répliquées au serveur PostgreSQL maître, et les autres requêtes seront réparties parmi les différents serveurs lorsque c'est possible. L'algorithme de pgpool-II prend bien sûr en compte les requêtes qui ne peuvent être réparties ; elles sont alors systématiquement envoyées au serveur maître.

Dans le mode maître-esclave, les DDL et DML pour une table temporaire ne peuvent être exécutées que sur le serveur maître. Vous pouvez forcer un SELECT à ne s'exécuter que sur le maître en ajoutant un commentaire /*NO LOAD BALANCE*/ devant le SELECT.

Dans le mode maître-esclave, vous devez positionner replication_mode à false et master_slave_mode à true.

Le mode maître-esclave a un sous-mode piloté par le paramètre 'master_slave_sub_mode'. Il vaut par défaut slony et convient si vous utilisez Slony-I. Vous pouvez aussi le paramétrer à stream si vous utilisez le système de réplication intégré à PostgreSQL (le Streaming Replication). Le fichier de configuration d'exemple pour le sous-mode Slony-I est pgpool.conf.sample-master-slave, et celui concernant la Streaming Replication est pgpool.conf.sample-stream.

Vous devez redémarrer pgpool-II si vous changez l'un des paramètres vu précédemment.

Vous devrez probablement aussi renseigner les paramètres white_function_list et black_function_list si vous voulez contrôler plus finement la répartition de charge dans le mode maître-esclave. Reportez-vous à white_function_list pour plus de détails.

Streaming Replication

Comme nous l'avons vu précédemment, pgpool-II peut fonctionner de pair avec la Streaming Replication, qui est disponible depuis la version 9.0 de PostgreSQL. Pour l'utiliser, il faut activer le paramètre master_slave et positionner le paramètre master_slave_sub_mode1 à stream. pgpool-II suppose que le Streaming Replication fonctionne et que les serveurs PostgreSQL esclaves sont en Hot Standby, ce qui signifie que les bases de données sont ouvertes en lecture seule sur ces derniers. Les directives suivantes peuvent être utilisées dans ce mode :

  • delay_threshold

    Permet de spécifier le décalage maximum toléré entre le serveur maître et un serveur esclave dans une réplication, exprimé en octets de journaux de transactions. Si le décalage dépasse delay_threshold, pgpool-II n'envoie alors plus de SELECT au serveur(s) esclave(s). Tout est alors envoyé au serveur maître, même si la répartition de charge est activée, jusqu'à ce que le(s) serveur(s) esclave(s) soit(soient) en deçà du décalage maximum autorisé. Si delay_threshold est à 0 ou si le test de vie est désactivé, ce test de décalage n'est jamais fait. Ce dernier est effectué tous les health_check_period. La valeur par défaut pour delay_threshold est 0. Vous devez recharger la configuration de pgpool-II si vous changez cette directive.

  • log_standby_delay

    Permet de spécifier comment le décalage de réplication est tracé dans le journal applicatif de pgpool-II. Si none est spécifié ici, rien n'est écrit. Si always est spécifié, alors le décalage sera tracé à chaque fois que le test est effectué. Si if_over_threshold est spécifié, alors le décalage est tracé uniquement lorsqu'il dépasse le delay_threshold. La valeur par défaut pour log_standby_delay est none. Vous devez recharger la configuration de pgool-II si vous changez ce paramètre.

    Vous pouvez aussi superviser le décalage éventuel de la réplication en utilisant la commande "show pool_status".

Le failover avec la Streaming Replication

Dans le mode maître/esclave avec la Streaming Replication, si le nœud primaire ou le nœud en attente s'arrête, pgpool-II peut être configuré pour exécuter un Failover. Les nœuds peuvent alors être attachés automatiquement sans configuration ou opérations complémentaires. Alors qu'il est en pleine réplication [~], le nœud en attente vérifie régulièrement si un fichier de déclenchement existe. S'il le trouve, le nœud en attente sort de son mode réplication et s'ouvre en mode lecture/écriture. En utilisant ce mécanisme, on peut avoir une base de données en attente qui prends le relais quand le nœud primaire tombe.

Attention : si vous pensez utiliser plusieurs nœuds en mode standby, il est recommandé de définir le paramètre delay_threshold pour empêcher tout requête dirigée vers d'autres nœuds en standby de récupérer des données plus vieilles.

Si un second nœud en standby prends le relais quand le premier nœud en standby avait déjà pris le relais, vous pourriez avoir des données erronnées en provenance du second standby. Nous vous recommandons de ne pas utiliser ce genre de configuration.

Voici commment configurer un mécanisme de Failover.

  1. Il faut créer un script de Failover quelque part sur le système, par exemple dans /usr/local/pgsql/bin, puis le rendre exécutable.
    $ cd /usr/loca/pgsql/bin
    $ cat failover_stream.sh
    #! /bin/sh
    # Commandes pour faire un Failover en mode Streaming Replication
    # Ce script suppose que le nœud Maitre est le 0 et 1 le standby
    # 
    # Si le Standby s'arrête, ne rien faire. Si le Primaire s'arrête, créer
    # un fichier de déclenchement afin que le standby prenne le relais sur le 
    # nœud Primaire.
    #
    # Arguments: 
    #   $1: identifiant du nœud qui ne répond plus
    #   $2: nom d'hôte du nouveau maître 
    #   $3: chemin vers le fichier trigger 
    
    failed_node=$1
    new_master=$2
    trigger_file=$3
    
    # Ne rien faire si c'est le standby qui tombe
    if [ $failed_node = 1 ]; then
    	exit 0;
    fi
    
    # Créer un fichier de déclenchement
    /usr/bin/ssh -T $new_master /bin/touch $trigger_file
    
    exit 0;
    
    chmod 755 failover_stream.sh
    
  2. Il faut à présent définir la commande failover_commmand dans le fichier pgpool.conf :
    failover_command = '/usr/local/src/pgsql/9.0-beta/bin/failover_stream.sh %d %H /tmp/trigger_file0'
    
  3. Et créer le fichier recovery.conf sur le nœud en standby. Un exemple de fichier recovery.conf est disponible dans le répertoire d'installation de PostgreSQL. Son nom complet est "share/recovery.conf.sample". Copier recovery.conf.sample en recovery.conf dans le répertoire de base de PostgreSQL et l'éditer comme suit.
    standby_mode = 'on'
    primary_conninfo = 'host=nom_du_nœud_primaire user=postgres'
    trigger_file = '/tmp/trigger_file0'
    
  4. Ajuster le postgresql.conf sur le nœud primaire. La configuration ci-dessous est donneé à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
    wal_level = hot_standby
    max_wal_senders = 1
    
  5. Définir pg_hba.conf sur le nœud Primaire. La configuration ci-dessous est donnée à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
    host	replication	postgres		192.168.0.10/32		trust
    

Démarrez PostgreSQL sur les nœuds primaire et secondaire pour initialiser la réplication. Si le nœud primaire venait à tomber, le nœud secondaire prendra automatiquement le relais, en tant que nouveau nœud primaire, et sera alors prêt à recevoir les requêtes en écriture.

Streaming Replication

Lorsqu'on utilise la Streaming Replication et le Hot Standby, il est important de déterminer les requêtes pouvant être envoyées sur le nœud principal ou sur le nœud en standby (secondaire), et les requêtes qui ne peuvent pas l'être. Le mode Streaming Replication de pgpool-II se charge complètement de cette problématique. Dans ce chapitre, nous expliquerons comment pgpool-II parvient à cela.

Nous distinguons les requêtes qui devraient être envoyées à tel ou tel nœud en les examinant.

  • Les requêtes suivantes devraient être envoyées au nœud primaire uniquement :
    • INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE, CREATE, DROP, ALTER, COMMENT
    • SELECT ... FOR SHARE | UPDATE
    • SELECT dans un niveau d'isolation transactionnel de type SERIALIZABLE
    • LOCK, commande plus stricte que ROW EXCLUSIVE MODE
    • Quelques commandes transactionnelles :
      • BEGIN READ WRITE, START TRANSACTION READ WRITE
      • SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE
      • SET transaction_read_only = off
    • Les commandes relatives à la validation en deux phases : PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED
    • LISTEN, UNLISTEN, NOTIFY
    • VACUUM
    • Quelques fonctions liées aux séquences (nextval et setval)
    • Les commandes de création de « Large Objects »
  • Ces requêtes peuvent être envoyées à la fois au nœud primaire et au nœud en standby. Si la répartition de charge est activée, ce type de requêtes peut être envoyé au nœud en standby. Cependant, si le paramètre delay_threshold est défini et que le délai dans la réplication est supérieur au delay_threshold, les requêtes sont envoyées au nœud primaire.
    • tout SELECT non listé ci-dessus
    • COPY TO
    • DECLARE, FETCH, CLOSE
    • SHOW
  • Les requêtes suivantes sont envoyées à la fois au nœud primaire et secondaire :
    • SET
    • DISCARD
    • DEALLOCATE ALL

Dans une transaction explicite :

  • Toute transaction commençant par une commande comme BEGIN est envoyée au nœud primaire.
  • Tout SELECT qui survient immédiatement après, ainsi que toutes les requêtes qui peuvent être envoyées aussi bien au primaire qu'au secondaire, sont réparties entre les nœuds.
  • Toute commande qui ne peut être exécutée sur un nœud en standby (secondaire) comme un INSERT sont envoyées uniquement au primaire. Après toute commande de ce type, absolument tous les ordres SQL sont envoyés au nœud primaire. En effet, les SELECT suivant pourraient vouloir voir les résultats d'un INSERT immédiatement. Ce comportement continue jusqu'à ce que la transaction se ferme ou soit interrompue.

Dans le protocole étendu, il est possible de déterminer si la requête peut être envoyée au nœud en standby ou pas dans le mode de répartition de charge au moment où on analyse la requête. Les rêgles sont les mêmes que dans le protocole non-étendu. Par exemple, les INSERT sont envoyés au primaire, ainsi que toute requête qui suivra.

Note : si l'analyse d'une requête en SELECT est envoyée sur le standby à cause de la répartition de charge et qu'une requête en modification de données, comme un INSERT est envoyé à pgpool-II, alors le SELECT analysé devra être exécuté sur le nœud primaire. Cependant, on analyse de nouveau le SELECT sur le nœud primaire.

Enfin, les requêtes qui semblent douteuses ou possiblement en erreur sont envoyées sur le nœud primaire.

Online recovery avec la Streaming Replication

Dans le mode maître/esclave avec la Streaming Replication, on peut procéder à une restauration à chaud (« Online recovery »). Cependant, seul un nœud en standby peut être ainsi récupéré. On ne peut pas reconstruire un nœud primaire. Pour ce faire, il faudra stopper toutes les bases de données, ainsi que pgpool-II, puis restaurer le nœud primaire à partir d'une sauvegarde.

Voici les étapes.

  1. Définir le paramètre recovery_user. C'est s1e object » sur tous les serveurs PostgreSQL lorsque pgpool-II est dans le mode réplication. Notez que PostgreSQL 8.0 et ultérieur n'a plus de fonction lo_create. Du coup, cette fonctionalité est pas utilisable pour ces versions.

    Un appel à la fonction de la libpq lo_creat() utilisera cette fonctionalité. De même, la création de « large objects » via l'API Java (driver JDBC) devrait fonctionner, tout comme l'API PHP (pg_lo_create, ou API similaire dans la bibliothèque de PHP, comme PDO), et ce genre d'API similaires dans plusieurs langages de programmation qui sont réputées pour utiliser un protocole similaire.

    Les opérations suivantes de création d'un « large object » ne fonctionneront pas :

    • lo_create de la libpq
    • l'API d'un langage qui utilise lo_create
    • la fonction lo_import dans le serveur PostgreSQL
    • SELECT lo_creat

    Peu importe le schéma où est stockée la table lobj_lock_table, celle-ci doit en revanche être accessible en écriture à tous les utilisateurs. Voici un exemple de création d'une telle table :

    CREATE TABLE public.my_lock_table ();
    GRANT ALL ON public.my_lock_table TO PUBLIC;
    

    La table spécifiée par lobj_lock_table doit être créée à l'avance. Vous pouvez par exemple la créer dans la base template1 afin que toute base de données créée par la suite en dispose.

    Si lobj_lock_table contient une chaîne vide (''), la fonctionalité est désactivée. Du coup, la réplication des « large objects » ne fonctionnera pas. La valeur par défaut de ce paramètre est justement la chaîne vide ('').

    Pré-requis pour la répartition de charge

    Pour qu'une requête soit répartie, les pré-requis suivants doivent être respectés :

    • Version 7.4 ou ultérieure de PostgreSQL
    • La requête ne doit pas être déclarée explicitement (c'est-à-dire qu'on ne doit pas être dans un bloc BEGIN ~ END)
    • Il ne s'agit pas d'un SELECT nextval ou d'un SELECT setval
    • Il ne s'agit pas d'un SELECT INTO
    • Il ne s'agit pas d'un SELECT FOR UPDATE ou FOR SHARE
    • La requête commence par un SELECT ou COPY TO STDOUT, EXPLAIN, EXPLAIN ANALYZE SELECT... le paramètre ignore_leading_white_space = true permettra d'ignorer tous les éventuels espaces présents avant la requête.

    Notez que vous pouvez interdire de manière explicite la répartition d'une charge sur une requête SELECT en ajoutant un commentaire au début de la requête SELECT (quel que ce soit ce commentaire). Par exemple :

      /*REPLICATION*/ SELECT ...
    

    Merci de lire attentivement la page replicate_select au sujet de la réplication. De même, étudiez attentivement ce schéma qui explique comment pgpool-II détermine à quel serveur PostgreSQL envoyer telle ou telle requête.

    Attention : le connecteur JDBC a une option autocommit. Si autocommit est à false, le connecteur JDBC envoie un BEGIN et un COMMIT lui-même. Ainsi, pgpool-II ne pourra faire aucune répartition de charge. Vous devez alors appeler setAutoCommit(true) pour activer l'autocommit.

    Failover dans le mode Réplication

    pgpool-II désactive un serveur « mort » et le service continue, à condition qu'il y ait au moins un serveur PostgreSQL en vie.

    Mode Maître-Esclave

    Ce mode est utilisé lorsque pgpool-II est couplé avec un autre outil de réplication de type maître/esclave(s) (comme Slony-I ou le Streaming Réplication intégré à PostgreSQL). Cet outil est alors responsable de la réplication des données. L'information sur les serveurs PostgreSQL doit être renseignée (les paramètres backend_hostname, backend_port, backend_weight et backend_data_directory), de la même façon que dans le mode réplication. De plus, il faut paramétrer master_slave_mode et load_balance_mode à true. pgpool-II enverra alors les requêtes qui doivent être répliquées au serveur PostgreSQL maître, et les autres requêtes seront réparties parmi les différents serveurs lorsque c'est possible. L'algorithme de pgpool-II prend bien sûr en compte les requêtes qui ne peuvent être réparties ; elles sont alors systématiquement envoyées au serveur maître.

    Dans le mode maître-esclave, les DDL et DML pour une table temporaire ne peuvent être exécutées que sur le serveur maître. Vous pouvez forcer un SELECT à ne s'exécuter que sur le maître en ajoutant un commentaire /*NO LOAD BALANCE*/ devant le SELECT.

    Dans le mode maître-esclave, vous devez positionner replication_mode à false et master_slave_mode à true.

    Le mode maître-esclave a un sous-mode piloté par le paramètre 'master_slave_sub_mode'. Il vaut par défaut slony et convient si vous utilisez Slony-I. Vous pouvez aussi le paramétrer à stream si vous utilisez le système de réplication intégré à PostgreSQL (le Streaming Replication). Le fichier de configuration d'exemple pour le sous-mode Slony-I est pgpool.conf.sample-master-slave, et celui concernant la Streaming Replication est pgpool.conf.sample-stream.

    Vous devez redémarrer pgpool-II si vous changez l'un des paramètres vu précédemment.

    Vous devrez probablement aussi renseigner les paramètres white_function_list et black_function_list si vous voulez contrôler plus finement la répartition de charge dans le mode maître-esclave. Reportez-vous à white_function_list pour plus de détails.

    Streaming Replication

    Comme nous l'avons vu précédemment, pgpool-II peut fonctionner de pair avec la Streaming Replication, qui est disponible depuis la version 9.0 de PostgreSQL. Pour l'utiliser, il faut activer le paramètre master_slave et positionner le paramètre master_slave_sub_mode1 à stream. pgpool-II suppose que le Streaming Replication fonctionne et que les serveurs PostgreSQL esclaves sont en Hot Standby, ce qui signifie que les bases de données sont ouvertes en lecture seule sur ces derniers. Les directives suivantes peuvent être utilisées dans ce mode :

    • delay_threshold

      Permet de spécifier le décalage maximum toléré entre le serveur maître et un serveur esclave dans une réplication, exprimé en octets de journaux de transactions. Si le décalage dépasse delay_threshold, pgpool-II n'envoie alors plus de SELECT au serveur(s) esclave(s). Tout est alors envoyé au serveur maître, même si la répartition de charge est activée, jusqu'à ce que le(s) serveur(s) esclave(s) soit(soient) en deçà du décalage maximum autorisé. Si delay_threshold est à 0 ou si le test de vie est désactivé, ce test de décalage n'est jamais fait. Ce dernier est effectué tous les health_check_period. La valeur par défaut pour delay_threshold est 0. Vous devez recharger la configuration de pgpool-II si vous changez cette directive.

    • log_standby_delay

      Permet de spécifier comment le décalage de réplication est tracé dans le journal applicatif de pgpool-II. Si none est spécifié ici, rien n'est écrit. Si always est spécifié, alors le décalage sera tracé à chaque fois que le test est effectué. Si if_over_threshold est spécifié, alors le décalage est tracé uniquement lorsqu'il dépasse le delay_threshold. La valeur par défaut pour log_standby_delay est none. Vous devez recharger la configuration de pgool-II si vous changez ce paramètre.

      Vous pouvez aussi superviser le décalage éventuel de la réplication en utilisant la commande "show pool_status".

    Le failover avec la Streaming Replication

    Dans le mode maître/esclave avec la Streaming Replication, si le nœud primaire ou le nœud en attente s'arrête, pgpool-II peut être configuré pour exécuter un Failover. Les nœuds peuvent alors être attachés automatiquement sans configuration ou opérations complémentaires. Alors qu'il est en pleine réplication [~], le nœud en attente vérifie régulièrement si un fichier de déclenchement existe. S'il le trouve, le nœud en attente sort de son mode réplication et s'ouvre en mode lecture/écriture. En utilisant ce mécanisme, on peut avoir une base de données en attente qui prends le relais quand le nœud primaire tombe.

    Attention : si vous pensez utiliser plusieurs nœuds en mode standby, il est recommandé de définir le paramètre delay_threshold pour empêcher tout requête dirigée vers d'autres nœuds en standby de récupérer des données plus vieilles.

    Si un second nœud en standby prends le relais quand le premier nœud en standby avait déjà pris le relais, vous pourriez avoir des données erronnées en provenance du second standby. Nous vous recommandons de ne pas utiliser ce genre de configuration.

    Voici commment configurer un mécanisme de Failover.

    1. Il faut créer un script de Failover quelque part sur le système, par exemple dans /usr/local/pgsql/bin, puis le rendre exécutable.
      $ cd /usr/loca/pgsql/bin
      $ cat failover_stream.sh
      #! /bin/sh
      # Commandes pour faire un Failover en mode Streaming Replication
      # Ce script suppose que le nœud Maitre est le 0 et 1 le standby
      # 
      # Si le Standby s'arrête, ne rien faire. Si le Primaire s'arrête, créer
      # un fichier de déclenchement afin que le standby prenne le relais sur le 
      # nœud Primaire.
      #
      # Arguments: 
      #   $1: identifiant du nœud qui ne répond plus
      #   $2: nom d'hôte du nouveau maître 
      #   $3: chemin vers le fichier trigger 
      
      failed_node=$1
      new_master=$2
      trigger_file=$3
      
      # Ne rien faire si c'est le standby qui tombe
      if [ $failed_node = 1 ]; then
      	exit 0;
      fi
      
      # Créer un fichier de déclenchement
      /usr/bin/ssh -T $new_master /bin/touch $trigger_file
      
      exit 0;
      
      chmod 755 failover_stream.sh
      
    2. Il faut à présent définir la commande failover_commmand dans le fichier pgpool.conf :
      failover_command = '/usr/local/src/pgsql/9.0-beta/bin/failover_stream.sh %d %H /tmp/trigger_file0'
      
    3. Et créer le fichier recovery.conf sur le nœud en standby. Un exemple de fichier recovery.conf est disponible dans le répertoire d'installation de PostgreSQL. Son nom complet est "share/recovery.conf.sample". Copier recovery.conf.sample en recovery.conf dans le répertoire de base de PostgreSQL et l'éditer comme suit.
      standby_mode = 'on'
      primary_conninfo = 'host=nom_du_nœud_primaire user=postgres'
      trigger_file = '/tmp/trigger_file0'
      
    4. Ajuster le postgresql.conf sur le nœud primaire. La configuration ci-dessous est donneé à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
      wal_level = hot_standby
      max_wal_senders = 1
      
    5. Définir pg_hba.conf sur le nœud Primaire. La configuration ci-dessous est donnée à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
      host	replication	postgres		192.168.0.10/32		trust
      

    Démarrez PostgreSQL sur les nœuds primaire et secondaire pour initialiser la réplication. Si le nœud primaire venait à tomber, le nœud secondaire prendra automatiquement le relais, en tant que nouveau nœud primaire, et sera alors prêt à recevoir les requêtes en écriture.

    Streaming Replication

    Lorsqu'on utilise la Streaming Replication et le Hot Standby, il est important de déterminer les requêtes pouvant être envoyées sur le nœud principal ou sur le nœud en standby (secondaire), et les requêtes qui ne peuvent pas l'être. Le mode Streaming Replication de pgpool-II se charge complètement de cette problématique. Dans ce chapitre, nous expliquerons comment pgpool-II parvient à cela.

    Nous distinguons les requêtes qui devraient être envoyées à tel ou tel nœud en les examinant.

    • Les requêtes suivantes devraient être envoyées au nœud primaire uniquement :
      • INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE, CREATE, DROP, ALTER, COMMENT
      • SELECT ... FOR SHARE | UPDATE
      • SELECT dans un niveau d'isolation transactionnel de type SERIALIZABLE
      • LOCK, commande plus stricte que ROW EXCLUSIVE MODE
      • Quelques commandes transactionnelles :
        • BEGIN READ WRITE, START TRANSACTION READ WRITE
        • SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE
        • SET transaction_read_only = off
      • Les commandes relatives à la validation en deux phases : PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED
      • LISTEN, UNLISTEN, NOTIFY
      • VACUUM
      • Quelques fonctions liées aux séquences (nextval et setval)
      • Les commandes de création de « Large Objects »
    • Ces requêtes peuvent être envoyées à la fois au nœud primaire et au nœud en standby. Si la répartition de charge est activée, ce type de requêtes peut être envoyé au nœud en standby. Cependant, si le paramètre delay_threshold est défini et que le délai dans la réplication est supérieur au delay_threshold, les requêtes sont envoyées au nœud primaire.
      • tout SELECT non listé ci-dessus
      • COPY TO
      • DECLARE, FETCH, CLOSE
      • SHOW
    • Les requêtes suivantes sont envoyées à la fois au nœud primaire et secondaire :
      • SET
      • DISCARD
      • DEALLOCATE ALL

    Dans une transaction explicite :

    • Toute transaction commençant par une commande comme BEGIN est envoyée au nœud primaire.
    • Tout SELECT qui survient immédiatement après, ainsi que toutes les requêtes qui peuvent être envoyées aussi bien au primaire qu'au secondaire, sont réparties entre les nœuds.
    • Toute commande qui ne peut être exécutée sur un nœud en standby (secondaire) comme un INSERT sont envoyées uniquement au primaire. Après toute commande de ce type, absolument tous les ordres SQL sont envoyés au nœud primaire. En effet, les SELECT suivant pourraient vouloir voir les résultats d'un INSERT immédiatement. Ce comportement continue jusqu'à ce que la transaction se ferme ou soit interrompue.

    Dans le protocole étendu, il est possible de déterminer si la requête peut être envoyée au nœud en standby ou pas dans le mode de répartition de charge au moment où on analyse la requête. Les rêgles sont les mêmes que dans le protocole non-étendu. Par exemple, les INSERT sont envoyés au primaire, ainsi que toute requête qui suivra.

    Note : si l'analyse d'une requête en SELECT est envoyée sur le standby à cause de la répartition de charge et qu'une requête en modification de données, comme un INSERT est envoyé à pgpool-II, alors le SELECT analysé devra être exécuté sur le nœud primaire. Cependant, on analyse de nouveau le SELECT sur le nœud primaire.

    Enfin, les requêtes qui semblent douteuses ou possiblement en erreur sont envoyées sur le nœud primaire.

    Online recovery avec la Streaming Replication

    Dans le mode maître/esclave avec la Streaming Replication, on peut procéder à une restauration à chaud (« Online recovery »). Cependant, seul un nœud en standby peut être ainsi récupéré. On ne peut pas reconstruire un nœud primaire. Pour ce faire, il faudra stopper toutes les bases de données, ainsi que pgpool-II, puis restaurer le nœud primaire à partir d'une sauvegarde.

    Voici les étapes.

    1. Définir le paramètre recovery_user. C'est s1e object » sur tous les serveurs PostgreSQL lorsque pgpool-II est dans le mode réplication. Notez que PostgreSQL 8.0 et ultérieur n'a plus de fonction lo_create. Du coup, cette fonctionalité est pas utilisable pour ces versions.

      Un appel à la fonction de la libpq lo_creat() utilisera cette fonctionalité. De même, la création de « large objects » via l'API Java (driver JDBC) devrait fonctionner, tout comme l'API PHP (pg_lo_create, ou API similaire dans la bibliothèque de PHP, comme PDO), et ce genre d'API similaires dans plusieurs langages de programmation qui sont réputées pour utiliser un protocole similaire.

      Les opérations suivantes de création d'un « large object » ne fonctionneront pas :

      • lo_create de la libpq
      • l'API d'un langage qui utilise lo_create
      • la fonction lo_import dans le serveur PostgreSQL
      • SELECT lo_creat

      Peu importe le schéma où est stockée la table lobj_lock_table, celle-ci doit en revanche être accessible en écriture à tous les utilisateurs. Voici un exemple de création d'une telle table :

      CREATE TABLE public.my_lock_table ();
      GRANT ALL ON public.my_lock_table TO PUBLIC;
      

      La table spécifiée par lobj_lock_table doit être créée à l'avance. Vous pouvez par exemple la créer dans la base template1 afin que toute base de données créée par la suite en dispose.

      Si lobj_lock_table contient une chaîne vide (''), la fonctionalité est désactivée. Du coup, la réplication des « large objects » ne fonctionnera pas. La valeur par défaut de ce paramètre est justement la chaîne vide ('').

      Pré-requis pour la répartition de charge

      Pour qu'une requête soit répartie, les pré-requis suivants doivent être respectés :

      • Version 7.4 ou ultérieure de PostgreSQL
      • La requête ne doit pas être déclarée explicitement (c'est-à-dire qu'on ne doit pas être dans un bloc BEGIN ~ END)
      • Il ne s'agit pas d'un SELECT nextval ou d'un SELECT setval
      • Il ne s'agit pas d'un SELECT INTO
      • Il ne s'agit pas d'un SELECT FOR UPDATE ou FOR SHARE
      • La requête commence par un SELECT ou COPY TO STDOUT, EXPLAIN, EXPLAIN ANALYZE SELECT... le paramètre ignore_leading_white_space = true permettra d'ignorer tous les éventuels espaces présents avant la requête.

      Notez que vous pouvez interdire de manière explicite la répartition d'une charge sur une requête SELECT en ajoutant un commentaire au début de la requête SELECT (quel que ce soit ce commentaire). Par exemple :

        /*REPLICATION*/ SELECT ...
      

      Merci de lire attentivement la page replicate_select au sujet de la réplication. De même, étudiez attentivement ce schéma qui explique comment pgpool-II détermine à quel serveur PostgreSQL envoyer telle ou telle requête.

      Attention : le connecteur JDBC a une option autocommit. Si autocommit est à false, le connecteur JDBC envoie un BEGIN et un COMMIT lui-même. Ainsi, pgpool-II ne pourra faire aucune répartition de charge. Vous devez alors appeler setAutoCommit(true) pour activer l'autocommit.

      Failover dans le mode Réplication

      pgpool-II désactive un serveur « mort » et le service continue, à condition qu'il y ait au moins un serveur PostgreSQL en vie.

      Mode Maître-Esclave

      Ce mode est utilisé lorsque pgpool-II est couplé avec un autre outil de réplication de type maître/esclave(s) (comme Slony-I ou le Streaming Réplication intégré à PostgreSQL). Cet outil est alors responsable de la réplication des données. L'information sur les serveurs PostgreSQL doit être renseignée (les paramètres backend_hostname, backend_port, backend_weight et backend_data_directory), de la même façon que dans le mode réplication. De plus, il faut paramétrer master_slave_mode et load_balance_mode à true. pgpool-II enverra alors les requêtes qui doivent être répliquées au serveur PostgreSQL maître, et les autres requêtes seront réparties parmi les différents serveurs lorsque c'est possible. L'algorithme de pgpool-II prend bien sûr en compte les requêtes qui ne peuvent être réparties ; elles sont alors systématiquement envoyées au serveur maître.

      Dans le mode maître-esclave, les DDL et DML pour une table temporaire ne peuvent être exécutées que sur le serveur maître. Vous pouvez forcer un SELECT à ne s'exécuter que sur le maître en ajoutant un commentaire /*NO LOAD BALANCE*/ devant le SELECT.

      Dans le mode maître-esclave, vous devez positionner replication_mode à false et master_slave_mode à true.

      Le mode maître-esclave a un sous-mode piloté par le paramètre 'master_slave_sub_mode'. Il vaut par défaut slony et convient si vous utilisez Slony-I. Vous pouvez aussi le paramétrer à stream si vous utilisez le système de réplication intégré à PostgreSQL (le Streaming Replication). Le fichier de configuration d'exemple pour le sous-mode Slony-I est pgpool.conf.sample-master-slave, et celui concernant la Streaming Replication est pgpool.conf.sample-stream.

      Vous devez redémarrer pgpool-II si vous changez l'un des paramètres vu précédemment.

      Vous devrez probablement aussi renseigner les paramètres white_function_list et black_function_list si vous voulez contrôler plus finement la répartition de charge dans le mode maître-esclave. Reportez-vous à white_function_list pour plus de détails.

      Streaming Replication

      Comme nous l'avons vu précédemment, pgpool-II peut fonctionner de pair avec la Streaming Replication, qui est disponible depuis la version 9.0 de PostgreSQL. Pour l'utiliser, il faut activer le paramètre master_slave et positionner le paramètre master_slave_sub_mode1 à stream. pgpool-II suppose que le Streaming Replication fonctionne et que les serveurs PostgreSQL esclaves sont en Hot Standby, ce qui signifie que les bases de données sont ouvertes en lecture seule sur ces derniers. Les directives suivantes peuvent être utilisées dans ce mode :

      • delay_threshold

        Permet de spécifier le décalage maximum toléré entre le serveur maître et un serveur esclave dans une réplication, exprimé en octets de journaux de transactions. Si le décalage dépasse delay_threshold, pgpool-II n'envoie alors plus de SELECT au serveur(s) esclave(s). Tout est alors envoyé au serveur maître, même si la répartition de charge est activée, jusqu'à ce que le(s) serveur(s) esclave(s) soit(soient) en deçà du décalage maximum autorisé. Si delay_threshold est à 0 ou si le test de vie est désactivé, ce test de décalage n'est jamais fait. Ce dernier est effectué tous les health_check_period. La valeur par défaut pour delay_threshold est 0. Vous devez recharger la configuration de pgpool-II si vous changez cette directive.

      • log_standby_delay

        Permet de spécifier comment le décalage de réplication est tracé dans le journal applicatif de pgpool-II. Si none est spécifié ici, rien n'est écrit. Si always est spécifié, alors le décalage sera tracé à chaque fois que le test est effectué. Si if_over_threshold est spécifié, alors le décalage est tracé uniquement lorsqu'il dépasse le delay_threshold. La valeur par défaut pour log_standby_delay est none. Vous devez recharger la configuration de pgool-II si vous changez ce paramètre.

        Vous pouvez aussi superviser le décalage éventuel de la réplication en utilisant la commande "show pool_status".

      Le failover avec la Streaming Replication

      Dans le mode maître/esclave avec la Streaming Replication, si le nœud primaire ou le nœud en attente s'arrête, pgpool-II peut être configuré pour exécuter un Failover. Les nœuds peuvent alors être attachés automatiquement sans configuration ou opérations complémentaires. Alors qu'il est en pleine réplication [~], le nœud en attente vérifie régulièrement si un fichier de déclenchement existe. S'il le trouve, le nœud en attente sort de son mode réplication et s'ouvre en mode lecture/écriture. En utilisant ce mécanisme, on peut avoir une base de données en attente qui prends le relais quand le nœud primaire tombe.

      Attention : si vous pensez utiliser plusieurs nœuds en mode standby, il est recommandé de définir le paramètre delay_threshold pour empêcher tout requête dirigée vers d'autres nœuds en standby de récupérer des données plus vieilles.

      Si un second nœud en standby prends le relais quand le premier nœud en standby avait déjà pris le relais, vous pourriez avoir des données erronnées en provenance du second standby. Nous vous recommandons de ne pas utiliser ce genre de configuration.

      Voici commment configurer un mécanisme de Failover.

      1. Il faut créer un script de Failover quelque part sur le système, par exemple dans /usr/local/pgsql/bin, puis le rendre exécutable.
        $ cd /usr/loca/pgsql/bin
        $ cat failover_stream.sh
        #! /bin/sh
        # Commandes pour faire un Failover en mode Streaming Replication
        # Ce script suppose que le nœud Maitre est le 0 et 1 le standby
        # 
        # Si le Standby s'arrête, ne rien faire. Si le Primaire s'arrête, créer
        # un fichier de déclenchement afin que le standby prenne le relais sur le 
        # nœud Primaire.
        #
        # Arguments: 
        #   $1: identifiant du nœud qui ne répond plus
        #   $2: nom d'hôte du nouveau maître 
        #   $3: chemin vers le fichier trigger 
        
        failed_node=$1
        new_master=$2
        trigger_file=$3
        
        # Ne rien faire si c'est le standby qui tombe
        if [ $failed_node = 1 ]; then
        	exit 0;
        fi
        
        # Créer un fichier de déclenchement
        /usr/bin/ssh -T $new_master /bin/touch $trigger_file
        
        exit 0;
        
        chmod 755 failover_stream.sh
        
      2. Il faut à présent définir la commande failover_commmand dans le fichier pgpool.conf :
        failover_command = '/usr/local/src/pgsql/9.0-beta/bin/failover_stream.sh %d %H /tmp/trigger_file0'
        
      3. Et créer le fichier recovery.conf sur le nœud en standby. Un exemple de fichier recovery.conf est disponible dans le répertoire d'installation de PostgreSQL. Son nom complet est "share/recovery.conf.sample". Copier recovery.conf.sample en recovery.conf dans le répertoire de base de PostgreSQL et l'éditer comme suit.
        standby_mode = 'on'
        primary_conninfo = 'host=nom_du_nœud_primaire user=postgres'
        trigger_file = '/tmp/trigger_file0'
        
      4. Ajuster le postgresql.conf sur le nœud primaire. La configuration ci-dessous est donneé à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
        wal_level = hot_standby
        max_wal_senders = 1
        
      5. Définir pg_hba.conf sur le nœud Primaire. La configuration ci-dessous est donnée à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
        host	replication	postgres		192.168.0.10/32		trust
        

      Démarrez PostgreSQL sur les nœuds primaire et secondaire pour initialiser la réplication. Si le nœud primaire venait à tomber, le nœud secondaire prendra automatiquement le relais, en tant que nouveau nœud primaire, et sera alors prêt à recevoir les requêtes en écriture.

      Streaming Replication

      Lorsqu'on utilise la Streaming Replication et le Hot Standby, il est important de déterminer les requêtes pouvant être envoyées sur le nœud principal ou sur le nœud en standby (secondaire), et les requêtes qui ne peuvent pas l'être. Le mode Streaming Replication de pgpool-II se charge complètement de cette problématique. Dans ce chapitre, nous expliquerons comment pgpool-II parvient à cela.

      Nous distinguons les requêtes qui devraient être envoyées à tel ou tel nœud en les examinant.

      • Les requêtes suivantes devraient être envoyées au nœud primaire uniquement :
        • INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE, CREATE, DROP, ALTER, COMMENT
        • SELECT ... FOR SHARE | UPDATE
        • SELECT dans un niveau d'isolation transactionnel de type SERIALIZABLE
        • LOCK, commande plus stricte que ROW EXCLUSIVE MODE
        • Quelques commandes transactionnelles :
          • BEGIN READ WRITE, START TRANSACTION READ WRITE
          • SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE
          • SET transaction_read_only = off
        • Les commandes relatives à la validation en deux phases : PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED
        • LISTEN, UNLISTEN, NOTIFY
        • VACUUM
        • Quelques fonctions liées aux séquences (nextval et setval)
        • Les commandes de création de « Large Objects »
      • Ces requêtes peuvent être envoyées à la fois au nœud primaire et au nœud en standby. Si la répartition de charge est activée, ce type de requêtes peut être envoyé au nœud en standby. Cependant, si le paramètre delay_threshold est défini et que le délai dans la réplication est supérieur au delay_threshold, les requêtes sont envoyées au nœud primaire.
        • tout SELECT non listé ci-dessus
        • COPY TO
        • DECLARE, FETCH, CLOSE
        • SHOW
      • Les requêtes suivantes sont envoyées à la fois au nœud primaire et secondaire :
        • SET
        • DISCARD
        • DEALLOCATE ALL

      Dans une transaction explicite :

      • Toute transaction commençant par une commande comme BEGIN est envoyée au nœud primaire.
      • Tout SELECT qui survient immédiatement après, ainsi que toutes les requêtes qui peuvent être envoyées aussi bien au primaire qu'au secondaire, sont réparties entre les nœuds.
      • Toute commande qui ne peut être exécutée sur un nœud en standby (secondaire) comme un INSERT sont envoyées uniquement au primaire. Après toute commande de ce type, absolument tous les ordres SQL sont envoyés au nœud primaire. En effet, les SELECT suivant pourraient vouloir voir les résultats d'un INSERT immédiatement. Ce comportement continue jusqu'à ce que la transaction se ferme ou soit interrompue.

      Dans le protocole étendu, il est possible de déterminer si la requête peut être envoyée au nœud en standby ou pas dans le mode de répartition de charge au moment où on analyse la requête. Les rêgles sont les mêmes que dans le protocole non-étendu. Par exemple, les INSERT sont envoyés au primaire, ainsi que toute requête qui suivra.

      Note : si l'analyse d'une requête en SELECT est envoyée sur le standby à cause de la répartition de charge et qu'une requête en modification de données, comme un INSERT est envoyé à pgpool-II, alors le SELECT analysé devra être exécuté sur le nœud primaire. Cependant, on analyse de nouveau le SELECT sur le nœud primaire.

      Enfin, les requêtes qui semblent douteuses ou possiblement en erreur sont envoyées sur le nœud primaire.

      Online recovery avec la Streaming Replication

      Dans le mode maître/esclave avec la Streaming Replication, on peut procéder à une restauration à chaud (« Online recovery »). Cependant, seul un nœud en standby peut être ainsi récupéré. On ne peut pas reconstruire un nœud primaire. Pour ce faire, il faudra stopper toutes les bases de données, ainsi que pgpool-II, puis restaurer le nœud primaire à partir d'une sauvegarde.

      Voici les étapes.

      1. Définir le paramètre recovery_user. C'est s1e object » sur tous les serveurs PostgreSQL lorsque pgpool-II est dans le mode réplication. Notez que PostgreSQL 8.0 et ultérieur n'a plus de fonction lo_create. Du coup, cette fonctionalité est pas utilisable pour ces versions.

        Un appel à la fonction de la libpq lo_creat() utilisera cette fonctionalité. De même, la création de « large objects » via l'API Java (driver JDBC) devrait fonctionner, tout comme l'API PHP (pg_lo_create, ou API similaire dans la bibliothèque de PHP, comme PDO), et ce genre d'API similaires dans plusieurs langages de programmation qui sont réputées pour utiliser un protocole similaire.

        Les opérations suivantes de création d'un « large object » ne fonctionneront pas :

        • lo_create de la libpq
        • l'API d'un langage qui utilise lo_create
        • la fonction lo_import dans le serveur PostgreSQL
        • SELECT lo_creat

        Peu importe le schéma où est stockée la table lobj_lock_table, celle-ci doit en revanche être accessible en écriture à tous les utilisateurs. Voici un exemple de création d'une telle table :

        CREATE TABLE public.my_lock_table ();
        GRANT ALL ON public.my_lock_table TO PUBLIC;
        

        La table spécifiée par lobj_lock_table doit être créée à l'avance. Vous pouvez par exemple la créer dans la base template1 afin que toute base de données créée par la suite en dispose.

        Si lobj_lock_table contient une chaîne vide (''), la fonctionalité est désactivée. Du coup, la réplication des « large objects » ne fonctionnera pas. La valeur par défaut de ce paramètre est justement la chaîne vide ('').

        Pré-requis pour la répartition de charge

        Pour qu'une requête soit répartie, les pré-requis suivants doivent être respectés :

        • Version 7.4 ou ultérieure de PostgreSQL
        • La requête ne doit pas être déclarée explicitement (c'est-à-dire qu'on ne doit pas être dans un bloc BEGIN ~ END)
        • Il ne s'agit pas d'un SELECT nextval ou d'un SELECT setval
        • Il ne s'agit pas d'un SELECT INTO
        • Il ne s'agit pas d'un SELECT FOR UPDATE ou FOR SHARE
        • La requête commence par un SELECT ou COPY TO STDOUT, EXPLAIN, EXPLAIN ANALYZE SELECT... le paramètre ignore_leading_white_space = true permettra d'ignorer tous les éventuels espaces présents avant la requête.

        Notez que vous pouvez interdire de manière explicite la répartition d'une charge sur une requête SELECT en ajoutant un commentaire au début de la requête SELECT (quel que ce soit ce commentaire). Par exemple :

          /*REPLICATION*/ SELECT ...
        

        Merci de lire attentivement la page replicate_select au sujet de la réplication. De même, étudiez attentivement ce schéma qui explique comment pgpool-II détermine à quel serveur PostgreSQL envoyer telle ou telle requête.

        Attention : le connecteur JDBC a une option autocommit. Si autocommit est à false, le connecteur JDBC envoie un BEGIN et un COMMIT lui-même. Ainsi, pgpool-II ne pourra faire aucune répartition de charge. Vous devez alors appeler setAutoCommit(true) pour activer l'autocommit.

        Failover dans le mode Réplication

        pgpool-II désactive un serveur « mort » et le service continue, à condition qu'il y ait au moins un serveur PostgreSQL en vie.

        Mode Maître-Esclave

        Ce mode est utilisé lorsque pgpool-II est couplé avec un autre outil de réplication de type maître/esclave(s) (comme Slony-I ou le Streaming Réplication intégré à PostgreSQL). Cet outil est alors responsable de la réplication des données. L'information sur les serveurs PostgreSQL doit être renseignée (les paramètres backend_hostname, backend_port, backend_weight et backend_data_directory), de la même façon que dans le mode réplication. De plus, il faut paramétrer master_slave_mode et load_balance_mode à true. pgpool-II enverra alors les requêtes qui doivent être répliquées au serveur PostgreSQL maître, et les autres requêtes seront réparties parmi les différents serveurs lorsque c'est possible. L'algorithme de pgpool-II prend bien sûr en compte les requêtes qui ne peuvent être réparties ; elles sont alors systématiquement envoyées au serveur maître.

        Dans le mode maître-esclave, les DDL et DML pour une table temporaire ne peuvent être exécutées que sur le serveur maître. Vous pouvez forcer un SELECT à ne s'exécuter que sur le maître en ajoutant un commentaire /*NO LOAD BALANCE*/ devant le SELECT.

        Dans le mode maître-esclave, vous devez positionner replication_mode à false et master_slave_mode à true.

        Le mode maître-esclave a un sous-mode piloté par le paramètre 'master_slave_sub_mode'. Il vaut par défaut slony et convient si vous utilisez Slony-I. Vous pouvez aussi le paramétrer à stream si vous utilisez le système de réplication intégré à PostgreSQL (le Streaming Replication). Le fichier de configuration d'exemple pour le sous-mode Slony-I est pgpool.conf.sample-master-slave, et celui concernant la Streaming Replication est pgpool.conf.sample-stream.

        Vous devez redémarrer pgpool-II si vous changez l'un des paramètres vu précédemment.

        Vous devrez probablement aussi renseigner les paramètres white_function_list et black_function_list si vous voulez contrôler plus finement la répartition de charge dans le mode maître-esclave. Reportez-vous à white_function_list pour plus de détails.

        Streaming Replication

        Comme nous l'avons vu précédemment, pgpool-II peut fonctionner de pair avec la Streaming Replication, qui est disponible depuis la version 9.0 de PostgreSQL. Pour l'utiliser, il faut activer le paramètre master_slave et positionner le paramètre master_slave_sub_mode1 à stream. pgpool-II suppose que le Streaming Replication fonctionne et que les serveurs PostgreSQL esclaves sont en Hot Standby, ce qui signifie que les bases de données sont ouvertes en lecture seule sur ces derniers. Les directives suivantes peuvent être utilisées dans ce mode :

        • delay_threshold

          Permet de spécifier le décalage maximum toléré entre le serveur maître et un serveur esclave dans une réplication, exprimé en octets de journaux de transactions. Si le décalage dépasse delay_threshold, pgpool-II n'envoie alors plus de SELECT au serveur(s) esclave(s). Tout est alors envoyé au serveur maître, même si la répartition de charge est activée, jusqu'à ce que le(s) serveur(s) esclave(s) soit(soient) en deçà du décalage maximum autorisé. Si delay_threshold est à 0 ou si le test de vie est désactivé, ce test de décalage n'est jamais fait. Ce dernier est effectué tous les health_check_period. La valeur par défaut pour delay_threshold est 0. Vous devez recharger la configuration de pgpool-II si vous changez cette directive.

        • log_standby_delay

          Permet de spécifier comment le décalage de réplication est tracé dans le journal applicatif de pgpool-II. Si none est spécifié ici, rien n'est écrit. Si always est spécifié, alors le décalage sera tracé à chaque fois que le test est effectué. Si if_over_threshold est spécifié, alors le décalage est tracé uniquement lorsqu'il dépasse le delay_threshold. La valeur par défaut pour log_standby_delay est none. Vous devez recharger la configuration de pgool-II si vous changez ce paramètre.

          Vous pouvez aussi superviser le décalage éventuel de la réplication en utilisant la commande "show pool_status".

        Le failover avec la Streaming Replication

        Dans le mode maître/esclave avec la Streaming Replication, si le nœud primaire ou le nœud en attente s'arrête, pgpool-II peut être configuré pour exécuter un Failover. Les nœuds peuvent alors être attachés automatiquement sans configuration ou opérations complémentaires. Alors qu'il est en pleine réplication [~], le nœud en attente vérifie régulièrement si un fichier de déclenchement existe. S'il le trouve, le nœud en attente sort de son mode réplication et s'ouvre en mode lecture/écriture. En utilisant ce mécanisme, on peut avoir une base de données en attente qui prends le relais quand le nœud primaire tombe.

        Attention : si vous pensez utiliser plusieurs nœuds en mode standby, il est recommandé de définir le paramètre delay_threshold pour empêcher tout requête dirigée vers d'autres nœuds en standby de récupérer des données plus vieilles.

        Si un second nœud en standby prends le relais quand le premier nœud en standby avait déjà pris le relais, vous pourriez avoir des données erronnées en provenance du second standby. Nous vous recommandons de ne pas utiliser ce genre de configuration.

        Voici commment configurer un mécanisme de Failover.

        1. Il faut créer un script de Failover quelque part sur le système, par exemple dans /usr/local/pgsql/bin, puis le rendre exécutable.
          $ cd /usr/loca/pgsql/bin
          $ cat failover_stream.sh
          #! /bin/sh
          # Commandes pour faire un Failover en mode Streaming Replication
          # Ce script suppose que le nœud Maitre est le 0 et 1 le standby
          # 
          # Si le Standby s'arrête, ne rien faire. Si le Primaire s'arrête, créer
          # un fichier de déclenchement afin que le standby prenne le relais sur le 
          # nœud Primaire.
          #
          # Arguments: 
          #   $1: identifiant du nœud qui ne répond plus
          #   $2: nom d'hôte du nouveau maître 
          #   $3: chemin vers le fichier trigger 
          
          failed_node=$1
          new_master=$2
          trigger_file=$3
          
          # Ne rien faire si c'est le standby qui tombe
          if [ $failed_node = 1 ]; then
          	exit 0;
          fi
          
          # Créer un fichier de déclenchement
          /usr/bin/ssh -T $new_master /bin/touch $trigger_file
          
          exit 0;
          
          chmod 755 failover_stream.sh
          
        2. Il faut à présent définir la commande failover_commmand dans le fichier pgpool.conf :
          failover_command = '/usr/local/src/pgsql/9.0-beta/bin/failover_stream.sh %d %H /tmp/trigger_file0'
          
        3. Et créer le fichier recovery.conf sur le nœud en standby. Un exemple de fichier recovery.conf est disponible dans le répertoire d'installation de PostgreSQL. Son nom complet est "share/recovery.conf.sample". Copier recovery.conf.sample en recovery.conf dans le répertoire de base de PostgreSQL et l'éditer comme suit.
          standby_mode = 'on'
          primary_conninfo = 'host=nom_du_nœud_primaire user=postgres'
          trigger_file = '/tmp/trigger_file0'
          
        4. Ajuster le postgresql.conf sur le nœud primaire. La configuration ci-dessous est donneé à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
          wal_level = hot_standby
          max_wal_senders = 1
          
        5. Définir pg_hba.conf sur le nœud Primaire. La configuration ci-dessous est donnée à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
          host	replication	postgres		192.168.0.10/32		trust
          

        Démarrez PostgreSQL sur les nœuds primaire et secondaire pour initialiser la réplication. Si le nœud primaire venait à tomber, le nœud secondaire prendra automatiquement le relais, en tant que nouveau nœud primaire, et sera alors prêt à recevoir les requêtes en écriture.

        Streaming Replication

        Lorsqu'on utilise la Streaming Replication et le Hot Standby, il est important de déterminer les requêtes pouvant être envoyées sur le nœud principal ou sur le nœud en standby (secondaire), et les requêtes qui ne peuvent pas l'être. Le mode Streaming Replication de pgpool-II se charge complètement de cette problématique. Dans ce chapitre, nous expliquerons comment pgpool-II parvient à cela.

        Nous distinguons les requêtes qui devraient être envoyées à tel ou tel nœud en les examinant.

        • Les requêtes suivantes devraient être envoyées au nœud primaire uniquement :
          • INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE, CREATE, DROP, ALTER, COMMENT
          • SELECT ... FOR SHARE | UPDATE
          • SELECT dans un niveau d'isolation transactionnel de type SERIALIZABLE
          • LOCK, commande plus stricte que ROW EXCLUSIVE MODE
          • Quelques commandes transactionnelles :
            • BEGIN READ WRITE, START TRANSACTION READ WRITE
            • SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE
            • SET transaction_read_only = off
          • Les commandes relatives à la validation en deux phases : PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED
          • LISTEN, UNLISTEN, NOTIFY
          • VACUUM
          • Quelques fonctions liées aux séquences (nextval et setval)
          • Les commandes de création de « Large Objects »
        • Ces requêtes peuvent être envoyées à la fois au nœud primaire et au nœud en standby. Si la répartition de charge est activée, ce type de requêtes peut être envoyé au nœud en standby. Cependant, si le paramètre delay_threshold est défini et que le délai dans la réplication est supérieur au delay_threshold, les requêtes sont envoyées au nœud primaire.
          • tout SELECT non listé ci-dessus
          • COPY TO
          • DECLARE, FETCH, CLOSE
          • SHOW
        • Les requêtes suivantes sont envoyées à la fois au nœud primaire et secondaire :
          • SET
          • DISCARD
          • DEALLOCATE ALL

        Dans une transaction explicite :

        • Toute transaction commençant par une commande comme BEGIN est envoyée au nœud primaire.
        • Tout SELECT qui survient immédiatement après, ainsi que toutes les requêtes qui peuvent être envoyées aussi bien au primaire qu'au secondaire, sont réparties entre les nœuds.
        • Toute commande qui ne peut être exécutée sur un nœud en standby (secondaire) comme un INSERT sont envoyées uniquement au primaire. Après toute commande de ce type, absolument tous les ordres SQL sont envoyés au nœud primaire. En effet, les SELECT suivant pourraient vouloir voir les résultats d'un INSERT immédiatement. Ce comportement continue jusqu'à ce que la transaction se ferme ou soit interrompue.

        Dans le protocole étendu, il est possible de déterminer si la requête peut être envoyée au nœud en standby ou pas dans le mode de répartition de charge au moment où on analyse la requête. Les rêgles sont les mêmes que dans le protocole non-étendu. Par exemple, les INSERT sont envoyés au primaire, ainsi que toute requête qui suivra.

        Note : si l'analyse d'une requête en SELECT est envoyée sur le standby à cause de la répartition de charge et qu'une requête en modification de données, comme un INSERT est envoyé à pgpool-II, alors le SELECT analysé devra être exécuté sur le nœud primaire. Cependant, on analyse de nouveau le SELECT sur le nœud primaire.

        Enfin, les requêtes qui semblent douteuses ou possiblement en erreur sont envoyées sur le nœud primaire.

        Online recovery avec la Streaming Replication

        Dans le mode maître/esclave avec la Streaming Replication, on peut procéder à une restauration à chaud (« Online recovery »). Cependant, seul un nœud en standby peut être ainsi récupéré. On ne peut pas reconstruire un nœud primaire. Pour ce faire, il faudra stopper toutes les bases de données, ainsi que pgpool-II, puis restaurer le nœud primaire à partir d'une sauvegarde.

        Voici les étapes.

        1. Définir le paramètre recovery_user. C'est s1e object » sur tous les serveurs PostgreSQL lorsque pgpool-II est dans le mode réplication. Notez que PostgreSQL 8.0 et ultérieur n'a plus de fonction lo_create. Du coup, cette fonctionalité est pas utilisable pour ces versions.

          Un appel à la fonction de la libpq lo_creat() utilisera cette fonctionalité. De même, la création de « large objects » via l'API Java (driver JDBC) devrait fonctionner, tout comme l'API PHP (pg_lo_create, ou API similaire dans la bibliothèque de PHP, comme PDO), et ce genre d'API similaires dans plusieurs langages de programmation qui sont réputées pour utiliser un protocole similaire.

          Les opérations suivantes de création d'un « large object » ne fonctionneront pas :

          • lo_create de la libpq
          • l'API d'un langage qui utilise lo_create
          • la fonction lo_import dans le serveur PostgreSQL
          • SELECT lo_creat

          Peu importe le schéma où est stockée la table lobj_lock_table, celle-ci doit en revanche être accessible en écriture à tous les utilisateurs. Voici un exemple de création d'une telle table :

          CREATE TABLE public.my_lock_table ();
          GRANT ALL ON public.my_lock_table TO PUBLIC;
          

          La table spécifiée par lobj_lock_table doit être créée à l'avance. Vous pouvez par exemple la créer dans la base template1 afin que toute base de données créée par la suite en dispose.

          Si lobj_lock_table contient une chaîne vide (''), la fonctionalité est désactivée. Du coup, la réplication des « large objects » ne fonctionnera pas. La valeur par défaut de ce paramètre est justement la chaîne vide ('').

          Pré-requis pour la répartition de charge

          Pour qu'une requête soit répartie, les pré-requis suivants doivent être respectés :

          • Version 7.4 ou ultérieure de PostgreSQL
          • La requête ne doit pas être déclarée explicitement (c'est-à-dire qu'on ne doit pas être dans un bloc BEGIN ~ END)
          • Il ne s'agit pas d'un SELECT nextval ou d'un SELECT setval
          • Il ne s'agit pas d'un SELECT INTO
          • Il ne s'agit pas d'un SELECT FOR UPDATE ou FOR SHARE
          • La requête commence par un SELECT ou COPY TO STDOUT, EXPLAIN, EXPLAIN ANALYZE SELECT... le paramètre ignore_leading_white_space = true permettra d'ignorer tous les éventuels espaces présents avant la requête.

          Notez que vous pouvez interdire de manière explicite la répartition d'une charge sur une requête SELECT en ajoutant un commentaire au début de la requête SELECT (quel que ce soit ce commentaire). Par exemple :

            /*REPLICATION*/ SELECT ...
          

          Merci de lire attentivement la page replicate_select au sujet de la réplication. De même, étudiez attentivement ce schéma qui explique comment pgpool-II détermine à quel serveur PostgreSQL envoyer telle ou telle requête.

          Attention : le connecteur JDBC a une option autocommit. Si autocommit est à false, le connecteur JDBC envoie un BEGIN et un COMMIT lui-même. Ainsi, pgpool-II ne pourra faire aucune répartition de charge. Vous devez alors appeler setAutoCommit(true) pour activer l'autocommit.

          Failover dans le mode Réplication

          pgpool-II désactive un serveur « mort » et le service continue, à condition qu'il y ait au moins un serveur PostgreSQL en vie.

          Mode Maître-Esclave

          Ce mode est utilisé lorsque pgpool-II est couplé avec un autre outil de réplication de type maître/esclave(s) (comme Slony-I ou le Streaming Réplication intégré à PostgreSQL). Cet outil est alors responsable de la réplication des données. L'information sur les serveurs PostgreSQL doit être renseignée (les paramètres backend_hostname, backend_port, backend_weight et backend_data_directory), de la même façon que dans le mode réplication. De plus, il faut paramétrer master_slave_mode et load_balance_mode à true. pgpool-II enverra alors les requêtes qui doivent être répliquées au serveur PostgreSQL maître, et les autres requêtes seront réparties parmi les différents serveurs lorsque c'est possible. L'algorithme de pgpool-II prend bien sûr en compte les requêtes qui ne peuvent être réparties ; elles sont alors systématiquement envoyées au serveur maître.

          Dans le mode maître-esclave, les DDL et DML pour une table temporaire ne peuvent être exécutées que sur le serveur maître. Vous pouvez forcer un SELECT à ne s'exécuter que sur le maître en ajoutant un commentaire /*NO LOAD BALANCE*/ devant le SELECT.

          Dans le mode maître-esclave, vous devez positionner replication_mode à false et master_slave_mode à true.

          Le mode maître-esclave a un sous-mode piloté par le paramètre 'master_slave_sub_mode'. Il vaut par défaut slony et convient si vous utilisez Slony-I. Vous pouvez aussi le paramétrer à stream si vous utilisez le système de réplication intégré à PostgreSQL (le Streaming Replication). Le fichier de configuration d'exemple pour le sous-mode Slony-I est pgpool.conf.sample-master-slave, et celui concernant la Streaming Replication est pgpool.conf.sample-stream.

          Vous devez redémarrer pgpool-II si vous changez l'un des paramètres vu précédemment.

          Vous devrez probablement aussi renseigner les paramètres white_function_list et black_function_list si vous voulez contrôler plus finement la répartition de charge dans le mode maître-esclave. Reportez-vous à white_function_list pour plus de détails.

          Streaming Replication

          Comme nous l'avons vu précédemment, pgpool-II peut fonctionner de pair avec la Streaming Replication, qui est disponible depuis la version 9.0 de PostgreSQL. Pour l'utiliser, il faut activer le paramètre master_slave et positionner le paramètre master_slave_sub_mode1 à stream. pgpool-II suppose que le Streaming Replication fonctionne et que les serveurs PostgreSQL esclaves sont en Hot Standby, ce qui signifie que les bases de données sont ouvertes en lecture seule sur ces derniers. Les directives suivantes peuvent être utilisées dans ce mode :

          • delay_threshold

            Permet de spécifier le décalage maximum toléré entre le serveur maître et un serveur esclave dans une réplication, exprimé en octets de journaux de transactions. Si le décalage dépasse delay_threshold, pgpool-II n'envoie alors plus de SELECT au serveur(s) esclave(s). Tout est alors envoyé au serveur maître, même si la répartition de charge est activée, jusqu'à ce que le(s) serveur(s) esclave(s) soit(soient) en deçà du décalage maximum autorisé. Si delay_threshold est à 0 ou si le test de vie est désactivé, ce test de décalage n'est jamais fait. Ce dernier est effectué tous les health_check_period. La valeur par défaut pour delay_threshold est 0. Vous devez recharger la configuration de pgpool-II si vous changez cette directive.

          • log_standby_delay

            Permet de spécifier comment le décalage de réplication est tracé dans le journal applicatif de pgpool-II. Si none est spécifié ici, rien n'est écrit. Si always est spécifié, alors le décalage sera tracé à chaque fois que le test est effectué. Si if_over_threshold est spécifié, alors le décalage est tracé uniquement lorsqu'il dépasse le delay_threshold. La valeur par défaut pour log_standby_delay est none. Vous devez recharger la configuration de pgool-II si vous changez ce paramètre.

            Vous pouvez aussi superviser le décalage éventuel de la réplication en utilisant la commande "show pool_status".

          Le failover avec la Streaming Replication

          Dans le mode maître/esclave avec la Streaming Replication, si le nœud primaire ou le nœud en attente s'arrête, pgpool-II peut être configuré pour exécuter un Failover. Les nœuds peuvent alors être attachés automatiquement sans configuration ou opérations complémentaires. Alors qu'il est en pleine réplication [~], le nœud en attente vérifie régulièrement si un fichier de déclenchement existe. S'il le trouve, le nœud en attente sort de son mode réplication et s'ouvre en mode lecture/écriture. En utilisant ce mécanisme, on peut avoir une base de données en attente qui prends le relais quand le nœud primaire tombe.

          Attention : si vous pensez utiliser plusieurs nœuds en mode standby, il est recommandé de définir le paramètre delay_threshold pour empêcher tout requête dirigée vers d'autres nœuds en standby de récupérer des données plus vieilles.

          Si un second nœud en standby prends le relais quand le premier nœud en standby avait déjà pris le relais, vous pourriez avoir des données erronnées en provenance du second standby. Nous vous recommandons de ne pas utiliser ce genre de configuration.

          Voici commment configurer un mécanisme de Failover.

          1. Il faut créer un script de Failover quelque part sur le système, par exemple dans /usr/local/pgsql/bin, puis le rendre exécutable.
            $ cd /usr/loca/pgsql/bin
            $ cat failover_stream.sh
            #! /bin/sh
            # Commandes pour faire un Failover en mode Streaming Replication
            # Ce script suppose que le nœud Maitre est le 0 et 1 le standby
            # 
            # Si le Standby s'arrête, ne rien faire. Si le Primaire s'arrête, créer
            # un fichier de déclenchement afin que le standby prenne le relais sur le 
            # nœud Primaire.
            #
            # Arguments: 
            #   $1: identifiant du nœud qui ne répond plus
            #   $2: nom d'hôte du nouveau maître 
            #   $3: chemin vers le fichier trigger 
            
            failed_node=$1
            new_master=$2
            trigger_file=$3
            
            # Ne rien faire si c'est le standby qui tombe
            if [ $failed_node = 1 ]; then
            	exit 0;
            fi
            
            # Créer un fichier de déclenchement
            /usr/bin/ssh -T $new_master /bin/touch $trigger_file
            
            exit 0;
            
            chmod 755 failover_stream.sh
            
          2. Il faut à présent définir la commande failover_commmand dans le fichier pgpool.conf :
            failover_command = '/usr/local/src/pgsql/9.0-beta/bin/failover_stream.sh %d %H /tmp/trigger_file0'
            
          3. Et créer le fichier recovery.conf sur le nœud en standby. Un exemple de fichier recovery.conf est disponible dans le répertoire d'installation de PostgreSQL. Son nom complet est "share/recovery.conf.sample". Copier recovery.conf.sample en recovery.conf dans le répertoire de base de PostgreSQL et l'éditer comme suit.
            standby_mode = 'on'
            primary_conninfo = 'host=nom_du_nœud_primaire user=postgres'
            trigger_file = '/tmp/trigger_file0'
            
          4. Ajuster le postgresql.conf sur le nœud primaire. La configuration ci-dessous est donneé à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
            wal_level = hot_standby
            max_wal_senders = 1
            
          5. Définir pg_hba.conf sur le nœud Primaire. La configuration ci-dessous est donnée à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
            host	replication	postgres		192.168.0.10/32		trust
            

          Démarrez PostgreSQL sur les nœuds primaire et secondaire pour initialiser la réplication. Si le nœud primaire venait à tomber, le nœud secondaire prendra automatiquement le relais, en tant que nouveau nœud primaire, et sera alors prêt à recevoir les requêtes en écriture.

          Streaming Replication

          Lorsqu'on utilise la Streaming Replication et le Hot Standby, il est important de déterminer les requêtes pouvant être envoyées sur le nœud principal ou sur le nœud en standby (secondaire), et les requêtes qui ne peuvent pas l'être. Le mode Streaming Replication de pgpool-II se charge complètement de cette problématique. Dans ce chapitre, nous expliquerons comment pgpool-II parvient à cela.

          Nous distinguons les requêtes qui devraient être envoyées à tel ou tel nœud en les examinant.

          • Les requêtes suivantes devraient être envoyées au nœud primaire uniquement :
            • INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE, CREATE, DROP, ALTER, COMMENT
            • SELECT ... FOR SHARE | UPDATE
            • SELECT dans un niveau d'isolation transactionnel de type SERIALIZABLE
            • LOCK, commande plus stricte que ROW EXCLUSIVE MODE
            • Quelques commandes transactionnelles :
              • BEGIN READ WRITE, START TRANSACTION READ WRITE
              • SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE
              • SET transaction_read_only = off
            • Les commandes relatives à la validation en deux phases : PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED
            • LISTEN, UNLISTEN, NOTIFY
            • VACUUM
            • Quelques fonctions liées aux séquences (nextval et setval)
            • Les commandes de création de « Large Objects »
          • Ces requêtes peuvent être envoyées à la fois au nœud primaire et au nœud en standby. Si la répartition de charge est activée, ce type de requêtes peut être envoyé au nœud en standby. Cependant, si le paramètre delay_threshold est défini et que le délai dans la réplication est supérieur au delay_threshold, les requêtes sont envoyées au nœud primaire.
            • tout SELECT non listé ci-dessus
            • COPY TO
            • DECLARE, FETCH, CLOSE
            • SHOW
          • Les requêtes suivantes sont envoyées à la fois au nœud primaire et secondaire :
            • SET
            • DISCARD
            • DEALLOCATE ALL

          Dans une transaction explicite :

          • Toute transaction commençant par une commande comme BEGIN est envoyée au nœud primaire.
          • Tout SELECT qui survient immédiatement après, ainsi que toutes les requêtes qui peuvent être envoyées aussi bien au primaire qu'au secondaire, sont réparties entre les nœuds.
          • Toute commande qui ne peut être exécutée sur un nœud en standby (secondaire) comme un INSERT sont envoyées uniquement au primaire. Après toute commande de ce type, absolument tous les ordres SQL sont envoyés au nœud primaire. En effet, les SELECT suivant pourraient vouloir voir les résultats d'un INSERT immédiatement. Ce comportement continue jusqu'à ce que la transaction se ferme ou soit interrompue.

          Dans le protocole étendu, il est possible de déterminer si la requête peut être envoyée au nœud en standby ou pas dans le mode de répartition de charge au moment où on analyse la requête. Les rêgles sont les mêmes que dans le protocole non-étendu. Par exemple, les INSERT sont envoyés au primaire, ainsi que toute requête qui suivra.

          Note : si l'analyse d'une requête en SELECT est envoyée sur le standby à cause de la répartition de charge et qu'une requête en modification de données, comme un INSERT est envoyé à pgpool-II, alors le SELECT analysé devra être exécuté sur le nœud primaire. Cependant, on analyse de nouveau le SELECT sur le nœud primaire.

          Enfin, les requêtes qui semblent douteuses ou possiblement en erreur sont envoyées sur le nœud primaire.

          Online recovery avec la Streaming Replication

          Dans le mode maître/esclave avec la Streaming Replication, on peut procéder à une restauration à chaud (« Online recovery »). Cependant, seul un nœud en standby peut être ainsi récupéré. On ne peut pas reconstruire un nœud primaire. Pour ce faire, il faudra stopper toutes les bases de données, ainsi que pgpool-II, puis restaurer le nœud primaire à partir d'une sauvegarde.

          Voici les étapes.

          1. Définir le paramètre recovery_user. C'est s1e object » sur tous les serveurs PostgreSQL lorsque pgpool-II est dans le mode réplication. Notez que PostgreSQL 8.0 et ultérieur n'a plus de fonction lo_create. Du coup, cette fonctionalité est pas utilisable pour ces versions.

            Un appel à la fonction de la libpq lo_creat() utilisera cette fonctionalité. De même, la création de « large objects » via l'API Java (driver JDBC) devrait fonctionner, tout comme l'API PHP (pg_lo_create, ou API similaire dans la bibliothèque de PHP, comme PDO), et ce genre d'API similaires dans plusieurs langages de programmation qui sont réputées pour utiliser un protocole similaire.

            Les opérations suivantes de création d'un « large object » ne fonctionneront pas :

            • lo_create de la libpq
            • l'API d'un langage qui utilise lo_create
            • la fonction lo_import dans le serveur PostgreSQL
            • SELECT lo_creat

            Peu importe le schéma où est stockée la table lobj_lock_table, celle-ci doit en revanche être accessible en écriture à tous les utilisateurs. Voici un exemple de création d'une telle table :

            CREATE TABLE public.my_lock_table ();
            GRANT ALL ON public.my_lock_table TO PUBLIC;
            

            La table spécifiée par lobj_lock_table doit être créée à l'avance. Vous pouvez par exemple la créer dans la base template1 afin que toute base de données créée par la suite en dispose.

            Si lobj_lock_table contient une chaîne vide (''), la fonctionalité est désactivée. Du coup, la réplication des « large objects » ne fonctionnera pas. La valeur par défaut de ce paramètre est justement la chaîne vide ('').

            Pré-requis pour la répartition de charge

            Pour qu'une requête soit répartie, les pré-requis suivants doivent être respectés :

            • Version 7.4 ou ultérieure de PostgreSQL
            • La requête ne doit pas être déclarée explicitement (c'est-à-dire qu'on ne doit pas être dans un bloc BEGIN ~ END)
            • Il ne s'agit pas d'un SELECT nextval ou d'un SELECT setval
            • Il ne s'agit pas d'un SELECT INTO
            • Il ne s'agit pas d'un SELECT FOR UPDATE ou FOR SHARE
            • La requête commence par un SELECT ou COPY TO STDOUT, EXPLAIN, EXPLAIN ANALYZE SELECT... le paramètre ignore_leading_white_space = true permettra d'ignorer tous les éventuels espaces présents avant la requête.

            Notez que vous pouvez interdire de manière explicite la répartition d'une charge sur une requête SELECT en ajoutant un commentaire au début de la requête SELECT (quel que ce soit ce commentaire). Par exemple :

              /*REPLICATION*/ SELECT ...
            

            Merci de lire attentivement la page replicate_select au sujet de la réplication. De même, étudiez attentivement ce schéma qui explique comment pgpool-II détermine à quel serveur PostgreSQL envoyer telle ou telle requête.

            Attention : le connecteur JDBC a une option autocommit. Si autocommit est à false, le connecteur JDBC envoie un BEGIN et un COMMIT lui-même. Ainsi, pgpool-II ne pourra faire aucune répartition de charge. Vous devez alors appeler setAutoCommit(true) pour activer l'autocommit.

            Failover dans le mode Réplication

            pgpool-II désactive un serveur « mort » et le service continue, à condition qu'il y ait au moins un serveur PostgreSQL en vie.

            Mode Maître-Esclave

            Ce mode est utilisé lorsque pgpool-II est couplé avec un autre outil de réplication de type maître/esclave(s) (comme Slony-I ou le Streaming Réplication intégré à PostgreSQL). Cet outil est alors responsable de la réplication des données. L'information sur les serveurs PostgreSQL doit être renseignée (les paramètres backend_hostname, backend_port, backend_weight et backend_data_directory), de la même façon que dans le mode réplication. De plus, il faut paramétrer master_slave_mode et load_balance_mode à true. pgpool-II enverra alors les requêtes qui doivent être répliquées au serveur PostgreSQL maître, et les autres requêtes seront réparties parmi les différents serveurs lorsque c'est possible. L'algorithme de pgpool-II prend bien sûr en compte les requêtes qui ne peuvent être réparties ; elles sont alors systématiquement envoyées au serveur maître.

            Dans le mode maître-esclave, les DDL et DML pour une table temporaire ne peuvent être exécutées que sur le serveur maître. Vous pouvez forcer un SELECT à ne s'exécuter que sur le maître en ajoutant un commentaire /*NO LOAD BALANCE*/ devant le SELECT.

            Dans le mode maître-esclave, vous devez positionner replication_mode à false et master_slave_mode à true.

            Le mode maître-esclave a un sous-mode piloté par le paramètre 'master_slave_sub_mode'. Il vaut par défaut slony et convient si vous utilisez Slony-I. Vous pouvez aussi le paramétrer à stream si vous utilisez le système de réplication intégré à PostgreSQL (le Streaming Replication). Le fichier de configuration d'exemple pour le sous-mode Slony-I est pgpool.conf.sample-master-slave, et celui concernant la Streaming Replication est pgpool.conf.sample-stream.

            Vous devez redémarrer pgpool-II si vous changez l'un des paramètres vu précédemment.

            Vous devrez probablement aussi renseigner les paramètres white_function_list et black_function_list si vous voulez contrôler plus finement la répartition de charge dans le mode maître-esclave. Reportez-vous à white_function_list pour plus de détails.

            Streaming Replication

            Comme nous l'avons vu précédemment, pgpool-II peut fonctionner de pair avec la Streaming Replication, qui est disponible depuis la version 9.0 de PostgreSQL. Pour l'utiliser, il faut activer le paramètre master_slave et positionner le paramètre master_slave_sub_mode1 à stream. pgpool-II suppose que le Streaming Replication fonctionne et que les serveurs PostgreSQL esclaves sont en Hot Standby, ce qui signifie que les bases de données sont ouvertes en lecture seule sur ces derniers. Les directives suivantes peuvent être utilisées dans ce mode :

            • delay_threshold

              Permet de spécifier le décalage maximum toléré entre le serveur maître et un serveur esclave dans une réplication, exprimé en octets de journaux de transactions. Si le décalage dépasse delay_threshold, pgpool-II n'envoie alors plus de SELECT au serveur(s) esclave(s). Tout est alors envoyé au serveur maître, même si la répartition de charge est activée, jusqu'à ce que le(s) serveur(s) esclave(s) soit(soient) en deçà du décalage maximum autorisé. Si delay_threshold est à 0 ou si le test de vie est désactivé, ce test de décalage n'est jamais fait. Ce dernier est effectué tous les health_check_period. La valeur par défaut pour delay_threshold est 0. Vous devez recharger la configuration de pgpool-II si vous changez cette directive.

            • log_standby_delay

              Permet de spécifier comment le décalage de réplication est tracé dans le journal applicatif de pgpool-II. Si none est spécifié ici, rien n'est écrit. Si always est spécifié, alors le décalage sera tracé à chaque fois que le test est effectué. Si if_over_threshold est spécifié, alors le décalage est tracé uniquement lorsqu'il dépasse le delay_threshold. La valeur par défaut pour log_standby_delay est none. Vous devez recharger la configuration de pgool-II si vous changez ce paramètre.

              Vous pouvez aussi superviser le décalage éventuel de la réplication en utilisant la commande "show pool_status".

            Le failover avec la Streaming Replication

            Dans le mode maître/esclave avec la Streaming Replication, si le nœud primaire ou le nœud en attente s'arrête, pgpool-II peut être configuré pour exécuter un Failover. Les nœuds peuvent alors être attachés automatiquement sans configuration ou opérations complémentaires. Alors qu'il est en pleine réplication [~], le nœud en attente vérifie régulièrement si un fichier de déclenchement existe. S'il le trouve, le nœud en attente sort de son mode réplication et s'ouvre en mode lecture/écriture. En utilisant ce mécanisme, on peut avoir une base de données en attente qui prends le relais quand le nœud primaire tombe.

            Attention : si vous pensez utiliser plusieurs nœuds en mode standby, il est recommandé de définir le paramètre delay_threshold pour empêcher tout requête dirigée vers d'autres nœuds en standby de récupérer des données plus vieilles.

            Si un second nœud en standby prends le relais quand le premier nœud en standby avait déjà pris le relais, vous pourriez avoir des données erronnées en provenance du second standby. Nous vous recommandons de ne pas utiliser ce genre de configuration.

            Voici commment configurer un mécanisme de Failover.

            1. Il faut créer un script de Failover quelque part sur le système, par exemple dans /usr/local/pgsql/bin, puis le rendre exécutable.
              $ cd /usr/loca/pgsql/bin
              $ cat failover_stream.sh
              #! /bin/sh
              # Commandes pour faire un Failover en mode Streaming Replication
              # Ce script suppose que le nœud Maitre est le 0 et 1 le standby
              # 
              # Si le Standby s'arrête, ne rien faire. Si le Primaire s'arrête, créer
              # un fichier de déclenchement afin que le standby prenne le relais sur le 
              # nœud Primaire.
              #
              # Arguments: 
              #   $1: identifiant du nœud qui ne répond plus
              #   $2: nom d'hôte du nouveau maître 
              #   $3: chemin vers le fichier trigger 
              
              failed_node=$1
              new_master=$2
              trigger_file=$3
              
              # Ne rien faire si c'est le standby qui tombe
              if [ $failed_node = 1 ]; then
              	exit 0;
              fi
              
              # Créer un fichier de déclenchement
              /usr/bin/ssh -T $new_master /bin/touch $trigger_file
              
              exit 0;
              
              chmod 755 failover_stream.sh
              
            2. Il faut à présent définir la commande failover_commmand dans le fichier pgpool.conf :
              failover_command = '/usr/local/src/pgsql/9.0-beta/bin/failover_stream.sh %d %H /tmp/trigger_file0'
              
            3. Et créer le fichier recovery.conf sur le nœud en standby. Un exemple de fichier recovery.conf est disponible dans le répertoire d'installation de PostgreSQL. Son nom complet est "share/recovery.conf.sample". Copier recovery.conf.sample en recovery.conf dans le répertoire de base de PostgreSQL et l'éditer comme suit.
              standby_mode = 'on'
              primary_conninfo = 'host=nom_du_nœud_primaire user=postgres'
              trigger_file = '/tmp/trigger_file0'
              
            4. Ajuster le postgresql.conf sur le nœud primaire. La configuration ci-dessous est donneé à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
              wal_level = hot_standby
              max_wal_senders = 1
              
            5. Définir pg_hba.conf sur le nœud Primaire. La configuration ci-dessous est donnée à titre indicatif, vous devrez probablement l'ajuster pour votre environnement.
              host	replication	postgres		192.168.0.10/32		trust
              

            Démarrez PostgreSQL sur les nœuds primaire et secondaire pour initialiser la réplication. Si le nœud primaire venait à tomber, le nœud secondaire prendra automatiquement le relais, en tant que nouveau nœud primaire, et sera alors prêt à recevoir les requêtes en écriture.

            Streaming Replication

            Lorsqu'on utilise la Streaming Replication et le Hot Standby, il est important de déterminer les requêtes pouvant être envoyées sur le nœud principal ou sur le nœud en standby (secondaire), et les requêtes qui ne peuvent pas l'être. Le mode Streaming Replication de pgpool-II se charge complètement de cette problématique. Dans ce chapitre, nous expliquerons comment pgpool-II parvient à cela.

            Nous distinguons les requêtes qui devraient être envoyées à tel ou tel nœud en les examinant.

            • Les requêtes suivantes devraient être envoyées au nœud primaire uniquement :
              • INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE, CREATE, DROP, ALTER, COMMENT
              • SELECT ... FOR SHARE | UPDATE
              • SELECT dans un niveau d'isolation transactionnel de type SERIALIZABLE
              • LOCK, commande plus stricte que ROW EXCLUSIVE MODE
              • Quelques commandes transactionnelles :
                • BEGIN READ WRITE, START TRANSACTION READ WRITE
                • SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE
                • SET transaction_read_only = off
              • Les commandes relatives à la validation en deux phases : PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED
              • LISTEN, UNLISTEN, NOTIFY
              • VACUUM
              • Quelques fonctions liées aux séquences (nextval et setval)
              • Les commandes de création de « Large Objects »
            • Ces requêtes peuvent être envoyées à la fois au nœud primaire et au nœud en standby. Si la répartition de charge est activée, ce type de requêtes peut être envoyé au nœud en standby. Cependant, si le paramètre delay_threshold est défini et que le délai dans la réplication est supérieur au delay_threshold, les requêtes sont envoyées au nœud primaire.
              • tout SELECT non listé ci-dessus
              • COPY TO
              • DECLARE, FETCH, CLOSE
              • SHOW
            • Les requêtes suivantes sont envoyées à la fois au nœud primaire et secondaire :
              • SET
              • DISCARD
              • DEALLOCATE ALL

            Dans une transaction explicite :

            • Toute transaction commençant par une commande comme BEGIN est envoyée au nœud primaire.
            • Tout SELECT qui survient immédiatement après, ainsi que toutes les requêtes qui peuvent être envoyées aussi bien au primaire qu'au secondaire, sont réparties entre les nœuds.
            • Toute commande qui ne peut être exécutée sur un nœud en standby (secondaire) comme un INSERT sont envoyées uniquement au primaire. Après toute commande de ce type, absolument tous les ordres SQL sont envoyés au nœud primaire. En effet, les SELECT suivant pourraient vouloir voir les résultats d'un INSERT immédiatement. Ce comportement continue jusqu'à ce que la transaction se ferme ou soit interrompue.

            Dans le protocole étendu, il est possible de déterminer si la requête peut être envoyée au nœud en standby ou pas dans le mode de répartition de charge au moment où on analyse la requête. Les rêgles sont les mêmes que dans le protocole non-étendu. Par exemple, les INSERT sont envoyés au primaire, ainsi que toute requête qui suivra.

            Note : si l'analyse d'une requête en SELECT est envoyée sur le standby à cause de la répartition de charge et qu'une requête en modification de données, comme un INSERT est envoyé à pgpool-II, alors le SELECT analysé devra être exécuté sur le nœud primaire. Cependant, on analyse de nouveau le SELECT sur le nœud primaire.

            Enfin, les requêtes qui semblent douteuses ou possiblement en erreur sont envoyées sur le nœud primaire.

            Online recovery avec la Streaming Replication

            Dans le mode maître/esclave avec la Streaming Replication, on peut procéder à une restauration à chaud (« Online recovery »). Cependant, seul un nœud en standby peut être ainsi récupéré. On ne peut pas reconstruire un nœud primaire. Pour ce faire, il faudra stopper toutes les bases de données, ainsi que pgpool-II, puis restaurer le nœud primaire à partir d'une sauvegarde.

            Voici les étapes.

            1. Définir le paramètre recovery_user. C'est s1e object » sur tous les serveurs PostgreSQL lorsque pgpool-II est dans le mode réplication. Notez que PostgreSQL 8.0 et ultérieur n'a plus de fonction lo_create. Du coup, cette fonctionalité est pas utilisable pour ces versions.

              Un appel à la fonction de la libpq lo_creat() utilisera cette fonctionalité. De même, la création de « large objects » via l'API Java (driver JDBC) devrait fonctionner, tout comme l'API PHP (pg_lo_create, ou API similaire dans la bibliothèque de PHP, comme PDO), et ce genre d'API similaires dans plusieurs langages de programmation qui sont réputées pour utiliser un protocole similaire.

              Les opérations suivantes de création d'un « large object » ne fonctionneront pas :

              • lo_create de la libpq
              • l'API d'un langage qui utilise lo_create
              • la fonction lo_import dans le serveur PostgreSQL
              • SELECT lo_creat

              Peu importe le schéma où est stockée la table lobj_lock_table, celle-ci doit en revanche être accessible en écriture à tous les utilisateurs. Voici un exemple de créatio