By digoal
Since PostgreSQL 10, the libpq driver layer has been supporting simple failover with simple setups. Similarly, the JDBC driver supports simple failover and load balancing, also with simple setups.
Such functions, with a few link configurations, are available for clients who use JDBC or libpq.
It is possible to specify multiple host components, each with an optional port component, in a single URI. A URI of the form postgresql://host1:port1,host2:port2,host3:port3/
is equivalent to a connection string of the form host=host1,host2,host3 port=port1,port2,port3
. Each host will be tried in turn until a connection is successfully established.
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 host, hostaddr, and port options accept a comma-separated list of values. You must give the same number of elements in each option specified, such that, for example, the first hostaddr corresponds to the first hostname, the second hostaddr corresponds to the second hostname, and so forth. As an exception, if you specify only one port, it applies to all the hosts.
In the connection URI format, you can list multiple host:port
pairs separated by commas in the host component of the URI.
In either format, a single hostname can translate to multiple network addresses. A typical example of this is a host that has both an IPv4 and an IPv6 address.
When you specify multiple hosts, or when a single hostname is translated to multiple addresses, all the hosts and addresses will be tried in order until one succeeds. The connection fails if none of the hosts can be reached. If a connection is established successfully but authentication fails, the remaining hosts in the list will not be tried.
If you use a password file, you can have different passwords for different hosts. All the other connection options are the same for every host in the list; it is impossible to specify different usernames for different hosts.
When using multi-host for configuration, you can only configure host:port
pairs with multiple passwords. You can configure other parameters with only one password. All host:port
pairs share the same password. If you configure different passwords on multiple hosts, it is necessary to point them out in the password file. Otherwise, a single shared password configured in URI will cause other connection errors.
It specifies the name of the file used to store passwords (see Section 33.15). Defaults to ~/.pgpass
, or %APPDATA%\postgresql\pgpass.conf
on Microsoft Windows. No error is reported if this file does not exist.
If you set this parameter to read-write, only a connection in which read-write transactions are accepted by default is considered acceptable.
The query SHOW transaction_read_only
will be sent upon any successful connection. The connection will be closed if it returns “on”.
If you specify multiple hosts in the connection string, any remaining servers will be tried just as if the connection attempt had failed.
The default value of this parameter, any, regards all connections as acceptable.
It specified the maximum wait for a connection in seconds (write as a decimal integer, e.g., 10). Zero, negative, or not specified means wait indefinitely. The minimum allowed timeout is 2 seconds; therefore, a value of 1 is interpreted as 2. This timeout applies separately to each hostname or IP address. For example, if you specify two hosts and connect_timeout is 5, each host will time out if no connection is made within 5 seconds, so the total time spent waiting for a connection might be up to 10 seconds.
In default mode (disabled) hosts are connected in the given order. If enabled, hosts are chosen randomly from the set of suitable candidates.
It allows opening connections to only servers with the required state. The allowed values are any, master, slave, secondary, preferSlave, and preferSecondary. The master/slave distinction is currently done by observing if the server allows writes. The value preferSecondary tries to connect to secondary if any are available. Otherwise, it falls back to connect to the master.
jdbc:postgresql://node1,node2,node3/accounting?targetServerType=master.
jdbc:postgresql://node1,node2,node3/accounting?targetServerType=preferSlave&loadBalanceHosts=true
psql uses libpq driver to link to the database and supports multi-master URI, as shown in these examples.
Environment:
192.168.70.10 is the master
192.168.70.20 is the first standby
192.168.70.30 is the second standby
View the address and port of the linked database through inet_server_addr()
and inet_server_port()
. You can use Pg_is_in_recovery()
to see whether the database is in recovery, which database it is, what role it currently belongs to, and whether it is read-write or in recovery.
$psql -h 192.168.70.10
Password for user postgres:
psql (11.5)
Type "help" for help.
postgres=# select inet_server_addr() as "connected_to";
connected_to
---------------
192.168.70.10 主库
(1 row)
postgres=# select client_addr, write_lag,flush_lag,replay_lag from pg_stat_replication;
client_addr | write_lag | flush_lag | replay_lag
---------------+-----------------+-----------------+-----------------
192.168.70.20 | 00:00:00.058204 | 00:00:00.058617 | 00:00:00.058619
192.168.70.30 | 00:00:00.03639 | 00:00:00.036689 | 00:00:00.036693
(2 rows)
The following settings are connected to three databases. Specifying the target_session_attrs=read-write
requires connection to a read-write library.
$ psql 'postgres://192.168.70.20:5432,192.168.70.10:5432,192.168.70.30:5432/postgres?target_session_attrs=read-write' -c "select inet_server_addr()"
Password for user postgres:
inet_server_addr
------------------
192.168.70.10
(1 row)
Specify the target_session_attrs=ANY
to link to any library selected at random from all configurations, as you can see by checking inet_server_addr:
$ psql 'postgres://192.168.70.20:5432,192.168.70.10:5432,192.168.70.30:5432/postgres?target_session_attrs=any' -c "select inet_server_addr()"
inet_server_addr
------------------
192.168.70.20
(1 row)
Or,
$ psql 'postgres://192.168.70.10:5432,192.168.70.20:5432,192.168.70.30:5432/postgres?target_session_attrs=any' -c "select inet_server_addr()"
inet_server_addr
------------------
192.168.70.10
(1 row)
Disable the main library. Specify target_session_attrs=ANY
to link to any library, namely the second one randomly selected from all configurations.
-- On Server : 192.168.70.10
$ pg_ctl -D $PGDATA stop -mf
waiting for server to shut down.... done
server stopped
[postgres@pg1]$ psql 'postgres://192.168.70.10:5432,192.168.70.20:5432,192.168.70.30:5432/postgres?target_session_attrs=any' -c "select inet_server_addr()"
inet_server_addr
------------------
192.168.70.20
(1 row)
$ cat pg_conn.py
import psycopg2
conn = psycopg2.connect(database="postgres",host="192.168.70.10,192.168.70.20,192.168.70.30", user="postgres", password="secret", port="5432", target_session_attrs="read-write")
cur = conn.cursor()
cur.execute("select pg_is_in_recovery(), inet_server_addr()")
row = cur.fetchone()
print "recovery =",row[0]
print "server =",row[1]
$ python pg_conn.py
recovery = False
server = 192.168.70.10
# cat pg_conn.php
<?php
$conn = pg_connect("host=192.168.70.10,192.168.70.20,192.168.70.30 port=5432 dbname=postgres user=postgres password=secret target_session_attrs=read-write") or die("Could not connect");
$status = pg_connection_status($conn);
if ($status === PGSQL_CONNECTION_OK) {
print "Connection status ok\n";
} else {
print "Connection status bad\n";
}
$sql = pg_query($conn, "select pg_is_in_recovery()");
while ($row = pg_fetch_row($sql)) {
echo "Recovery-status: $row[0]\n";
}
?>
$ php -f pg_conn.php
Connection status ok
Recovery-status: f
Server: 192.168.70.10
Multi-host is supported since PostgreSQL 10, so be sure to use a driver above 10.
The libpq dependencies for the PHP or python driver are as follows. The result is based on libpq 11, meaning that this version supports multi-host.
# yum info python2-psycopg2-2.8.3-2.rhel7.x86_64 | grep repo
From repo : pgdg11
# rpm -q --requires python2-psycopg2-2.8.3-2.rhel7.x86_64 | grep libpq
libpq.so.5()(64bit)
# rpm -q --requires php-pgsql-5.4.16-46.el7 | grep libpq
libpq.so.5()(64bit)
# locate libpq.so.5
/usr/pgsql-11/lib/libpq.so.5
How to Write into a Database Using reWriteBatchedInserts Parameter
How to Use pg_receivewal with Synchronous Replication to Mirror Redo Logs
digoal - June 2, 2021
digoal - September 20, 2019
Apache Flink Community China - April 23, 2020
Alibaba Cloud MaxCompute - June 2, 2021
Alibaba Cloud Native Community - July 20, 2023
digoal - April 28, 2021
Alibaba Cloud PolarDB for PostgreSQL is an in-house relational database service 100% compatible with PostgreSQL and highly compatible with the Oracle syntax.
Learn MoreLeverage cloud-native database solutions dedicated for FinTech.
Learn MoreMigrate your legacy Oracle databases to Alibaba Cloud to save on long-term costs and take advantage of improved scalability, reliability, robust security, high performance, and cloud-native features.
Learn MoreMigrating to fully managed cloud databases brings a host of benefits including scalability, reliability, and cost efficiency.
Learn MoreMore Posts by digoal