Commit 7b02ba62 authored by Heikki Linnakangas's avatar Heikki Linnakangas

Allow multiple hostaddrs to go with multiple hostnames.

Also fix two other issues, while we're at it:

* In error message on connection failure, if multiple network addresses
were given as the host option, as in "host=127.0.0.1,127.0.0.2", the
error message printed the address twice.

* If there were many more ports than hostnames, the error message would
always claim that there was one port too many, even if there was more than
one. For example, if you gave 2 hostnames and 5 ports, the error message
claimed that you gave 2 hostnames and 3 ports.

Discussion: https://www.postgresql.org/message-id/10badbc6-4d5a-a769-623a-f7ada43e14dd@iki.fi
parent 260ba852
...@@ -887,6 +887,42 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname ...@@ -887,6 +887,42 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
host will be tried in turn until a connection is successfully established. host will be tried in turn until a connection is successfully established.
</para> </para>
</sect3> </sect3>
<sect3 id="libpq-multiple-hosts">
<title>Specifying Multiple Hosts</title>
<para>
It is possible to specify multiple hosts to connect to, so that they are
tried in the given order. In the Keyword/Value format, the <literal>host</>,
<literal>hostaddr</>, and <literal>port</> options accept a comma-separated
list of values. The same number of elements must be given in each option, such
that e.g. the first <literal>hostaddr</> corresponds to the first host name,
the second <literal>hostaddr</> corresponds to the second host name, and so
forth. As an exception, if only one <literal>port</literal> is specified, it
applies to all the hosts.
</para>
<para>
In the connection URI format, you can list multiple <literal>host:port</> pairs
separated by commas, in the <literal>host</> component of the URI. In either
format, a single hostname can also translate to multiple network addresses. A
common example of this is a host that has both an IPv4 and an IPv6 address.
</para>
<para>
When multiple hosts are specified, or when a single hostname is
translated to multiple addresses, all the hosts and addresses will be
tried in order, until one succeeds. If none of the hosts can be reached,
the connection fails. If a connection is established successfully, but
authentication fails, the remaining hosts in the list are not tried.
</para>
<para>
If a password file is used, you can have different passwords for
different hosts. All the other connection options are the same for every
host, it is not possible to e.g. specify a different username for
different hosts.
</para>
</sect2> </sect2>
<sect2 id="libpq-paramkeywords"> <sect2 id="libpq-paramkeywords">
...@@ -900,7 +936,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname ...@@ -900,7 +936,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>host</literal></term> <term><literal>host</literal></term>
<listitem> <listitem>
<para> <para>
Comma-separated list of host names.<indexterm><primary>host name</></> Name of host to connect to.<indexterm><primary>host name</></>
If a host name begins with a slash, it specifies Unix-domain If a host name begins with a slash, it specifies Unix-domain
communication rather than TCP/IP communication; the value is the communication rather than TCP/IP communication; the value is the
name of the directory in which the socket file is stored. If name of the directory in which the socket file is stored. If
...@@ -912,6 +948,11 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname ...@@ -912,6 +948,11 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
when <productname>PostgreSQL</> was built). On machines without when <productname>PostgreSQL</> was built). On machines without
Unix-domain sockets, the default is to connect to <literal>localhost</>. Unix-domain sockets, the default is to connect to <literal>localhost</>.
</para> </para>
<para>
A comma-separated list of host names is also accepted, in which case
each host name in the list is tried in order. See
<xref linkend="libpq-multiple-hosts"> for details.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -965,6 +1006,11 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname ...@@ -965,6 +1006,11 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<xref linkend="libpq-pgpass">). <xref linkend="libpq-pgpass">).
</para> </para>
<para>
A comma-separated list of <literal>hostaddrs</> is also accepted, in
which case each host in the list is tried in order. See
<xref linkend="libpq-multiple-hosts"> for details.
</para>
<para> <para>
Without either a host name or host address, Without either a host name or host address,
<application>libpq</application> will connect using a <application>libpq</application> will connect using a
...@@ -981,9 +1027,10 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname ...@@ -981,9 +1027,10 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
Port number to connect to at the server host, or socket file Port number to connect to at the server host, or socket file
name extension for Unix-domain name extension for Unix-domain
connections.<indexterm><primary>port</></> connections.<indexterm><primary>port</></>
If the <literal>host</> parameter included multiple, comma-separated If multiple hosts were given in the <literal>host</literal> or
hosts, this parameter may specify a list of ports of equal length, <literal>hostaddr</> parameters, this parameter may specify a list
or it may specify a single port number to be used for all hosts. of ports of equal length, or it may specify a single port number to
be used for all hosts.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
......
This diff is collapsed.
...@@ -304,8 +304,9 @@ typedef enum pg_conn_host_type ...@@ -304,8 +304,9 @@ typedef enum pg_conn_host_type
*/ */
typedef struct pg_conn_host typedef struct pg_conn_host
{ {
char *host; /* host name or address, or socket path */
pg_conn_host_type type; /* type of host */ pg_conn_host_type type; /* type of host */
char *host; /* host name or socket path */
char *hostaddr; /* host address */
char *port; /* port number for this host; if not NULL, char *port; /* port number for this host; if not NULL,
* overrides the PGConn's pgport */ * overrides the PGConn's pgport */
char *password; /* password for this host, read from the char *password; /* password for this host, read from the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment