Allow dbname in pg_basebackup/pg_receivewal connstring

As physical replication work at the cluster level and not database
level, any dbname in the connection string is ignored. Proxies and
middleware used in connecting to the cluster might however need to
know the dbname in order to make the correct routing decision for
the connection.

With this the startup packet will include the dbname parameter.

Author: Jelte Fennema-Nio <me@jeltef.nl>
Reviewed-by: Tristen Raab <tristen.raab@highgo.ca>
Reviewed-by: Jim Jones <jim.jones@uni-muenster.de>
Discussion: https://postgr.es/m/CAGECzQTw-dZkVT_RELRzfWRzY714-VaTjoBATYfZq93R8C-auA@mail.gmail.com
This commit is contained in:
Daniel Gustafsson 2023-09-21 13:53:07 +02:00
parent c621467d2b
commit cca97ce6a6
3 changed files with 27 additions and 14 deletions

View File

@ -778,7 +778,10 @@ PostgreSQL documentation
The option is called <literal>--dbname</literal> for consistency with other
client applications, but because <application>pg_basebackup</application>
doesn't connect to any particular database in the cluster, any database
name in the connection string will be ignored.
name in the connection string will be ignored
by <productname>PostgreSQL</productname>. Middleware, or proxies, used in
connecting to <productname>PostgreSQL</productname> might however
utilize the value.
</para>
</listitem>
</varlistentry>

View File

@ -316,8 +316,11 @@ PostgreSQL documentation
<para>
The option is called <literal>--dbname</literal> for consistency with other
client applications, but because <application>pg_receivewal</application>
doesn't connect to any particular database in the cluster, database
name in the connection string will be ignored.
doesn't connect to any particular database in the cluster, any database
name in the connection string will be ignored by
<productname>PostgreSQL</productname>. Middleware, or proxies, used in
connecting to <productname>PostgreSQL</productname> might however
utilize the value.
</para>
</listitem>
</varlistentry>

View File

@ -79,9 +79,6 @@ GetConnection(void)
/*
* Merge the connection info inputs given in form of connection string,
* options and default values (dbname=replication, replication=true, etc.)
* Explicitly discard any dbname value in the connection string;
* otherwise, PQconnectdbParams() would interpret that value as being
* itself a connection string.
*/
i = 0;
if (connection_string)
@ -92,18 +89,24 @@ GetConnection(void)
for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
{
if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
strcmp(conn_opt->keyword, "dbname") != 0)
if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
argcount++;
}
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
values = pg_malloc0((argcount + 1) * sizeof(*values));
/*
* Set dbname here already, so it can be overridden by a dbname in the
* connection string.
*/
keywords[i] = "dbname";
values[i] = "replication";
i++;
for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
{
if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
strcmp(conn_opt->keyword, "dbname") != 0)
if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
{
keywords[i] = conn_opt->keyword;
values[i] = conn_opt->val;
@ -115,11 +118,11 @@ GetConnection(void)
{
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
values = pg_malloc0((argcount + 1) * sizeof(*values));
keywords[i] = "dbname";
values[i] = dbname;
i++;
}
keywords[i] = "dbname";
values[i] = dbname == NULL ? "replication" : dbname;
i++;
keywords[i] = "replication";
values[i] = dbname == NULL ? "true" : "database";
i++;
@ -171,7 +174,11 @@ GetConnection(void)
values[i] = NULL;
}
tmpconn = PQconnectdbParams(keywords, values, true);
/*
* Only expand dbname when we did not already parse the argument as a
* connection string ourselves.
*/
tmpconn = PQconnectdbParams(keywords, values, !connection_string);
/*
* If there is too little memory even to allocate the PGconn object