pgpool2.git / summary / log / commit / refs

commit    fc495aee0b3a91ad250d94ad6ebb3d1f12660f09
Author:   Toshihiro Kitagawa <kitagawa at sraoss.co.jp>
Date:     Sat Sep 03 14:48:48 2011 +0000

    Add French version of documents.
    Contributed by Jean-Paul Argudo.


Makefile.am | 1 + Makefile.in | 1 + doc/pgpool-fr.html | 4117 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 4119 insertions(+) diff --git a/Makefile.am b/Makefile.am index a74f0ba57..1fe3dea6d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -62,6 +62,7 @@ pgpool.8: pgpool.8.in CLEANFILES = pgpool.8 EXTRA_DIST = pgpool.8.in sample/pgpool.pam \ doc/pgpool-ja.html doc/pgpool-en.html doc/pgpool-zh_cn.html \ + doc/pgpool-fr.html \ doc/tutorial-ja.html doc/tutorial-en.html doc/tutorial-zh_cn.html \ doc/pgpool.css doc/pgpool-ja.css \ doc/where_to_send_queries.pdf doc/where_to_send_queries.odg \ diff --git a/Makefile.in b/Makefile.in index dd50ccac3..3f35f8075 100644 --- a/Makefile.in +++ b/Makefile.in @@ -307,6 +307,7 @@ man_MANS = pgpool.8 CLEANFILES = pgpool.8 EXTRA_DIST = pgpool.8.in sample/pgpool.pam \ doc/pgpool-ja.html doc/pgpool-en.html doc/pgpool-zh_cn.html \ + doc/pgpool-fr.html \ doc/tutorial-ja.html doc/tutorial-en.html doc/tutorial-zh_cn.html \ doc/pgpool.css doc/pgpool-ja.css \ doc/where_to_send_queries.pdf doc/where_to_send_queries.odg \ diff --git a/doc/pgpool-fr.html b/doc/pgpool-fr.html new file mode 100644 index 000000000..bb2689db9 --- /dev/null +++ b/doc/pgpool-fr.html @@ -0,0 +1,4117 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr"> + <head> + <title>Manuel de l'utilisateur pgpool-II</title> + <meta http-equiv="Content-Type" content="text/HTML; charset=utf-8" /> + </head> + +<!-- hhmts start --> +Last modified: Sun Jan 30 09:14:28 JST 2011 +<!-- hhmts end --> + +<body bgcolor="#ffffff"> +<a name="top"></a> +<table border="0" cellpadding="2" cellspacing="1"> + <tr> + <td colspan="2" valign="top"><div class="header_text">Bievenue sur la page de pgpool-II</div></td> + </tr> + <tr> + <td valign="top" style="border-right:1px dotted #cccccc;"> + <br /> + + <div id="navcontainer"> + <ul id="navlist"> + <li id="active"><a href="#Whatis" id="current">Qu'est ce que pgpool</a></li> + <li><a href="#platform">Plates-formes</a></li> + <li><a href="#install">Installation de pgpool-II</a></li> + <li><a href="#config">Configuration de pgpool-II</a></li> + <li><a href="#common">Configuration des options communes</a></li> + <li><a href="#connection_pool_mode">Mode pooling de connexions</a></li> + <li><a href="#replication_mode">Mode Réplication</a></li> + <li><a href="#master_slave_mode">Mode Maître-Esclave</a></li> + <li><a href="#start">Arrêter/Démarrer pgpool-II</a></li> + <li><a href="#reload">Recharger les fichiers de configuration de pgpool-II</a></li> + <li><a href="#show-commands">Commandes SHOW</a></li> + <li><a href="#online-recovery">Online recovery</a></li> + <li><a href="#troubleshooting">Que faire en cas d'erreur</a></li> + <li><a href="#restriction">Restrictions</a></li> + <li><a href="#reference">Références</a></li> + <li><a href="#internal">Fonctionnement interne</a></li> + </ul> + </div> + <br /> + + <div class="header_small" align="center"> + + [<a href="pgpool-ja.html">Page Japonaise</a>] </div> </td> + <td valign="top" style="border-left:1px dotted #cccccc;"> + + + + +<h1>Qu'est-ce que pgpool-II?<a name="whatis"></a></h1> + +<p>pgpool-II est un middleware qui se place entre les serveurs PostgreSQL +et les clients de ces derniers. Voici ses différentes fonctionalités:</p> +<p> +<ul> + +<li>Pooling de connexions</li> + <p>pgpool-II maintiens les connections établies aux serveurs PostgreSQL + et les réutilise dès qu'une nouvelle connexion avec les mêmes propriétés + (c'est à dire même utilisateur, même base de données et même version de + protocoles) arrive. Il réduit ainsi le coût de la connexion, et améliore + les performances générales du système.</p> + +<li>Réplication</li> + <p>pgpool-II peut gérer plusieurs serveurs PostgreSQL. En activant le + mode réplication, il devient possible de créer un backup continu sur + d'autres clusters PostgreSQL, afin que le service puisse continuer sans + interruption si l'un de ces clusters était défaillant.</p> + +<li>Load-Balancing</li> + <p>Si une base de données est répliquée, exécuter une requête en SELECT + sur n'importe lequel de ceux-ci retournera le même résultat. pgpool-II + profite ainsi avantageusement de la réplication pour réduire la charge + sur chacun des serveurs PostgreSQL. Il parvient à cela en distribuant + les requêtes SELECT ente 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. Le load-balancing 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.</p> + +<li>Limitation des connections excédentaires</li> + <p>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 une erreur immédiatement.</p> + +<li>Requêtes parallèles</li> + <p>En utilisant la fonctionalité des requêtes parallèles, 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é + a les meilleurs résultats lorsqu'on requête un très grand ensemble de + données.</p> + +</ul> +</p> + +<p> +pgpool-II dialogue dans 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.</p> + +<p> +<strong>Il y a cependant quelques restrictions à l'utilisation du SQL via +pgpool-II. Veuillez vous reporter à la section <a href="#restriction">Restrictions</a> pour +plus de détails.</strong> +</p> + +<h1>Plates-formes supportées<a name="platform"></a></h1> + +<p>pgpool-II fonctionne sous Linux, Solaris, FreeBSD, et la +plupart des architectures UNIX. <b>Windows n'est pas supporté</b>. +Les versions supportées de PostgreSQL sont la 6.4 et au-delà. +Cependant, pour utiliser la fonctionalité de requêtage en +parallèle, vous devez avoir un serveur en version 7.4 ou +supérieure.</p> + +<p>Si vous utilisez PostgreSQL en version 7.3 ou inférieure, certaines +fonctionalités de pgpool-II ne seront pas disponibles. Cependant, vous +ne devriez pas utiliser une si vieille version de toute façons.</p> + +<p> +Vous devez aussi être certains que vos serveurs PostgreSQL sont tous dans la même +version majeure. De plus, les architectures matérièles et logicielles (systèmes +d'exploitation) doivent-être identiques si vous voulez utiliser le online recovery. +</p> + +<h1>Installation de pgpool-II<a name="install"></a></h1> + +<p> +pgpool-II peut-être téléchargé sur<a href="http://pgfoundry.org/projects/pgpool/">la page de développement +de pgpool</a>. Plusieurs packages sont aussi fournis pour diverses plates-formes incluant +CentOS, RedHat Enterprise Linux, Fedora et Debian. +</p> + +<p> +le code source de pgpool-II peut-être téléchargé sur <a href="http://pgfoundry.org/projects/pgpool/">la page de développement +de pgpool</a> +</p> + +<p>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 se linkant avec la +librairie libpq de PostgreSQL, celle-ci doit-être aussi installée ainsi +que ses headers de développement 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 librairie ainsi que ses headers +d'installés sur la machine.</p> + +<dl> +<dt>configuration</dt> +<dd> +<p> +Après avoir extrait les sources depuis l'archive, exécutez le script de +configuration comme suit. +<pre> +./configure +</pre> + +Plusieurs valeurs de configuration ont des valeurs par défaut, +mais vous pouvez cependant les modifier comme suit: + +<ul> + <li><code>--prefix=path</code><br/> + les binaires de pgpool-II ainsi que sa documentation seront + installés dans ce répertoire. La valeur par défaut est <code>/usr/local</code></li> + <li><code>--with-pgsql=path</code><br/> + répertoire sous lequel les librairies clientes de PostgreSQL + sont installées. La valeur par défaut est fournie par + l'utilitaire <code>pg_config</code></li> + <li><code>--with-openssl</code><br/> + avec cette option, les binaires de pgpool-II seront compilés + avec le support d'OpenSSL. Par défautn le support d'OpenSSL + est désactivé.</li> +</ul> +</p> +</dd> + +<dt>compilation</dt> +<dd> +<p> +<pre> +make +make install +</pre> +installera pgpool-II. Si vous utiliser Solaris ou FreeBSD, remplacez +make par gmake. +</p> +</dd> + +<dt>Installation de pgpool_regclass</dt> +<dd> +<p> +Si vous utiliser PostgreSQL 8.0 ou supérieur, l'installation des +fonctions pgpool_regclass, utiles à pgpool-II, est fortement +recommandée. Sans celles-ci, le support de tables homonymes mais +figurant dans des schémas différents pourrait ne pas fonctionner +correctement (pour les tables temporaires, il n'y a aucun +problème). +</p> +<p> +<pre> +cd pgpool-II-x.x.x/sql/pgpool-regclass +make +make install +psql -f pgpool-regclass.sql template1 +</pre> +</p> +<p> +L'exécution du script pgpool-regclass.sql doit être faite sur toutes les +bases qui sont accédées via pgpool-II. + +Vous n'avez pas besoin de le faire pour toutes les bases de données +créés après l'exécution de "psql -f pgpool-regclass.sql template1", car +c'est la base template1 qui est en fait clonée pour créer de nouvelles +bases de données sous PostgreSQL. +</p> + +<dt>Installing pgpool_regclass</dt> +<dd> +<p> +Si vous utilisez PostgreSQL 9.0 ou supérieur avec le streamint replication, +vous aurez besoin d'installer la fonction pgpool_walrecrunning surtous les +serveurs PostgreSQL accedées par pgpool-II. +</p> +<p> +<pre> +cd pgpool-II-x.x.x/sql/pgpool-walrecrunning +make +make install +psql -f pgpool-walrecrunning.sql template1 +</pre> +</p> +<p> +L'exécution du script pgpool-walrecrunning.sql doit-être faite sur +toutes les bases de données accedées par pgpool-II. + +Comme précedemment, vous n'avez pas besoin de le faire pour les +bases créés ultérieurement à l'exécution de "psql -f pgpool-regclass.sql template1", +car c'est cette base qui est en fait clonée lorsqu'on crée une +nouvelle base dans un serveur PostgreSQL. +</p> + +</dl> + +<h1>Configuration de pgpool-II<a name="config"></a></h1> + +<p>Les fichiers de configuration par défaut de pgpool-II sont +<code>/usr/local/etc/pgpool.conf</code> et +<code>/usr/local/etc/pcp.conf</code>. Plusieurs modes de fonctionnement +sont disponibles sous pgpool-II. Chaque mode a des fonctionnalités +associées qui peuvent-être activées ou désactivées, et il existe +des paramètres spécifiques pour contrôler leur comportement.</p> + +<table border> + + <tr> + <th>Fonction/Mode</th> + <th>Raw Mode (*3)</th> + <th>Mode Réplication</th> + <th>Mode Maître/Esclave</th> + <th>Mode de Requêtage en Parallèle</th> + </tr> + + <tr> + <td>Pooling de Connexions</td> + <td align="center">X</td> + <td align="center">O</td> + <td align="center">O</td> + <td align="center">O</td> + </tr> + + <tr> + <td>Réplication</td> + <td align="center">X</td> + <td align="center">O</td> + <td align="center">X</td> + <td align="center">(*1)</td> + </tr> + + <tr> + <td>Load-Balancing</td> + <td align="center">X</td> + <td align="center">O</td> + <td align="center">O</td> + <td align="center">(*1)</td> + </tr> + + <tr> + <td>Failover</td> + <td align="center">O</td> + <td align="center">O</td> + <td align="center">O</td> + <td align="center">X</td> + </tr> + + <tr> + <td>Online recovery</td> + <td align="center">X</td> + <td align="center">0</td> + <td align="center">(*2)</td> + <td align="center">X</td> + </tr> + + <tr> + <td>Requêtage en Parallèle</td> + <td align="center">X</td> + <td align="center">X</td> + <td align="center">X</td> + <td align="center">O</td> + </tr> + + <tr> + <td>Nombre de serveurs requis</td> + <td align="center">1 ou plus</td> + <td align="center">2 ou plus</td> + <td align="center">2 ou plus</td> + <td align="center">2 ou plus</td> + </tr> + + <tr> + <td>Base de donnée système requise?</td> + <td align="center">non</td> + <td align="center">non</td> + <td align="center">non</td> + <td align="center">oui</td> + </tr> + +</table> + +<p> +<ul> + <li>0 signigie 'disponible' et X 'indisponible' + <li>(*1) Le mode de requêtage en parallèle nécessite que la réplication et le + load-balancing soient activés, cependant la réplication et le + load-balancing ne peuvent pas être utilisés pour les tables distribuées en + mode de requêtage parallèle. + <li>(*2) Le online recovery peut-être utilisé en mode Maître/Esclave avec + Streaming Replication. + <li>(*3) Les clients se connectent simplement aux serveurs PostgreSQL via + pgpool-II. Ce mode est utile pour limiter simplement les connexions + exédentaires au serveurs, ou activer le failover avec de multiples + serveurs. +</ul> +</p> + +<h2>Configuration de <code>pcp.conf</code></h2> + +<p>Une interface de contrôle est fournie avec pgpool-II et permet à +l'administrateur de vérifier l'état de pgpool-II et arrêter les processus +de pgpool-II à distance. <code>pcp.conf</code> est le fichier contenant +la définition des utilisateurs et de leurs mots de passe pour accéder +à cette interface. Tous les modes d'utilisation de pgpool-II nécessitent +que le fichier <code>pcp.conf</conf> soit renseigné. Un fichier d'exemple +<code>$prefix/etc/pcp.conf.sample</code> est créé lors de l'installation +de pgpool-II. Renommez ce fichier en <code>pcp.conf</code>, ajoutez-y votre +nom d'utilisateur ainsi que votre mot de passe. +</p> + +<pre> +cp $prefix/etc/pcp.conf.sample $prefix/etc/pcp.conf +</pre> +<p> +Une ligne vide ou commençant par "<code>#</code>" 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: +</p> +<pre> +nom_d_utilisateur:[mot de passe crypté en md5] +</pre> +<p> +Le <code>[mot de passe crypté en md5]</code> peut-être obtenu avec la +commande <code>$prefix/bin/pg_md5</code>. +</p> + +<pre> +pg_md5 -p +password: &lt;votre mot de passe&gt; +</pre> +<p> +ou +</p> +<pre> +./pg_md5 foo +acbd18db4cc2f85cedef654fccc4a4d8 +</pre> +<p> +Le fichier <code>pcp.conf</code> doit-être lisible par l'utilisateur qui +exécute pgpool-II.</p> + +<h2>Configuration de <code>pgpool.conf</code></h2> + +<p>Comme cela a déjà été expliqué, chaque mode de pgpool-II a ses propres +paramètres de configuration dans le fichier <code>pgpool.conf</code>. Un fichier +d'exemple <code>$prefix/etc/pgpool.conf.sample</code> est créé lors de +l'installation de pgpool-II. Renommez ce fichier en <code>pgpool.conf</code> +et éditez son contenu. + +<pre> +cp $prefix/etc/pgpool.conf.sample $prefix/etc/pgpool.conf +</pre> +<p> +Toute ligne vide ou commençant par "#" sera traitée comme un commentaire et sera +donc ignorée.</p> +</p> +<h3><a name="common"></a>Paramètres communs</h3> + +<dl> + <dt>listen_addresses</dt> + <dd> + <p>Spécifie le nom de la machine ou son adresse IP, sur laquelle + pgpool-II acceptera les connexions TCP/IP. <code>'*'</code> accepte + toutes les connexions. <code>''</code> empêchera toute connexion + TCP/IP. La valeur par défaut est <code>'localhost'</code>. Les connexions + via les sockets UNIX sont toujours acceptées. Ce paramètre ne peut être + modifié qu'au démarrage du serveur. + </dd> + + <dt>port</dt> + <dd> + <p>Spécifie le numéro de port sur lequel pgpool-II écoute les + connexions. La valeur par défaut est <code>9999</code>. Ce paramètre + ne peut-être modifié qu'au démarrage du serveur. + </dd> + + <dt>socket_dir</dt> + <dd> + <p>Répertoire dans lequel sera créé le socket UNIX de pgpool-II + pour les connexions entrantes. La valeur par défaut est + <code>'/tmp'</code>. Faites attention au fait que cette socket + pourrait-être effacée par une tâche programmée en <code>cron</code>. + Aussi, nous vous reccomandons de configurer cette valeur à + <code>'/var/run'</code> ou un répertoire de ce type. Ce paramètre ne + peut-être modifié qu'au démarrage du serveur.</p> + </dd> + + <dt>pcp_port</dt> + <dd> + <p>Numéro de port sur lequel le processus PCP accepte les connexions. + La valeur par défaut est <code>9898</code>. Ce paramètre ne peut-être + modifié qu'au démarrage du serveur.</p> + </dd> + + <dt>pcp_socket_dir</dt> + <dd> + <p>Chemin du répertoire UNIX où le socket UNIX acceptant les connexions + pour les commandes PCP est créé. La valeur par défaut est + <code>'/tmp'</code>. Faites attention au fait que cette socket + pourrait-être effacée par une tâche programmée en <code>cron</code>. + Aussi, nous vous reccomandons de configurer cette valeur à + <code>'/var/run'</code> ou un répertoire de ce type. Ce paramètre ne + peut-être modifié qu'au démarrage du serveur.</p> + </dd> + + <dt>backend_socket_dir</dt> + <dd> + <p><font color="red"><em>À NE PLUS UTILISER</em> + Ce paramètre n'est présent que pour garantir la consistence avec la + politique par défaut de la libpq. Reportez-vous à la définition du + paramètre <code>backend_hostname</code> pour adapter votre configuration. + </font></p> + <p>Ce paramètre permettait de définir le répertoire UNIX servant au + serveur PostgreSQL.</p> + </dd> + + <dt>pcp_timeout</dt> + <dd> + <p>Timout en secondes pour 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 10 Secondes. 0 signifie qu'il n'y + a aucun timeout. Ce paramètre peut-être pris en compte avec rechargement + des fichiers de configuration.</p> + </dd> + + <dt>num_init_children</dt> + <dd> + <p>Nombre de processus pré-forkés de pgpool-II. La valeur par défaut + est de 32. <code>num_init_children</code> est aussi la lmite du nombre + de connexions clientes concurrentes à pgpool-II. Si plus de + <code>num_init_children</code> clients essaient de se connecter à + pgpool-II, ceux-ci sont bloqués (mais pas rejettés), jusqu'à ce qu'une + connexion à l'un des des processus de pgpool-II soit fermé. On peut avoir + ansi jusqu'à <b>deux fois <code>num_init_children</code></b> clients + dans la queue de connexion. + <p>Quelques précisions et astuces:</p> + <p> + <ul> + <li>L'annulation d'une requête crée une autre connexion au + backed; ainsi, une requête ne peut-être annulée si toutes les + connexions sont utilisées. Si vous voulez vous assurer que les + requêtes puissent-être annulées, positionnez cette valeur au + double des connexions attendues.</li> + + <li>PostgreSQL permet un certain nombre de connexions pour les + utilisateurs qui ne sont pas superutilisateurs. On le calcule + comme suit:<code>max_connections - superuser_reserved_connections</code></li> + </ul> + </p> + <p>Pour résumer, <code>max_pool</code>,<code>num_init_children</code>, + <code>max_connections</code> et + <code>superuser_reserved_connections</code> doivent satisfaire + la formule suivante: + </p> + <p> +Si on n'a pas besoin de l'annulation de requêtes: + <pre>max_pool*num_init_children <= (max_connections - superuser_reserved_connections)</pre> +Si on a besoin de l'annulation de requêtes: +<pre>max_pool*num_init_children*2 <= (max_connections - superuser_reserved_connections)</pre> + <p> + Ce paramètre ne peut-être modifié qu'au démarrage du serveur.</p> + </dd> + + <dt>child_life_time</dt> + <dd> + <p>Durée de vie en secondes d'un processus enfant de pgpool-II. Lorsqu'un + processus enfant est sans activité depuis ce nombre de secondes, il se + termine et un nouveau processus enfant 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). 0 désactive cette + fonctionalité. Notez que cela ne s'applique qu'aux processus qui n'ont + pas encore été utilisés, soit, qui n'ont pas encore accepté de connexions. + Vous devrez recharger le fichier de configuration <code>pgpool.conf</code> + si vous changez cette valeur. + </p> + </dd> + + <dt>child_max_connections</dt> + <dd> + <p>Un processus enfant de pgpool-II sera terminé après ce + nombre de connexions clientes acceptées. Ce paramètre est + utile sur un serveur à ce point chargé que ni + <code>child_life_time</code>, ni <code>connection_life_time</code> + ne sont jamais déclenchés. Vous devrez recharger pgpool-II si vous + changez cette valeur. + </p> + </dd> + + <dt>client_idle_limit + <dd> + <p>Déconnecte un client s'il est resté inactif pendant ce nombre de secondes + après que la dernière requête ait été complétée. Ceci est utile pour + empêcher qu'un processus enfant 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 <code>client_idle_limit</code> 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 <code>client_idle_limit</code>.</p> + + <dt>authentication_timeout + <dd> + <p>Spécifie le timeout en secondes pour une authentification. 0 désactive + ce dernier. Vous aurez besoin de redémarrer pgpool-II si vous changez cette + valeur.</p> + + <dt>logdir</dt> + <dd> + <p>Répertoire utilisé pour les logs. <code>pgpool_status</code> + est écrit dans ce répertoire.</p> + </p> + </dd> + <dt>log_destination</dt> + <dd> + <p>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.</p> + <p>Note: vous aurez besoin de modifier la configuration du serveur + syslog de votre système pour que l'écriture des messages vers + syslog fonctionne si vous configurez <code>log_destination</code> + en ce sens. pgpool-II peut logguer vers les facilités 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 besoind d'ajouter quelque chose + comme + </p> + <pre> + local0.* /var/log/pgpool.log + </pre> + <p>au fichier de configuration de votre démon syslog pour le faire + fonctionner. + </p> + </dd> + + <dt>syslog_facility</dt> + <dd> + <p>Lorsque la sortie des messages vers syslog est configurée, ce paramètre + détermine quelle "facility" syslog est à 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. + </p> + </dd> + + <dt>syslog_ident</dt> + <dd> + <p>Lorsque la sortie vers syslog est configurée, ce paramèter permet de + déterminer le nom du programme utilisé pour identifier les messages + de pgpool-II dans les logs de syslog. La valeur par défaut est pgpool. + </p> + </dd> + + <dt>pid_file_name</dt> + <dd> + <p>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. + </p> + </dd> + + <dt>print_timestamp</dt> + <dd> + <p>Ajoute un timestamp dans les logs 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. + </p> + </dd> + + <dt>connection_cache</dt> + <dd> + <p>Cache les connexions aux backends PostgreSQL lorsque + cette valeur est configurée à true. La valeur par défaut + est true.</p> + </dd> + + <dt>health_check_timeout</dt> + <dd> + <p>pgpool-II essaie périodiquement de se connecter aux + backends 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 de compléter 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. 0 désactive ce timeout (on attend donc + alors jusqu'au timeout TCP/IP). + + Ce health check nécessite une connexion supplémentaire à + chacun des backends, ainsi, <code>max_connections</code> + dans le <code>postgresql.conf</code> doit être augmenté + en conséquence. + + Vous aurez besoin de recharger pgpool-II après toute modification + de ce paramètre. + </p> + </dd> + + <dt>health_check_period</dt> + <dd> + <p>Ce paramètre spécifie l'intervale de temps entre deux + "health check", en secondes. La valeur par défaut est de 0, + ce qui signifie que le "health check" est désactivé. + Vous aurez besoin de recharger pgpool-II après tout changement + de ce paramétrage. + </p> + </dd> + + <dt>health_check_user</dt> + <dd> + <p>Nom de l'utilisateur de bases de données utilisé pour + exécuter le "health check". Cet utilisateur doit exister + dans tous les backends PostgreSQL. Vous aurez besoin de + recharger pgpool-II après tout changement de la valeur de + ce paramètre. + </p> + </dd> + +<dt>failover_command +<dd> +<p> +Ce paramètre spécifie la commande à exécuter lorsqu'un noeud est détaché. +pgpool-II remplace les caractères spéciaux suivants avec les informations +en provenance des backends. +</p> + +<blockquote> +<table border> +<tr><td>Caractère spécial</td><td>Description</td></tr> +<tr><td>%d</td><td>ID du backend correspondant au noeud détaché</td></tr> +<tr><td>%h</td><td>Nom d'hôte du noeud détaché</td></tr> +<tr><td>%p</td><td>Numéro de port du noeud détaché</td></tr> +<tr><td>%D</td><td>Répertoire du cluster PostgreSQL du noeud détaché</td></tr> +<tr><td>%M</td><td>ID du noeud de l'ancien Maître</td></tr> +<tr><td>%m</td><td>ID du noeud du nouveau Maître</td></tr> +<tr><td>%H</td><td>Nom d'hôte du nouveau noeud Maître</td></tr> +<tr><td>%P</td><td>ID de l'ancien noeud primaire</td></tr> +<tr><td>%%</td><td>caractère '%'</td></tr> +</table> +</blockquote> +<p> +Vous devrez recharger pgpool.conf si vous changez la valeur de +<code>failover_command</code>. +</p> + +<p> +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 <code>failover_command</code> 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. +</p> + +<dt>failback_command +<dd> +<p> +Ce paramètre contient une commande à exécuter lors qu'un noeud est attaché. +pgpool-II remplace les caractères spéciaux suivants avec les informations en +provenance des backends. +</p> +<blockquote> +<table border> +<tr><td>Caractère spécial</td><td>Description</td></tr> +<tr><td>%d</td><td>ID du backend d'un noeud attaché</td></tr> +<tr><td>%h</td><td>Nom d'hôte d'un noeud attaché</td></tr> +<tr><td>%p</td><td>Numéro de port d'un noeud attaché</td></tr> +<tr><td>%D</td><td>Répertoire du cluster PostgreSQL d'un noeud attaché</td></tr> +<tr><td>%M</td><td>Ancien noeud Maître</td></tr> +<tr><td>%m</td><td>Nouveau noeud Maître</td></tr> +<tr><td>%H</td><td>Nom d'hôte du nouveau noeud Maître</td></tr> +<tr><td>%P</td><td>ID de l'ancien noeud primaire</td></tr> +<tr><td>%%</td><td>caractère '%'</td></tr> +</table> +</blockquote> +<p> +Vous devrez recharger pgpool.conf si vous changez le contenu de la +commande <code>failback_command</code>. +</p> + + <dt>fail_over_on_backend_error</dt> + <dd> + <p> +Si ce paramètre est à true, et qu'une erreur apparaît lorsqu'on écrit sur le +canal de communication d'un backend, pgpool-II déclenchera une procédure de +failover. C'est le même comportement qu'avec les versions 2.2.x ou précédentes +de pgpool-II. Si ce paramètre est à false, pgpool reportera une erreur dans ses +fichiers de traces et déconnectera la session. +Notez cependant que si ce paramètre est activé, pgpool effectuera aussi un +failover lorsque la connexion à un backend échoue ou lorsqu'il détecte l'arrêt +du postmaster par un administrateur. Vous devrez recharger pgpool.conf si vous +changez cette valeur. +</p> +</dd> + + <dt>ignore_leading_white_space</dt> + <dd> + <p>pgpool-II ignorera les espaces en début de requête SQL lorsqu'il + est dans le mode load balancing si ce paramètre est activé. C'est + particulièrement intéressant lorsqu'il est utilisé avec des APIs + comme DBI/DBD::Pg qui ajoutent des espaces sans que l'utilisateur + le demande. Vous aurez besoin de recharger le pgpool.conf pour que + ce paramètre soit pris en compte. + </p> + </dd> + + <dt>log_statement</dt> + <dd> + <p>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. + </p> + </dd> + + <dt>log_per_node_statement</dt> + <dd> + <p>Similaire à log_statement, à l'exception qu'il écrit les logs + de manière séparée par noeud. Cela peut-être très utile si vous + voulez par exemple vous assurer que votre réplication fonctionne. + Vous aurez besoin de recharger pgpool.conf pour que ce paramètre + soit pris en compte. + </p> + </dd> + + <dt>log_hostname</dt> + <dd> + <p> + Si ce paramètre est positionné à true, le nom de la commande affichée + dans la sortie de ps sera le nom d'hôte plutôt que son IP. De même, si + log_connections est activé, le nom d'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. + </p> + </dd> + + <dt>log_connections</dt> + <dd> + <p> + Si ce paramètre est à true, toutes les connexions entrantes seront + écrites dans les fichiers de trace. Ce paramètre est pris en compte + au rechargement de pgpool.conf. + </p> + </dd> + + <dt>enable_pool_hba</dt> + <dd> + <p> + Si ce paramètre est à vrai, on utilisera le fichier pool_hba.conf pour + l'authentification des clients. Voir la <a href="#hba">configuration +de pool_hba.conf pour l'authentification des clients</a>. Ce paramètre + est pris en compte au rechargement de pgpool-II. + </p> + </dd> + + <dt>backend_hostname</dt> + <dd> + <p>Permet de spécifier à quel backend PostgreSQL on se connecte. + C'est utilisé par pgpool-II pour communiquer avec le serveur. + Ce paramètre n'est lu qu'au démarrage du serveur pgpool-II. + </p> + <p> + 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 une communication UNIX plutôt que TCP/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 (<code>''</code>), le comportement par + défaut de pgpool-II est de se connecter à un socket UNIX stocké dans le + répertoire <code>/tmp</code>. + </p> + <p> + On peut spécifier ici plusieurs backends en ajoutant un nombre à la + fin du nom du paramète (par exemple <code>backend_hostname0</code>). + Ce nombre est l'identifiant du noeud au sein de pgpool-II. Le premier + noeud est toujours le noeud 0. Le backend PostgreSQL a qui a été + attribué l'ID 0 sera appelé le "Master DB". Lorsque plusieurs backends + sont définis, le service peut continuer même si le Master DB est arrêté + (ce n'est cependant pas vrai pour certains modes de pgpool-II). Dans ce + cas, c'est toujours le backend qui a le plus petit identifiant de noeud + et qui est encore disponible qui sera alors promu Master DB.</p> + + <p>Si vous pensez n'utiliser qu'un seul serveur PostgreSQL, spécifiez-le + avec <code>backend_hostname0</code>.</p> + <p> + De nouveaux backends PostgreSQL peuvent-être ajoutés grâce à ce paramètre + mais vous devrez 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. + </p> + </dd> + + <dt>backend_port</dt> + <dd> + <p>Spécifie le numéro de port des backends. Comme précédemment, on peut + spécifier le port de plusieurs backends en ajoutant à la fin du nom du + paramètre l'identifiant du noeud (par exemple <code>backend_port0</code>). + Si vous n'utilisez qu'un seul serveur, vous devrez le spécifier donc par + <code>backend_port0</code>.</p> + + <p> + Comme précédemment, vous pouvez ajouter de nouveaux paramètres concernant + de nouveaux noeuds, 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. + </p> + </dd> + + <dt>backend_weight</dt> + <dd> + <p>Spécifie le ratio de load balancing entre les backends. + On peut spéficier une valeur pour chacun des backends, il suffit + pour cela d'ajouter le numéro de backend à la fin du nom du + paramètre (par exemple <code>backend_weight0</code>). Si vous + n'utilisez qu'un seul serveur PostgreSQL, spécifiez le en utilisant + <code>backend_weight0</code>. Si vous êtes dans le mode RAW de pgpool-II, + mettez toujours cette valeur à 1.</p> + <p> + De nouveaux poids pour les backends peuvent-être ajoutés pour de nouveaux + noeuds. Cependant, si vous mettez à jour des valeurs de paramètres existant, vous + devrez redémarrer le serveur pgpool-II. + </p> + <p> + À 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. + </p> + </dd> + + <dt>backend_data_directory</dt> + <dd> + <p>Précise le répertoire où se trouve le cluster PostgreSQL + des backends. Plusieurs backends peuvent-être spécifiés en ajoutant + un nombre à la fin du nom de paramètre. (par exemple + <code>backend_data_directory0</code>). + Si vous ne pensez pas utiliser le "online recovery", vous n'avez pas + besoin de spécifier ce paramètre. + </p> + + <p> + Des spécifications d'emplacement de cluster 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, + ainsi, vous devrez redémarrer pgpool-II si vous modifiez la valeur du + paramètre. + </p> + </dd> + + <dt><a name="ssl">ssl</a></dt> + <dd> + <p> + Si ce paramètre est à "true", autorise le support de SSL à la fois pour + les connexions clientes et les connexions aux serveurs PostgreSQL. + Notez que <code>ssl_key</code> et <code>ssl_cert</code> + doivent-être aussi renseignés pour que les connexions clientes puissent + fonctionner en SSL. + </p> + + <p> + 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 <a href="#install">installation</a>. + </p> + + <p> + Le démon de pgpool-II doit être redémarré lorsqu'on met à jour les + paramètres relatifs à SSL. + </p> + </dd> + + <dt>ssl_key</dt> + <dd> + <p> + Chemin du fichier de clé privée pour les connexions clientes entrantes. + </p> + + <p> + Il n'y a aucune valeur par défaut pour ce paramètre, et si on le laisse + ainsi, le support de SSL sera désactivé pour les connexions clientes + entrantes. + </p> + </dd> + + <dt>ssl_cert</dt> + <dd> + <p> + Chemin complet vers le certificat public x509 à utiliser pour les + connexions clientes entrantes. + </p> + + <p> + Il n'y a aucune valeur par défaut pour ce paramètre, et si on le laisse + ainsi, le support de SSL sera désactivé pour les connexions clientes + entrantes. + </p> + </dd> + + <dt>debug_level</dt> + <dd> + <p> + 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. + </p> + </dd> + + <dt>relcache_expire</dt> + <dd> + <p> + Duré 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 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 consistent. + A cet effet, le paramète relcache_expiration contrôle la durée de vie du + cache. + </p> + </dd> + </dl> +</dl> + +<h4>Génération de certificats SSL</h4> +<p> +La manipulation des certificats est hors scope de ce document. La page +<a href="http://developer.postgresql.org/pgdocs/postgres/ssl-tcp.html"> +Secure TCP/IP Connections with SSL</a> (en anglais) sur le site +PostgreSQL.org référence des documents qui expliquent de détails +les commandes à taper pour engendrer des certificats auto-signés. +</p> + +<h4>Failover dans le mode Raw</h4> + +<p>Le Failover peut-être accompli dans le mode raw si plusieurs serveurs +sont définis. pgpool-II accède en général au backend spécifié par +<code>backend_hostname0</code> pendant son fonctionnement normal. +Si le backend_hostname0 est en échec, quelle que soit la raison, pgpool-II +essaie d'accéder au backend spécifié par backend_hostname1. Si cela +échoue, pgpool-II essaie alors le backend_hostname2, et ainsi de suite. +</p> + +<h3><a name="connection_pool_mode"></a>Mode pooling de connexions</h3> + +<p>Dans le mode de pooling de connexions, toutes les fonctions du mode +raw et du mode pooling de connexions peuvent être utilisées. Pour activer ce +mode, configurez les paramètres du mode raw ainsi que les autres +paramètres ci-après.</p> + +<dl> + <dt>max_pool</dt> + <dd> + <p>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 backend 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 backend PostgreSQL + poruraient atteindre ainsi: + <code>num_init_children</code> * <code>max_pool</code>. + + Ce paramètre n'est pris en compte qu'au démarrage du serveur + pgpool-II. + </p> + </dd> + + <dt>connection_life_time</dt> + <dd> + <p> + 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.</p> + </dd> + + <dt>reset_query_list</dt> + <dd> + <p>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. + + <pre> + reset_query_list = 'ABORT; DISCARD ALL' + </pre> + +<p> + Les commandes diffèrent dans chaque version de PostgreSQL. Voici les + paramètres reccomandés par version. + </p> +<p> +<table border> +<tr><th>Version de PostgreSQL</th><th>reset_query_list value</th></tr> +<tr><td>7.1 ou précédent</td><td>ABORT</td></tr> +<tr><td>7.2 à 8.2</td><td>ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT</td></tr> +<tr><td>8.3 et suivantes</td><td>ABORT; DISCARD ALL</td></tr> +</table> +</p> +<ul> +<li>"ABORT" n'est pas envoyé lorsqu'on n'est pas dansun bloc de transactions, +à partir ce la 7.4. +</ul> + +<p> +Vous aurez besoin de recharger pgpool.conf après toute modification de +ce paramètre, pour qu'il soit pris en compte. +</p> +</dd> +</dl> + +<h4><p>Le failover dans le mode pooling de connexions</p></h4> + +<p>Le failover dans le mode pooling de connexions est identique à celui du +mode raw.</p> + +<h3><a name="replication_mode"></a>Mode Réplication</h3> + +<p>Ce mode permet la réplication des données entre les backends PostgreSQL. +Les paramètres de configuration ci-desous doivent être renseignés, en plus +de tout ce qui a été vu plus haut. +</p> + +<dl> + <dt>replication_mode + <dd> + <p>Mettre ce paramètre à <code>true</code> active le mode de + réplication. La valeur par défaut est <code>false</code>. + </p> + </dd> + + <dt>load_balance_mode</dt> + <dd> + <p>Lorsque ce paramètre est à <code>true</code>, les requêtes de + type SELECT seront ditribuées à chaque backend PostgreSQL pour + obtenir un "load balancing". La valeur par défaut est + <code>false</code>. + </p> + </dd> + + <dt>failover_if_affected_tuples_mismatch</dt> + <dd> + <p>Lorsque ce paramètre est positionné à <code>true</code>, + si les backends PostgreSQL ne retournent pas le même nombre de + tuples affectés lors d'un INSERT, UPDATE ou DELETE, les backends + 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 inconsistents). + Si ce paramètre est à <code>false</code>, la session est terminée + et les backends PostgreSQL ne sont pas "dégénérés". La valeur par + défaut est à <code>false</code>. + </p> + </dd> + + <dt>replication_stop_on_mismatch</dt> + <dd> + <p>Si ce paramètre est à <code>true</code>, si tous les backends + PostgreSQL ne retournent pas le même type de paquet, les backends + dont la valeur diffère du résultat le plus fréquent sont "dégénérés". + Un cas d'utilisation typoque est une requête SELECT dans une + transaction, avec replicate_select à <code>true</code>, qui + retournerait un nombre d'enregistrements différent entre les + backend PostgreSQL. + Les requêtes qui ne sont pas en SELECT pourraient aussi déclencher + cela cependant. Par exemple, si un backend PostgreSQL réussit un + UPDATE alors que les autres échouent. + Notez que pgpool-II n'examine <b>pas</b> le contenu des + enregistrements retournés par un SELECT. + Si ce paramètre est à <code>false</code>, la session est terminée + et les backends PostgreSQL ne sont pas "dégénérés". La valeur par + défaut est <code>false</code>. + </p> + </dd> + +<a name="white_function_list"></a> +<dt>white_function_list +<dd> +<p> +Permet de spécifier une liste de noms de fonctions, séparées par des virgules, +qui ne font <strong>pas</strong> 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 balancés 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. +</p> +<p> +Vous pouvez utiliser des expressions régulières dans la liste pour faire +correspondre à 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: + +</p> +<pre> +white_function_list = 'get_.*,select_.*' +</pre> +</dd> + +<a name="black_function_list"></a> +<dt>black_function_list +<dd> +<p> +Permet de spécifier une liste de noms de fonctions, séparées par des virgules, +qui <strong>font</strong> des écritures dans la base de données. +Les SELECTs qui utilisent les fonctions spécifiées dans cette liste ne seront +jamais balancés entre les backends PostgreSQL, ni répliqués dans le mode +de réplication. +Dans le mode maître/esclave, de tels SELECTs sont envoyés uniquement au +maître. +</p> +<p> +Vous pouvez utiliser des expressions régulières dans la liste pour faire +correspondre à 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: +</p> +<pre> +black_function_list = 'nextval,setval,set_.*,update_.*,delete_.*,insert_.*' +</pre> +<p> +<b>Attention</b>, une seule de ces deux listes ne peut-être renseignée +dans la configuration de pgpool-II. (NDT: autrement dit, +vous devez opter pour l'un ou +l'autre des fonctionnements: 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 la "white list". +En effet, en cas +d'oubli d'une fonction en écriture dans la "black 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!). +</p> +<p> +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: +</p> +<p> +<pre> +white_function_list = '' +black_function_list = 'nextval,setval,lastval,currval' +</pre> +</p> +<p> +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 balancées entre les différents noeuds. +Ainsi, les ajouter à la black_function_list permettra d'éviter qu'elles soient +load-balancées. +</p> +</dd> + +<a name="replicate_select"></a> + <dt>replicate_select</dt> + <dd> + <p>Lorsque ce paramètre est à <code>true</code>, pgpool-II va répliquer + les SELECTs dans le mode de réplication. Si c'est à <code>false</code>, + pgpool-II va les envoyer uniquement au serveur maître (primaire). La valeur + par défaut est <code>false</code>.</p> + +<p> +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 comment fonctionne +la réplication. Les détails sont expliqués ci-dessous. +</p> + +<p> +<table border> + +<tr> +<td>Le SELECT est à l'intérieur d'une block de transaction</td> +<td>O</td> +<td>O</td> +<td>O</td> +<td>N</td> +<td>N</td> +<td>N</td> +<td>O</td> +<td>N</td> +</tr> + +<tr> +<td>replicate_select = true</td> +<td>O</td> +<td>O</td> +<td>N</td> +<td>N</td> +<td>O</td> +<td>O</td> +<td>N</td> +<td>N</td> +</tr> + +<tr> +<td>load_balance_mode = true</td> +<td>O</td> +<td>N</td> +<td>N</td> +<td>N</td> +<td>O</td> +<td>N</td> +<td>O</td> +<td>O</td> +</tr> + +<tr> +<td>resultats(R:réplication, M: envoyé au maître uniquement, L: load-balancé)</td> +<td>R</td> +<td>R</td> +<td>M</td> +<td>M</td> +<td>R</td> +<td>R</td> +<td>M</td> +<td>L</td> +</tr> +</table> +</p> + </dd> + + <dt>insert_lock</dt> + <dd> + <p>Si on réplique une table qui utilise le type de données SERIAL, + la valeur du SERIAL pourraît être différente entre les backends + PostgreSQL. On peut éviter ce problème en vérouillant la table + de manière explicite (bien que le parallélisme des transactions sera + alors sévèrement dégradé). Pour arriver à cela, cependant les + changements suivants doivent êter faits: + + <pre> + INSERT INTO ... + </pre> + <p> + to + </p> + <pre> + BEGIN; + LOCK TABLE ... + INSERT INTO ... + COMMIT; + </pre> + + <p>Lorsque <code>insert_lock</code> est à + <code>true</code>, 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. + </p> + <p>À 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 vérouillés de manière exclusive. + </p> + <p> + pgpool-II 3.0 utilise désormais un lock de ligne sur la relation + de la séquence, plutôt qu'un vérouillage de table exclusif. Cela + minimise les conflits sur les vérouillages, comme par exemple + VACUUM (direct ou via autovacuum). + </p> + <p> + Peut-être souhaiterez vous avoir un contrôle plus fin (par + requête): + </p> + + <ol> + <li>positionnez <code>insert_lock</code> à <code>true</code>, et + ajoutez <code>/*NO INSERT LOCK*/</code> au début d'une requête + INSERT pour laquelle vous ne voulez pas qu'un vérouillage exclusive de + table soit provoqué.</li> + + <li>positionnez <code>insert_lock</code> à <code>false</code>, et + ajoutez <code>/*INSERT LOCK*/</code> au début d'une requête + INSERT pour laquelle vous voulez provoquer un vérouillage + exclusif de la table.</li> + </ol> + + <p> + La valeur par défaut est <code>false</code>. Si + <code>insert_lock</code> est activé, les tests de régression pour + PostgreSQL 8.0 échoueront dans les transactions, privilèges, règles + (rules) et alter_table. La raison à cela est que pgpool-II essaie de + vérouiller une vue pour le test sur les règles, et produira donc le + message d'erreur suivant:</p> + <pre> + ! ERROR: current transaction is aborted, commands ignored until + end of transaction block + </pre> + + <p>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 vérouillage + exclusif avant cela. La transaction sera alors interrompue et la requête + d'INSERT qui suit produira le message ci-dessus.</p> + +<dt>recovery_user +<dd> +<p> +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. +</p> + +<dt>recovery_password +<dd> +<p> +Ce paramètre permet de spécifier le mot de passe de l'utilisateur spécifié dans +le paramètre ci-dessus, à savoir <code>recovery_user</code>, 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. +</p> + +<dt>recovery_1st_stage_command +<dd> +<p> +Ce paramètre permet de préciser une commande à exécuter pour la première +phase du online recovery. Le fichier de commandes spécifié ici doit être placé +dans le cluster de PostgreSQL (le répertoire racine de PostgreSQL), pour des +raisons de sécurité. + +Par exemple, si <code>recovery_1st_stage_command = 'sync-command'</code>, +alors pgpool-II exécute <code>$PGDATA/sync-command</code>. + +Notez que pgpool-II <b>accepte</b> les connexions et les requêtes alors que +<code>recovery_1st_stage command</code> 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. +</p> +<p> +Ce paramèter peut-être changé sans avoir à redémarrer pgpool-II. +</p> + +<dt>recovery_2nd_stage_command +<dd> +<p> +Ce paramètre spécifie une commande à exécuter lors de la seconde phase +du online recovery. Ce fichier de commandes doit être placé dans le cluster +de PostgreSQL pour des raisons de sécurité. + +Par exemple, si <code>recovery_2nd_stage_command = 'sync-command'</code>, +alors pgpool-II exécute <code>$PGDATA/sync-command</code>. + +Notez que pgpool-II <b>n'accepte pas</b> de connexions ou d'exécution de +requêtes pendant que <code>recovery_2nd_stage_command</code> 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é. +</p> +<p> +Ce paramètre peut-être changé sans redémarrer pgpool-II. +</p> + +<dt>recovery_timeout +<dd> +<p> +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. +</p> +<p> +Ce paramètre spécifie un temps au delà 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 <code>0</code> signifie qu'il n'y a pas de +paramétrage de ce temps. +</p> +<p> +Ce paramètre peut être changé sans avoir à redémarrer pgpool-II. +</p> + + <dt>client_idle_limit_in_recovery + <dd> + <p>Similaire à <code>client_idle_limit</code>, cependant, n'agit + que lors de la seconde phase du online recovery. Un client qui aura + été inactif pendant <code>client_idle_limit_in_recovery</code> + secondes depuis sa dernière requête sera déconnecté. + Ce paramètre permet d'éviter que le le online recovery 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 à <code>-1</code>, le client + est déconnecté immédiatement. La valeur par défaut de ce paramètre + est <code>0</code>, ce qui signifie que cette fonctionalité est + désactivée. + </p> + <p> 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 + <code>client_idle_limit_in_recovery</code> que vous aurez choisie. + Dans ce cas, vous pouvez paramétrer <code>client_idle_limit_in_recovery</code> + à <code>-1</code>, afin que pgpool-II puisse déconnecter immédiatement + des clients aussi actifs avant de passer à la seconde phase du online + recovery. + </p> + <p> + Vous devrez recharger la configuration de pgpool-II si vous changer la + valeur de <code>client_idle_limit_in_recovery</code>.</p> + +<dt><a name="lobj_lock_table"></a>lobj_lock_table +<dd> +<p> +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 vérouillera +cette table-là, 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" dans tous les backends PostgreSQL lorsque pgpool-II est dans +le mode réplication. Notez que PostgreSQL 8.0 ou ultérieur n'a plus de +"lo_create", aussi, cette fonctionalité ne fonctionnera pas. +</p> +<p> +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 librairie de PHP, comme PDO), et ce genre d'APIs similaires dans +plusieurs langages de programmation qui sont réputées pour utiliser un +protocole similaire. +</p> +<p> +Les opérations suivantes de création d'un large object ne fonctionnera pas: +<p> +<ul> +<li>lo_create de la libpq +<li>l'API d'un langage qui utilise lo_create +<li>la fonction lo_import dans le backend PostgreSQL +<li>SELECT lo_creat +</ul> +</p> +<p> +Peu importe le schéma où est stockée la table <code>lobj_lock_table</code>, +celle-ci doit en revanche être accessible en écriture à tous les utilisateurs. +Voici un exemple de création d'une telle table: +</p> +<p> +<pre> +CREATE TABLE public.my_lock_table (); +GRANT ALL ON public.my_lock_table TO PUBLIC; +</pre> +</p> +<p> +La table spécifiée par <code>lobj_lock_table</code> doit être créée à +l'avance. Vous pouvez par exemple la créer dans la base <code>template1</code>, +afin que toute base de données créée par la suite en dispose. +</p> +<p> +Si <code>lobj_lock_table</code> contient une chaîne vide (<code>''</code>), +la fonctionalité est désactivée, et ainsi, la réplication des large objects ne fonctionnera +pas. + +La valeur par défaut de ce paramètre est justement la chaîne vide (<code>''</code>). +</p> + +</dl> + +<h4><p>pré-requis au load-balancing</p></h4> +<p> +Pour qu'une requête soit load-balancée, les pre-requis suivants +doivent-être respectés: +<ul> + <li>Version 7.4 de PostgreSQL ou plus récente</li> + <li>la requête ne doit pas être déclarée explicitement + (c'est à dire qu'on ne doit pas être dans un block + BEGIN ~ END)</li> + <li>il ne s'agit pas d'un SELECT nextval ou d'un SELECT setval + <li>il ne s'agit pas d'un SELECT INTO + <li>il ne s'agit pas d'un SELECT FOR UPDATE ou FOR SHARE + <li>la requête commence par un "SELECT" ou COPY TO STDOUT, EXPLAIN, EXPLAIN ANALYZE SELECT... + le paramètre <code>ignore_leading_white_space = true</code> permettra + d'ignorer tous les éventuels espaces présents avant la requête. +</ul> +</p> +<p> +Notez que vous pouvez interdire de manière explicite le balancement d'une requête +SELECT en ajoutant un commentaire au début de la requête SELECT (quel que ce +soit ce commentaireà. Par exemple: +<pre> + /*REPLICATION*/ SELECT ... +</pre> +</p> + +<p> +Merci de lire attentivement la page +<a href="#replicate_select">replicate_select</a>, au sujet de la réplication. +De même, étudiez attentivement +<a href="where_to_send_queries.pdf">ce schéma</a>, qui explique comment +pgpool-II détermine à quel backend PostgreSQL envoyer telle ou telle requête. +</p> + +<p> +<font color="red"> +Attention: le driver JDBC a une option autocommit. Si autocommit est à +<code>false</code>, le driver JDBC envoie un "BEGIN" et un "COMMIT" +lui-même. Ainsi, pgpool-II ne pourra faire aucun load-balancing. Vous devez +alors appeler <code>setAutoCommit(true)</code> pour activer +l'autocommit. +</font> +</p> + +<h4><p>Failover dans le mode Réplication</p></h4> + +<p> pgpool-II désactive un backend "mort" et le service continue, à condition +qu'il y ait au moins un backend PostgreSQL en vie. +</p> + +<h3><a name="master_slave_mode"></a>Mode Maître-Esclave</h3> + +<p>Ce mode est utilisé pour 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), qui est alors responsable de la +réplication des données. + +L'information sur les backends PostgreSQL doit être renseignée (les paramètres +backend_hostname, backend_port, backend_weight, and backend_data_directory), +de la même façon que dans le mode réplication. + +De plus, il faut paramétrer <code>master_slave_mode</code> et +<code>load_balance_mode</code> à <code>true</code>. + +pgpool-II enverra alors les requêtes qui doivent-être répliquées au backend +PostgreSQL maître, et les autres requêtes seront load-balancées, si possible. + +L'algorithme de pgpool-II prend bien sûr en compte les requêtes qui ne peuvent-être +balancées ; elles sont alors systématiquement envoyées au serveur maître.</p> + +<p>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 rajoutant un +commentaire <code>/*NO LOAD BALANCE*/</code> devant le SELECT.</p> + +<p>Dans le mode Maître-Esclave, vous devez positionner +<code>replication_mode</code> à <code>false</code> et +<code>master_slave_mode</code> à <code>true</code>.</p> + +<p>Le mode Maître-Esclave a un sous-mode +(<code>'master_slave_sub_mode'</code>), qui est par défaut +<code>slony</code> et qui convient si vous utilisez Slony-I. + +Vous pouvez aussi le paramétrer sur <code>stream</code>, 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 <code>pgpool.conf.sample-master-slave</code>, et celui +concernant le Streaming Replication est +<code>pgpool.conf.sample-stream</code>. +</p> +<p> +Vous devrez redémarrer pgpool-II si vous changez l'un des paramètres +vu précédemment. +</p> +<p> +Vous devrez probablement aussi renseigner les paramètres +<code>white_function_list</code> et +<code>black_function_list</code> si vous voulez contrôler plus finement +le load-balancing dans le mode Maître-Esclave. +Reportez-vous à <a href="#white_function_list">white_function_list</a> +pour plus de détails. +</p> + +<h4>Streaming Replication</h4> +<p> +Comme nous l'avons vu précédemment, pgpool-II peut fonctionner de pair avec +le Streaming Replication, qui est disponible depuis la version 9.0 de PostgreSQL. +Pour l'utiliser, il faut activer "master_slave" et positionner "master_slave_sub_mode" +sur "stream". pgpool-II suppose que le Streaming Replication fonctionne et que les +backend 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: +</p> +<p> +<ul> +<li>delay_threshold +<p> +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 WAL. +Si le décalage dépasse <code>delay_threshold</code>, pgpool-II n'envoie +alors plus de SELECT au serveur(s) esclave(s). Tout est alors envoyé au serveur +maître, même si le load-balancing est activé, jusqu'à ce que le(s) serveur(s) +esclave(s) soit(soient) en deçà du décalage maximum autorisé. + +Si <code>delay_threshold</code> est à <code>0</code>, ou si le test +de vie est désactivé, ce test de décalage n'est jamais fait. Ce dernier est +effectué tous les <code>health_check_period</code>. La valeur par défaut +pour <code>delay_threshold</code> est <code>0</code>. + +Vous devrez recharger la configuration de pgpool-II si vous changez cette +directive. +</p> + +<li>log_standby_delay +<p> +Permet de spécifier comment le décalage de réplication est tracé dans le +fichier de traces de pgpool-II. Si <code>none</code> est spécifié ici, +rien n'est écrit. Si <code>always</code> est spécifié, alors le décalage +sera tracé à chaque fois que le test est effectué. +Si <code>if_over_threshold</code> est spécifié, alors le décalage est +tracé uniquement lorsqu'il dépasse le <code>delay_threshold</code>. +La valeur par défaut pour <code>log_standby_delay</code> est +<code>none</code>. + +Vous devrez recharger la configuration de pgool-II si vous changez ce +paramètre. +</p> +<p> +Vous pouvez aussi monitorer le décalage éventuel de la réplication en +utilisant la commande "show pool_status". +</p> +</ul> +</p> + +<h4>Le failover avec Streaming Replication</h4> +<p> +Dans le mode maître/esclave avec le Streaming Replication, si le +noeud primaire ou le noeud en attente s'arrête, pgpool-II peut-être +configuré pour lancer un Failover. +Les noeuds peuvent alors être attachés automatiquement sans +configuration ou opérations complémentaires. +Alors qu'il est en pleine réplication [~], le noeud en attente vérifie +régulièrement si un fichier de "trigger file" existe, et s'il le trouve, +le noeud en attente sort de son mode recovery 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 noeud primaire +vient à tomber. +</p> +<p> +<strong>Attention: si vous pensez utiliser plusieurs noeuds en mode +standby, il est reccomandé de définir un "delay_threshold" pour +empêcher tout requête dirigée vers d'autres noeuds en standby de +récupérer des données plus vieilles.</strong> +</p> +<p> +Si un second noeud en standby prends le relais quand le premier +noeud en standby avait déjà pris le relais, vous pourriez avoir +des données erronnées en provenance du second standby. +Nous vous reccomandons de ne pas utiliser ce genre de configuration. +</p> +<p> +Voici commment configurer un mécanisme de Failover. +</p> +<p> +<ol> + <li>Il faut créer un script de Failover quelque part sur le système, + par exemple dans /usr/local/pgsql/bin, puis le rendre exécutable. + +<pre> +$ cd /usr/loca/pgsql/bin +$ cat failover_stream.sh +#! /bin/sh +# Commandes pour faire un Failover en mode Streaming Replication +# Ce script présuppose que le noeud 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 trigger afin que le standby prenne le relais sur le +# noeud Primaire. +# +# Arguments: +# $1: identifiant du noeud 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 + +# Creer un fichier de trigger +/usr/bin/ssh -T $new_master /bin/touch $trigger_file + +exit 0; + +chmod 755 failover_stream.sh +</pre> +<li>Il faut à présent définir la commande failover_commmand +dans le fichier pgpool.conf. +<pre> +failover_command = '/usr/local/src/pgsql/9.0-beta/bin/failover_stream.sh %d %H /tmp/trigger_file0' +</pre> + +<li>Et créer le recovery.conf sur le noeud en standby +<a href="recovery.conf.sample">Un fichier recovery.conf d'exemple</a> +peut-être trouvé dans le répertoire d'installation de PostgreSQL. +Son nom est "share/recovery.conf.sample". +Copier recovery.conf.sample en recovery.conf dans le répertoire de base +de PostgreSQL et l'éditer comme suit. +<pre> +standby_mode = 'on' +primary_conninfo = 'host=nom_du_noeud_primaire user=postgres' +trigger_file = '/tmp/trigger_file0' +</pre> + +<li>Ajuster le postgresql.conf sur le noeud Primaire. La configuration +ci-dessous est donneé à titre indicatif, vous devrez probablement +l'ajuster pour votre environnement. +<pre> +wal_level = hot_standby +max_wal_senders = 1 +</pre> + +<li>Définir pg_hba.conf sur le noeud Primaire. La configuration +ci-dessous est donneé à titre indicatif, vous devrez probablement +l'ajuster pour votre environnement. +<pre> +host replication postgres 192.168.0.10/32 trust +</pre> + +</ol> + +<p> +Démarrez PostgreSQL sur les noeuds Primaire et Secondaire pour initialiser +la réplication. Si le noeud Primaire venait à tomber, le noeud Secondaire +prendra automatiquement le relais, en tant que nouveau noeud Primaire, et +sera alors prêt à recevoir les requêtes en écriture. +</p> + +<h4>Streaming Replication</h4> +<p> +Lorsqu'on utilise le Streaming Replication et le Hot Standby, il est important +de déterminer quelle requête peut-être envoyée sur le noeud Principal ou +sur le noeud en Standby (Secondaire), et quelle requête ne devraît pas +être envoyée au Standby. +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. +</p> +<p> +Nous distinguons les requêtes qui devraient être envoyées à tel ou tel +noeud en les examinant elles-même. +</p> +<p> +<ul> + <li>Les requêtes suivantes devraient être envoyées au noeud Primaire uniquement: + <ul> + <li>INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE, CREATE, DROP, ALTER, COMMENT + <li>SELECT ... FOR SHARE | UPDATE + <li>SELECT dans un niveau d'isolation transactionnel de type SERIALIZABLE + <li>LOCK, commande plus stricte que ROW EXCLUSIVE MODE + <li>Quelques commandes transactionnelles: + <ul> + <li>BEGIN READ WRITE, START TRANSACTION READ WRITE + <li>SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE + <li>SET transaction_read_only = off + </ul> + <li>Les commandes relatives au commit en deux phases: PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED + <li>LISTEN, UNLISTEN, NOTIFY + <li>VACUUM + <li>Quelques fonctions liées aux séquences (nextval et setval) + <li>Les commandes de création de "Large Objects" + </ul> + <li>Ces requêtes peuvent-être envoyées à la fois au noeud Primaire et au + noeud en Standby. Si le Load-Balancing est activé, ce type de requêtes + peut-être envoyé au noeud en Standby. + Cependant, si "delay_threshold" est défini et que le délai dans la + réplication est supérieur au "delay_threshold", les requêtes sont envoyées au + noeud Primaire. + <ul> + <li>tout SELECT non listé ci-dessus + <li>COPY TO + <li>DECLARE, FETCH, CLOSE + <li>SHOW + </ul> + <li>Les requêtes suivantes sont envoyées à la fois au noeud Primaire et Secondaire: + <ul> + <li>SET + <li>DISCARD + <li>DEALLOCATE ALL + </ul> +</ul> +</p> + +<p> +Dans une transaction explicite: +<ul> + <li>Toute transaction commençant par une commande comme BEGIN est envoyée + au noeud Primaire. + <li>Tout SELECT qui survient immédiatement après, ainsi que toutes les requêtes + qui peuvent-être envoyées aussi bien au Primaire qu'au Secondaire, sont balancés + entre les noeuds. + <li><p> + Toute commande qui ne peut-être exécutée sur un noeud 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 noeud Primaire. En effet, les SELECTs 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. +</p> +</ul> +</p> + +<p> +Dans le protocole étendu, il est possible de déterminer si la requête +peut-être envoyée au noeud en Standby ou pas dans le mode Load-Balancing +au moment où on parse la requête. Les rêgles sont les mêmes que dans le +protocole non-étendu. +Par exemple, les INSERTs sont envoyés au Primaire, ainsi que toute requête +qui suivra. +</p> + +<p> +[Note: si le parsing d'une requête en SELECT est envoyée sur le Standby à +cause du load-balancing, et qu'une requête en modification de données, comme +un INSERT est envoyé à pgpool-II, alors le SELECT parsé devra être exécuté +sur le noeud Primaire. Cependant, on re-parse le SELECT sur le noeud primaire.] +<p> +Enfin, les requêtes qui semblent douteuses ou possiblement en erreur sont +envoyées sur le noeud Primaire. +</p> + +<h4>Online recovery avec Streaming Replication</h4> +<p> +Dans le mode Maître/Esclave avec Streaming Replication, on peut procéder à une +récupération à chaud (Online recovery). +Cependant, seul un noeud en Standby peut-être ainsi récupéré. On ne peut pas +reconstruire un noeud Primaire. Pour ce faire, il faudra stoper toutes les +bases de données, ainsi que pgpool-II, puis restaurer le noeud Primaire à +partir d'une sauvegarde. +</p> + +<p> +Voici les étapes. +<ol> + <li>Définir le paramètre recovery_user. C'est souvent "postgres". +<pre> +recovery_user = 'postgres' +</pre> +<li>Définir le paramètre recovery_password pour que le recovery_user +puisse se connecter à la base. +<pre> +recovery_password = 't-ishii' +</pre> + +<li> Définir le paramètre recovery_1st_stage_command. +Le script pour cette étape (stage) devrait procéder à une sauvegarde +du noeud Primaire et à sa restauration sur le noeud en Standby. +Placer ce script à l'intérieur du répertoire de données du noeud Primaire +et donnez-lui les droits nécessaires pour être exécutable. +Voici un script d'exemple <a href="basebackup.sh">(basebackup.sh)</a>, +avec une configuration simple d'un Primaire et d'un Standby. +il faut configurer SSH pour que le recovery_user puisse se logguer depuis +le Primaire vers le Standby sans qu'on lui demande de mot de passe. +<pre> +recovery_1st_stage_command = 'basebackup.sh' +</pre> +<li>Laisser le paramètre recovery_2nd_stage_command vide. +<pre> +recovery_2nd_stage_command = '' +</pre> + +<li>Installer à présent les fonctions C et SQL nécessaires dans chacune +des bases de données pour que le online reconvery fonctionne. +</p> + +<pre> +# cd pgpool-II-x.x.x/sql/pgpool-recovery +# make +# make install +# psql -f pgpool-recovery.sql template1 +</pre> + +<li>Après avoir terminé le Online recovery, pgpool-II démarre PostgreSQL +sur le noeud Standby. +À cet effet, il faut installer un script sur chacun des noeuds. +<a href="pgpool_remote_start">Un script d'exemple</a> est inclus dans le +répertoire "sample", dans le code source. +Ce script utilise SSH. Il faudra permettre à recovery_user de se logguer +depuis le noeud Primaire vers le noeud Standby sans qu'on lui demande un +mot de passe. +</ol> +</p> + +<p> +C'est tout. +On peut à présent utiliser pcp_recovery_node (dès qu'un noeud en Standby +s'arrête) ou alors cliquer sur le bouton "recovery" dans l'interface de +pgpoolAdmin pour exécuter un Online Recovery. +</p> + +<h3>Mode Parallele</h3> + +<p>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 noeud. De plus, +les fonctionalités de réplication et de load-balancing 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_slae 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. +</p> + +<h4><p>Configuration de la base Système</p></h4> + +<p>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 +<code>pgpool.conf</code>.</p> + +<dl> + <dt>system_db_hostname</dt> + <dd> + <p>Nom de l'hôte où la base de données système réside. Une chaîne vide + dans ce paramètre ('') signigie que celle-ci est sur le même nœud que + pgpool-II, et sera alors accédée via un socket UNIX.</p> + </dd> + + <dt>system_db_port</dt> + <dd> + <p>Numéro de port de la base de données système</p> + </dd> + + <dt>system_dbname</dt> + <dd> + <p>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: + <code>'pgpool'</code>.</p> + </dd> + + <dt>system_db_schema</dt> + <dd> + <p>Les règles de partitionnement et autres informations seront stockées + dans le schéma spécifié ici. La valeur par défaut est: + <code>'pgpool_catalog'</code>.</p> + </dd> + + <dt>system_db_user</dt> + <dd> + <p>Nom de l'utilisateur qui se connecte à la base de données système.</p> + </dd> + + <dt>system_db_password</dt> + <dd> + <p>Mot de passe pour 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 ('').</p> + </dd> + + <dt>ssl_ca_cert</dt> + <dd> + <p> + Chemin complet vers un fichier au format PEM contenant un ou plusieurs + certificats CA, qui peuvent-être utilisés pour vérifier le certificat du + backend. C'est analogue à l'option <code>-CAfile</code> de la + commande <code>verify(1)</code> d'OpenSSL. + </p> + + <p> + Il n'y a pas de valeur par défaut pour cette option, ainsi, aucune + vérification n'a lieu. Une vérification aura toujours lieu si cette + option reste ainsi, mais qu'on a défini une valeur pour + <code>ssl_ca_cert_dir</code>. + </p> + </dd> + + <dt>ssl_ca_cert_dir</dt> + <dd> + <p> + Chemin vers un répertoire qui contient les certificats CA au format PEM, + qui peuvent être utilisés pour vérifier le certificat du backend. + C'est analogue à l'option <code>-CAfile</code> de la commande + <code>verify(1)</code> d'OpenSSL. + </p> + + <p> + Il n'y a pas de valeur par défaut pour cette option, ainsi, aucune + vérification n'a lieu. Une vérification aura toujours lieu si cette + option reste ainsi, mais qu'on a défini une valeur pour + <code>ssl_ca_cert</code>. + </p> + </dd> + +</dl> + +<h4><p>Configuration initiale de la base de données système</p></h4> + +<p>Il faut d'abord créer la base de données et le schéma spécifié dans le +fichier <code>pgpool.conf</code>. Un script d'exemple peut-être trouvé dansun +<code>$prefix/share/system_db.sql</code>. Si vous avez spécifié un nom +différent pour la base de données ou le schéma, adaptez ce script en +conséquence. +<pre> +psql -f $prefix/share/system_db.sql pgpool +</pre> + +</p> + +<h4><p>Enregistrement d'une règle de partitionnement</p></h4> + +<p>Les règles pour le partitionnement des données doivent être enregistrées +dans la table <code>pgpool_catalog.dist_def</code>.</p> + +<pre> +CREATE TABLE pgpool_catalog.dist_def( +dbname TEXT, -- nom de la BD +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 de la règle de partitionnement +PRIMARY KEY (dbname,schema_name,table_name) +); +</pre> + + +<h4><p>Enregistrement d'une règle de réplication</p></h4> +<p> +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 doit-être soit répliquée, soit +ditribuée. +</p> + +<pre> +CREATE TABLE pgpool_catalog.replicate_def( + dbname TEXT, --nom de la base de données + 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) +); +</pre> + +<h4><p>Exemple basé sur le partitionnement des tables de pgbench</p></h4> + +<p>[NDT: pgbench est un outil de benchmark simple de PostgreSQL, disponible +dans le répertoire "contrib" de PostgreSQL]</p> + +<p> +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". + +</p> +<pre> +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)'] +); +</pre> + +<p>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. +</p> +<pre> +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 +</pre> + +<h2><a name="hba"></a>Configuiration de pool_hba.conf pour l'authentification +des clients (HBA)</h2> +<p> + Tout comme le fichier "pg_hba.conf" pour PostgreSQL, pgpool a la même + fonction d'authentification des clients, qui est basée sur un fichier + appelé "pool_hba.conf". +</p> +<p> + Lorsqu'on installe pgpool, 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 + é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. +</p> +<p> + Le format du fichier "pool_hba.conf" est très similaire à celui du fichier + "pg_hba.conf" de PostgreSQL. +</p> +<pre> + local DATABASE USER METHOD [OPTION] + host DATABASE USER CIDR-ADDRESS METHOD [OPTION] +</pre> +<p> + Voir "pool_hba.conf.sample" pour une explication détaillée de chaque champ. +</p> +<p> + Voici les limitations de "pool_hba". +<ul> +<li>la connexion de type "hostssl" n'est pas supportée</li> +<p> + Bien que "hostssl" soit invalide, pgpool-II 2.3 et supérieur supporte + SSL. Voir <a href="#ssl">SSL</a> pour plus de détails. +</p> +<li>"samegroup" dans la colonne DATABASE n'est pas supporté</li> +<p> + Comme pgpool ne sait rien à propos des utilisateurs déclarés dans le + backend 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. +</p> +<li>les noms de groupes suivis de "+" pour la colonne USER ne sont pas +supportés</li> +<p> + 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. +</p> +<li>l'IPv6 pour l'adresse/masque dans la colonne IP n'est pas supporté</li> +<p> + À ce jour, pgpool ne supporte pas l'IPv6. +</p> +<li>Seules les méthodes "trust", "reject", "md5" et "pam" sont supportées +dans la colonne METHOD</li> +<p> + 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 backend PostgreSQL. +</p> +<p> +Pour utiliser l'authentification md5, il faudra enregistrer votre nom +d'utilisateur et son mot de passe dans "pool_passwd". +Voir <a href="#md5">Authentification / Contrôle d'accès</a> pour plus de +détails. +</ul> +<p> + 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 backend. pool_hba ne regarde en effet que si une + correspondance est trouvée dans le pool_hba.conf ou pas. +</p> + +<p> + 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 du "configure": +</p> +<pre> + configure --with-pam +</pre> +<p> + 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. +</p> + +<h2>Configuration de la méthode de cache de requêtes</h2> +<p>Le cache de requêtes peut-être utilisé dans tous les modes de pgpool-II. +Son activation dans le fichier pgpool.conf est faite de la manière suivante: +<pre> +enable_query_cache = true +</pre> + +<p> +On aura cependant besoin de créer aussi la table suivante dans la base de +données système de pgpool-II: +</p> +<pre> +CREATE TABLE pgpool_catalog.query_cache ( + hash TEXT, + query TEXT, + value bytea, + dbname TEXT, + create_time TIMESTAMP WITH TIME ZONE, + PRIMARY KEY(hash, dbname) +); +</pre> +<p> +Cependant, il faudra peut-être modifier le nom de schéma dans l'exemple +ci-dessus si le "pgpool_catalog" n'est pas utilisé. +</p> + +<h1>Démarrage et arrêt de pgpool-II<a name="start"></a></h1> + +<p>Tous les backends 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. +</p> + +<pre> +pgpool [-c][-f config_file][-a hba_file][-F pcp_config_file][-n][-D][-d] +</pre> +<p> +<table> + <tr><td>-c<br/>--clear-cache</td><td>vide le cache de requêtes</tr> + <tr><td>-f config_file<br/>--config-file config-file</td><td>spécifie +le fichier pgpool.conf</tr> + <tr><td>-a hba_file<br/>--hba-file hba_file</td><td>spécifie le +fichier pool_hba.conf</tr> + <tr><td>-F pcp_config_file<br/>--pcp-password-file</td><td>spécifie +le fichier pcp.conf</tr> + <tr><td>-n<br/>--no-daemon</td><td>ne pas fonctionner en mode démon +(le terminal n'est alors pas détaché)</tr> + <tr><td>-D<br/>--discard-status</td><td>Ignore le fichier de statut +précédent</tr> + <tr><td>-d<br/>--debug</td><td>mode de débogage</tr> +</table> +pgpool-II peut être arrêté de deux façons. La première est d'utiliser une +commande PCP (détaillé plus loin dans ce document). La seconde est d'utiliser +une commande pgpool-II, dont voici un exemple: +</p> + +<pre> +pgpool [-f config_file][-F pcp_config_file] [-m {s[mart]|f[ast]|i[mmediate]}] stop +</pre> +<p> +<table> + <tr><td><code>-m s[mart]</code><br/><code>--mode s[mart]</code></td> + <td>attends que les clients se déconnecte avant de s'arrêter (mode par +défaut)</td></tr> + <tr><td><code>-m f[ast]</code><br/><code>--mode f[ast]</code></td> + <td>n'attend pas la déconnexion des clients, et s'arrête +immédiatement</td></tr> + <tr><td><code>-m i[mmediate]</code><br/><code>--mode i[mmediate]</code></td> + <td>même chose que <code>'-m f'</code></td></tr> </table> +</p> +<p> +pgpool enregistre son état dans le fichier [logdir]/pgpool_status. Lorsque +pgpool redémarre, il lit ce fichier et restaure le statut du backend (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: +<ol> +<li>Un backend s'arrête inopinément et pgpool exécute la procédure de fail-over +<li>Une mise à jour est effectuée sur l'une des bases de données actives, via +pgpool +<li>L'administrateur décide d'arrêter pgpool +<li>Quelqu'un d'autre décide de redémarrer la base de données qui est en train +de s'arrêter, sans en informer l'administrateur +<li>L'administrateur redémarre pgpool +</ol> +</p> +<p> +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. +</p> + +<h1>Rechargement des fichiers de configuration de pgpool-II<a +name="reload"></a></h1> +<p>pgpool-II peut recharger ses fichiers de configuration, et se mettre alors à +jour par rapport à ces derniers, sans avoir à être redémarré. +</p> + +<pre> +pgpool [-c][-f config_file][-a hba_file][-F pcp_config_file] reload +</pre> +<p> +<table> + <tr><td>-f config_file<br/>--config-file config-file</td><td>spécifie +le fichier pgpool.conf</tr> + <tr><td>-a hba_file<br/>--hba-file hba_file</td><td>spécifie le +fichier pool_hba.conf</tr> + <tr><td>-F pcp_config_file<br/>--pcp-password-file</td><td>spécifie +le fichier pcp.conf</tr> +</table> + +<p> +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. +</p> + +<h1><a name="show-commands"></a>Commandes SHOW</h1> +<h2>Overview</h2> +<p> +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: +<ul> + <li>pool_status, pour avoir la configuration</li> + <li>pool_nodes, pour avoir des informations sur les nœuds</li> + <li>pool_processes, pour avoir l'information sur les processus de +pgpool-II</li> + <li>pool_pools, pour avoir l'information sur les pools de pgpool-II</li> + <li>pool_version, pour avoir la version de pgpool-II</li> +</ul> +<p> +<u>Note</u> : 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. +</p> +</p> +<p>l'option "pool_status" était disponible dans les versions précédentes, mais +les autres sont apparues avec la version 3.0</p> +<h2>pool_status</h2> +<p>"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: +<pre> +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 +</pre> +</p> +<h2>pool_nodes</h2> +<p>"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 ip), son port, son statut et le +poids (qui n'a d'intérêt que si on utilise le mode de load-balancing de +requêtes en lecture). Les valeurs possibles pour la colonne status +sont explicitées dans <a href="#pcp_node_info">la partie dédiée à +pcp_node_info</a>. +<pre> + + +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) +</pre> +</p> +<h2>pool_processes</h2> +<p>"SHOW pool_processes" renvoie une liste de tous les processus qui attendent +une connexion ou interragissent avec une connexion. +</p> +<p> +Cette liste a 6 colonnes: +<ul> +<li>pool_pid est le PID du process pgpool affiché</li> +<li>start_time est le timestamp correspondant au démarrage du processus</li> +<li>database est le nom de la base de données où le backend est actuellement +connecté</li> +<li>username est le nom de l'utilisateur utilisé dans la connexion au backend +pour ce processus</li> +<li>create_time est le timestamp correspondant à la création de la +connexion</li> +<li>pool_counter compte le nombre de fois que ce pool de connexions (le +processus) a été utilisé par les clients</li> +</ul> +</p> +<p>Cette vue retournera toujours un nombre de lignes +équivalent à "num_init_children".</p> +<pre> +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) +</pre> +<h2>pool_pools</h2> +<p>"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: +</p> +<p> +Cette liste a 11 colonnes: +<ul> +<li>pool_pid est le PID du processus pgpool-II</li> +<li>start_time est le timestamp qui correspond au lancement du processus</li> +<li>pool_id est l'identifiant du pool (qui devraît être entre 0 et +"max_pool"-1)</li> +<li>backend_id est l'identifiant du backend (qui devraît être entre 0 et le +nombre de backends configurés moins un).</li> +<li>database est le nom de la base de données utilisée dans cette connexion</li> +<li>username est le nom d'utilisateur utilisé dans cette connexion</li> +<li>create_time est le timestamp de création de cette connexion</li> +<li>majorversion et minorversion sont les versions de protocole utilisés par +cette connexion</li> +<li>pool_counter compte le nombre de vois que cette connexion a été utilisée +par les clients</li> +<li>pool_backendpid et le PID du processus PostgreSQL</li> +<li>pool_connected et à vrai (1) si un client utilise actuellement cette +connexion</li> +</ul> +</p> +<p>Cette vue retournera toujours le même nombre de lignes que +"num_init_children" * "max_pool"</p> +<pre> + 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) +</pre> +</p> +<h2>pool_version</h2> +<p>"SHOW pool_version" affiche la version de pgpool-II. En voici un exemple: +<pre> +benchs2=# show pool_version; + pool_version +------------------------ + 3.0-dev (umiyameboshi) +(1 line) +</pre> +</p> +<h1><a name="online-recovery"></a>Online Recovery</h1> +<h2>Aperçu</h2> +<p> +pgpool-II, alors qu'il est en mode réplication, peut synchroniser une base de +données et attacher un nœud tout en rendant le service au clients. Cette +fonctionnalité est appelée "online recovery". +</p> + +<p> +Le nœud cible de cette restauration doit être dans un état "détaché" avant de +lancer le online recovery. + +Si on veut ajouter un serveur PostgreSQL dynamiquement, ajouter un +"backend_hostname" et ces paramètres associés et recharger pgpool.conf. +pgpool-II va alors enregistrer ce nouveau serveur et l'afficher dans l'état +"détaché". +</p> + +<p> +<font color="red">Attention: Penser à arrêter l'autovacuum sur le nœud maître +(soit 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 +inconsistance 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.</font> +</p> + +<p> + Si le serveur PostgreSQL a déjà été démarré, il faut tout l'arrêter. +</p> + +<p> +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: + <ol> + <li> CHECKPOINT + <li> Première phase du online recovery + <li> Attendre que tous les clients soient déconnectés + <li> CHECKPOINT + <li> Seconde phase du online recovery + <li> Démarrage du nouveau postmaster (effectué par pgpool_remote_start) + <li> Attachement du nœud + </ol> +</p> + +<p> + La première étape de la synchronisation des données et appelée "première + phase". Les données sont en effet synchronisées pendant cette étape. + Pendant cette dernière, les données <b>peuvent</b> être mises à jour ou + récupérées par les client, sur toutes les tables, de manière concurrente. +</p> + +<p> + On peut spécifier un script qui sera exécuté pendant cette première phase. + pgpool-II passe alors trois arguments à ce dernier: + + <ol> + <li> le chemin complet du cluster PostgreSQL du noeud maître + <li> le nom d'hôte (ou IP) du serveur à restaurer + <li> le chemin complet du cluster PostgreSQL du serveur à restaurer + </ol> +</p> + +<p> + 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 soit 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. +</p> + +<p> + <font color="red"> + 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. +</font> +</p> + +<h2>Configuration du online recovery</h2> +<p> +Il convient de configurer les paramètres suivants pour le online recovery +dans le fichier pgpool.conf. + <ul> + <li> backend_data_directory + <li> recovery_user + <li> recovery_password + <li> recovery_1st_stage_command + <li> recovery_2nd_stage_command + </ul> +</p> + + +<h2><a name="installing-c-functions"></a>Installation des fonctions en +langage C</h2> +<p> +Les fonctions en langage C suivants doivent-être installées dans la base +"template1" de tous les backends PostgreSQL pour que le online recovery +fonctionne. + +Leur code source est dans l'archive de pgpool-II dans le répertoire suivant: +</p> + +<pre> + pgpool-II-x.x.x/sql/pgpool-recovery/ +</pre> + +<p> +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 tape "make install": + +</p> + +<pre> + % cd pgpool-II-x.x.x/sql/pgpool-recovery/ + % make install +</pre> + +<p> +À présent, il faut installer les fonctions SQL correspondantes +</p> + +<pre> + % cd pgpool-II-x.x.x/sql/pgpool-recovery/ + % psql -f pgpool-recovery.sql template1 +</pre> + + +<h2>Déploiement du script de restauration</h2> +<p> +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 du cluster de PostgreSQL ($PGDATA). Plusieurs scripts d'exemple sont +disponibles dans le répertoire "pgpool-II-x.x.x/sample". +</p> + +<h3>Online recovery grâce au PITR</h3> +<p> +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 dûment +configuré. +</p> + +<p> +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. +</p> + +<pre> + #! /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 +</pre> + +<p> +Ce script place le serveur maître en mode sauvegarde à chaud, puis génère le +fichier recovery.conf suivant: +</p> +<pre> +restore_command = 'scp master:/data/archive_log/%f %p' +</pre> +Ensuite, il effectue la sauvegarde, puis sors le serveur maître du mode backup +et copie enfin la sauvegarde sur le nœud désiré. +</p> + +<p> +La seconde phase de cette procédure est un script qui va forcer un changement +de fichier wal (XLOG). Ce script est nommé "pgpool_recovery_pitr" ici. +Il provoque un changement de journal de transactions. +À cet effet, pg_switch_xlog peut être utilisé. +Cependant, il pourrait rendre la main <b>avant</b> que le changement de fichier +wal 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 lors de la procédure explicitée dans la section +<a href="#installing-c-functions">Installation des fonctions en +langage C</a>. +</p> +<p> +Voici un script d'exemple: +</p> +<p> +<pre> +#! /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 +</pre> +</p> + +<p> +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. +</p> + +<p> +Ces scripts doivent-être déployés dans le répertoire du cluster PostgreSQL (le +$PGDATA). +</p> +<p> +Enfin, on édite le fichier pgpool.conf. + +<pre> +recovery_1st_stage_command = 'copy-base-backup' +recovery_2nd_stage_command = 'pgpool_recovery_pitr' +</pre> + +</p> + +<p> +Cette opération termine la préparation du online recovery via le PITR. +</p> + +<h4><p>pgpool_remote_start</p></h4> +<p> +Ce script démarre le processus postmaster sur les nœuds distants. +pgpool-II l'exécute de la manière suivante. +</p> + +<pre> + % pgpool_remote_start remote_host remote_datadir + remote_host: Nom d'hôte de la machine cible à restaurer + remote_datadir: Chemin du cluster PostgreSQL sur une machine en +restauration +</pre> + +<p> +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 +pour que cela fonctionne. +</p> + +<p> +Si la restauration se fait avec PIRT, on doit déployer le script de backup de +base. PostgreSQL démarrera alors automatiquement en effectuant une restauration +via le PITR. Il acceptera ensuite les connexions. +</p> + +<pre> +#! /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 & +</pre> + +<h3>Online recovery avec rsync</h3> +<p> +PostgreSQL 7.4 n'a pas le PITR, apparu en version 8.0. rsync peut alors être +utilisé pour effectuer le online recovery. Dans le script d'exemple qu'on +trouve dans les sources de pgpool-II, il y a un script de recovery qui est +nommé "pgpool_recovery". Ce dernier utilise la commande rsync. pgpool-II +appelle ce script avec trois arguments. +</p> + +<pre> + % pgpool_recovery datadir remote_host remote_datadir + datadir: Répertoire du cluster PostgreSQL sur un serveur maître + remote_host: Nom d'hôte (ou IP) du serveur cible à restaurer + remote_datadir: Répertoire du cluster PostgreSQL du serveur cible à +restaurer +</pre> + +<p> +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. +</p> + +<p> +Note à propos de rsync: +<ul> + <li>-c (or --checksum) : cette option est requise pour assurer une +transmission fiable + + <li>-z (or --compress) : cette option fait de la compression des fichiers lors +de leur transmission. Cela sera fort utile pour les connexions réseau lentes, +mais pourrait ajouter une grosse surcharge inutile sur le CPU (à cause de la +compression) pour des réseaux à 100 Mbits voire supérieurs. Dans ces derniers +cas, il sera préférable de ne pas utiliser la compression. + + <li>rsync 3.0.5 a d'excellentes améliorations de performances en vitesse (près +de 50% plus rapide d'après les discussions qui ont eu lieu sur la liste de +discussion pgpool-general) +</ul> + +</p> + +<p> +Si on utilise pgpool_recovery, il convient d'ajouter les lignes suivantes au +ficher pgpool.conf. + +<pre> +recovery_1st_stage_command = 'pgpool_recovery' +recovery_2nd_stage_command = 'pgpool_recovery' +</pre> +</p> + +<h2>Comment effectuer un online recovery</h2> +<p> +Afin de réaliser un online recovery, on peut utiliser la commande +pcp_recovery_node ou bien pgpoolAdmin. +</p> + +<p> +Il est à noter qu'on doit positionner un nombre important dans le tout premier +argument de pcp_recovery_node. Il s'agit d'un timeout 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. +</p> + +<h1><a name="troubleshooting"></a>Que faire en cas d'erreur</h1> +<p> +Cette section décrit quelques problèmes qui peuvent survenir lors de +l'utilisation de pgpool-II, ainsi que leur solutions. +</p> +<p> +<ul> + +<dt>Health check failed +<dd> +<p> +pgpool-II vérifie périodiquement que tous les serveurs configurés fonctionnent +correctement. +</p> +<p> +<pre> +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) +</pre> +</p> +<p> +Ici, la trace mointre que le serveur 1 (nom d'hôte "foo") s'arrête puis est +déconnecté (shutdown) de pgppol. 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. +</p> + +<dt>Failed to read kind from frontend +<dd> +<p> +<pre> +2010-07-26 18:43:24 LOG: pid 24161: ProcessFrontendResponse: failed to read kind from frontend. frontend abnormally exited +</pre> +<p> +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ènent 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. +</p> + +<dt>Kind mismatch errors +<dd> +<p> +Cette erreur peut survenir si pgpool-II fonctionne en mode réplication. +</p> +<pre> +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] +</pre> +<p> +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. +<p> +Attention: on pourrait avoir aussi 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. +</p> +<p> +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. +</p> + +<p> +<dt>Pgpool detected difference of the number of inserted, updated or deleted tuples +<dd> +<p> +Dans le mode réplication, pgpool-II détecte un nombre différent +d'enregistrements mis à jour (en INSERT, UPDATE ou DELETE) dans les différents +serveurs. +</p> +<p> +<pre> +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 +</pre> +<p> +Dans l'exemple ci-dessus, le nombre d'enregistrements mis à jour grace à +"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 alors é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. +</p> +<p> +Il convient alors d'arrêter le serveur que l'on suspecte désynchronisé (ou +simplement ne pas avoir les bonnes données), puis de procéder à un online +recovery. +</ul> + + +<h1>Restrictions<a name="restriction"></a></h1> + +<p> +<h2>Fonctionalités de PostgreSQL</h2> +<p> +<ul> +<li>Si on utilise pg_terminate_backend() pour arrêter un backend PostgreSQL, +cela provoquera un failover. La raison de ce comportement est que PostgreSQL +envoie alors exactement le même message que si c'était le postmaster lui-même +qui s'arrêtait complètement. Il n'y a pas de contournement de ce problème à ce +jour. Aussi, il faut veiller à ne pas utiliser cette fonction pour le moment. +</ul> + +<p> +<h2><a name="md5"></a>Authentification / Contrôle d'accès</h2> + +<p> +<ul> + <li>Dans le mode réplication ou maître-esclave, les méthode +d'authentification supportées sont trust, clear text password et pam. md5 est +aussi supporté depuis la version 3.0 de pgpool-II. +md5 est supporté en utilisant "pool_passwd". Voici les étapes à respecter pour +autoriser l'authentification md5: + <ol> + <li>Se connecter au système d'exploitation du serveur de +données, avec l'utilisateur qui a les droits (postgres) et entrer: + "pg_md5 --md5auth <mot_de_passe>" + le nom d'utilisateur et son mot de passe encrypté md5 sont +alors enregistrés dans "pool_passwd". Si ce dernier n'existe pas encore, la +commande pg_md5 va le créer automatiquement..</li> + <li>Le format utilisé par "pool_passwd" est +"nom_d_utilisateur:mot_de_passe_encrypté_md5"</li> + <li>Il faudra bien sur aussi une entrée appropriée md5 dans le +fichier pool_hba.conf. A cet effet, voir <a href="#hba">Configuration de pool_hba.conf +pour l'authentification des clients</a> pour plus de détails</li> + <li>Il faut bien veiller à ce que le nom d'utilisateur et son +mot de passe soient strictement identiques à ce qui se trouvent dans le serveur +PostgreSQL pour que cela fonctionne</li> + </ol> + + </li> + <li>Dans tous les autres modes, les méthodes trust, clear text password, +crypt, md5 et pam sont supportées.</li> + <li>pgpool-II ne supporte pas les controles d'accès comme pg_hba.conf de +PostgreSQL. Par exemple, si les connexions TCP/IP sont activées, pgpool-II +accepte toutes les connexions TCP/IP, quelles que soient leurs origines. Si +c'est absolument requis dans les contexte, il convient d'utiliser un programme +comme iptables afin de contrôler les accès TCP/IP. Bien sûr, les serveurs +PostgreSQL qui acceptent les connexions pgpool-II peuvent utiliser leur +configuration pg_hba.conf propre.</li> + </ul> +</p> + +<h2>Large objects</h2> +<p> +pgpool-II 2.3.2 et suivants supportent la réplication des large objects si le +backend PostgreSQL est au moins en version 8.1. + +Pour que cela fonctionne, il faut autoriser la directive de configuration <a +href="#lobj_lock_table">lobj_lock_table</a> dans le fichier pgpool.conf. + +Cependant, la réplication des large objects en utilisant la fonction PostgreSQL +lo_import n'est pas supportée. +</p> + +<h2>Tables temporaires en mode maître-esclave</h2> +<p> +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, et alors, les SELECT seront +balancés 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. +</p> +<p> +<pre> +Voici en exemple de SELECT qui cause problème: +SELECT 't1'::regclass::oid; +</pre> +</p> +<p> +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. +</p> + +<h2>Fonctions et autres en mode Réplication</h2> + +<p> +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. +</p> +<p>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()".</p> + +<p> +À 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 value) 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: +<ul> +<li>Le calcul de la donnée temporelle n'est pas correct dans quelques cas. Par +exemple, voici une définition de table: +<pre> +CREATE TABLE rel1( + d1 date DEFAULT CURRENT_DATE + 1 +) +</pre> +Ceci est traité de la même façon que: +<pre> +CREATE TABLE rel1( + d1 date DEFAULT CURRENT_DATE +) +</pre> +<p> +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: +<pre> +foo bigint default (date_part('epoch'::text,('now'::text)::timestamp(3) with time zone) * (1000)::double precision) +</pre> +</p> +<li>Supposons à présent que nous ayons la table suivante: +<pre> +CREATE TABLE rel1( + c1 int, + c2 timestamp default now() +) +</pre> +On peut répliquer: +<pre> +INSERT INTO rel1(c1) VALUES(1) +</pre> +puis que cela se transforme en: +<pre> +INSERT INTO rel1(c1, c2) VALUES(1, '2009-01-01 23:59:59.123456+09') +</pre> +Cependant: +<pre> +INSERT INTO rel1(c1) SELECT 1 +</pre> +ne peut pas être transformé, et donc, ne sera pas correctement répliqué avec +l'implémentation actuelle. Les valeurs seront cependant insérées, mais sans +aucune transformation. +</ul> +</p> +<p> +Les tables créées avec <code>CREATE TEMP TABLE</code> 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. +</p> +<p> +Pour les version 8.2.X et précédentes, <code>CREATE TEMP TABLE</code> ne +sera pas supprimé à la sortie de la session. + +Ceci est dû au pooling de connexion, qui, du point de vue du backend +PostgreSQL, garde la session en vie. + +Pour éviter cela, on doit supprimer explicitement la table dans le bloc de +transaction, soit en ajoutant un <code>DROP TABLE</code>, soit en créant la +table temporaire avec <code>CREATE TEMP TABLE ... ON COMMIT DROP</code>. + +<h2>Requêtes</h2> + +<p>Voici les requêtes qui ne peuvent pas être traitées par pgpool-II</p> + +<h3>INSERT (en mode parallèle)</h3> + +<p>On ne peut pas utiliser <code>DEFAULT</code> 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: + +<pre> +INSERT INTO t(x) VALUES (DEFAULT); +</pre> +<p> +est invalide. De même, les fonctions ne peuvent pas être utilisées pour cette +valeur non plus.</p> + +<pre> +INSERT INTO t(x) VALUES (func()); +</pre> +<p> +Les valeurs constantes doivent-être utilisées pour un INSERT avec la clé de +partitionnement. + +<code>SELECT INTO</code> et <code>INSERT INTO ... SELECT</code> +ne sont pas supportés non plus. +</p> + +<h3>UPDATE (en mode parallèle)</h3> + +<p>La consistence des données entre les backends pourraît être perdue si la +colonne qui sert de clé de partitionnement subit des mises à jour. En effet, +pgpool-II ne re-partitionnement pas les données ainsi mises à jour.</p> + +<p>Une transaction ne peut pas être annulée (ROLLBACK) si la requête qui a +causé l'erreur sur un ou plusieurs backends postgreSQL est due à une violation +de contrainte.</p> + +<p> +Si une fonction est appelée dans la clause <code>WHERE</code>, la requête +pourrait ne pas être correctement exécutée. Par exemple: +<pre> +UPDATE branches set bid = 100 where bid = (select max(bid) from beances); +</pre> +</p> + +<h3>SELECT ... FOR UPDATE (en mode parallèle)</h3> + +<p>Si une fonction est appelée dans la clause <code>WHERE</code>, la requête +pourrait ne pas être correctement exécutée. Par exemple: +<pre> +SELECT * FROM branches where bid = (select max(bid) from beances) FOR UPDATE; +</pre> +</p> + +<h3>COPY (en mode parallèle)</h3> + +<p><code>COPY BINARY</code> n'est pas supporté. + +COPY à partir de fichiers n'est pas non plus supporté. Seuls <code>COPY FROM +STDIN</code> et <code>COPY TO STDOUT</code> sont supportés</p> + +<h3>ALTER/CREATE TABLE (en mode parallèle)</h3> + +<p>Pour mettre à jour une règle de partitionnement, pgpool-II doit-être +redémarré pour qu'il puisse les relire dans sa base de données système.</p> + +<h3>Transactions (en mode parallèle)</h3> + +<p>Les requêtes <code>SELECT</code> exécutées à l'intérieur d'un bloc +de transactions seront exécutés dans des transactions séparées. Voici un +exemple: + +<pre> +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; +</pre> + +<h3>Vues et Règles (en mode parallèle)</h3> + +<p> +La même définition de vue ou de règle (RULE) sera créé sur tous les backends. +</p> + +<pre> +SELECT * FROM a, b where a.i = b.i +</pre> +<p> +Les <code>jointures</code> comme celles ci-dessus seront exécutées sur chaque +backend, et le résultat de chaque backend 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. +</p> + +<h3>Fonctions et Triggers (en mode parallèle)</h3> + +<p>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.</p> + +<h3>Protocole étendu de requêtage (en mode parallèle)</h3> + +<p>Le protocole étendu de requêtage ("extended query protocol") utilisé par les +drivers 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 ("prepared statments").</p> + +<h3>Jointure Naturelle (en mode parallèle)</h3> + +<p>Il n'est pas supporté non plus. "ON join condition" et "USING (join_column)" +doivent être utilisés à la place.</p> + +<h3>Clause USING (en mode parallèle)</h3> + + +<p>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.</p> +<p> +Voici un exemple: +</p> +<p><pre> + =# SELECT * FROM t1 JOIN t2 USING(id); + id | t | t + ----+-----+------- + 1 | 1st | first + (1 row) +</pre></p> +<p> +Le processus de réécriture de requêtes va réécrire "USING" en "ON". Le résultat +est alors: +</p><p><pre> + =# SELECT * FROM t1 JOIN t2 ON t1.id = t2.id; + id | t | id | t + ----+-----+----+------- + 1 | 1st | 1 | first + (1 row) +</pre> +</p> +<p> +On remarque que la colonne "t" est dupliquée. +</p> + +<h3>Caractères Multi-octets (pour tous les modes)</h3> + +<p>pgpool-II n'opère pas de traduction entre les différents caractères +multi-octets. L'encodage utilisé le client, le backend et la base de données +système doit donc être identique. +</p> + +<h3>Les requêtes multiples (tous modes)</h3> +<p> +pgpool-II ne peut pas prendre en charge les requêtes multiples. (NDT: par +exemple, plusieurs requêtes séparées par un point-virgule). +</p> + +<h3>Deadlocks (en mode parallèle)</h3> + +<p>Les deadlocks à travers plusieurs backends ne peuvent pas être +détectés. Par exemple: +</p> +<pre> +(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; +</pre> +<p> +Dans le cas ci-dessus, un serveur seul ne peut pas détecter de deadlock, ainsi, +pgpool-II attendra une réponse indéfiniment. Ce phénomène peut apparaître avec +toute requête qui acquiert un lock au niveau de l'enregistrement. +</p> +<p>Aussi, si un deadlock arrive sur un serveur, l'état de la transaction sur +chaque serveur ne sera pas consistent. Ainsi, pgpool-II arrête le processus si +un deadlock est détecté. +</p> +<pre> +pool_read_kind: kind does not match between master(84) slot[1] (69) +</pre> + +<h3>Schemas (en mode parallèle)</h3> + +<p>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: +</p> +<pre> +schema.objet +</pre> +<p> +pgpool-II ne peut pas résoudre le nom de schéma correct lorsque le chemin est +configuré comme suit: +</p> +<pre> +set search_path = xxx +</pre> +<p> +et que le nom du schéma n'est pas précisé dans la requête. +</p> +<h3>nom de table - nom de colonne (en mode parallèle)</h3> +<p> +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. +</p> + +</p> +<h2>Base de données système</h2> + +<h3>Règles de partitionnement</h3> + +<p>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. +</p> + +<h2>Pré-requis de l'environnement</h2> + +<h3>libpq</h3> + +<p>La librairie <code>libpq</code> est linké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 +sera un échec. De même, la base de données système doit être au minimum dans +une version 7.4 de PostgreSQL. +</p> + +<h2>Cache de requêtes</h2> + +<p>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. +</p> + +<h2>Compatibilité avec pgpool</h2> + +<h1>Référence<a name="reference"></a></h1> +<h2>Référence des commandes PCP</h2> + +<h3>Liste des commandes PCP</h3> + +<p>les commandes PCP sont des commandes UNIX qui interagissent avec pgpool-II à +travers le réseau. + +<pre> +* pcp_node_count - retourne le nombre de noeuds (serveurs PostgreSQL) +* pcp_node_info - retourne l'inforation 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_stop_pgpool - stoppe pgpool-II +</pre> +</p> + + +<h2>Arguments communs aux outils en ligne de commande</h2> + +<p>Il y a cinq arguments qui sont communs à toutes les commandes PCP. Ils donne +l'information relative à l'authentification et à pgpool-II. Des arguments +complémentaires peuvent-être nécessaires pour quelques commandes. + +<pre> +e.g.) $ pcp_node_count 10 localhost 9898 postgres hogehoge + +1er argument - valeur de timeout 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 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 +</pre> + +<p>Les noms d'utilisateurs et mot de passe PCP doivent-être déclarés +dans <code>pcp.conf</code> dans le répertoire <code>$prefix/etc</code>. + +L'option <code>-F</code> peut-être utilisée lors du démarrage de pgpool-II si +<code>pcp.conf</code> est placé ailleurs. Les mots de passe n'ont pas besoin +d'être au format md5 lorsqu'on les passe aux commandes PCP. +</p> + + +<h2>Commandes PCP</h2> + +<p>Toutes les commandes PCP renvoie les résultats vers la sortie standard.</p> + + +<h3>pcp_node_count</h3> + +<pre> +Format: +pcp_node_count _timeout_ _hôte_ _port_ _userid_ _passwd_ +</pre> + +<p> +Affiche le nombre total de nœuds définis dans <code>pgpool.conf</code>. Il ne +fait aucun distingo entre le statut des différents nœuds. Ainsi, TOUS les nœuds +sont comptés ici. +</p> + + +<h3><a name="pcp_node_info"/>pcp_node_info</h3> + +<pre> +Format: +pcp_node_info _timeout_ _hôte_ _port_ _userid_ _passwd_ _nodeid_ +</pre> + +<p> +Affiche l'information relative au numéro de nœud donné. Voici un exemple de +sortie: +</p> + +<pre> +$ 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 le load-balancing + +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é +</pre> +<p> +Le poids configuré pour le load-balancing est affiché dans un format normalisé. +</p> + +<p> +L'option --verbose peut permettre une meilleure compréhension. Par exemple: +</p> + +<pre> +$ pcp_node_info --verbose 10 localhost 9898 postgres hogehoge 0 +Hostname: host1 +Port : 5432 +Status : 1 +Weight : 0.5 +</pre> + +<p>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é.</p> + +<h3>pcp_proc_count</h3> +<p> +<pre> +Format: +pcp_proc_count _timeout_ _host_ _port_ _userid_ _passwd_ +</pre> +<p> +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. +</p> +<h3>pcp_proc_info</h3> +<p> +<pre> +Format: +pcp_proc_info _timeout_ _host_ _port_ _userid_ _passwd_ _processid_ +</pre> +<p> +Affiche l'information d'un processus fils de pgpool-II, désigné par son ID de +processus. Voici un exemple de retour de cette commande: +</p> +<pre> +$ 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. timestamp correspondant au démarrage du processus +4. timestamp 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'ID du backend PostgreSQL +9. 1 si le client est connecté, 0 sinon +</pre> +<p> +S'il n'y a aucune connexion aux backends, rien ne sera affiché. S'il y a de +multiples connexions, les informations seront affichées sur plusieurs lignes et +plusieurs fois. Les timestamp sont affichés au format EPOCH. +</p> + +<p> +L'option --verbose permet de mieux comprendre la sortie de la commande. Par +exemple: +</p> + +<pre> +$ 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 +</pre> + +<p>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é.</p> + +<h3>pcp_systemdb_info</h3> +<p> +<pre> +Format: +pcp_systemdb_info _timeout_ _host_ _port_ _userid_ _passwd_ +</pre> +<p> +Affiche des informations sur la base de données système. Voici un exemple de +sortie: +</p> +<pre> +$ 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. '' 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 +</pre> +<p> + +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 +multiples. Le résultat s'affiche dans l'ordre suivant: +</p> +<pre> +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 +</pre> +<p> +Si la base de données système n'est pas définie (i.e. 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é.</p> + + +<h3>pcp_detach_node</h3> +<pre> +Format: +pcp_detach_node [-g] _timeout_ _host_ _port_ _userid_ _passwd_ _nodeid_ +</pre> +<p> +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 "client_idle_limit_in_recovery" soit à -1 ou que le +"recovery_timeout" soit expiré). +</p> + + +<h3>pcp_attach_node</h3> +<p> +<pre> +Format: +pcp_attach_node _timeout_ _host_ _port_ _userid_ _passwd_ _nodeid_ + +Attche le nœud spécifié à pgpool-II. +</pre> +</p> + +<h3>pcp_stop_pgpool</h3> +<pre> +Format: +pcp_stop_pgpool _timeout_ _host_ _port_ _userid_ _passwd_ _mode_ +</pre> + +<p> +Arrête le processus de pgpool-II dans le mode d'arrêt spécifié. Les +différents modes d'arrêt sont les suivants: +</p> + +<pre> +s - mode smart +f - mode fast +i - mode immediate +</pre> +<p> +Si le processus pgpool-II n'existe pas, on a une erreur avec un statut de +sortie à 8, et le message "ConnectionError" sera affiché. +</p> +<p> +En fait, il n'y a pas de différence entre les modes "fast" et "immediate". +pgpool-II arrête tous les processus, qu'il y ait des clients connectés aux +backends ou pas.</p> + + +<h2>Statuts de sortie</h2> + +<p>Les commandes PCP on un statut de sortie à 0 lorsque tout se passe bien. Si +une erreur arrive, ces dernières ont un statue de sortie différent, dont voici +la liste. + +<pre> +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 +</pre> +</p> + +<h1>Fonctionnement interne<a name="internal"></a></h1> +<p> +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. +</p> + +<h2>Moteur d'exécution parallèle</h2> +<p> +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. +</p> + +<h2>Réécriture de requêtes</h2> +<p> +Cette partie explique le fonctionnement de la réécriture de requêtes que fait +pgpool-II en mode parallèle. +</p> +<p> +En mode parallèle, une requête transmise par les clients passe par deux étapes +de traitements: +</p> +<ul> +<li>Analyse de la requête +<li>Réécriture de la requête +</ul> +<p> +Ce qui suit détaille ces deux étapes. +</p> +<h3>Analyse de la requête</h3> +<h4><p>Introduction</p></h4> +<p> +La récupération de la requête soumise par le client passe par le parseur 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 d'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". +</p> + +<p> +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. +</p> + +<ol> + <li>Est-ce que UNION, EXTRACT, ou INTERSECT sont utilisées? + <li>Quel est le statut d'exécution de la clause FROM? + <li>Changer le statut d'exécution par TARGETLIST + <li>Changer le statut d'exécution en fonction de la clause WHERE + <li>Changer le statut d'exécution en fonction de la clause GROUP BY + <li>Changer le statut d'exécution en fonction de la clause HAVING + <li>Changer le statut d'exécution en fonction de la clause ORDER BY + <li>Changer le statut d'exécution en fonction de la du prédicat LIMIT OFFSET + <li>Acquisition du statut final d'exécution du SELECT +</ol> + +<p> +La relation entre le statut d'exécution final du SELECT et l'endroit où il est +exécuté est comme suit: +</p> + +<p> +<table border> + <tr><td>Statut d'exécution</td><td>Lieu d'exécution</td></tr> + <tr><td align=center>L</td><td>La requête peut-être +exécutée sur n'importe quel serveur</td></tr> + <tr><td align=center>P</td><td>Retourne les données au client +en exécutant la même requêtes sur tous les serveurs en utilisant le moteur +d'exécution en parallèle.</td></tr> + <tr><td align=center>S</td><td>Après traitement dans la base de +données système, les données sont renvoyées au client.</td></tr> +</table> +</p> + +<p> +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. +</p> + +<pre> +SELECT * FROM (SELECT * FROM P1-table) as P2-table; +</pre> + +<p> +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. +</p> + + + +<h4><p>Statut d'exécution de la clause FROM</p></h4> +<p> +Ceci est une requête qui récupère des données (SELECT). Le set 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 du set de données entier et 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. +</p> + +<p> +<table border> +<tr><td>type de JOINture</td><td align = center colspan = 3> LEFT OUTER JOIN +</td><td align = center colspan = 3> RIGHT OUTER JOIN </td><td align = center +colspan = 3>FULL OUTER JOIN</td><td align = center colspan = 3>Other</td></tr> + <tr><td align = center>left/right</td><td> P </td><td> L </td><td> S </td><td> P </td><td> L </td><td> S </td><td> P </td><td> L </td><td> S </td><td> P </td><td> L </td><td> S </td></tr> + +<tr><td align = center> P </td><td> S </td><td> P </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> P </td><td> S </td></tr> + +<tr><td align = center> L </td><td> S </td><td> L </td><td> S </td><td> P </td><td> L </td><td> S </td><td> S </td><td> L </td><td> S </td><td> P </td><td> L </td><td> S </td></tr> + +<tr><td align = center> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td><td> S </td></tr> + +</td></tr> +</table> +</p> + +<p> +Dans les exemple suivants, la table P1-table est en statut P. +Les tables L1-table et L2-table sont dans le statut L. +<pre> +SELECT * FROM P1-table,L1-table,L2-table; +</pre> + + +P1-table (left) et L1-table (right) sont jointes, et en fonction du tableau +ci-dessus, prennent le statut P. Avec ce statut P, elles sont jointes avec les +tables L2-table, qui est de statut L, qui devient alors en statut P aussi. +</p> + + +<h4><p>Changement de statut d'exécution dus aux clause TARGETLIST et +WHERE</p></h4> +<p> +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: +</p> +<ol> + <li>Lorsqu'il y a une sous-requête + <li>Lorsqu'il y a une fonction d'agrégat ou un DISTINCT dans la +TARGETLIST marquée 'P' + <li>Losqu'une colonne qui n'existe pas dans la table (le +set de données) est utilisée dans la clause FROM +</ol> +<p> +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. +<p> +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. +<pre> + SELECT * FROM L1-table where L1-table.column IN (SELECT * FROM P1-table); +</pre> +<p> +La clause FROM passe au statut S lorsqu'il y a une fonction d'agrégat maqué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.</p> +<p> +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: +</p> +<pre> + SELECT * FROM L1-table WHERE L1-table.col1 IN (SELECT * FROM +P1-table WHERE P1-table.col = L1-table.col1); +</pre> +<p> +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'. +</p> +<h4><p>Changement de statuts d'exécution provoqués par GROUP BY, HAVING, ORDER +BY et LIMIT/OFFSET</p></h4> + +<p> +Le statut d'exécution de la lcause 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. +</p> + +<h4><p>Lorsque UNION, EXTRACT et INTERSECT sont utilisés</p></h4> +<p> +Le statut des requêtes avec UNION, EXTRACT, ou INTERSECT dépend des deux statuts +d'exécution finaux des requêtes gauches et droites à 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. +</p> +<h4><p>Acquisition du statut d'exécution final d'un requête SELECT</p></h4> +<p> +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 "loadbalance_mode" est vrai (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. +</p> + +<h3>Réécriture de requête</h3> +<p> +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. + +</p> +<pre> +SELECT P1-table.col, L1-table.col +FROM P1-table,L1-table +where P1-table.col = L1-table.col +order by P1-table.col; +</pre> + +<p> +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 comme ceci: +</p> + +<pre> +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; +</pre> +<p> +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. +</p> +<p>Dans cet exemple, les clauses FROM et WHERE, ainsi que la TARGETLIST sont +exécutés en mod 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. +</p> +<p> +Voici un autre cas: +</p> + +<pre> +SELECT L1-table.col FROM L1-table WHERE L1-table.col % 2 = 0 AND L1-table.col IN (SELECT P1-table FROM P1-table) ; +</pre> + +<p> +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: +</p> +<pre> + 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)) + ) ; +</pre> +<p> +La fonction pool_loadbalance is a la responsabilité de répartir les requêtes +sur les différents noeuds. +</p> + + +<h3>Réécriture de requêtes pour les fonctions d'agrégat</h3> +<p> +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. +</p> +<p> +Voyons tout d'abord comment pgpool-II fait cette réécriture. +</p> +<p> +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. +</p> +<pre> + 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); +</pre> +<p> +Une réécriture comme ci-dessus est faite dans les conditions suivantes. +</p> +<ol> + <li>La clause FROM est de statut P + <li>La colonne spécifiée est dans la fonction d'agrégat +(seulement COUNT, SUM, MIN, MAX et AVG) et GROUP BY est utilisé dans la +TARGETLIST + <li>La clause WHERE est de statut P + <li>Seules les colonnes définies dans la fonction d'agrégat +(seulement COUNT, SUM, MIN, MAX et AVG), utilisées dans la clause HAVING et la +clause FROM, et la colonne spécifiée pour le GROUP BY sont utilisées +</ol> +<h3>Notes sur le mode parallèle</h3> +<p> +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). + +<h3>À propos des performances du mode parallèle</h3> +<p>Voici une estimation des performances de la requête en fonction de son +statut d'exécution</p> +<p> +<table border> + <tr><td>Statut d'exécution</td><td>Performances</td></tr> +<tr><td align = center>L</td><td>Il n'y a aucune déterioration de performance +avec un unique serveur, mis à part l'overhead provoqué par pgpool-II, +parce qu'aucune exécution en parallèle n'est possible.</td></tr> +<tr><td align = center>P</td><td>Le traitement parallélisé est rapide, en +particulier, pour les scans séquentiels. Il est alors aisé d'avoir de grandes +améliorations de performances car le scan séquentiel d'une grosse table devient +un scan en parallèle sur des tables bien plus petites, distribuées sur +plusieurs serveurs. +<tr><td align = center>S</td><td>Lorsque les fonctions d'agrégat peuvent être +réécrites pour être compatibles avec une exécution en parallèle, elles +deviennent rapides.</td></tr> +</td></tr> +</table> +</p> + +<h1>Tutoriel</h1> +<p> +<a href="tutorial-en.html">Un tutoriel (en anglais) pour pgpool-II</a> est +disponible. +</p> + +<div class="copyright"> +<hr> +<copyright> +Copyright &copy; 2003 &ndash; 2010 pgpool Global Development Group +</copyright> +</div> +</body> +</html> [parent: 291e2619c473]