<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Pgbouncer on Carnet de découvertes</title><link>https://fljd.in/tags/pgbouncer/</link><description>Recent content in Pgbouncer on Carnet de découvertes</description><generator>Hugo -- gohugo.io</generator><language>fr</language><managingEditor>Florent Jardin</managingEditor><lastBuildDate>Fri, 21 Aug 2020 00:00:00 +0000</lastBuildDate><atom:link href="https://fljd.in/tags/pgbouncer/index.xml" rel="self" type="application/rss+xml"/><item><title>Tour d'horizon de PgBouncer</title><link>https://fljd.in/2020/08/21/tour-d-horizon-de-pgbouncer/</link><pubDate>Fri, 21 Aug 2020 00:00:00 +0000</pubDate><author>Florent Jardin</author><guid>https://fljd.in/2020/08/21/tour-d-horizon-de-pgbouncer/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Les programmes de regroupement de connexions (&lt;em&gt;pooling&lt;/em&gt;) vous permettent de
réduire la surcharge liée à la base de données lorsque le nombre de connexions
physiques réduit les performances. Ceci est particulièrement pertinent sous
Windows, où les limitations du système empêchent un grand nombre de connexions.
C&amp;rsquo;est également vital pour les applications Web où le nombre de connexions peut
devenir très important.&lt;/p&gt;
&lt;p&gt;(Source : &lt;a href="https://wiki.postgresql.org/wiki/Replication,_Clustering,_and_Connection_Pooling#Connection_Pooling_and_Acceleration" target="_blank" rel="noopener"&gt;https://wiki.postgresql.org&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Je n&amp;rsquo;ai pas trouvé meilleure approche que la traduction du wiki communautaire du
projet PostgreSQL pour aborder l&amp;rsquo;outil PgBouncer, faisant partie avec Pgpool-II,
des deux seuls &lt;em&gt;poolers&lt;/em&gt; de connexions largement répandus. Le produit est
déconcertant de facilité, sa documentation et la littérature qui gravitent sur
Internet sont claires et unanimes : PgBouncer améliorera grandement les
performances de votre instance PostgreSQL !&lt;/p&gt;
&lt;p&gt;Dans cet article, je vous propose un rapide aperçu de PgBouncer avec quelques
cas possibles d&amp;rsquo;utilisation. Nous parlerons aussi du récent support de
l&amp;rsquo;authentification SCRAM et comment le configurer sans effort.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="théorie-ma-vieille-amie"&gt;Théorie, ma vieille amie&lt;/h2&gt;
&lt;p&gt;Depuis ses origines, le fonctionnement de PostgreSQL repose sur le modèle
client/serveur &lt;a href="https://docs.postgresql.fr/12/tutorial-arch.html" target="_blank" rel="noopener"&gt;multi-processus&lt;/a&gt;, c&amp;rsquo;est-à-dire que chaque processus aura une
tâche définie et une zone mémoire qui lui est propre. Ce modèle s&amp;rsquo;oppose à
l&amp;rsquo;architecture &lt;a href="https://fr.wikipedia.org/wiki/Thread_%28informatique%29" target="_blank" rel="noopener"&gt;multi-thread&lt;/a&gt; dans laquelle un processus peut être partagé par
plusieurs instructions indépendantes et présenterait des risques de
&lt;a href="https://www.postgresql.org/message-id/flat/3647.130.243.12.138.1098892576.squirrel%40130.243.12.138" target="_blank" rel="noopener"&gt;corruptions de mémoire&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ainsi, pour chaque &lt;a href="https://www.postgresql.org/docs/12/connect-estab.html" target="_blank" rel="noopener"&gt;demande de connexion&lt;/a&gt; vers l&amp;rsquo;instance, le processus
principal &lt;code&gt;postgres&lt;/code&gt; se charge de l&amp;rsquo;authentification avant de créer un nouveau
processus &lt;em&gt;backend&lt;/em&gt; qui maintiendra le lien entre les deux parties et assurera
l&amp;rsquo;aboutissement des commandes du processus client, appelé &lt;em&gt;frontend&lt;/em&gt;. Le
&lt;em&gt;backend&lt;/em&gt; ne sera libéré qu&amp;rsquo;à la déconnexion de la session utilisateur, comme
l&amp;rsquo;illustre le schéma ci-après.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://fljd.in/img/fr/2020-08-21-architecture-classique.png" alt="Architecture simplifiée"&gt;&lt;/p&gt;
&lt;p&gt;Cependant, l&amp;rsquo;établissement de la connexion n&amp;rsquo;est pas une opération anodine. Les
coûts des échanges à travers le réseau, de création d&amp;rsquo;un processus, de l&amp;rsquo;allocation
de sa mémoire et du paramétrage de la session, représenteraient une &lt;a href="https://www.depesz.com/2012/12/02/what-is-the-point-of-bouncing/" target="_blank" rel="noopener"&gt;poignée de
millisecondes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Comme indiqué en préambule, les applications critiques telles que celles du
e-commerce requièrent des temps de réponses les plus faibles possibles, avec des
exigences de l&amp;rsquo;ordre d&amp;rsquo;une centaine de millisecondes par appel de page, contenant
elles-mêmes des centaines de requêtes… C&amp;rsquo;est à ce moment-là que PgBouncer entre
en jeu.&lt;/p&gt;
&lt;p&gt;Le schéma précédent évolue avec le &lt;em&gt;pooler de connexions&lt;/em&gt; entre les connexions
clientes et l&amp;rsquo;instance de base de données. Le processus &lt;code&gt;pgbouncer&lt;/code&gt; est donc
responsable des demandes entrantes et se comporte comme un proxy, qu&amp;rsquo;il soit sur
le serveur hébergeant les données, sur les serveurs frontaux ou même sur un
serveur tiers, dédié à ces redirections.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://fljd.in/img/fr/2020-08-21-architecture-pgbouncer.png" alt="Architecture avec PgBouncer"&gt;&lt;/p&gt;
&lt;p&gt;PgBouncer ne présente qu&amp;rsquo;une faible empreinte mémoire équivalente à &lt;a href="https://www.pgbouncer.org/features.html" target="_blank" rel="noopener"&gt;2 ko par
connexion&lt;/a&gt; et repose sur un binaire et un fichier de configuration. L&amp;rsquo;outil
gère des &lt;em&gt;pools&lt;/em&gt; de connexions par bases de données ou par rôles (ou les deux)
et maintient un certain nombre de connexions actives vers l&amp;rsquo;instance pour les
recycler en cas d&amp;rsquo;arrivée de nouveaux &lt;em&gt;frontends&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;La configuration est extrêmement simple et épurée, et ne devrait rebuter personne.
Par exemple, en supposant que l&amp;rsquo;instance PostgreSQL écoute localement sur le port
5433 et dispose d&amp;rsquo;une base &lt;code&gt;data1&lt;/code&gt;, nous cherchons à définir un &lt;em&gt;pool&lt;/em&gt; de 5 à 50
&lt;em&gt;backends&lt;/em&gt; avec un délai de 30 secondes d&amp;rsquo;inactivité avant la déconnexion réelle
au serveur. Le fichier de configuration suivant est alors parfaitement adapté :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[pgbouncer]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;listen_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;demo.priv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;listen_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;5432&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;auth_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;userlist.txt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;server_idle_timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;min_pool_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[database]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;data1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;host=localhost port=5433 dbname=data1 pool_size=50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="chérie-tu-as-les-clés"&gt;Chérie, tu as les clés ?&lt;/h2&gt;
&lt;p&gt;Puisque PgBouncer fait office de proxy entre les applications et les bases de
données en respectant le protocole de connexion, il lui revient d&amp;rsquo;assurer la
validation des mots de passe de chaque nouvelle demande entrante. L&amp;rsquo;implémentation
des différentes méthodes telles que &lt;code&gt;md5&lt;/code&gt; ou &lt;code&gt;scram-sha-256&lt;/code&gt; se trouve dans le
fichier &lt;code&gt;src/proto.c&lt;/code&gt;(&lt;a href="https://github.com/pgbouncer/pgbouncer/blob/master/src/proto.c" target="_blank" rel="noopener"&gt;source&lt;/a&gt;) et garantit qu&amp;rsquo;une demande de connexion réalisée sur
l&amp;rsquo;interface de PgBouncer soit bien légitime et autorisée auprès de l&amp;rsquo;instance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fichier auth_file&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;À ce sujet, l&amp;rsquo;outil propose deux solutions pour vérifier un mot de passe. La plus
basique consiste à renseigner un fichier (ou &lt;code&gt;auth_file&lt;/code&gt;) avec les couples
&lt;em&gt;login/password&lt;/em&gt; qui seront consultés à chaque demande, et les comparer avec les
éléments de l&amp;rsquo;utilisateur. Les données doivent être identiques aux informations
stockées dans l&amp;rsquo;instance PostgreSQL, plus précisément dans la relation système
&lt;code&gt;pg_authid&lt;/code&gt;, ou historiquement &lt;code&gt;pg_shadow&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;password_encryption&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;scram-sha-256&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ROLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;frontend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PASSWORD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pass&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LOGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rolpassword&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pg_authid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rolname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;frontend&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;gx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- -[ RECORD 1 ]----------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- rolpassword | SCRAM-SHA-256$4096:e2iH7Tv/XJrD0bxiSNt4yA==$Pxhbz2…
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;L&amp;rsquo;ajout d&amp;rsquo;une nouvelle ligne dans le fichier &lt;code&gt;userlist.txt&lt;/code&gt; nécessite uniquement
de prendre soin d&amp;rsquo;entourer chaque mot par des guillemets doubles. PgBouncer
surveillera alors son contenu afin de disposer des bonnes informations à tout
moment.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# userlist.txt &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;&amp;#34;frontend&amp;#34; &amp;#34;SCRAM-SHA-256$4096:e2iH7Tv/XJrD0bxiSNt4yA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;=$Pxhbz2…&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Délégation auth_user&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Si la maintenance d&amp;rsquo;un tel fichier s&amp;rsquo;avère complexe pour quelque raison que ce
soit, il est possible de déléguer un rôle à la consultation de la table &lt;code&gt;pg_authid&lt;/code&gt;
directement dans l&amp;rsquo;instance, en précisant le paramètre &lt;code&gt;auth_user&lt;/code&gt;. Le paramètre
&lt;code&gt;auth_query&lt;/code&gt; définit la requête à exécuter pour ensuite comparer les résultats
avec les identifiants de connexion. Cette requête repose sur la vue &lt;code&gt;pg_shadow&lt;/code&gt;
mais de nombreuses variantes sont possibles, comme une requête plus élaborée sur
&lt;code&gt;pg_authid&lt;/code&gt; ou une &lt;a href="https://github.com/CrunchyData/crunchy-containers/blob/master/bin/postgres-ha/sql/pgbouncer/pgbouncer-install.sql#L71" target="_blank" rel="noopener"&gt;fonction&lt;/a&gt; qui dispose des bons droits de consultation avec
la clause &lt;code&gt;SECURITY DEFINER&lt;/code&gt; comme le suggère la &lt;a href="http://www.pgbouncer.org/config.html#auth_query" target="_blank" rel="noopener"&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Le support de la méthode d&amp;rsquo;authentification par SCRAM est arrivé avec la version
PgBouncer 1.14 en juin 2020. Le mot de passe chiffré avec SCRAM ne peut pas être
utilisé pour de la &lt;a href="http://www.pgbouncer.org/config.html#authentication-file-format" target="_blank" rel="noopener"&gt;délégation de connexion&lt;/a&gt;, tel que le propose le paramètre
&lt;code&gt;auth_user&lt;/code&gt;. &lt;a href="https://github.com/pgbouncer/pgbouncer/issues/508#issuecomment-678142543" target="_blank" rel="noopener"&gt;L&amp;rsquo;un des contournements&lt;/a&gt; consiste à hacher le mot de passe en &lt;code&gt;md5&lt;/code&gt;
pour le rôle de délégation.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;password_encryption&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;md5&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ROLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;admin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SUPERUSER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PASSWORD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pass&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LOGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rolpassword&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pg_authid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rolname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;admin&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;gx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- -[ RECORD 1 ]------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- rolpassword | md57a25b0bc04e77a2f7453dd021168cdc2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Le fichier &lt;code&gt;userlist.txt&lt;/code&gt; ne contiendra donc qu&amp;rsquo;une seule ligne pour le rôle
&lt;code&gt;admin&lt;/code&gt; défini comme &lt;code&gt;auth_user&lt;/code&gt; dans la configuration PgBouncer.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# userlist.txt &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;&amp;#34;admin&amp;#34; &amp;#34;md57a25b0bc04e77a2f7453dd021168cdc2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[pgbouncer]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;listen_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;demo.priv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;listen_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;5432&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;auth_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;scram-sha-256&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;auth_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;userlist.txt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;auth_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;admin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;auth_query = SELECT usename, passwd FROM pg_shadow WHERE usename=$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[database]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;data1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;host=localhost port=5433 dbname=data1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Côté client, l&amp;rsquo;illusion est parfaite ! Le rôle &lt;code&gt;frontend&lt;/code&gt; se connecte à l&amp;rsquo;instance
sans besoin d&amp;rsquo;ajouter ses identifiants dans le fichier &lt;code&gt;userlist.txt&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ psql &amp;#34;host=priv.demo dbname=data1 user=frontend&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Password for user frontend:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;psql (12.4)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Type &amp;#34;help&amp;#34; for help.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;data1=&amp;gt; \conninfo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;You are connected to database &amp;#34;data1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; as user &amp;#34;frontend&amp;#34; on host &amp;#34;priv.demo&amp;#34; at port &amp;#34;5432&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="vers-linfini-et-au-delà"&gt;Vers l&amp;rsquo;infini et au-delà&lt;/h2&gt;
&lt;p&gt;PgBouncer est un outil à connaître et à déployer sans modération pour la recherche
de performance. Il se couple parfaitement bien avec une configuration HAProxy
pour une architecture de haute-disponibilité si le besoin se fait sentir. Le
support de l&amp;rsquo;authentification SCRAM est une excellente avancée, alors que la
communauté se décide de la définir comme un &lt;a href="https://www.postgresql.org/message-id/flat/d5b0ad33-7d94-bdd1-caac-43a1c782cab2@2ndquadrant.com" target="_blank" rel="noopener"&gt;standard&lt;/a&gt; pour les prochaines versions
majeures de PostgreSQL.&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;autres fonctionnalités essentielles n&amp;rsquo;ont volontairement pas été abordées dans
cet article, comme le &lt;em&gt;pooling&lt;/em&gt; de transactions et le paramètre &lt;code&gt;pool_mode&lt;/code&gt;, ou
simplement la pseudo-base &lt;code&gt;pgbouncer&lt;/code&gt; qui joue le rôle de console d&amp;rsquo;administration
très fournie en informations sur les &lt;em&gt;pools&lt;/em&gt; et sessions actives. Gageons que
j&amp;rsquo;y passe plus de temps à l&amp;rsquo;avenir pour vous les présenter !&lt;/p&gt;</description></item></channel></rss>