Last modified: Thu Aug 11 09:10:34 JST 2011
Bienvenue sur la page de pgpool-II |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
pgpool-IIpgpool-II est un middleware qui se place entre les serveurs PostgreSQL et les clients de ces derniers. Voici ses différentes fonctionalités:
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. 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. Si une base de données est répliquée (car elle est soit en mode réplication, soit en mode maître-esclave), 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. 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. 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éespgpool-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-IIpgpool-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. Vérifiez le repository approprié. 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.
L'installation est à présent terminée. Si vous utilisez Solaris ou FreeBSD, vous aurez besoin de remplacer "make" par "gmake" dans les exemples ci-dessus, puisque ces systèmes nécessitent la version GNU de make. Configuration de pgpool-IILes fichiers de configuration par défaut de pgpool-II sont
Configuration de
|
Mode | fichier d'exemple |
---|---|
Mode réplication | pgpool.conf.sample-replication |
Mode maître/esclave (Slony-I) | pgpool.conf.sample-master-slave |
Mode maître/esclave (Streaming replication) | pgpool.conf.sample-stream |
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.
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.
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.
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.
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.
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.
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.
À 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. La valeur par défaut est '/tmp'
.
Ce paramètre n'est défini qu'au démarrage du serveur.
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.
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. Le nombre de connexions à chaque serveur
PostgreSQL est alors à peu près max_pool*num_init_children
Quelques précisions et astuces :
max_connections - superuser_reserved_connections
Pour résumer, max_pool
,num_init_children
,
max_connections
et
superuser_reserved_connections
doivent satisfaire
la formule suivante :
max_pool*num_init_children <= (max_connections - superuser_reserved_connections)
max_pool*num_init_children*2 <= (max_connections - superuser_reserved_connections)
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.
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. C'est aussi très utile pour éviter que le serveurs
PostgreSQL ne deviennent trop gros. Vous devez recharger pgpool-II si vous
changez cette valeur.
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
.
Spécifie le délai maximum en secondes pour terminer une authentification. 0 désactive cette fonctionnalité. La valeur par défaut est de 60. Vous aurez besoin de redémarrer pgpool-II si vous changez cette valeur.
pgpool_status
est écrit dans ce répertoire.
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.
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.
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.
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.
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.
Cache les connexions à PostgreSQL lorsque
cette valeur est configurée à true
. La valeur par défaut
est true
. Vous aurez besoin de redémarrer pgpool-II après toute modification de ce paramètre.
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.
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.
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.
Mot de passe de l'utilisateur PostgreSQL utilisé pour exécuter la vérification. Vous aurez besoin de recharger pgpool-II après tout changement de la valeur de ce paramètre.
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écial Description %d ID du processus serveur correspondant au nœud détaché %h Nom d'hôte du nœud détaché %p Numéro de port du nœud détaché %D Répertoire de l'instance PostgreSQL du nœud détaché %M ID du nœud de l'ancien maître %m ID du nœud du nouveau maître %H Nom d'hôte du nouveau nœud maître %P ID 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.
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écial Description %d ID du processus serveur d'un nœud attaché %h Nom d'hôte d'un nœud attaché %p Numéro de port d'un nœud attaché %D Répertoire de l'instance PostgreSQL d'un nœud attaché %M Ancien nœud maître %m Nouveau nœud maître %H Nom d'hôte du nouveau nœud maître %P ID de l'ancien nœud primaire %% Caractère '%'
Vous devez recharger pgpool.conf si vous changez le contenu de la
commande failback_command
.
Ce paramètre permet de spécifier une commande à exécuter dans le mode maître/esclave (Streaming Replication) après un failover du maître. pgpool-II remplace les caractères spéciaux suivants avec les informations spécifiques au backend.
Caractère spécial Description %d ID d'un nœud détaché/ %h Nom d'hôte d'un nœud détaché. %p Numéro de port d'un nœud détaché. %D Répertoire du cluster PostgreSQL d'un nœud détaché. %M ID de l'ancien nœud maître. %m ID du nouveau maître. %H Nom d'hôte du nouveau nœud maître. %P ID de l'ancien nœud primaire. %% caractère '%'
Vous devez recharger pgpool.conf si vous changez le contenu de la
commande follow_master_command
.
Si follow_master_command
n'est pas vide, lorsqu'un failover du maître est terminé dans le mode de réplication maître/esclave (dans le sous-mode Streaming Replication), pgpool-II marque tous les nœuds comme dégénérés, à l'exception du nouveau maître, puis démarre de nouveau processus fils pour être prêt à accepter à nouveau les connexions des clients. Après, pgpool-II exécute la commande paramétrée dans follow_master_command
pour chacun des nœuds dégénérés. Typiquement, cette commande devrait-être utilisée pour restaurer un esclave à partir du nouveau maître en appelant la commande pcp_recovery_node
par exemple.
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. Si ce paramètre est à off, il est recommandé d'activer la vérification des serveurs (voir health_checking). 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.
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.
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.
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.
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.
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.
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.
Permet de spécifier à quel serveur PostgreSQL on se connecte. C'est utilisé par pgpool-II pour communiquer avec le serveur.
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.
Notez que le le nœud qui a l'identifiant 0 n'a pas de sens particulier si on est en mode Streaming Replication. Dans ce cas, il alors plus intéressant de savoir si le nœud est le nœud "primaire" ou pas. Voir Streaming Replication pour plus de détails.
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.
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.
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.
À 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.
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é.
Contrôle plusieurs comportements du backend. On peut spécifier
plusieurs backend en ajoutant un numéro à la fin du nom de paramètre,
comme par exemple backend_flag0
.
Les "flags" suivants peuvent-être spécifiés. On peut positionner plusieurs "flags", en les séparant par "|".
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.
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.
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.
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.
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.
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.
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.
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, on doit activer le connexion_cache
. Les paramètres suivants influent sur le pool de connexions.
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.
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.
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 PostgreSQL | reset_query_list value |
---|---|
7.1 ou précédentes | ABORT |
7.2 à 8.2 | ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT |
8.3 et suivantes | ABORT; DISCARD ALL |
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.
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.
Mettre ce paramètre à true
active le mode de
réplication. La valeur par défaut est false
.
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
.
Ce paramètre n'est lu qu'au démarrage de pgpool-II.
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
.
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
.
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_.*'
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.
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 |
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.
La version 3.0 de pgpool-II, jusqu'à la 3.0.4, utilise un verrou sur l'enregistement de la séquence, plutôt qu'un verrou au niveau de la table. C'est fait ainsi pour minimiser les conflits de verrouillage avec le VACUUM (et l'autovacuum). Cependant, cela amène un autre problème. Après le recyclage des numéros de transaction (transaction wraparound), le verrouillage d'enregistrement sur la séquence va provoquer une erreur interne à PostgreSQL (plus précisément, il s'agit d'une erreur d'accès à pg_clog, qui garde le statut des transactions). Pour éviter cette erreur, les développeurs de PostgreSQL on décidé de ne plus permettre le verrouillage d'enregistrement dans les séquences, et cela va provoquer bien sûr un dysfonctionnement de pgpool-II (la version "corrigée" de PostgreSQL sera la 9.0.5, 8.4.9, 8.3.16 et 8.2.22).
À partir de la version 3.0.5 de pgpool-II, ce dernier utilise un verrouillage de ligne sur la table pgpool_catalog.insert_lock, puisque les nouvelles versions de PostgreSQL (voir ci-dessus) ne permettent plus le verrouillage d'enregistrements. Aussi il est nécessaire de créer une table insert_lock au préalable dans toutes les bases qui sont accédées par pgpool-II. Voir Création de la table insert_lock pour plus de détails. S'il n'existe pas de table insert_lock, pgpool-II va verrouiller entièrement la table cible de l'insertion. C'est le même comportement que pour les versions 2.2 et 2.3 de pgpool-II. Si vous voulez utiliser la table insert_lock, qui est compatible avec des versions plus vieilles de pgpool-II, vous pouvez spécifier la méthode de verrouillage par le script de configure. Voir configure pour plus de détails à ce sujet.
Si vous souhaitez un contrôle plus fin (par requête) :
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é.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.
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.
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.
Ce paramètre permet de préciser une commande à exécuter par le serveur PostgreSQL
maître (primaire) lors de 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
.
recovery_1st_stage_command accepte 3 paramètres qui sont les suivants:
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.
Ce paramètre spécifie une commande à exécuter par le serveur PostgreSQL
maître (primaire) 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
.
recovery_2nd_stage_command accepte 3 paramètres qui sont les suivants:
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.
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.
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
.
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 :
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 :
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.
Erreurs spécifiques en mode réplication
En mode réplication, si pgpool s'aperçoit que le nombre de tuples affectés par INSERT, UPDATE ou DELETE ne sont pas identiques (NDT: sur tous les nœuds), il envoie une requête SQL erronée sur tous les nœuds pour que la transaction soit annulée, si le paramète failover_if_affected_tuple_mistmatch est positionné à "false" (une dégénération se produit s'il est sur "true"). Dans ce cas, les messages suivants seront envoyés sur le terminal du client:
=# UPDATE t SET a = a + 1; ERROR: pgpool detected difference of the number of update tuples Possible last query was: "update t1 set i = 1;" HINT: check data consistency between master and other db nodeOn peut voir le nombre d'enregistrements mis à jours dans le fichier de traces de PostgreSQL (dans ce cas le nœud 0 a 0 enregistrements mis à jour alors que le nœud 1 a 1 enregistrement mis à jour):
2010-07-22 13:23:25 LOG: pid 5490: SimpleForwardToFrontend: Number of affected tuples are: 0 1 2010-07-22 13:23:25 LOG: pid 5490: ReadyForQuery: Degenerate backends: 1 2010-07-22 13:23:25 LOG: pid 5490: ReadyForQuery: Number of affected tuples are: 0 1
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, backend_flag 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.
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 :
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 or si le test du Streaming Replication est
désactivé, la vérification du décalage n'est plus faite. La vérification est alors
effectuée toutes les 'sr_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.
Ce paramètre spécifie l'intervalle entre deux points de vérification du Streaming Replication, en secondes. La valeur par défaut est de 0, ce signifie que ce test est désactivé. Vous devrez recharger pgpool.conf si vous changez le paramètre sr_check_period.
Nom d'utilisateur avec lequel effectuer le test sur le Streaming Replication. Cet utilisateur doit exister dans tous les backends PostgreSQL, sans quoi le test provoque une erreur. Notez que sr_check_user et sr_check_password sont utilisés même si sr_check_period est à 0. Pour identifier le nœud primaire, pgpool-II envoie un appel à une fonction à chacun des backends PostgreSQL. sr_check_user et sr_check_password sont alors utilisés dans cette session. Vous devrez recharger pgpool.conf si vous changez la valeur de sr_check_user.
Mot de passe de l'utilisateur qui effectue les tests du Streaming Replication. Si aucun mot de passe n'est requis, vous pouvez le spécifiez avec une chaîne vide (''). Vous devrez recharger pgpool.conf si vous changez la valeur de ce paramètre.
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 nom de la colonne est "standby_delay#" (où "#" est remplacé par le numéro d'identifiant du nœud).
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.
$ 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
failover_command = '/usr/local/src/pgsql/9.0-beta/bin/failover_stream.sh %d %H /tmp/trigger_file0'
standby_mode = 'on' primary_conninfo = 'host=nom_du_nœud_primaire user=postgres' trigger_file = '/tmp/trigger_file0'
wal_level = hot_standby max_wal_senders = 1
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.
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.
Dans une transaction explicite :
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.
Dans le mode maître/esclave avec la Streaming Replication, on peut procéder à une restauration à chaud (« Online recovery »). Dans la procédure de « Online Recovery », le nœud primaire joue le rôle de serveur maître et est utilisé pour restaurer un nœud en standby spécifié. Ainsi, la procédure de restauration nécessite que le nœud primaire soit complètement fonctionnel. Si ce dernier vient à tomber, et qu'aucun serveur en standby n'est promu maître, vous devrez arrêter pgpool-II ainsi que tous les serveurs PostgreSQL et procéder à leur restauration manuellement.
Voici les étapes.
recovery_user = 'postgres'
recovery_password = 't-ishii'
recovery_1st_stage_command = 'basebackup.sh'
recovery_2nd_stage_command = ''
# cd pgpool-II-x.x.x/sql/pgpool-recovery # make # make install # psql -f pgpool-recovery.sql template1
C'est tout. On peut à présent utiliser pcp_recovery_node (dès qu'un nœud en standby s'arrête) ou alors cliquer sur le bouton « recovery » dans l'interface de pgpoolAdmin pour exécuter un « Online Recovery ». Si quelque chose tourne mal, veuillez examiner le fichier de trace de pgpool-II, celui du serveur primaire et celui du(des) serveur(s) en standby.
Pour votre gouverne, voici les étapes effectuées lors d'une procédure de restauration:
Ce mode permet l'exécution en parallèle de requêtes. Les tables peuvent être découpées, et les données distribuées sur chaque nœud. De plus, les fonctionnalités de réplication et de répartition de charge peuvent être utilisées avec ce mode, en même temps. Dans le mode parallèle, replication_mode et load_balance_mode sont positionnés à true dans le fichier pgpool.conf, alors que master_slave est positionné à false, et que parallel_mode est positionné à true. Si ce paramètre est changé, il faut redémarrer pgpool-II pour qu'il soit pris en compte.
Configuration de la base système
Pour utiliser le mode parallèle, la base système doit être configurée
correctement. La base système contient des règles, stockées dans une table,
pour choisir le nœud PostgreSQL approprié auquel envoyer les données.
La base de données système n'a pas besoin d'être créée sur le même nœud que
pgpool-II. La configuration de cette dernière est faite dans
pgpool.conf
.
Nom de l'hôte où la base de données système réside. Une chaîne vide dans ce paramètre ('') signifie que celle-ci est sur le même nœud que pgpool-II, et sera alors accédée via un socket UNIX.
Numéro de port de la base de données système
Les règles de partitionnement et autres informations seront définies
dans la base de données spécifiée ici. La valeur par défaut est
'pgpool'
.
Les règles de partitionnement et autres informations seront stockées
dans le schéma spécifié ici. La valeur par défaut est
'pgpool_catalog'
.
Nom de l'utilisateur qui se connecte à la base de données système.
Mot de passe pour l'utilisateur de la base de données système. Si aucun mot de passe n'est nécessaire, laissez une chaîne vide dans ce paramètre ('').
Chemin complet vers un fichier au format PEM contenant un ou plusieurs
certificats CA, qui doivent être utilisés pour vérifier le certificat du
serveur. C'est analogue à l'option -CAfile
de la
commande verify(1)
d'OpenSSL.
Il n'y a pas de valeur par défaut pour cette option. Du coup, aucune
vérification n'a lieu par défaut. Par contre, une vérification sera réalisée
si une valeur a été définie pour ssl_ca_cert_dir
.
Chemin vers un répertoire qui contient les certificats CA au format PEM,
qui peuvent être utilisés pour vérifier le certificat du serveur.
C'est analogue à l'option -CAfile
de la commande
verify(1)
d'OpenSSL.
Il n'y a pas de valeur par défaut pour cette option. Du coup, aucune
vérification n'a lieu par défaut. Par contre, une vérification sera réalisée
si une valeur a été définie pour ssl_ca_cert
.
Configuration initiale de la base de données système
Il faut d'abord créer la base de données et le schéma spécifiés dans le
fichier pgpool.conf
. Un script d'exemple peut être trouvé dans
$prefix/share/system_db.sql
. Si vous avez indiqué un nom
différent pour la base de données ou le schéma, adaptez ce script en
conséquence.
psql -f $prefix/share/system_db.sql pgpool
Enregistrement d'une règle de partitionnement
Les règles pour le partitionnement des données doivent être enregistrées
dans la table pgpool_catalog.dist_def
.
CREATE TABLE pgpool_catalog.dist_def( dbname TEXT, -- nom de la base schema_name TEXT, -- nom du schéma table_name TEXT, -- nom de la table col_name TEXT NOT NULL CHECK (col_name = ANY (col_list)), -- nom de la colonne de la clé de partitionnement col_list TEXT[] NOT NULL, -- noms des attributs de la table type_list TEXT[] NOT NULL, -- types de données de la table des attributs dist_def_func TEXT NOT NULL, -- nom de la fonction pour la règle de partitionnement PRIMARY KEY (dbname,schema_name,table_name) );
Enregistrement d'une règle de réplication
Les tables qui ne sont pas distribuées doivent être répliquées. Lorsqu'une requête fait la jointure d'une table distribuée avec une autre table, pgpool récupère l'information de réplication dans la table pgpool_catalog.replicate_def. Ainsi, une table est soit répliquée, soit ditribuée.
CREATE TABLE pgpool_catalog.replicate_def( dbname TEXT, --nom de la base schema_name TEXT, --nom du schéma table_name TEXT, --nom de la table col_list TEXT[] NOT NULL, -- nom des attributs de la table type_list TEXT[] NOT NULL, -- types de données des attributs de la table PRIMARY KEY (dbname,schema_name,table_name) );
Exemple basé sur le partitionnement des tables de pgbench
pgbench est un outil simple de tests de performance de PostgreSQL, disponible dans le répertoire contrib de PostgreSQL.
Dans cet exemple, la table accounts est partitionnée, les tables branches et tellers sont répliquées. Les tables accounts et branches sont jointes sur la colonne bid. La table branches est enregistrée dans la table de réplication. Si les trois tables (accounts, branches et tellers) doivent être jointes, il est nécessaire d'enregistrer aussi une règle de réplication pour la table tellers.
INSERT INTO pgpool_catalog.dist_def VALUES ( 'pgpool', 'public', 'accounts', 'aid', ARRAY['aid','bid','abalance','filler'], ARRAY['integer','integer','integer','character(84)'], 'pgpool_catalog.dist_def_accounts' ); INSERT INTO pgpool_catalog.replicate_def VALUES ( 'pgpool', 'public', 'branches', ARRAY['bid','bbalance','filler'], ARRAY['integer','integer','character(84)'] );
La règle de partitionnement (ici, pgpool_catalog.dist_def_accounts) prends une valeur pour la colonne qui sert de clé de partitionnement, et retourne le numéro du nœud de la base de données correspondante. Notez que l'identifiant des nœuds doit commencer par 0. Voici un exemple de cette fonction pour pgbench.
CREATE OR REPLACE FUNCTION pgpool_catalog.dist_def_accounts (val ANYELEMENT) RETURNS INTEGER AS ' SELECT CASE WHEN $1 >= 1 and $1 <= 30000 THEN 0 WHEN $1 > 30000 and $1 <= 60000 THEN 1 ELSE 2
Tout comme le fichier pg_hba.conf pour PostgreSQL, pgpool a la même fonctionnalité d'authentification des clients, qui est basée sur un fichier appelé pool_hba.conf.
Lorsque pgpool est installé, le fichier pool_hba.conf.sample est installé dans /usr/local/etc, qui est le répertoire par défaut des fichiers de configuration. Il faut copier pool_hba.conf.sample en pool_hba.conf puis l'éditer si nécessaire. Par défaut, l'authentification par pool_hba est activée. Se reporter à « 6. Configuration de pgpool.conf » pour plus de détails.
Le format du fichier pool_hba.conf est très similaire à celui du fichier pg_hba.conf de PostgreSQL.
local DATABASE USER METHOD [OPTION] host DATABASE USER CIDR-ADDRESS METHOD [OPTION]
Voir pool_hba.conf.sample pour une explication détaillée de chaque champ.
Voici les limitations de pool_hba.
Bien que hostssl soit invalide, pgpool-II 2.3 et supérieur supporte SSL. Voir SSL pour plus de détails.
Comme pgpool ne sait rien à propos des utilisateurs déclarés dans le serveur PostgreSQL, le nom de la base de données est testé simplement par rapport aux entrées de la colonne DATABASE dans le fichier pool_hba.conf.
Cela est dû à la même raison que pour samegroup décrit ci-dessus. Un nom d'utilisateur est testé simplement par rapport aux entrées dans la colonne USER du fichier pool_hba.conf.
À ce jour, pgpool ne supporte pas l'IPv6.
Encore une fois, c'est pour la même raison que pour samegroup (décrit ci-dessus) : pgpool n'a pas accès aux informations sur les utilisateurs et mots de passes stockés dans le serveur PostgreSQL.
Pour utiliser l'authentification md5, il faudra enregistrer votre nom d'utilisateur et son mot de passe dans pool_passwd. Voir Authentification / Contrôle d'accès pour plus de détails.
Notez que tout ce qui est décrit dans cette section concerne l'authentification entre un client et pgpool ; un client doit toujours passer à travers le processus d'authentification de PostgreSQL. Bien que pool_hba soit concerné, cela n'a pas d'importance si un nom d'utilisateur et/ou de base de données donné par un client (i.e. psql -U testuser testdb) existe ou non dans le serveur. pool_hba ne regarde en effet que si une correspondance est trouvée dans le fichier pool_hba.conf.
L'authentification PAM fonctionne grâce à l'information sur l'utilisateur trouvée sur le serveur où pgpool est exécuté. Pour activer le support de PAM dans pgpool, spécifier l'option "--with-pam" lors de la phase de configuration de la compilation :
configure --with-pam
Pour activer l'authentification PAM, on a besoin de créer un fichier de configuration du service pour pgpool dans le répertoire de configuration de PAM sur le système (qui est en général /etc/pam.d). Un fichier d'exemple nommé share/pgpool.pam est présent dans le répertoire d'installation.
Le cache de requêtes est utilisable dans tous les modes de pgpool-II. Il permet la réutilisation du résultat d'un SELECT pour améliorer les performances. Son activation dans le fichier pgpool.conf se fait de la manière suivante :
enable_query_cache = true
Cependant, il faut aussi créer la table suivante dans la base de données système de pgpool-II :
CREATE TABLE pgpool_catalog.query_cache ( hash TEXT, query TEXT, value bytea, dbname TEXT, create_time TIMESTAMP WITH TIME ZONE, PRIMARY KEY(hash, dbname) );
Notez qu'il peut aussi être nécessaire de modifier le nom du schéma dans l'exemple ci-dessus si pgpool_catalog n'est pas utilisé.
Attention: l'implémentation actuelle du cache de requête créée un cache de données dans une base de données. Ainsi, activer le cache de requêtes pourraît ne pas contribuer à une amélioration des performances. Le cache de requêtes n'est pas mis à jour, même si une table utilisée par la requête est mise à jour. Le cache de requêtes ne peut-être effacé qu'en effaçant les données de la table de cache, ou alors en redémarrant pgpool-II avec l'option -c (dont l'objet est justement d'effacer le cache).
Tous les serveurs PostgreSQL doivent être démarrés, y compris celui qui contient la base de données système de pgpool-II (si le mode utilisé l'impose), avant de démarrer pgpool-II.
pgpool [-c][-f config_file][-a hba_file][-F pcp_config_file][-n][-D][-d]
-c --clear-cache | vide le cache de requêtes |
-f config_file --config-file config-file | spécifie le fichier pgpool.conf |
-a hba_file --hba-file hba_file | spécifie le fichier pool_hba.conf |
-F pcp_config_file --pcp-password-file | spécifie le fichier pcp.conf |
-n --no-daemon | ne pas fonctionner en mode démon (le terminal n'est alors pas détaché) |
-D --discard-status | ignore le fichier de statut précédent |
-d --debug | mode de débogage |
pgpool [-f config_file][-F pcp_config_file] [-m {s[mart]|f[ast]|i[mmediate]}] stop
-m s[mart] --mode s[mart] |
attends que les clients se déconnectent avant de s'arrêter (mode par défaut) |
-m f[ast] --mode f[ast] |
n'attend pas la déconnexion des clients, et s'arrête immédiatement |
-m i[mmediate] --mode i[mmediate] |
même chose que '-m f' |
pgpool enregistre son état dans le fichier [logdir]/pgpool_status. Lorsque pgpool redémarre, il lit ce fichier et restaure le statut de chaque serveur (tel qu'il était à l'arrêt de pgpool). Cela permettra d'éviter une différence au niveau des données dans les différents nœuds PostgreSQL, qui pourrait être causée selon le scénario suivant :
Si, pour une raison quelconque, la base de données arrêtée a été synchronisée avec la base de données active d'une autre manière, pgpool_status peut alors être supprimé sereinement avant de démarrer pgpool.
pgpool-II peut recharger ses fichiers de configuration et se mettre alors à jour par rapport à ces derniers, sans avoir à être redémarré.
pgpool [-c][-f config_file][-a hba_file][-F pcp_config_file] reload
-f config_file --config-file config-file | spécifie le fichier pgpool.conf |
-a hba_file --hba-file hba_file | spécifie le fichier pool_hba.conf |
-F pcp_config_file --pcp-password-file | spécifie le fichier pcp.conf |
Il faut bien faire attention au fait que certains paramètres de configuration ne peuvent pas être changés par un rechargement. De plus, la nouvelle configuration ne prend effet qu'à partir des nouvelles sessions créées.
pgpool-II donne quelques informations via les commandes SHOW. SHOW est une commande SQL existante, mais pgpool-II l'intercepte si la requête concerne des informations spécifiques à pgpool-II. Voici les options spécifiques à pgpool-II :
Toutes les options autres que "pool_status" ont été ajoutées depuis la version 3.0
Note : Le terme 'pool' réfère au nombre de sessions PostgreSQL détenues par un processus pgpool, et non le nombre total de sessions détenues par pgpool.
L'option pool_status était disponible dans les versions précédentes, mais les autres sont apparues avec la version 3.0.
"SHOW pool_status" renvoie la liste des paramètres de configuration avec leur nom, leur valeur et leur description. Voici un exemple du résultat obtenu avec cette commande :
benchs2=# show pool_status; item | value | description -------------------------------+---------------------------------+------------------------------------------------------------------ listen_addresses | 127.0.0.1 | host name(s) or IP address(es) to listen to port | 9999 | pgpool accepting port number socket_dir | /tmp | pgpool socket directory num_init_children | 5 | # of children initially pre-forked child_life_time | 300 | if idle for this seconds, child exits
"SHOW pool_nodes" renvoie une liste de nœuds configurés. Il affiche l'identifiant du nœud, son nom d'hôte (ou son adresse IP), son port, son statut et le poids (qui n'a d'intérêt que si on utilise le mode de répartition de charge des requêtes en lecture). Les valeurs possibles pour la colonne status sont explicitées dans la partie dédiée à pcp_node_info.
benchs2=# show pool_nodes; id | hostname | port | status | lb_weight ------+-------------+------+--------+----------- 0 | 127.0.0.1 | 5432 | 2 | 0.5 1 | 192.168.1.7 | 5432 | 3 | 0.5 (2 lignes)
"SHOW pool_processes" renvoie une liste de tous les processus qui attendent une connexion ou interagissent avec une connexion.
Cette liste a 6 colonnes :
Cette vue retournera toujours un nombre de lignes équivalent à num_init_children.
benchs2=# show pool_processes; pool_pid | start_time | database | username | create_time | pool_counter ----------+---------------------+----------+-----------+---------------------+-------------- 8465 | 2010-08-14 08:35:40 | | | | 8466 | 2010-08-14 08:35:40 | benchs | guillaume | 2010-08-14 08:35:43 | 1 8467 | 2010-08-14 08:35:40 | | | | 8468 | 2010-08-14 08:35:40 | | | | 8469 | 2010-08-14 08:35:40 | | | | (5 lines)
"SHOW pool_pools" renvoie une liste de pools détenus par pgpool-II, avec leurs noms, valeurs et description. Voici un exemple de résultat :
Cette liste a 11 colonnes :
Cette vue retournera toujours le même nombre de lignes que num_init_children * max_pool
pool_pid | start_time | pool_id | backend_id | database | username | create_time | majorversion | minorversion | pool_counter | pool_backendpid | pool_connected ----------+---------------------+---------+------------+----------+-----------+---------------------+--------------+--------------+--------------+-----------------+---------------- 8465 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 0 | 0 | benchs | guillaume | 2010-08-14 08:35:43 | 3 | 0 | 1 | 8473 | 1 8466 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | (20 lines)
"SHOW pool_version" affiche la version de pgpool-II. En voici un exemple :
benchs2=# show pool_version; pool_version ------------------------ 3.0-dev (umiyameboshi) (1 line)
pgpool-II, alors qu'il est en mode réplication, peut synchroniser une base de données et attacher un nœud tout en continuant à répondre aux clients. Cette fonctionnalité est appelée « online recovery ».
Le nœud cible de cette restauration doit être dans l'état détaché avant de lancer le « online recovery ». Si on veut ajouter un serveur PostgreSQL dynamiquement, ajoutez un paramètre backend_hostname et ces paramètres associés, et rechargez pgpool.conf. pgpool-II va alors enregistrer ce nouveau serveur et l'afficher dans l'état détaché.
Attention : Penser à arrêter l'autovacuum sur le nœud maître (autrement dit le premier qui est ouvert et en fonctionnement). En effet, autovacuum pourrait changer le contenu d'une base de données et alors causer une incohérence après un « online recovery ». Cela s'applique uniquement si on fait la restauration avec un mécanisme simple tel que la technique rsync détaillée plus bas. Cela ne s'applique bien sûr pas si on utilise la technique basée sur le PITR de PostgreSQL.
Si le serveur PostgreSQL a déjà été démarré, il faut l'arrêter.
pgpool-II effectue le « online recovery » en deux phase séparées. Il y a quelques secondes ou minutes pendant lesquelles un client sera en attente de connexion à pgpool-II, lorsque la restauration et la synchronisation du nœud a lieu. Ce mécanisme suit les étapes suivantes :
La première étape de la synchronisation des données est appelée première phase. Les données sont en effet synchronisées pendant cette étape. Pendant cette dernière, les données peuvent être mises à jour ou récupérées par les clients, sur toutes les tables, de manière concurrente.
On peut spécifier un script qui sera exécuté pendant cette première phase. pgpool-II passe alors trois arguments à ce dernier :
La synchronisation des données est finalisée dans ce qui est appelé la seconde phase. Avant d'entrer dans cette dernière, pgpool-II attend que tous les clients soient déconnectés. Il bloque alors toute nouvelle connexion jusqu'à ce que cette seconde phase soit terminée. Après que toutes les connexions soient terminées, pgpool-II applique toutes les données mises à jour pendant la première et la seconde phase sur le nœud en cours de restauration. Cela achève ainsi la dernière phase de synchronisation des données.
Il est à noter qu'il y a une restriction sur le « online recovery ». Si pgpool-II lui-même est installé sur plusieurs serveurs, le « online recovery » ne fonctionnera pas correctement car pgpool-II doit arrêter tous les clients pendant la seconde phase du « online recovery ». Ainsi, s'il y a plusieurs serveurs pgpool, un seul aura reçu la commande de « online recovery » et bloquera les connexions.
Il convient de configurer les paramètres suivants pour le « online recovery » dans le fichier pgpool.conf.
Les fonctions en langage C suivantes doivent être installées dans la base template1 de tous les serveurs PostgreSQL pour que le « online recovery » fonctionne. Leur code source est dans le répertoire suivant de l'archive de pgpool-II :
pgpool-II-x.x.x/sql/pgpool-recovery/
Il convient de changer le nom du répertoire ci-dessus pour l'ajuster à votre version précise de pgpool-II. On se place dans ce dernier et on lance la commande « make install » :
% cd pgpool-II-x.x.x/sql/pgpool-recovery/ % make install
À présent, il faut installer les fonctions SQL correspondantes :
% cd pgpool-II-x.x.x/sql/pgpool-recovery/ % psql -f pgpool-recovery.sql template1
Des scripts de synchronisation de données doivent être déployés ainsi qu'un script qui permet de démarrer PostgreSQL à distance, et tout ceci, dans le répertoire des données de l'instance de PostgreSQL ($PGDATA). Plusieurs scripts d'exemple sont disponibles dans le répertoire pgpool-II-x.x.x/sample.
Voici comment faire un « online recovery » grâce au Point In Time Recovery (PITR), qui est disponible à partir de la version 8.2 de PostgreSQL. Attention, tous les serveurs impliqués doivent avoir le PITR d'activé et correctement configuré.
Il est nécessaire d'avoir un script qui se charge d'effectuer une sauvegarde complète du serveur PostgreSQL sur un nœud maître et de l'envoyer sur un nœud cible pour la restauration lors de la première phase. Ce script peut être nommé copy-base-backup par exemple. Voici un exemple de ce script :
#! /bin/sh DATA=$1 RECOVERY_TARGET=$2 RECOVERY_DATA=$3 psql -c "select pg_start_backup('pgpool-recovery')" postgres echo "restore_command = 'scp $HOSTNAME:/data/archive_log/%f %p'" > /data/recovery.conf tar -C /data -zcf pgsql.tar.gz pgsql psql -c 'select pg_stop_backup()' postgres scp pgsql.tar.gz $RECOVERY_TARGET:$RECOVERY_DATA
Ce script place le serveur maître en mode sauvegarde à chaud, puis génère le fichier recovery.conf suivant :
restore_command = 'scp master:/data/archive_log/%f %p'Ensuite, il effectue la sauvegarde, puis sort le serveur maître du mode sauvegarde à chaud et copie enfin la sauvegarde sur le nœud désiré.
La seconde phase de cette procédure est un script qui va forcer un changement de journal de transactions (XLOG). Ce script est nommé pgpool_recovery_pitr ici. Il utilise pg_switch_xlog. Cependant, il pourrait rendre la main avant que le changement de journal ne soit fait, ce qui pourrait alors provoquer un échec de la procédure d'« online recovery ». pgpool-II fournit une méthode plus sûre avec la fonction pgpool_swich_xlog, qui attend que le changement effectif de journal de transaction ait eu lieu. Cette fonction est installée avec la procédure explicitée dans la section Installation des fonctions en langage C.
Voici un script d'exemple :
#! /bin/sh # Online recovery 2nd stage script # datadir=$1 # master dabatase cluster DEST=$2 # hostname of the DB node to be recovered DESTDIR=$3 # database cluster of the DB node to be recovered port=5432 # PostgreSQL port number archdir=/data/archive_log # archive log directory # Force to flush current value of sequences to xlog psql -p $port -t -c 'SELECT datname FROM pg_database WHERE NOT datistemplate AND datallowconn' template1| while read i do if [ "$i" != "" ];then psql -p $port -c "SELECT setval(oid, nextval(oid)) FROM pg_class WHERE relkind = 'S'" $i fi done psql -p $port -c "SELECT pgpool_switch_xlog('$archdir')" template1
Cette mise à jour des séquences est uniquement utile dans le mode réplication : dans ce cas, les séquences doivent avoir le même numéro de démarrage sur tous les nœuds. Ça n'est pas utile dans le mode maître-esclave. La boucle dans ce script force PostgreSQL à émettre la valeur courante de toutes les séquences dans toutes les bases du nœud maître dans le journal de transactions afin que celles-ci soient propagées au nœud en cours de restauration.
Ces scripts doivent être déployés dans le répertoire des données de l'instance PostgreSQL (autrement dit $PGDATA).
Enfin, on édite le fichier pgpool.conf.
recovery_1st_stage_command = 'copy-base-backup' recovery_2nd_stage_command = 'pgpool_recovery_pitr'
Cette opération termine la préparation du « online recovery » via le PITR.
pgpool_remote_start
Ce script démarre le processus postmaster sur les nœuds distants. pgpool-II l'exécute de la manière suivante.
% pgpool_remote_start remote_host remote_datadir remote_host: Nom d'hôte de la machine cible à restaurer remote_datadir: Chemin vers le répertoire des données de l'instance PostgreSQL sur une machine en restauration
Dans ce script d'exemple, on démarre le processus postmaster via ssh. Afin qu'il fonctionne, on doit pouvoir se connecter via ssh sans mot de passe.
Si la restauration se fait avec PITR, il faut déployer le script de sauvegarde de base. PostgreSQL démarrera alors automatiquement en effectuant une restauration via le PITR. Il acceptera ensuite les connexions.
#! /bin/sh DEST=$1 DESTDIR=$2 PGCTL=/usr/local/pgsql/bin/pg_ctl # Déploiement du script de backup ssh -T $DEST 'cd /data/; tar zxf pgsql.tar.gz' 2>/dev/null 1>/dev/null < /dev/null # Démarrage du serveur PostgreSQL ssh -T $DEST $PGCTL -w -D $DESTDIR start 2>/dev/null 1>/dev/null < /dev/null &
PostgreSQL 7.4 n'a pas le PITR. PostgreSQL 8.0 et 8.1 n'ont pas l'option qui permet de forcer un changement de fichier de transactions. rsync peut alors être utilisé pour effectuer le « online recovery ». Dans le script d'exemple disponible dans les sources de pgpool-II, il y a un script de restauration qui est nommé pgpool_recovery. Ce dernier utilise la commande rsync. pgpool-II appelle ce script avec trois arguments.
% pgpool_recovery datadir remote_host remote_datadir datadir: Répertoire des données de l'instance PostgreSQL sur un serveur maître remote_host: Nom d'hôte (ou IP) du serveur cible à restaurer remote_datadir: Répertoire des données de l'instance PostgreSQL du serveur cible à restaurer
Ce script copie les fichiers de manière physique grâce à rsync et via ssh. Comme précédemment, on doit pouvoir se connecter via ssh sans mot de passe.
Note à propos de rsync :
Si on utilise pgpool_recovery, il convient d'ajouter les lignes suivantes au ficher pgpool.conf :
recovery_1st_stage_command = 'pgpool_recovery' recovery_2nd_stage_command = 'pgpool_recovery'
Afin de réaliser un « online recovery », on peut utiliser la commande pcp_recovery_node ou bien pgpoolAdmin.
Il est à noter qu'on doit positionner un nombre important dans le tout premier argument de pcp_recovery_node. Il s'agit d'un délai maximum en secondes. Si on utilise pgpoolAdmin, il convient aussi de mettre un grand nombre au paramètre "_PGPOOL2_PCP_TIMEOUT" dans le fichier de configuration pgmgt.conf.php.
Vous pouvez mettre à jour PostgreSQL sur chaque nœud sans stopper pgpool-II si ce dernier est en mode réplication. Veuillez notre que les sessions actives des clients vers pgpool-II seront déconnectées pendant que pgpool-II se déconnecte pour attacher des nœuds. Notez aussi que vous ne pouvez pas faire de montée en version majeure en utilisant la méthode décrite ci-dessous (c'est à dire qu'une montée en version mineure ne requiert pas de dump/restore).
Préparation du Online Recovery.
La montée en version devrait être effectuée en premier sur tous les nœuds qui ne sont pas maîtres. Arrêtez PostgreSQL sur un des nœuds non-maître. pgpool-II va détecter l'arrêt de PostgreSQL et va provoquer sa dégénération, et notifier tout cela dans le fichier de traces, comme ci-dessous. À ce niveau, toutes les sessions connectées à pgpool-II sont déconnectées.
2010-07-27 16:32:29 LOG: pid 10215: set 1 th backend down status 2010-07-27 16:32:29 LOG: pid 10215: starting degeneration. shutdown host localhost(5433) 2010-07-27 16:32:29 LOG: pid 10215: failover_handler: set new master node: 0 2010-07-27 16:32:29 LOG: pid 10215: failover done. shutdown host localhost(5433)
Mettez à jour la version de PostgreSQL sur le nœud arrêté. Vous pouvez écraser l'ancienne version de PostgreSQL, bien que nous reccommandions que vous déplaciez l'ancien PostgreSQL ailleurs, afin que vous puissiez l'avoir à disposition, au cas où.
Si vous installez le nouveau PostgreSQL dans un endroit différent de l'ancien et ne ne souhaitez pas mettre à jour votre script de restauration, vous devrez néanmoins avoir des chemins qui correspondent en utilisant des outils comme le lien symbolique. Si vous décidez d'écraser, vous pouvez vous passer des étapes qui suivent jusqu'à celle qui concerne l'installation de la fonction en C. Vous pouvez exécuter le online recovery immédiatement.
Changer le répertoire d'installation d'un ancien PostgreSQL. Le répertoire d'installation de PostgreSQL est supposé être /usr/local/pgsql dans la description suivante.
$ mv /usr/local/pgsql /usr/local/pgsql-old
Créer un lien symbolique vers l'endroit où la nouvelle version de PostgreSQL est installée. Cela vous permettra de continuer à utiliser le même chemin de recherche des commandes que vous utilisez actuellement (NDT: le $PATH pour les Linux/Unix par exemple). Le répertoire d'installation de la nouvelle version de PostgreSQL est supposée être /usr/local/pgsql-new dans la description suivante.
$ ln -s /usr/local/pgsql-new /usr/local/pgsql
Si un répertoire de base de données est situé dans le répertoire de l'ancienne installation de PostgreSQL, vous devriez le créer ou le copier afin que la nouvelle version de PostgreSQL puisse y accéder. Dans l'exemple suivant, nous utilsons le lien symbolique.
$ ln -s /usr/local/pgsql-old/data /usr/local/pgsql/data
Installez les fonctions C dans PostgreSQL. La section "Installing C functions" de cette documentation devrait vous y aider. Puisque le Online Recovery va copier le cluster de base de données, la dernière étape qui consiste à installer les fonctions en utilisant psql n'est pas nécessaire. Faites un make install.
Faites le Online Recovery. Vous en avez terminé avec la mise à jour de la version. Pour exécuter le Online Recovery, vous pouvez utiliser la commande PCP pcp_recovery_node ou pgpoolAdmin.
Répétez les étapes ci-dessus sur chacun des nœuds. Le nœud maîte ne devrait être mis à jour qu'en dernier. Vous avez terminé.
Vous pouvez mettre à jour les serveurs PostgreSQL en standby sans arrêter pgpool-II.
La procédure pour mettre à jour les serveurs en standby est la même que celle du mode réplication plus haut. Merci de vous référer à la section "Online Recovery avec Streaming Replication" pour mettre en place recovery_1st_stage_command et recovery_2nd_stage_command.
Vous ne pouvez pas changer la version du nœud primaire sans arrêter pgpool-II. Vous devrez stopper pgpool-II pour mettre à jour le nœud primaire. La procédure pour mettre à jour le nœud primaire est la même que celle pour mettre à jour le(s) serveur(s) en standby. La procédure pour mettre à jour le nœud primaire PostgreSQL est la suivante:
Pour sauvegarder les serveurs PostgreSQL et la base de donnée système, vous pouvez faire une sauvegarde physique (fichiers), une sauvegarde logique (pg_dump, pg_dumpall) ou le PITR, de la même façon que PostgreSQL. Veuillez noter qu'une sauvegarde logique ou PITR devrait être faite directement via PostgreSQL, plutôt que via pgpool-II pour éviter les erreurs causées par load_balance_mode et replicate_select.
Si pgpool-II fonctionne en mode réplication ou en mode maître/esclave, faire une sauvegarde sur tous les nœuds du cluster.
Si vous utilisez le mode maître/esclave et un système de réplication asynchrone (comme Slony-I ou le Streaming Replication), et avez besoin de la dernière sauvegarde, vous devriez alors avoir aussi une sauvegarde du nœud maître.
pg_dump pose un verrou de type ACCESS SHARE sur la base de données. Les commandes qui posent un verrou de type ACCESS EXECUTE, comme ALTER TABLE, DROP TABLE, TRUNCATE, REINDEX, CLUSTER et VACUUM FULL devront attendre la fin du pg_dump à cause d'un conflit de verrou. Cela pourrait aussi affecter le nœud primaire même si vous faites un pg_dump sur le standby.
Si vous utilisez le mode parallèle et avez besoin d'une sauvegarde consistante, vous devrez arrêter pgpool-II.
Si vous utiliser une sauvegarde logique, arrêtez les applications puis pgpool-II et effectuez alors un pg_dump (ou pg_dumpall) sur tous les nœuds. Une fois ces sauvegardes terminées, démarrez pgpool-II puis vos applications.
Pour utiliser le PITR, veuillez vous assurer que les horloges systèmes sont identiques sur tous les nœuds. Préparez la sauvegarde des archives et effectuez une sauvegarde de la base. Après avoir terminé les sauvegardes, arrêter et redémarrez les applications ou pgpool-II. Notez le temps de l'arrêt et du démarrage. Cet arrêt temporaire permettra d'avoir un état consistant à travers tous les clusters. Si vous avez besoin de restaurer depuis la sauvegarde et des archives logs, placez recovery_target_time du fichier recovery.conf au beau milieu de l'arrêt et redémarrage, notés précédemment.
Vous devez sauvegarder la base système si pgpool-II fonctionne en mode parallèle ou si vous utilisez le cache de requêtes. Sauvegardez la base spécifiée par le paramètre system_db_dbname dans le fichier pgpool.conf.
pgpool-II peut fonctionner sur un serveur dédié, sur le serveur où les applications fonctionnent ou sur d'autres serveurs. Dans cette section nous abordons les différentes façons de déployer pgpool, avec leurs avantages et leurs inconvénients.
pgpool-II fonctionne sur un serveur dédié. C'est assez simple, et pgpool-II n'a pas d'interactions avec d'autres serveurs logiciels. L'inconvénient évident c'est qu'il vous faut plus de matériel. De plus, pgpool-II peut-être un SPOF (Single Point Of Failure) dans cette configuration (vous pouvez éviter cela en utilisant pgpool-HA décrit plus loin)
pgpool-II est déployé sur un serveur où Apache, JBoss, Tomcat ou autre serveur web fonctionne. Puisque la communication entre pgpool-II et les serveurs webs ou d'application se fait au sein de la même machine locale, la communication via des sockets peut-être plus rapide qu'entre serveurs distants. De plus, si vous utilisez plusieurs serveurs web ou d'application, vous pouvez éviter le problème du SPOF (dans ce cas, vous devez avoir un pgpool.conf identique sur toutes les instances pgpool-II). Il y a cependant plusieurs choses auxquelles vous devez faire attention dans cette configuration:
pgpool-II fonctionne sur le serveur où PostgreSQL est installé. Vous pouvez éviter le problème du SPOF par la configuration. De plus, vous devez de toute évidence acheter un serveur dédié supplémentaire. L'inconvénient de cette configuration est que les applications doivent savoir à quel serveur de données elles se connectent. Pour éviter ce problème vous pouvez utiliser une IP virtuelle avec pgpool-HA.
pgpool-HA est un logiciel qui apporte la haute-disponibilité à pgpool-II grâce à heartbeat. pgpool-HA est un sous-projet de pgpool, comme l'est pgpool-II. pgpool-HA est disponible sur le site de développement, et est un logiciel Open-Source.
Cette section décrit quelques problèmes qui peuvent survenir lors de l'utilisation de pgpool-II, ainsi que leur solutions.
pgpool-II vérifie périodiquement que tous les serveurs configurés fonctionnent correctement.
2010-07-23 16:42:57 ERROR: pid 20031: health check failed. 1 th host foo at port 5432 is down 2010-07-23 16:42:57 LOG: pid 20031: set 1 th backend down status 2010-07-23 16:42:57 LOG: pid 20031: starting degeneration. shutdown host foo(5432) 2010-07-23 16:42:58 LOG: pid 20031: failover_handler: set new master node: 0 2010-07-23 16:42:58 LOG: pid 20031: failover done. shutdown host foo(5432)
Ici, la trace montre que le serveur 1 (nom d'hôte "foo") s'arrête puis est déconnecté (shutdown) de pgpool. Ensuite, le serveur 0 devient le nouveau maître. Il convient donc de vérifier le serveur 1 et corriger la cause de l'erreur. Ensuite, il faudra effectuer un « online recovery » sur le serveur 1 si c'est possible.
2010-07-26 18:43:24 LOG: pid 24161: ProcessFrontendResponse: failed to read kind from frontend. frontend abnormally exited
Cette trace indique simplement que le programme client ne s'est pas connecté correctement à pgpool-II. Les causes possibles sont : un bug dans les applications clientes, la déconnexion forcée d'une application cliente (un "kill" par exemple) ou bien une erreur réseau temporaire. Ce genre d’événements ne mène pas à la destruction d'une base de données ou même à une corruption de données. Il s'agit juste d'un avertissement sur le fait qu'il y a eu une violation du protocole utilisé par pgpool-II. Il est cependant recommandé d'investiguer plus en avant si ce message arrive trop souvent.
Cette erreur peut survenir si pgpool-II fonctionne en mode réplication.
2010-07-22 14:18:32 ERROR: pid 9966: kind mismatch among backends. Possible last query was: "FETCH ALL FROM c;" kind details are: 0[T] 1[E: cursor "c" does not exist]
pgpool-II attend les réponses des serveurs PostgreSQL après leur avoir envoyé une commande SQL. Ce message indique que tous les serveurs de données ne retournent pas le même type de réponse. La requête SQL qui a causé l'erreur se trouve après « Possible last query was: ». Ensuite, le type de réponse suit. Ici, on peut lire que « 0[T] » affiche la réponse du serveur de données: « 0[T] » (renvoi de la description de l'enregistrement), et que « 1[E » affiche que le serveur 1 retourne une erreur avec le message « cursor c does not exist », alors que le serveur 0 renvoie bien la description de l'enregistrement.
Attention, on pourrait aussi avoir cette erreur dans le mode maître-esclave. Par exemple, même dans le mode maître-esclave, la commande SET sera envoyée à tous les serveurs de données pour qu'ils soient dans le même état.
Il convient de vérifier alors les serveurs de données et éventuellement les resynchroniser en utilisant le « Online Recovery », quand c'est possible et si nécessaire.
Dans le mode réplication, pgpool-II a détecté un nombre différent d'enregistrements mis à jour (en INSERT, UPDATE ou DELETE) sur les différents serveurs.
2010-07-22 11:49:28 ERROR: pid 30710: pgpool detected difference of the number of inserted, updated or deleted tuples. Possible last query was: "update t1 set i = 1;" 2010-07-22 11:49:28 LOG: pid 30710: ReadyForQuery: Degenerate backends: 1 2010-07-22 11:49:28 LOG: pid 30710: ReadyForQuery: Affected tuples are: 0 1
Dans l'exemple ci-dessus, le nombre d'enregistrements mis à jour grâce à « UPDATE t1 SET i = 1 » est différent à travers les différents serveurs de données. La ligne qui suit indique que le serveur 1 a été dégénéré (déconnecté) : c'est la conséquence du fait que pour le serveur 0 le nombre d'enregistrement mis à jours a été de 0, alors que pour le serveur 1 le nombre d'enregistrements modifiés a été de 1.
Il convient alors d'arrêter le serveur que l'on suspecte être désynchronisé (ou simplement ne pas avoir les bonnes données), puis de procéder à un « online recovery ».
pgpool-II 2.3.2 et suivants supportent la réplication des « large objects » si le serveur PostgreSQL est au moins en version 8.1. Pour que cela fonctionne, il faut activer la directive de configuration lobj_lock_table dans le fichier pgpool.conf. Cependant, la réplication des « large objects » utilisant la fonction PostgreSQL lo_import n'est pas supportée.
Tout ce qui concerne les tables temporaires est toujours exécuté sur le maître. À partir de la version 3.0 de pgpool-II, les SELECT sur ces tables sont eux-aussi exécutés sur le maître. Cependant, si le nom de la table temporaire est utilisé comme un littéral dans le SELECT, il n'y a aucun moyen de le détecter. Du coup, les SELECT seront répartis entre les serveurs PostgreSQL. Cela amènera à une erreur, la table n'existant que sur le maître ("not found the table..."). Pour éviter ce problème, il faut utiliser le commentaire « /*NO LOAD BALANCE*/ » dans le corps de la requête SQL contenant l'appel en SELECT sur la table temporaire.
Voici en uxemple de SELECT qui pose problème : SELECT 't1'::regclass::oid;
La commande "\d" de psql utilise les tables de nom en littéral. À partir de la version 3.0 de pgpool-II, ce dernier va tester si le SELECT contient un accès au catalogue système et enverra alors les requêtes au maître dans l'affirmative. Cela permet de contourner le problème.
Il n'y a aucune garantie que toute donnée obtenue via un mécanisme dépendant du contexte (par exemple un nombre au hasard, un numéro de transaction, un OID, un SERIAL ou une sequence) sera répliquée correctement sur plusieurs serveurs PostgreSQL.
Pour SERIAL, l'activation de la directive de configuration insert_lock permettra de répliquer correctement la donnée. Cela permettra aussi un bon fonctionnement de "SELECT setval()" et "SELECT nextval()".
À partir de la version 2.3 de pgpool, les INSERT et UPDATE qui utilisent CURRENT_TIMESTAMP, CURRENT_DATE et now() seront répliqués correctement. De même, les INSERT et UPDATE pour les tables qui utilisent CURRENT_TIMESTAMP, CURRENT_DATE et now() comme leur valeur par défaut (DEFAULT valeur) seront aussi répliqués correctement. Cela est obtenu en remplaçant ces fonctions par des constantes qui sont récupérées sur le maître au moment de l'exécution de la requête. Il y a cependant quelques limitations :
CREATE TABLE rel1( d1 date DEFAULT CURRENT_DATE + 1 )Ceci est traité de la même façon que :
CREATE TABLE rel1( d1 date DEFAULT CURRENT_DATE )
pgpool-II 3.1 et suivants gèrent ces cas correctement. Ainsi, la colonne "d1" aura demain comme valeur par défaut. Cependant, cette amélioration ne s'applique pas dans les protocoles étendus (qui sont utilisés en JDBC ou PHP PDO par exemple) ou si un PREPARE est utilisé.
Il est à noter que si le type de la colonne n'est pas temporel, la réécriture n'est pas effectuée. En voici un exemple :
foo bigint default (date_part('epoch'::text,('now'::text)::timestamp(3) with time zone) * (1000)::double precision)
CREATE TABLE rel1( c1 int, c2 timestamp default now() )On peut répliquer :
INSERT INTO rel1(c1) VALUES(1)puis que cela se transforme en :
INSERT INTO rel1(c1, c2) VALUES(1, '2009-01-01 23:59:59.123456+09')Cependant :
INSERT INTO rel1(c1) SELECT 1ne peut pas être transformé. Il ne sera donc pas correctement répliqué avec l'implémentation actuelle. Les valeurs seront cependant insérées, mais sans aucune transformation.
Les tables créées avec CREATE TEMP TABLE
seront supprimées à la
fin de la session en spécifiant DISCARD ALL dans le paramètre de configuration
reset_query_list si on utilise la version 8.3 ou supérieure de PostgreSQL.
Pour les version 8.2.X et précédentes, CREATE TEMP TABLE
ne
sera pas supprimé à la sortie de la session.
Ceci est dû au pooling de connexion, qui, du point de vue du serveur
PostgreSQL, garde la session en vie.
Pour éviter cela, on doit supprimer explicitement la table dans le bloc de
transaction, soit en ajoutant un DROP TABLE
, soit en créant la
table temporaire avec CREATE TEMP TABLE ... ON COMMIT DROP
.
Voici les requêtes qui ne peuvent pas être traitées par pgpool-II :
On ne peut pas utiliser DEFAULT
avec la colonne qui sert de clé
de partitionnement. Par exemple, si la colonne x dans la table t est la colonne
qui sert de clé de partitionnement :
INSERT INTO t(x) VALUES (DEFAULT);
est invalide. De même, les fonctions ne peuvent pas être utilisées pour cette valeur non plus.
INSERT INTO t(x) VALUES (func());
Les valeurs constantes doivent être utilisées pour un INSERT avec la clé de
partitionnement.
SELECT INTO
et INSERT INTO ... SELECT
ne sont pas supportés non plus.
La cohérence des données entre les serveurs pourrait être perdue si la colonne qui sert de clé de partitionnement subit des mises à jour. En effet, pgpool-II ne re-partitionne pas les données ainsi mises à jour.
Une transaction ne peut pas être annulée (ROLLBACK) si la requête qui a causé l'erreur sur un ou plusieurs serveurs PostgreSQL est due à une violation de contrainte.
Si une fonction est appelée dans la clause WHERE
, la requête
pourrait ne pas être correctement exécutée. Par exemple :
UPDATE branches set bid = 100 where bid = (select max(bid) from beances);
Si une fonction est appelée dans la clause WHERE
, la requête
pourrait ne pas être correctement exécutée. Par exemple :
SELECT * FROM branches where bid = (select max(bid) from beances) FOR UPDATE;
COPY BINARY
n'est pas supporté.
COPY à partir de fichiers n'est pas non plus supporté. Seuls COPY FROM
STDIN
et COPY TO STDOUT
sont supportés.
Pour mettre à jour une règle de partitionnement, pgpool-II doit être redémarré pour qu'il puisse relire les règles dans sa base de données système.
Les requêtes SELECT
exécutées à l'intérieur d'un bloc
de transactions seront exécutés dans des transactions séparées. Voici un
exemple :
BEGIN; INSERT INTO t(a) VALUES (1); SELECT * FROM t ORDER BY a; << l'INSERT ci-dessus n'est pas visible pour cette requête SELECT END;
La même définition de vue ou de règle (RULE) sera créée sur tous les serveurs.
SELECT * FROM a, b where a.i = b.i
Les jointures
comme celles ci-dessus seront exécutées sur chaque
serveur, et le résultat de chaque serveur sera intégré pour être retourné au
client. Les vues et règles ne peuvent pas faire de jointures à travers les
différents serveurs.
Cependant, pour faire une jointure entre des tables dont les données sont
présentes sur un même serveur, une vue peut être utilisée.
Cette vue doit être enregistrée dans la table du catalogue
pgpool_catalog.dist_def. De même, un col_name et un dist_def_func devront
être enregistrés. Ces derniers sont utilisés lors qu'une insertion est réalisée
sur la vue.
Pour les fonctions, c'est la même définition qui sera utilisée pour leur création dans les différents serveurs de données. Comme précédemment, on ne peut pas faire de jointure entre les différents serveurs au sein d'une fonction.
Le protocole étendu de requêtage (« extended query protocol ») utilisé par les connecteurs JDBC, entre autres, n'est pas supporté. Le protocole simple doit être utilisé à la place. Cela veut dire, entre autres, qu'on ne peut pas utiliser les requêtes préparées.
Ce n'est pas supporté non plus. Les clauses ON et USING doivent être utilisées à la place.
La clause USING est convertie en une clause ON par le processus qui réécrit les requêtes. Ainsi, lorsque * est utilisé comme liste cible, les colonnes jointes apparaissent deux fois.
Voici un exemple :
=# SELECT * FROM t1 JOIN t2 USING(id); id | t | t ----+-----+------- 1 | 1st | first (1 row)
Le processus de réécriture de requêtes va réécrire USING en ON. Le résultat est alors :
=# SELECT * FROM t1 JOIN t2 ON t1.id = t2.id; id | t | id | t ----+-----+----+------- 1 | 1st | 1 | first (1 row)
On remarque que la colonne t est dupliquée.
pgpool-II n'opère pas de traduction entre les différents caractères multi-octets. L'encodage utilisé par le client, le serveur et la base de données système doit donc être identique.
pgpool-II ne peut pas prendre en charge les requêtes multiples (plusieurs requêtes séparées par un point-virgule, exécutées en un coup).
Les deadlocks à travers plusieurs serveurs ne peuvent pas être détectés. Par exemple :
(la table "tellers" est partitionnée avec la règle suivante) tid <= 10 --> node 0 tid >= 10 --> node 1 A) BEGIN; B) BEGIN; A) SELECT * FROM tellers WHERE tid = 11 FOR UPDATE; B) SELECT * FROM tellers WHERE tid = 1 FOR UPDATE; A) SELECT * FROM tellers WHERE tid = 1 FOR UPDATE; B) SELECT * FROM tellers WHERE tid = 11 FOR UPDATE;
Dans le cas ci-dessus, un serveur seul ne peut pas détecter de deadlock. Du coup, pgpool-II attendra une réponse indéfiniment. Ce phénomène peut apparaître avec toute requête qui acquiert un verrou au niveau de l'enregistrement.
Aussi, si un deadlock arrive sur un serveur, l'état de la transaction sur chaque serveur ne sera pas cohérent. Ainsi, pgpool-II arrête le processus si un deadlock est détecté.
pool_read_kind: kind does not match between master(84) slot[1] (69)
Les objets qui se trouve dans un autre schéma que public doivent être préfixés par le nom du schéma dans lequel ils se trouvent :
schéma.objet
pgpool-II ne peut pas résoudre le nom de schéma correct lorsque le chemin est configuré comme suit :
set search_path = xxx
et que le nom du schéma n'est pas précisé dans la requête.
Une table ou un nom de colonne ne peut pas être préfixé par « pool_ ». En effet, lors de la réécriture des requêtes, ces noms sont utilisés par des processus internes à pgpool-II.
On ne peut définir qu'une seule clé de partitionnement par règle de partitionnement. Les condition comme « x ou y » ne sont pas supportées.
La bibliothèque libpq
est liée lors de la compilation de
pgpool-II. La version de la libpq doit être la 3.0.
Toute tentative de compilation de pgpool-II avec la version 2.0 de la libpq
finira par un échec. De même, la base de données système doit être au minimum dans
une version 7.4 de PostgreSQL.
Actuellement, le cache de requêtes doit être supprimé manuellement. pgpool-II n'a pas de mécanisme d'invalidation de cache automatique lorsque les données sont mises à jour.
Les commandes PCP sont des commandes UNIX qui interagissent avec pgpool-II à travers le réseau.
* pcp_node_count - retourne le nombre de nœuds (serveurs PostgreSQL) * pcp_node_info - retourne l'information sur un nœud * pcp_proc_count - retourne la liste des processus * pcp_proc_info - retourne l'information sur un processus * pcp_systemdb_info - retourne l'information sur la base de donnée système * pcp_detach_node - détache un nœud de pgpool-II * pcp_attach_node - attache un nœud à pgpool-II * pcp_promote_node - promeut un nouveau nœud maître à pgpool-II * pcp_stop_pgpool - stoppe pgpool-II
Il y a cinq arguments qui sont communs à toutes les commandes PCP. Ils donnent l'information relative à l'authentification et à pgpool-II. Des arguments complémentaires peuvent être nécessaires pour quelques commandes.
$ pcp_node_count 10 localhost 9898 postgres hogehoge 1er argument - délai maximum en secondes (PCP se déconnecte si pgpool-II ne répond pas dans le temps imparti ici) 2nd argument - nom d'hôte (ou adresse IP) du serveur pgpool-II 3ème argument - numéro de port de PCP 4ème argument - nom d'utilisateur de PCP 5ème argument - mot de passe de l'utilisateur de PCP
Les noms d'utilisateurs et mot de passe PCP doivent être déclarés
dans le fichier pcp.conf
installé dans le répertoire
$prefix/etc
.
L'option -F
peut être utilisée lors du démarrage de pgpool-II si
le fichier pcp.conf
est placé ailleurs. Les mots de passe n'ont pas besoin
d'être au format md5 lorsqu'on les passe aux commandes PCP.
Toutes les commandes PCP renvoie les résultats vers la sortie standard.
Format : pcp_node_count _timeout_ _hôte_ _port_ _userid_ _passwd_
Affiche le nombre total de nœuds définis dans le fichier pgpool.conf
. Il ne
fait aucune distinction entre le statut des différents nœuds. Ainsi, tous les nœuds
sont comptés ici.
Format : pcp_node_info _timeout_ _hôte_ _port_ _userid_ _passwd_ _nodeid_
Affiche l'information relative au numéro de nœud donné. Voici un exemple de sortie :
$ pcp_node_info 10 localhost 9898 postgres hogehoge 0 host1 5432 1 1073741823.500000 Le résultat est dans l'ordre suivant: 1. nom d'hôte 2. numéro de port 3. statut 4. poids configuré pour la répartition de charge Le statut est représenté par un chiffre de 0 à 3 : 0 - Cet état est uniquement utilisé pendant l'initialisation. PCP ne l'affichera jamais 1 - Le nœud est en ligne, mais aucune connexion n'est encore faite dessus 2 - Le nœud est en ligne, et les connexions sont poolés 3 - Le nœud est arrêté
Le poids configuré pour la répartition de charge est affiché dans un format normalisé.
L'option --verbose peut permettre une meilleure compréhension. Par exemple :
$ pcp_node_info --verbose 10 localhost 9898 postgres hogehoge 0 Hostname: host1 Port : 5432 Status : 1 Weight : 0.5
La spécification d'un identifiant de nœud invalide résultera dans une erreur avec un code de sortie 12, et « BackendError » sera alors affiché.
Format : pcp_proc_count _timeout_ _host_ _port_ _userid_ _passwd_
Liste les identifiants des processus fils de pgpool-II. S'il y a plus d'un processus, les identifiants seront délimités par un espace.
Format: pcp_proc_info _timeout_ _host_ _port_ _userid_ _passwd_ _processid_
Affiche l'information d'un processus fils de pgpool-II, désigné par son identifiant de processus. Voici un exemple de retour de cette commande :
$ pcp_proc_info 10 localhost 9898 postgres hogehoge 3815 postgres_db postgres 1150769932 1150767351 3 0 1 1467 1 postgres_db postgres 1150769932 1150767351 3 0 1 1468 1 Le résultat est affiché dans l'ordre suivant : 1. nom de la base de données connectée 2. nom de l'utilisateur connecté 3. horodatage correspondant au démarrage du processus 4. horodatage correspondant au démarrage de la connexion 5. numéro de version majeure du protocole 6. numéro de version mineure du protocole 7. compteur du nombre de réutilisations de cette connexion 8. numéro d'identifiant du processus serveur PostgreSQL 9. 1 si le client est connecté, 0 sinon
S'il n'y a aucune connexion aux processus serveurs, rien ne sera affiché. S'il y a plusieurs connexions, les informations seront affichées sur plusieurs lignes et plusieurs fois. Les horodatages sont affichés au format EPOCH.
L'option --verbose permet de mieux comprendre la sortie de la commande. Par exemple :
$ pcp_proc_info --verbose 10 localhost 9898 postgres hogehoge 3815 Database : postgres_db Username : postgres Start time : 1150769932 Creation time: 1150767351 Major : 3 Minor : 0 Counter : 1 PID : 1467 Connected : 1 Database : postgres_db Username : postgres Start time : 1150769932 Creation time: 1150767351 Major : 3 Minor : 0 Counter : 1 PID : 1468 Connected : 1
La spécification d'un identifiant de nœud invalide résultera dans une erreur avec un code de sortie 12, et « BackendError » sera alors affiché.
Format : pcp_systemdb_info _timeout_ _host_ _port_ _userid_ _passwd_
Affiche des informations sur la base de données système. Voici un exemple de sortie :
$ pcp_systemdb_info 10 localhost 9898 postgres hogehoge localhost 5432 yamaguti '' pgpool_catalog pgpool 3 yamaguti public accounts aid 4 aid bid abalance filler integer integer integer character(84) dist_def_accounts yamaguti public branches bid 3 bid bbalance filler integer integer character(84) dist_def_branches yamaguti public tellers bid 4 tid bid tbalance filler integer integer integer character(84) dist_def_tellers L'information sur la base de donnée système sera affichée sur la toute première ligne. Voici l'ordre des résultats : 1. nom d'hôte 2. numéro de port 3. nom d'utilisateur 4. mot de passe (une chaîne vide s'il n'y en a pas) 5. nom de schéma 6. nom de la base de données 7. nombre de règles de partitionnement définies
Ensuite, les règles de partitionnement sont affichées sur les lignes suivantes. S'il y a de multiples définitions, elles seront affichées sur autant de lignes que nécessaire. Le résultat s'affiche dans l'ordre suivant :
1. le nom de la base de données cible du partitionnement 2. le nom du schéma dans cette base 3. le nom de la table dans ce schéma 4. le nom de la colonne qui sert de clé de partitionnement 5. le nombre de colonnes dans la table 6. le nom de ces colonnes (autant de fois que précisé au 5.) 7. le nom des types de données de ces colonnes (autant de fois que précisé au 5.) 8. le nom de la fonction utilisée pour la règle de partitionnement
Si la base de données système n'est pas définie (autrement dit, on n'est pas dans un mode pgpool-II, et le cache de requêtes est désactivé), on a une erreur avec un statut de sortie à 12, et le message « BackendError » est affiché.
Format : pcp_detach_node [-g] _timeout_ _host_ _port_ _userid_ _passwd_ _nodeid_
Détache le nœud spécifié de pgpool-II. Si l'option -g est donnée, la commande attend que tous les clients soient déconnectés (à moins que le paramètre client_idle_limit_in_recovery soit configuré à -1 ou que le paramètre recovery_timeout soit expiré).
Format : pcp_attach_node _timeout_ _host_ _port_ _userid_ _passwd_ _nodeid_ Attache le nœud spécifié à pgpool-II.
Format: pcp_promote_node [-g] _timeout_ _host_ _port_ _userid_ _passwd_ _nodeid_ Promeut le nœud spécifié comme nouveau maître au sein de pgpool-II, en mode maître/esclave avec Streaming Replication uniquement. Si l'option -g est donnée, attend que tous les clients soient déconnectés (à moins que client_idle_limit_in_recovery soit à -1 ou que le recovery_timeout soit expiré).
Format : pcp_stop_pgpool _timeout_ _host_ _port_ _userid_ _passwd_ _mode_
Arrête le processus pgpool-II dans le mode d'arrêt spécifié. Les différents modes d'arrêt sont les suivants :
s - mode intelligent f - mode rapide i - mode immédiat
Si le processus pgpool-II n'existe pas, on a une erreur avec un statut de sortie à 8, et le message « ConnectionError » sera affiché.
En fait, il n'y a pas de différence entre les modes rapide et immédiat. pgpool-II arrête tous les processus, qu'il y ait des clients connectés aux processus serveurs ou pas.
Les commandes PCP on un code de sortie à 0 lorsque tout se passe bien. Si une erreur arrive, ces dernières ont un code de sortie différent, dont voici la liste :
UNKNOWNERR 1 Erreur inconnue (ne devrait pas arriver) EOFERR 2 Erreur de fin de fichier NOMEMERR 3 Erreur liée à une insuffisance de mémoire disponible READERR 4 Erreur alors qu'une lecture sur le serveur était en cours WRITEERR 5 Erreur alors qu'une écriture sur le serveur était en cours TIMEOUTERR 6 Timeout INVALERR 7 Les arguments passés à une commande PCP sont invalides CONNERR 8 Erreur de connexion au serveur NOCONNERR 9 Aucune connexion n'existe SOCKERR 10 Erreur de socket unix HOSTERR 11 Erreur de résolution de nom d'hôte BACKENDERR 12 Erreur sur le processus PCP sur le serveur AUTHERR 13 Erreur d'autorisation
La version 2.0 de pgpool-II amène de nombreuses améliorations, en comparaison à la version 1. Attention, ce qui suit ne s'applique pas à la version 1.
Le moteur d'exécution parallèle est implémenté dans pgpool-II. Ce moteur exécute la même requête sur tous les nœuds, et pilote le moteur qui transmet les résultats au client, en fonction de la réponse des différents nœuds.
Cette partie explique le fonctionnement de la réécriture de requêtes que fait pgpool-II en mode parallèle.
En mode parallèle, une requête transmise par les clients passe par deux étapes de traitements :
Ce qui suit détaille ces deux étapes.
Introduction
La récupération de la requête soumise par le client passe par l'analyseur SQL. Elle est alors analysée grâce aux informations stockées dans la base de données système. Le statut d'exécution stocke alors sur quel(s) nœud(s) la requête peut être traitée. Par exemple, si les données d'une table sont distribuées sur plusieurs serveurs (comme déclaré dans la table pgpool_catalog.dist_def du catalogue), ces dernières doivent être récupérées de plusieurs serveurs. Ainsi, cette étape retourne le statut P lors que les données doivent être récupérées sur tous les serveurs, L quand elles peuvent être récupérées sur un seul serveur. Le statut spécial S intervient dans un cas particulier : ce dernier signifie qu'il doit y avoir au moins une autre étape exécutée avant de pouvoir récupérer les données de tous les serveurs. Par exemple, trier les données en provenance d'une table enregistrée dans la table catalogue pgpool_catalog.dist_def.
La requête est analysée dans l'ordre suivant, et son statut d'exécution change alors au cours de cette analyse. Comment et où sera exécutée la requête dépend du statut final de la requête principale.
La relation entre le statut d'exécution final du SELECT et l'endroit où il est exécuté est comme suit :
Statut d'exécution | Lieu d'exécution |
L | La requête peut-être exécutée sur n'importe quel serveur |
P | Retourne les données au client en exécutant la même requête sur tous les serveurs en utilisant le moteur d'exécution en parallèle. |
S | Après traitement dans la base de données système, les données sont renvoyées au client. |
Ces règles s'appliquent aussi aux sous-requêtes. Dans l'exemple simple ci-dessous, si la table P1-table est enregistrée dans la table catalogue pgpool_catalog.dist_def sur la base de données système (P1-table est alors distribuée), le statut d'exécution final de la sous-requête est alors P, et comme résultat, la requête parent du SELECT devient alors obligatoirement P.
SELECT * FROM (SELECT * FROM P1-table) as P2-table;
Il convient d'expliquer à présent comment le statut d'exécution change concrètement. Commençons par un exemple simple, pour expliquer le statut lié à la clause FROM.
Statut d'exécution de la clause FROM
Ceci est une requête qui récupère des données (SELECT). L'ensemble de données et son statut (P, L et S) sont définis en fonction de la clause FROM. Le statut d'exécution de la table est comme suit : lorsqu'il n'y a qu'une seule table dans la clause FROM, le statut d'exécution de l'ensemble de données entier est le même que celui de cette table. Lorsqu'il y a deux ou plusieurs tables ou des sous-requêtes dans la clause FROM, l'exécution est décidée en fonction de la méthode de jointure et des statuts d'exécutions, comme précisé dans la table suivante.
Type de jointure | LEFT OUTER JOIN | RIGHT OUTER JOIN | FULL OUTER JOIN | Other | ||||||||
left/right | P | L | S | P | L | S | P | L | S | P | L | S |
P | S | P | S | S | S | S | S | S | S | S | P | S |
L | S | L | S | P | L | S | S | L | S | P | L | S |
S | S | S | S | S | S | S | S | S | S | S | S | S |
Dans les exemple suivants, la table P1-table est en statut P. Les tables L1-table et L2-table sont dans le statut L.
SELECT * FROM P1-table,L1-table,L2-table;P1-table (gauche) et L1-table (droite) sont jointes, et en fonction du tableau ci-dessus, prennent le statut P. Avec ce statut P, elles sont jointes avec la table L2-table, qui est de statut L et qui devient alors en statut P aussi.
Changement de statut d'exécution dus aux clause TARGETLIST et WHERE
Dans une requête simple, le statut d'exécution est le même que celui de la clause FROM. Cependant, s'il y a une TARGETLIST, le statut d'exécution de la clause WHERE peut changer dans les cas suivants :
Dans ces cas, le statut d'exécution final de la sous-requête, le statut d'exécution de la TARGETLIST et la clause WHERE passent en statut S si leur statut initial était P ou S.
Dans l'exemple suivant, lorsqu'une table de statut P est utilisée par une sous-requête, le statut d'exécution final de la sous-requête prend le statut P. Ainsi, le statut d'exécution de la clause WHERE passe au statut S, quel que soit le statut d'exécution de LA, et cette requête est exécutée dans la base de données système.
SELECT * FROM L1-table where L1-table.column IN (SELECT * FROM P1-table);
La clause FROM passe au statut S lorsqu'il y a une fonction d'agrégat marquée P dans la TARGETLIST, afin de faire cet agrégat après que toutes les données aient été récupérées. Certaines optimisations sur la fonction d'agrégat sont faites dans des cas spécifiques.
Une colonne qui n'existe pas dans la table peut être utilisée dans la requête. Par exemple, dans une sous-requête corrélée :
SELECT * FROM L1-table WHERE L1-table.col1 IN (SELECT * FROM P1-table WHERE P1-table.col = L1-table.col1);
Cette sous-requête fait référence à L1-table.col1, dans la table L1-table. Le statut d'exécution de la clause WHERE de la sous-requête est S.
Changement de statuts d'exécution provoqués par GROUP BY, HAVING, ORDER BY et LIMIT/OFFSET
Le statut d'exécution de la cause WHERE est changé à S lorsqu'il y a une clause GROUP BY, HAVING, ORDER BY ou bien un prédicat LIMIT/OFFSET avec un statut P. Une requête sans la clause GROUP BY prend le statut d'exécution de la clause WHERE. De même, le statut d'exécution de la clause GROUP BY est utilisé lorsqu'il n'y a pas de clause HAVING. La clause ORDER BY et le prédicat LIMIT/OFFSET ont aussi le même comportement.
Lorsque UNION, EXTRACT et INTERSECT sont utilisés
Le statut des requêtes avec UNION, EXTRACT, ou INTERSECT dépend des deux statuts d'exécution finaux des requêtes gauche et droite à la fois. Si les deux sont en P et que la requête est un UNION ALL, le statut d'exécution combiné est P. Dans toutes les autres combinaisons, le statut final sera S.
Acquisition du statut d'exécution final d'une requête SELECT
Si tout ce qui est dans le SELECT est de statut L, alors le statut d'exécution final est L. La même règle s'applique pour P. Pour toutes les autres combinaisons, le statut final est S. Si le statut est L, la charge est distribuée sur tous les serveurs lorsque le paramètre loadbalance_mode vaut true, sinon elle est envoyée sur le maître (false). Pour P, un traitement parallèle est fait grâce au moteur d'exécution parallèle. Pour S, la réécriture de la requête est présentée ci-dessous est effectuée.
La requête est réécrite ou pas en fonction de son statut d'exécution qui est acquis lors de l'analyse de la requête. Voici un exemple. La table P1-table est de statut P, la table L1-table est elle de statut L.
SELECT P1-table.col, L1-table.col FROM P1-table,L1-table WHERE P1-table.col = L1-table.col ORDER BY P1-table.col;
Dans cette requête, le statut est S à cause de la clause ORDER BY. Les clauses FROM, WHERE et TARGETLIST sont de statut P. La requête est alors réécrite en quelque chose ressemblant à ceci :
SELECT P1-table.col, L1-table.col FROM dblink(select pool_parallel(SELECT P1-table.col, L1-table.col FROM P1-table,L1-table where P1-table.col = L1-table.col)) ORDER BY P1-table.col;
dblink transmet ici la requête à pgpool-II. La fonction pool_parallel a la responsabilité de transmettre la requête au moteur d'exécution parallèle.
Dans cet exemple, les clauses FROM et WHERE, ainsi que la TARGETLIST, sont exécutés en mode parallèle. Ceci n'est pas la requête réellement réécrite, mais juste fournie en guise d'exemple, par soucis de lisibilité et de compréhension.
Voici un autre cas :
SELECT L1-table.col FROM L1-table WHERE L1-table.col % 2 = 0 AND L1-table.col IN (SELECT P1-table FROM P1-table) ;
Dans cet exemple, les clauses FROM, WHERE et la TARGETLIST sont en statut L, à cause de la sous-requête qui est de statut P. La requête elle-même est de statut S. En conséquence, une réécrite est effectuée comme suit :
SELECT L1-table.col FROM dblink(SELECT loadbalance(SELECT L1-table.col FROM L1-table WHERE L1-table.col % 2 = 0 AND TRUE)) WHERE L1-table.col %2 = 0 AND L1-table.col IN ( SELECT P1-Table FROM dblink(select pool_parallel(SELECT P1-table FROM P1-table)) ) ;
La fonction pool_loadbalance a la responsabilité de répartir les requêtes sur les différents nœuds.
Pour les requêtes d'agrégation (fonctions d'agrégat ainsi que GROUP BY), le mécanisme de réécriture tente de réduire la charge sur la base de données système en exécutant un premier agrégat sur chacun des serveurs.
Voyons tout d'abord comment pgpool-II fait cette réécriture.
Cette requête est en statut P dans la clause FROM et possède un count(*) dans la TARGETLIST. Aussi, la réécriture est faite comme suit.
SELECT count(*) from P1-table; -> réécriture SELECT sum(pool_c$1) AS count FROM dblink(select pool_parallel('SELECT count(*) FROM P1-table')) AS pool_$1g (pool_c$1 bigint);
Une réécriture comme ci-dessus est faite dans les conditions suivantes.
Le nom des colonnes et leur type de données doivent être connus lorsqu'une requête est analysée en mode parallèle. Ainsi, lorsqu'une expression ou une fonction est utilisée dans la TARGETLIST d'une sous-requête, l'alias et le type (via un CAST) sont nécessaires. Si aucun cast n'est défini explicitement dans une expression ou une fonction, le type TEXT sera choisi par défaut. Pour count(), le type BIGINT est celui par défaut, et pour sum(), NUMERIC. Pour min()/max(), si l'argument est de type DATE, le type de données retournée est DATE, sinon NUMERIC est utilisé. avg() est traité comme sum()/count() (sum divisé par count).
Voici une estimation des performances de la requête en fonction de son statut d'exécution
Statut d'exécution | Performances |
L | Il n'y a aucune déterioration de performance avec un unique serveur, mis à part la sucharge provoquée par pgpool-II, parce qu'aucune exécution en parallèle n'est possible. |
P | Le traitement parallélisé est rapide, en particulier, pour les parcours séquentiels. Il est alors aisé d'avoir de grandes améliorations de performances car le parcours séquentiel d'une grosse table devient un parcours en parallèle sur des tables bien plus petites, distribuées sur plusieurs serveurs. |
S | Lorsque les fonctions d'agrégat peuvent être réécrites pour être compatibles avec une exécution en parallèle, elles deviennent rapides. |
Un tutoriel (en anglais) pour pgpool-II est disponible.