<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Jdbc on inetshell</title><link>https://inet.sh/es/tags/jdbc/</link><description>Recent content in Jdbc on inetshell</description><generator>Hugo</generator><language>es</language><lastBuildDate>Sat, 26 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://inet.sh/es/tags/jdbc/index.xml" rel="self" type="application/rss+xml"/><item><title>pgbouncer: 'unsupported startup parameter: extra_float_digits' (y 'no such database')</title><link>https://inet.sh/es/posts/databases/pgbouncer-unsupported-startup-parameter/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/es/posts/databases/pgbouncer-unsupported-startup-parameter/</guid><description>JDBC, DBeaver, DataGrip, Npgsql o psycopg conectan directo a PostgreSQL pero a través de pgbouncer fallan con &amp;#39;unsupported startup parameter: extra_float_digits&amp;#39; (o &amp;#39;options&amp;#39;). pgbouncer rechaza los parámetros de sesión que no puede rastrear entre clientes; ignore_startup_parameters los acepta y descarta. Qué es seguro ignorar, qué no, track_extra_parameters, y el &amp;#39;pooler error: no such database&amp;#39; de la sección [databases].</description><content:encoded><![CDATA[<h2 id="en-corto">En corto</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="c1">; /etc/pgbouncer/pgbouncer.ini</span>
</span></span><span class="line"><span class="cl"><span class="k">[pgbouncer]</span>
</span></span><span class="line"><span class="cl"><span class="na">ignore_startup_parameters</span> <span class="o">=</span> <span class="s">extra_float_digits, options</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">systemctl reload pgbouncer          <span class="c1"># o RELOAD; en la consola de admin: psql -p 6432 -U pgbouncer pgbouncer</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>extra_float_digits</code> se puede ignorar sin efectos. <code>options</code> (lo que JDBC y DataGrip usan para <code>-c search_path=…</code>) también se ignora, pero entonces el <code>search_path</code> del cliente <strong>no llega</strong>: fíjalo en el rol con <code>alter role app set search_path = app, public</code>.</p>
<h2 id="el-error">El error</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">FATAL: unsupported startup parameter: extra_float_digits
</span></span></code></pre></td></tr></table>
</div>
</div><p>o, según el cliente, <code>pooler error: unsupported startup parameter: extra_float_digits</code>. Directo al puerto 5432 conecta; por el 6432 de pgbouncer, no. Lo mandan JDBC (todo lo que use el driver de PostgreSQL para Java: DBeaver, DataGrip, Spring, Jenkins), Npgsql y algunos ORMs; otros clientes mandan <code>options</code>.</p>
<h2 id="por-qué-pasa">Por qué pasa</h2>
<p>Cuando un cliente abre conexión, mete en el paquete de inicio los parámetros de sesión que quiere (<code>extra_float_digits=3</code>, <code>options=-c search_path=app</code>). pgbouncer, en modo <code>transaction</code> o <code>statement</code>, comparte una misma conexión de servidor entre muchos clientes, así que solo deja pasar los parámetros que sabe guardar por cliente y restaurar en el servidor cuando le toca a ese cliente: <code>client_encoding</code>, <code>datestyle</code>, <code>timezone</code>, <code>standard_conforming_strings</code>, <code>application_name</code>. Cualquier otro sería un ajuste que se filtra de un cliente a otro; antes que eso, pgbouncer rechaza la conexión.</p>
<p>Dos formas de resolverlo:</p>
<table>
  <thead>
      <tr>
          <th>Opción</th>
          <th>Qué hace</th>
          <th>Para qué parámetros</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>ignore_startup_parameters</code></td>
          <td>Acepta el parámetro y lo tira</td>
          <td>Los que no cambian nada (<code>extra_float_digits</code>) o los que puedes fijar en otro sitio (<code>options</code>)</td>
      </tr>
      <tr>
          <td><code>track_extra_parameters</code></td>
          <td>Lo guarda por cliente y lo restaura en el servidor, como hace con <code>timezone</code></td>
          <td>Parámetros que el servidor reporta al cliente (<code>ParameterStatus</code>) y que de verdad necesitas por sesión</td>
      </tr>
  </tbody>
</table>
<p><code>extra_float_digits</code> es inofensivo desde PostgreSQL 12: la salida de <code>float</code> ya es la representación más corta exacta y el parámetro no cambia nada. <code>options</code> con <code>search_path</code> <strong>sí</strong> importa: ignorado, el cliente verá el <code>search_path</code> por defecto de la base y las consultas sin esquema fallan con <code>relation does not exist</code>. La solución limpia es el rol:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">alter</span><span class="w"> </span><span class="k">role</span><span class="w"> </span><span class="n">app</span><span class="w"> </span><span class="k">set</span><span class="w"> </span><span class="n">search_path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">app</span><span class="p">,</span><span class="w"> </span><span class="k">public</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h2 id="no-such-database">&rsquo;no such database'</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">pooler error: no such database: app_db
</span></span></code></pre></td></tr></table>
</div>
</div><p>pgbouncer solo enruta bases que estén en <code>[databases]</code>. O añades la entrada, o pones un comodín:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[databases]</span>
</span></span><span class="line"><span class="cl"><span class="na">app_db</span> <span class="o">=</span> <span class="s">host=db.example port=5432 dbname=app_db</span>
</span></span><span class="line"><span class="cl"><span class="na">*</span> <span class="o">=</span> <span class="s">host=db.example port=5432</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Con <code>*</code>, un cliente que pida <code>otra_db</code> obtiene <code>host=db.example dbname=otra_db</code>; esas entradas automáticas se limpian solas tras <code>autodb_idle_timeout</code>. Y comprueba el <code>dbname=</code> de la entrada: es habitual apuntar <code>app_db</code> a otra base por un copy-paste.</p>
<h2 id="trampas">Trampas</h2>
<ul>
<li><strong><code>RELOAD</code> basta</strong> para <code>ignore_startup_parameters</code> y <code>[databases]</code>; <code>listen_*</code> y <code>auth_type</code> piden reinicio.</li>
<li><strong>Modo <code>transaction</code> y <code>SET</code></strong>: un <code>SET search_path</code> a mano en la sesión se pierde en cuanto la conexión de servidor pasa a otro cliente; usa <code>SET LOCAL</code> dentro de la transacción o el <code>alter role</code>.</li>
<li><strong>Prepared statements</strong> con nombre (JDBC <code>prepareThreshold</code>, <code>PREPARE</code>) no funcionan en modo <code>transaction</code> en pgbouncer antiguo; desde 1.21, <code>max_prepared_statements = 200</code> los soporta.</li>
<li><strong>SCRAM</strong>: con <code>auth_type = scram-sha-256</code> la <code>userlist.txt</code> necesita el hash SCRAM tal cual sale de <code>pg_authid</code>, o <code>auth_query</code> para que pgbouncer lo consulte.</li>
<li><code>SHOW CONFIG;</code> y <code>SHOW DATABASES;</code> en la consola de admin te dicen qué está cargado de verdad, no lo que crees haber escrito.</li>
</ul>
<p>Ver también: <a href="/es/posts/databases/postgresql-cheat-sheet-administracion/">PostgreSQL: cheat sheet de administración</a>. Referencia: <a href="https://www.pgbouncer.org/config.html">pgbouncer.ini</a>.</p>
]]></content:encoded></item></channel></rss>