Cloning standbysCloning a standby from Barmancloningfrom BarmanBarmancloning a standby can use
2ndQuadrant's
Barman application
to clone a standby (and also as a fallback source for WAL files).
Barman (aka PgBarman) should be considered as an integral part of any
PostgreSQL replication cluster. For more details see:
https://www.pgbarman.org/.
Barman support provides the following advantages:
the primary node does not need to perform a new backup every time a
new standby is cloned
a standby node can be disconnected for longer periods without losing
the ability to catch up, and without causing accumulation of WAL
files on the primary node
WAL management on the primary becomes much easier as there's no need
to use replication slots, and wal_keep_segments
does not need to be set.
Currently &repmgr;'s support for cloning from Barman is implemented by using
rsync to clone from the Barman server.
It is therefore not able to make use of Barman's parallel restore facility, which
is executed on the Barman server and clones to the target server.
Barman's parallel restore facility can be used by executing it manually on
the Barman server and configuring replication on the resulting cloned
standby using
repmgr standby clone --replication-conf-only.
Prerequisites for cloning from Barman
In order to enable Barman support for repmgr standby clone, following
prerequisites must be met:
the Barman catalogue must include at least one valid backup for this server;
the barman_host setting in repmgr.conf is set to the SSH
hostname of the Barman server;
the barman_server setting in repmgr.conf is the same as the
server configured in Barman.
For example, assuming Barman is located on the host "barmansrv"
under the "barman" user account,
repmgr.conf should contain the following entries:
barman_host='barman@barmansrv'
barman_server='somedb'
To use a non-default Barman configuration file on the Barman server,
specify this in repmgr.conf with barman_config:
barman_config=/path/to/barman.conf
We also recommend configuring the restore_command setting in repmgr.conf
to use the barman-wal-restore script
(see section below).
If you have a non-default SSH configuration on the Barman
server, e.g. using a port other than 22, then you can set those
parameters in a dedicated Host section in ~/.ssh/config
corresponding to the value of barman_host in
repmgr.conf. See the Host
section in man 5 ssh_config for more details.
It's now possible to clone a standby from Barman, e.g.:
$ repmgr -f /etc/repmgr.conf -h node1 -U repmgr -d repmgr standby clone
NOTICE: destination directory "/var/lib/postgresql/data" provided
INFO: connecting to Barman server to verify backup for "test_cluster"
INFO: checking and correcting permissions on existing directory "/var/lib/postgresql/data"
INFO: creating directory "/var/lib/postgresql/data/repmgr"...
INFO: connecting to Barman server to fetch server parameters
INFO: connecting to source node
DETAIL: current installation size is 30 MB
NOTICE: retrieving backup from Barman...
(...)
NOTICE: standby clone (from Barman) complete
NOTICE: you can now start your PostgreSQL server
HINT: for example: pg_ctl -D /var/lib/postgresql/data start
Barman support is automatically enabled if barman_server
is set. Normally it is good practice to use Barman, for instance
when fetching a base backup while cloning a standby; in any case,
Barman mode can be disabled using the --without-barman
command line option.
Using Barman as a WAL file sourceBarmanfetching archived WAL
As a fallback in case streaming replication is interrupted, PostgreSQL can optionally
retrieve WAL files from an archive, such as that provided by Barman. This is done by
setting restore_command in recovery.conf to
a valid shell command which can retrieve a specified WAL file from the archive.
barman-wal-restore is a Python script provided as part of the barman-cli
package (Barman 2.0 ~ 2.7) or as part of the core Barman distribution (Barman 2.8 and later).
To use barman-wal-restore with &repmgr;,
assuming Barman is located on the host "barmansrv"
under the "barman" user account,
and that barman-wal-restore is located as an executable at
/usr/bin/barman-wal-restore,
repmgr.conf should include the following lines:
barman_host='barman@barmansrv'
barman_server='somedb'
restore_command='/usr/bin/barman-wal-restore barmansrv somedb %f %p'barman-wal-restore supports command line switches to
control parallelism (--parallel=N) and compression
(--bzip2, --gzip).
Cloning and replication slotscloningreplication slotsreplication slotscloning
Replication slots were introduced with PostgreSQL 9.4 and are designed to ensure
that any standby connected to the primary using a replication slot will always
be able to retrieve the required WAL files. This removes the need to manually
manage WAL file retention by estimating the number of WAL files that need to
be maintained on the primary using wal_keep_segments.
Do however be aware that if a standby is disconnected, WAL will continue to
accumulate on the primary until either the standby reconnects or the replication
slot is dropped.
To enable &repmgr; to use replication slots, set the boolean parameter
use_replication_slots in repmgr.conf:
use_replication_slots=true
Replication slots must be enabled in postgresql.conf by
setting the parameter max_replication_slots to at least the
number of expected standbys (changes to this parameter require a server restart).
When cloning a standby, &repmgr; will automatically generate an appropriate
slot name, which is stored in the repmgr.nodes table, and create the slot
on the upstream node:
repmgr=# SELECT node_id, upstream_node_id, active, node_name, type, priority, slot_name
FROM repmgr.nodes ORDER BY node_id;
node_id | upstream_node_id | active | node_name | type | priority | slot_name
---------+------------------+--------+-----------+---------+----------+---------------
1 | | t | node1 | primary | 100 | repmgr_slot_1
2 | 1 | t | node2 | standby | 100 | repmgr_slot_2
3 | 1 | t | node3 | standby | 100 | repmgr_slot_3
(3 rows)
repmgr=# SELECT slot_name, slot_type, active, active_pid FROM pg_replication_slots ;
slot_name | slot_type | active | active_pid
---------------+-----------+--------+------------
repmgr_slot_2 | physical | t | 23658
repmgr_slot_3 | physical | t | 23687
(2 rows)
Note that a slot name will be created by default for the primary but not
actually used unless the primary is converted to a standby using e.g.
repmgr standby switchover.
Further information on replication slots in the PostgreSQL documentation:
https://www.postgresql.org/docs/current/interactive/warm-standby.html#STREAMING-REPLICATION-SLOTS
While replication slots can be useful for streaming replication, it's
recommended to monitor for inactive slots as these will cause WAL files to
build up indefinitely, possibly leading to server failure.
As an alternative we recommend using 2ndQuadrant's Barman,
which offloads WAL management to a separate server, removing the requirement to use a replication
slot for each individual standby to reserve WAL. See section
for more details on using &repmgr; together with Barman.
Cloning and cascading replicationcloningcascading replication
Cascading replication, introduced with PostgreSQL 9.2, enables a standby server
to replicate from another standby server rather than directly from the primary,
meaning replication changes "cascade" down through a hierarchy of servers. This
can be used to reduce load on the primary and minimize bandwith usage between
sites. For more details, see the
PostgreSQL cascading replication documentation.
&repmgr; supports cascading replication. When cloning a standby,
set the command-line parameter --upstream-node-id to the
node_id of the server the standby should connect to, and
&repmgr; will create recovery.conf to point to it. Note
that if --upstream-node-id is not explicitly provided,
&repmgr; will set the standby's recovery.conf to
point to the primary node.
To demonstrate cascading replication, first ensure you have a primary and standby
set up as shown in the .
Then create an additional standby server with repmgr.conf looking
like this:
node_id=3
node_name=node3
conninfo='host=node3 user=repmgr dbname=repmgr'
data_directory='/var/lib/postgresql/data'
Clone this standby (using the connection parameters for the existing standby),
ensuring --upstream-node-id is provide with the node_id
of the previously created standby (if following the example, this will be 2):
$ repmgr -h node2 -U repmgr -d repmgr -f /etc/repmgr.conf standby clone --upstream-node-id=2
NOTICE: using configuration file "/etc/repmgr.conf"
NOTICE: destination directory "/var/lib/postgresql/data" provided
INFO: connecting to upstream node
INFO: connected to source node, checking its state
NOTICE: checking for available walsenders on upstream node (2 required)
INFO: sufficient walsenders available on upstream node (2 required)
INFO: successfully connected to source node
DETAIL: current installation size is 29 MB
INFO: creating directory "/var/lib/postgresql/data"...
NOTICE: starting backup (using pg_basebackup)...
HINT: this may take some time; consider using the -c/--fast-checkpoint option
INFO: executing: 'pg_basebackup -l "repmgr base backup" -D /var/lib/postgresql/data -h node2 -U repmgr -X stream '
NOTICE: standby clone (using pg_basebackup) complete
NOTICE: you can now start your PostgreSQL server
HINT: for example: pg_ctl -D /var/lib/postgresql/data start
then register it (note that --upstream-node-id must be provided here
too):
$ repmgr -f /etc/repmgr.conf standby register --upstream-node-id=2
NOTICE: standby node "node2" (ID: 2) successfully registered
After starting the standby, the cluster will look like this, showing that node3
is attached to node2, not the primary (node1).
$ repmgr -f /etc/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Connection string
----+-------+---------+-----------+----------+----------+--------------------------------------
1 | node1 | primary | * running | | default | host=node1 dbname=repmgr user=repmgr
2 | node2 | standby | running | node1 | default | host=node2 dbname=repmgr user=repmgr
3 | node3 | standby | running | node2 | default | host=node3 dbname=repmgr user=repmgr
Under some circumstances when setting up a cascading replication
cluster, you may wish to clone a downstream standby whose upstream node
does not yet exist. In this case you can clone from the primary (or
another upstream node); provide the parameter --upstream-conninfo
to explictly set the upstream's primary_conninfo string
in recovery.conf.
Advanced cloning optionscloningadvanced optionspg_basebackup options when cloning a standby
As &repmgr; uses pg_basebackup to clone a standby, it's possible to
provide additional parameters for pg_basebackup to customise the
cloning process.
By default, pg_basebackup performs a checkpoint before beginning the backup
process. However, a normal checkpoint may take some time to complete;
a fast checkpoint can be forced with repmgr standby clone's
-c/--fast-checkpoint option.
Note that this may impact performance of the server being cloned from (typically the primary)
so should be used with care.
If Barman is set up for the cluster, it's possible to
clone the standby directly from Barman, without any impact on the server the standby
is being cloned from. For more details see .
Other options can be passed to pg_basebackup by including them
in the repmgr.conf setting pg_basebackup_options.
Not that by default, &repmgr; executes pg_basebackup with
(PostgreSQL 9.6 and earlier: ) set to stream.
From PostgreSQL 9.6, if replication slots are in use, it will also create a replication slot before
running the base backup, and execute pg_basebackup with the
option set to the name of the previously created replication slot.
These parameters can set by the user in pg_basebackup_options, in which case they
will override the &repmgr; default values. However normally there's no reason to do this.
If using a separate directory to store WAL files, provide the option --waldir
(--xlogdir in PostgreSQL 9.6 and earlier) with the absolute path to the
WAL directory. Any WALs generated during the cloning process will be copied here, and
a symlink will automatically be created from the main data directory.
See the PostgreSQL pg_basebackup documentation
for more details of available options.
Managing passwordscloningusing passwords
If replication connections to a standby's upstream server are password-protected,
the standby must be able to provide the password so it can begin streaming replication.
The recommended way to do this is to store the password in the postgres system
user's ~/.pgpass file. It's also possible to store the password in the
environment variable PGPASSWORD, however this is not recommended for
security reasons. For more details see the
PostgreSQL password file documentation.
If using a pgpass file, an entry for the replication user (by default the
user who connects to the repmgr database) must
be provided, with database name set to replication, e.g.:
node1:5432:replication:repmgr:12345
If, for whatever reason, you wish to include the password in recovery.conf,
set use_primary_conninfo_password to true in
repmgr.conf. This will read a password set in PGPASSWORD
(but not ~/.pgpass) and place it into the primary_conninfo
string in recovery.conf. Note that PGPASSWORD
will need to be set during any action which causes recovery.conf to be
rewritten, e.g. .
It is of course also possible to include the password value in the conninfo
string for each node, but this is obviously a security risk and should be avoided.
From PostgreSQL 9.6, libpq supports the passfile
parameter in connection strings, which can be used to specify a password file other than
the default ~/.pgpass.
To have &repmgr; write a custom password file in primary_conninfo,
specify its location in passfile in repmgr.conf.
Separate replication user
In some circumstances it might be desirable to create a dedicated replication-only
user (in addition to the user who manages the &repmgr; metadata). In this case,
the replication user should be set in repmgr.conf via the parameter
replication_user; &repmgr; will use this value when making
replication connections and generating recovery.conf. This
value will also be stored in the parameter repmgr.nodes
table for each node; it no longer needs to be explicitly specified when
cloning a node or executing .