Compare commits

..

782 Commits

Author SHA1 Message Date
John Sapienza
89f1936004 ci(FS-7045): Update sonarqube-scan.yml 2024-01-30 11:23:07 -05:00
Martín Marqués
d3b1ff45b0 Merge pull request #782 from EnterpriseDB/Fixed-reported-phrase
Update configuration-file-optional-settings.xml
2023-07-04 09:04:04 -03:00
Martín Marqués
450786ec29 Typo in the documentation
Signed-off-by: Martín Marqués <martin.marques@enterprisedb.com>
2023-07-04 14:02:08 +02:00
Ian Barwick
70b34308cc repmgrd: ensure witness node metadata is updated
If the primary changed while the witness repmgrd was not running,
ensure the witness's upstream node ID is updated when the witness
repmgrd is restarted.
2023-06-08 16:35:56 +09:00
Martín Marqués
19c92a7092 Merge pull request #803 from Nyantechnolog/patch-1
Update README.md
2023-04-17 12:57:51 -03:00
Sidorov Pavel
520ff25ef3 Update README.md
upd upper version according to https://repmgr.org
2023-04-04 11:54:59 +03:00
Martín Marqués
8e81c04b4a Add release notes for repmgr release 5.4.0
This release added support for pg-backup-api. Here we add the
release notes which expose the new feature.

Signed-off-by: Martín Marqués <martin.marques@enterprisedb.com>
2023-03-24 15:05:03 +00:00
Martín Marqués
aad988c292 Merge pull request #800 from EnterpriseDB/update-docs-for-pg-backupapi-mode
Adding new mode to clone standbys.
2023-03-16 07:14:33 -03:00
Martín Marqués
43b8a5f65f Various improvements and fixes to the pg-backup-api restore section on the docs
I added a paragraph at the beginning of the section on where to look for
instructions on how to install the pg-backup-api rest API.

Fixed typos and some gramatical changes. Also reworded the first paragraph
(which is now the second one).

Signed-off-by: Martín Marqués <martin.marques@enterprisedb.com>
2023-03-14 11:39:22 +01:00
Martín Marqués
26cfb56170 New sect2 block has to be inside the sect1. The closing tag has to go at the end.
Signed-off-by: Martín Marqués <martin.marques@enterprisedb.com>
2023-03-14 10:14:16 +01:00
Mario Gonzalez
f0cc225de0 Adding new mode to clone standbys.
repmgr v5.4.0 supports this new mode called `pg_backupapi` which is
enabled by defining `pg_backupapi_host` in repmgr.conf.
2023-03-13 11:03:02 -03:00
Martín Marqués
02d8e0c808 Merge pull request #799 from EnterpriseDB/validate-repmgr-options
Validate repmgr options
2023-03-08 07:13:45 -03:00
Mario Gonzalez
167d166ae8 Validate options when using pg_backupapi mode.
When `pg_backupapi` is enabled, we should validate if the remote ssh
command, node name and backup_id are also defined.
2023-03-07 16:51:25 -03:00
Mario Gonzalez
03c2ae1bd8 Connecting to default pg-backup-api port: 7480/TCP 2023-03-07 16:50:02 -03:00
Martín Marqués
4021037d38 Merge pull request #797 from EnterpriseDB/connect-to-pg-backup-api
Connect to pg backup api
2023-03-07 14:34:54 -03:00
Ian Barwick
7cd7566409 doc: update README
Remove reference to non-existent "scripts/" directory.
2023-03-07 08:36:00 +09:00
Mario Gonzalez
81c3200ef2 Integration of pgbackupapi 2023-02-27 12:23:57 -03:00
Mario Gonzalez
c6366db6f9 Library to connect to a pg-backup-api server.
Module to provide communication with a server in order to send new
tasks and query them.

pg-backup-api is a REST api that at the moment, is integrated with
barman only, and can provide a communication interface in order to
perform remote recoveries through background tasks. There are cases
where instead of writing a new repmgr module of some feature that
exists in backup tools already, like barman, pg-backup-api can
provide that integration.
2023-02-27 12:23:57 -03:00
Martín Marqués
078a47e182 Merge pull request #791 from EnterpriseDB/adding-flex-and-libs-as-deps
Adding flex and libs as deps
2023-01-27 06:32:59 -03:00
Mario Gonzalez
ed2c0aaf0b Checking for required libraries before compiling.
This commit ensures all the different libraries are installed before
starting to compile.
2023-01-25 15:51:55 -03:00
Martín Marqués
6249027a03 Merge pull request #792 from EnterpriseDB/dev/remove-sonarqube
Dev/remove sonarqube
2023-01-24 17:03:11 -03:00
Martín Marqués
b36fca17d9 Remove Sonarqube
Sonarqube has been failing for some time (seems like a user/credential
problem).

There will be discussion on how we'll resolve this, but that will be
sometime in the future. For now we are just removing the action.

Signed-off-by: Martín Marqués <martin.marques@enterprisedb.com>
2023-01-24 13:00:35 -03:00
Mario Gonzalez
a3b919d599 Checking if flex is installed before compiling.
We are checking for sed amd other external tools inside configure script,
now is turn of flex.

In systems without flex you will have this error:

gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement
[...]
postgresql/internal  -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2   -c -o configfile.o configfile.c
flex  -o'configfile-scan.c' configfile-scan.l
make: flex: No such file or directory
make: *** [Makefile.global:40: configfile-scan.c] Error 127
2023-01-20 18:48:51 -03:00
Dee Dee Rothery
4c95d8d75e Update configuration-file-optional-settings.xml 2022-12-08 06:26:52 -05:00
Martín Marqués
c21d452076 Fix typo in documentation
Fixed a mising closing quote and closing parenthesis in the repmgrd overview
section of the documentation.

Signed-off-by: Martín Marqués <martin.marques@enterprisedb.com>
2022-11-16 13:55:36 -03:00
Ian Barwick
3b89731899 doc: update release notes 2022-10-18 10:26:44 +09:00
Ian Barwick
138bee98e9 doc: update compatibility matrix
Additional "Notes" column added.
2022-10-17 10:05:48 +09:00
Ian Barwick
83ffe84ff5 doc: update compatibility matrix for repmgr 5.3 / PostgreSQL 15 2022-10-17 10:05:26 +09:00
Ian Barwick
bb3206a2bf doc: clarify failover behaviour when node priority is zero
Make it clear the node will not be promoted under any circumstances.
2022-09-20 09:35:19 +09:00
Ian Barwick
49dfaea471 repmgrd: ensure notification script is called for "repmgrd_upstream_disconnect"
GitHUb #760.
2022-09-02 17:20:39 +09:00
Ian Barwick
8edc64f64e doc: update note about pg_rewind corner-case bug
Sadly it's likely there are still installations running PostgreSQL
versions released prior to February 2021, so keep the note there
for now.
2022-07-14 10:11:01 +09:00
Ian Barwick
3ce646f960 doc: mention full_page_writes as prerequisite for pg_rewind
Anyone disabling it needs to examine their life choices, but as
we check for it anyway, might as well explicitly mention it for
completeness.
2022-07-14 09:45:33 +09:00
Ian Barwick
dc0e89e234 doc: consolidate PostgreSQL 9.4 pg_rewind references
Anyone still using PostgreSQL 9.4 should re-examine their life choices
at this point, but as it is not yet de-supported by repmgr, consolidate
the references to it whenever pg_rewind is mentioned to a single
section.
2022-07-14 09:33:12 +09:00
Ian Barwick
41b6194580 Replace some appendPQExpBuffer occurrences with appendPQExpBufferStr 2022-07-14 09:14:56 +09:00
Ian Barwick
d501781a5f repmgr: update README
- update current version
- remove reference to upgrading from 3.x
2022-07-06 09:39:31 +09:00
Ian Barwick
de5265f594 Update Makefile
Re-add $(LIBS), previously removed in 9d7eebef.

While not required for internal builds, per GitHub #755 this may be
required in some environments.
2022-06-03 10:30:18 +09:00
Ian Barwick
66ac4183b4 doc: clarifications for upgrade process 2022-05-26 10:18:05 +09:00
Ian Barwick
59e5bc1500 doc: update compatibility matrix for repmgr 5.4 / PostgreSQL 15 2022-05-25 14:05:04 +09:00
Ian Barwick
8164914598 Add 5.3.2 release date 2022-05-25 14:04:19 +09:00
Ian Barwick
eb867516ff doc: update release notes 2022-05-25 14:03:39 +09:00
Ian Barwick
6b961ab6a7 doc: update release notes 2022-05-25 14:03:36 +09:00
Ian Barwick
7e2d14d225 shared library: remove redundant code
This has never actually served any purpose; see core commit ab02d702ef.
2022-05-17 20:00:12 +09:00
Ian Barwick
a90d1cf3dd Ensure replication slots can be dropped by a replication-only user
If the repmgr user is a non-superuser, and a replication-only user exists,
ensure redundant replication slots are dropped correctly.
2022-05-16 16:37:25 +09:00
Ian Barwick
cce5ca2245 doc: update release notes 2022-05-16 12:05:35 +09:00
Ian Barwick
6f87d2c61e repmgrd: improve walsender disable check
Specifically, don't attempt to disable walsenders if "standby_disconnect_on_failover"
is "true", but the repmgr user is not a superuser.

This restriction can be lifted from PostgreSQL 15.
2022-05-16 11:52:10 +09:00
Ian Barwick
c0763c94c8 dbutils: move get_wal_receiver_pid() to a more consistent location 2022-05-16 10:40:42 +09:00
Ian Barwick
ea689d17b5 repmgr: add code comment about pg_stat_tmp in PostgreSQL 15+
See core commit 6f0cf8787.
2022-05-15 15:19:02 +09:00
Ian Barwick
de343f0cbe shared library: update for PostgreSQL 15
Core commit 4f2400cb3f adds shmem_request_hook, meaning the
memory initialization previously carried out in _PG_init() needs
to be handled in that hook.
2022-05-14 18:31:05 +09:00
Ian Barwick
e6f1b8c279 doc: expand non-superuser permissions explanation
Information about using repmgr with a non-superuser was spread
throughout individual documentation systems; this commit creates
an overview of requirements and potential issues.
2022-05-13 14:30:03 +09:00
Ian Barwick
8e5f469fa1 doc: clarify permissions requirements in "standby switchover" 2022-05-13 14:26:34 +09:00
Ian Barwick
73cb3abd44 doc: clarify permissions requirements in "standby clone" 2022-05-13 14:26:28 +09:00
Ian Barwick
a3c77cac41 standby clone: update source comment 2022-05-13 13:39:05 +09:00
Ian Barwick
706d570790 doc: add missing short form option to "standby clone" 2022-05-13 11:53:49 +09:00
Ian Barwick
433bde82e8 dbutils.c: fix typo in comment 2022-05-13 11:51:58 +09:00
Ian Barwick
8f5319ce75 Disable exclusive backup check in PostgreSQL 15 and later
Exclusive backup functionality was removed in core commit 39969e2a
so we can and must avoid checking for exclusive backups.
2022-05-11 15:25:38 +09:00
Ian Barwick
4c05307da1 repmgr: fix error message
It's possible the missing node record might be for a witness server,
though we have no way of knowing that.
2022-05-11 14:58:36 +09:00
zhouhj43183
743e0e5480 repmgrd: ensure witness node marked active
Previously, if the witness node's PostgreSQL was unreachable, it would
be marked as "inactive" on the primary, and under some circumstances
would not be corrected to "active" once the witness node's PostgreSQL
came back.

PR #754; some modifications by Ian Barwick.
2022-05-11 13:35:48 +09:00
Ian Barwick
35c4ba1fbe doc: update release notes
Add notes about when PostgreSQL and/or repmgrd restart required.

GitHub #752.
2022-05-10 16:22:51 +09:00
Ian Barwick
30082eab02 doc: update release notes 2022-05-10 16:09:17 +09:00
Ian Barwick
d9d60fa420 standby clone: don't error out if unable to determine cluster size
The cluster size check is purely informative, and is not in any way
essential for the standby clone operation. As it's possible the query
may fail if the repmgr user does not have sufficient privileges to
query all databases in the cluster, we can simply ignore any failure.

Note that the code comment indicated the query also served to sanity-
check that queries can actually be executed. While this was the case
historically, the preceding server version check now serves the same
purpose and will not have the same risk of failure due to missing
permissions.
2022-05-10 15:08:02 +09:00
Ian Barwick
2756d6fd94 node check: prevent WARNING in --downstream --nagios output 2022-04-20 17:45:00 +09:00
Ian Barwick
bb63fb08d0 node check: fix --downstream --nagios output
Ensure the performance data output (the bit after the pipe) contains
information in a pareseable format.

GitHub #749.
2022-04-20 17:35:44 +09:00
Ian Barwick
9508673e00 node check: tweak --upstream --nagios output
No data follows the pipe, so omit it and add missing line break.
2022-04-20 16:40:53 +09:00
Ian Barwick
3e3803fa32 doc: fix XML error 2022-04-19 11:26:22 +09:00
Felix Dreissig
8119aef378 Doc: Update or remove references to recovery.conf
The recovery.conf file is not present anymore for Postgres >= 12.

PR 748.
2022-04-19 11:06:08 +09:00
Felix Dreissig
35c8a53790 Sample config: Update link to docs 2022-04-19 10:20:18 +09:00
Doug Calobrisi
1c7fec9a1a Add SonarQube (#751) 2022-04-18 10:04:54 -04:00
James Stroud
3b8294e4cb Update install-packages.xml postgres 14 and not 11
Hi, I think you had a typo, you meant to say Postgres 14 and not 11.  If am wrong just ignore, thanks and take care James Stroud
2022-03-31 16:03:02 +09:00
Ian Barwick
f5e42e1851 doc: use "note" rather than "important" 2022-03-16 10:40:28 +09:00
Ian Barwick
f7b9e11d6f doc: update witness server notes
- clarify that a separate PostgreSQL instance is needed for each
  witness server
- remove historical 3.x reference
2022-03-16 10:26:47 +09:00
Ian Barwick
197c87d13b docs: update package installation instructions
- use "dnf" in place of "yum"
- mention Rocky Linux
- remove 9.6 examples
2022-03-11 10:23:51 +09:00
Ian Barwick
67e2e8e613 docs: update one more instance of the company name 2022-02-15 17:25:11 +09:00
Ian Barwick
c6f137d438 docs: update other instances of the company name, where appropriate 2022-02-15 17:25:07 +09:00
Ian Barwick
6cd41aaaf6 docs: update company name on cover pages 2022-02-15 17:25:03 +09:00
Ian Barwick
b4dca347b4 docs: finalize 5.3.1 release notes 2022-02-15 13:39:33 +09:00
Ian Barwick
2e1d1f9a57 Add include for pwd.h
This was previously included via the PostgreSQL source, but that
seems to have gone away in recent HEAD builds.
2022-02-03 14:20:22 +09:00
Ian Barwick
fa851ea38f doc: update version matrix
5.2.1 is the latest release in the 5.2.x series.
2022-02-03 13:31:04 +09:00
Ian Barwick
593bffb18f doc: repmgr 5.2 is no longer supported. 2022-02-03 13:26:26 +09:00
Ian Barwick
8a36cc3b2d doc: update version matrix 2022-02-03 13:26:20 +09:00
Ian Barwick
2733579a76 doc: update release notes 2022-02-03 13:09:42 +09:00
Ian Barwick
947d14979f Fix upgrade paths from 4.1 ~ 4.3 to 5.2 and later
A number of C functions were added in releases 4.2 to 4.4; however
these were renamed in 5.3 to prevent naming clashes with other
extensions.

This does however mean that when upgrading from one of the above
versions, the intermediate upgrade steps will attempt to create
SQL functions referencing C functions which no longer exist in
repmgr.so, and hence cause the upgrade to fail.

We can work around this by providing empty upgrade scripts
from these versions to 4.4, which skip the problematic CREATE
FUNCTION commands. The functions will be correctly created in
the 5.2--5.3 upgrade script.
2022-02-03 12:59:52 +09:00
Ian Barwick
b8cb1feb49 repmgrd: move connection pointer declaration inside relevant block
As it's used only there and nowhere else.
2022-01-04 12:45:28 +09:00
Ian Barwick
5de74d9e18 doc: update release notes 2022-01-04 12:32:43 +09:00
zhouhj43183
2dce8e14f9 repmgrd: ensure potentially open connections are closed
When recovering from degraded state in local node monitoring, in some
cases a new connection was opened to the local node without closing
the old one, which will result in memory leakage.
2022-01-04 12:22:09 +09:00
Ian Barwick
81f9c0ebd0 doc: update repmgr.conf.sample
Minor formatting fix.
2021-12-08 09:50:37 +09:00
Ian Barwick
9f53d45c74 doc: update repmgr.conf.sample
Remove bogus -W option in "repmgr standby follow" example invocation
for the "follow_command" parameter.

The option (which corresponds to "--no-wait") is not used by
"repmgr standby follow".

Per report from Jimmy Angelakos.
2021-12-08 09:50:19 +09:00
Ian Barwick
aef5a4f8cf doc: fix typo 2021-11-05 09:12:06 +09:00
Ian Barwick
580d112d3d Removed temporary include file workaround 2021-10-29 15:41:53 +09:00
Ian Barwick
6ba27a9c6b Add dummy include file
This is a workaround required to facilitate Debian package builds
against PostgreSQL Extended.
2021-10-12 16:51:51 +09:00
Ian Barwick
51e7025747 doc: update release notes 2021-10-12 10:13:42 +09:00
Ian Barwick
ded20be505 repmgrd: improve node activation at startup
Commit 79d1f00 modified repmgrd to automatically set an inactive node
to "active" at startup.

However we need to avoid doing that for cases where the node role has
changed (e.g. a former primary was recloned as a standby) but the node
record was not updated.
2021-10-11 14:39:04 +09:00
Ian Barwick
e7e62f7f35 repmgrd: add %p event notification parameter for "repmgrd_failover_promote"
This enables an event notification script to identify the former primary
node.
2021-09-28 10:25:27 +09:00
Ian Barwick
3870768d80 Add --repmgrd option to "repmgr node check"
This provides a simple way for checking whether the node's repmgrd is
running.

GitHub #719.
2021-09-28 09:46:31 +09:00
Ian Barwick
16349d95e9 Update Makefile for 5.4dev 2021-09-16 14:43:35 +09:00
Ian Barwick
bba282a131 Add extension script files for 5.4dev. 2021-09-16 14:32:55 +09:00
Ian Barwick
02c29dc860 Add extension script for unpackaged upgrades to 5.3 2021-09-16 13:56:38 +09:00
Ian Barwick
7c5efe2baa doc: update 5.3.0 release notes 2021-09-16 13:42:58 +09:00
Ian Barwick
b2756806d9 Bump master branch to 5.4dev 2021-09-16 10:15:20 +09:00
Ian Barwick
bf0478088c standby: add missing include 2021-08-18 10:26:56 +09:00
Ian Barwick
efd5792de4 Remove redundant shared library function prototypes
From PostgreSQL 9.4 (commit e7128e8d), explicit function prototypes
are not required as they will be generated by the PG_FUNCTION_INFO_V1
macro.

(We were supporting PostgreSQL 9.3 until relatively recently, so there
was nothing particular to gain by removing these earlier).
2021-08-18 10:19:13 +09:00
Ian Barwick
17987a2690 standby switchover: detect if demotion candidate is running as a primary
This shouldn't happen, but if it does, log the fact for easier analysis.
2021-07-28 11:50:57 +09:00
Ian Barwick
5f1ba6db3d standby switchover: improve handling of node rejoin failure
Explicitly check whether the "repmgr node rejoin" command on the
demotion candidate succeeded. Due to the way SSH execution is
currently implemented, we can return either the command execution
status or the command output; to ensure any errors are available,
log them to a temporary file on the demotion candidate and note
its location in case of an error.

While we're at it, improve error message handling when the demotion
candidate fails to rejoin.
2021-07-28 11:42:40 +09:00
Ian Barwick
55efbe60ea standby switchover: optionally delay promotion
This is for testing purposes only and should not be used in production.
2021-07-27 17:01:27 +09:00
Ian Barwick
132f5ebc08 standby switchover: improve logging of repmgrd pause actions
- state how many nodes are to be operated on
- if errors were encountered with any nodes, emit the total number
  of nodes as well as the number of affected nodes
- log nodes where repmgrd was not running anyway as NOTICE, not
  WARNING
2021-07-26 17:46:58 +09:00
Ian Barwick
c901f36f81 Standardize formatting of node ID in log messages
Mostly we have "(ID: %i)", so use that rather than "(ID %i)" which has
crept into a few places.
2021-07-26 17:27:36 +09:00
Ian Barwick
edb49b2747 doc: link to main documentation section about RemoveIPC 2021-07-26 11:01:03 +09:00
Ian Barwick
a35d85ed70 doc: link to service commands section from switchover docs 2021-07-26 09:47:14 +09:00
Ian Barwick
b6b91425d9 doc: document pg_bindir setting
Per suggestion in GitHub #705.
2021-07-20 13:36:08 +09:00
Ian Barwick
32329ca55a doc: link to sample configuration file
Unfortunately it hasn't been possible yet to include all available
configuration items in the main documentation, but we should at least
make it easier to find the full list.
2021-07-20 13:18:57 +09:00
Ian Barwick
79d1f005db repmgrd: activate inactive node record at startup
If a PostgreSQL instance was shut down while repmgrd was running, and
repmgrd was subsequently restarted (this chain of events could occur
during e.g. a server reboot), the node record will have been set to
"inactive". Previously, in this case repmgrd would refuse to start up.
However, as we can determine the node is running, it should normally
be no problem to automatically set the node record to "active".

The old behaviour can be restored by setting the new parameter
"repmgrd_exit_on_inactive_node" to "true".

RM19604.
2021-07-12 17:46:09 +09:00
Ian Barwick
f64f498afb Be more flexible when parsing the output from pg_config --version
The string may not always start with "PostgreSQL" when building
against non-community versions.

Life would be much easier here if there was an option like
"pg_config --version-number" or similar.
2021-07-05 15:38:34 +09:00
Ian Barwick
f10c013e89 doc: note PostgreSQL 14 support
repmgr 5.3 will provide support for PostgreSQL 14.
2021-07-01 16:00:21 +09:00
Ian Barwick
2059a55a99 doc: update release notes 2021-07-01 13:44:33 +09:00
Ian Barwick
99ed17b838 doc: update release notes 2021-07-01 13:28:15 +09:00
Ian Barwick
078b4ad863 standby clone: set "slot_name" in node record if required
If executing "repmgr standby clone --replication-conf-only" on a node
which was set up without replication slots, but the repmgr configuration
was since changed to "use_replication_slots=1", repmgr will attempt to
create the replication slot. This will however fail if "slot_name"
is not set in the node's record, so have repmgr set the slot_name in
this case.

It might be preferable to preemptively create the slot name for each
node when configuring the cluster, however this would be a behavioural
change which would be better off in a major release (for example, it's
conceivable a user runs sanity checks on the node records and expects
to find the slot names empty if replication slots are not in use).
2021-07-01 13:04:23 +09:00
Ian Barwick
2af71c6426 repmgrd: ensure short option "-s" is accepted
The long option --show-pid-file was fine.
2021-06-03 18:41:11 +09:00
Ian Barwick
9349520530 Remove reference to PostgreSQL 9.3 in --help output
It is not supported by repmgr 5.2 and later.
2021-04-15 15:31:59 +09:00
Ian Barwick
14851e61de doc: clarify "connection_check_type='query'" 2021-03-03 13:12:58 +09:00
Ian Barwick
888e1d7a3b docs: update repmgr.conf.sample
Fix description for connection_check_type='connection'.
2021-03-02 11:44:14 +09:00
Ian Barwick
1b4c2a60bb docs: update README
Note latest version number.
2021-03-02 11:26:15 +09:00
Ian Barwick
da163e811c doc: update README
Fix and update broken link.
2021-03-02 11:14:16 +09:00
Ian Barwick
80d1beef7e doc: update GitHub links to new location 2021-03-02 08:58:49 +09:00
Ian Barwick
4f009548f6 doc: remove generated .fo files 2021-03-01 11:06:41 +09:00
Ian Barwick
d266df3143 Change copyright information to "EnterpriseDB Corporation"
RM20485.
2021-03-01 11:03:52 +09:00
Ian Barwick
dd8204e013 Rename various shared library functions
Some of the more generically named functions are at risk of colliding
with functions defined in other libraries. To mitigate that risk,
prefix with "repmgr_", unless the name already has some reference
to repmgr.

This requires an extension version bump.

RM20471.
2021-02-23 10:14:28 +09:00
Ian Barwick
d34b4e71a6 Fix incorrect comment 2021-02-22 13:28:27 +09:00
Ian Barwick
12749c3f63 doc: fix XML markup
An incorrect column count was causing PDF builds to fail.
2021-02-19 20:39:41 +09:00
Ian Barwick
ce59d92731 doc: update repmgr.conf.sample 2021-01-14 15:27:24 +09:00
Ian Barwick
cfbeed50d6 node rejoin: emit rejoin target note information as NOTICE
As it's possible to specify the connection information for any available
node, but currently not possible to rejoin to a node other than the
primary, explicitly mention what the rejoin target will be.
2021-01-06 14:11:37 +09:00
Ian Barwick
da3eaee127 doc: "repmgr node rejoin" clarifications
- make it clearer a node can only be joined to the primary
- update patch status
2021-01-06 12:36:11 +09:00
Ian Barwick
b37a599fc6 Update copyright notices to 2021 2021-01-04 12:54:54 +09:00
Ian Barwick
f011e552d0 Add missing PQconninfoFree() call 2020-12-24 18:07:18 +09:00
Ian Barwick
d1cc05faf9 repmgrd: edit code comment for clarity 2020-12-22 13:58:34 +09:00
Ian Barwick
7ceba84e32 doc: minor grammar tweak 2020-12-22 13:57:31 +09:00
Josh Soref
842c67ca18 doc: various spelling fixes
Via GitHub #687.
2020-12-22 13:47:56 +09:00
Josh Soref
f619c3a8ff Fix various typos in code comments.
Via GitHub #687.
2020-12-22 13:43:06 +09:00
Josh Soref
5a88858596 repmgr: various log ouput typo fixes
Via GitHub #687.
2020-12-22 13:18:11 +09:00
Josh Soref
02bc143c75 repmgr: fix typo in "repmgr node --help" output
Via GitHub #687.
2020-12-22 13:07:16 +09:00
Ian Barwick
c480d01f9c Improve HINT about upgrading the repmgr extension
Per feedback in GitHub #685.
2020-12-15 08:41:46 +09:00
Ian Barwick
e762200a12 doc: update README
Link to recent-ish EDB blog article.
2020-12-08 13:31:21 +09:00
Ian Barwick
2133e1097e standby switchover: remove extraneous space in log message 2020-12-08 13:14:45 +09:00
Ian Barwick
77d7a098a1 doc: add 5.2.1 release date 2020-12-08 12:41:46 +09:00
Ian Barwick
4e9cdf0267 doc: update 5.2.1 release notes 2020-12-04 14:49:20 +09:00
Ian Barwick
0d8bf2a935 Minor string formatting optimization 2020-12-04 10:16:21 +09:00
Ian Barwick
debbda6074 standby clone: tweak error message
Probably a remnant from the 9.1 era, where it was not possible to
take a base backup from a standby.
2020-12-04 10:13:45 +09:00
Ian Barwick
d5b94431f2 standby follow: fix standby.signal generation
Oversight from previous a93c6dfc.
2020-12-02 09:11:20 +09:00
Ian Barwick
93187e9743 Add missing connection close
In a corner-case situation where a standby is unable to attach to
the new primary due to a mismatch in the WAL stream, the connection
used to verify the recovery status of the new primary was not being
closed, leading to a risk of connection exhaustion on the new primary.

Addresses GitHub #682.
2020-12-01 21:33:07 +09:00
Ian Barwick
f7e45863ad standby clone: fix data directory permissions handling for Pg11 and later
Previously, repmgr would forcibly change the permissions on a data
directory to 0700. However from PostgreSQL 11, 0750 is also valid,
so that value should not be changed.
2020-12-01 11:48:22 +09:00
Ian Barwick
89556d6488 standby clone: add --recovery-min-apply-delay to help output 2020-11-30 16:44:48 +09:00
Ian Barwick
4ad868d119 doc: update 5.2.1 release notes 2020-11-30 16:44:48 +09:00
Ian Barwick
a93c6dfca7 Ensure standby.signal is set correctly if -D/--data-directory supplied
When cloning a standby, it's possible to do a "raw" clone by providing
-D/--data-directory but no repmgr.conf file. However the code which
creates "standby.signal" was assuming the presence of a valid
repmgr.conf complete with "data_directory" configuration.

This is very much a niche-use case.
2020-11-27 11:24:15 +09:00
Ian Barwick
4d8bc63834 repmgrd: fix issue with incorrect reconnect_interval
Addresses GitHub #673.
2020-11-25 20:40:28 +09:00
Ian Barwick
7bca9df223 Update Makefile
We don't actually need $(LIBS) in there; this was cargo-culted in
from somewhere.
2020-11-24 17:37:48 +09:00
Ian Barwick
1ac62a4352 Avoid compiler warnings for various strncpy() operations
Here the compiler may complain that the source length is being used,
though in all cases the source length was previously used to
define the length of the destination buffer, so it's not actually
a problem.
2020-11-24 15:42:49 +09:00
Ian Barwick
8f7a32a9a2 repmgr: prevent termination in corner-case situation
If neither the local node nor the upstream are available, and
"standby_disconnect_on_failover" is set, attempting to fetch
the walreceiver PID will result in repmgrd terminating.

Add a check that the connection is valid before attempting to
fetch the walreceiver PID.

Addresses GitHub #675.
2020-11-17 16:34:55 +09:00
Ian Barwick
9c04de11fc standby clone: various clarifications for --replication-conf-only option
In particular, the emitted HINT was not really appropriate for Pg13 and
later.
2020-11-17 09:58:51 +09:00
Ian Barwick
040b1ae4e3 Update corner-case error message
Not possible to build repmgr compatible with Pg12+ against Pg11
and earlier due to the addition of FullTransactionId.
2020-11-17 09:39:41 +09:00
Ian Barwick
703aed3fa3 doc: tweak "repmgr standby clone" reference
As recovery.conf starts to fade away, mention that last.
2020-11-10 16:07:22 +09:00
Ian Barwick
7ee0098771 standby clone: add option --recovery-min-apply-delay
This overrides the equivalent setting in repmgr.conf, if present.

Note this option was available in repmgr versions prior to 4.0, but
was assumed to be redundant. However recently a use-case was made
for its reintroduction.
2020-11-10 15:55:04 +09:00
Ian Barwick
430d12b870 Fix typo 2020-11-10 13:40:38 +09:00
Romain Jacquier
c8b2d23361 Fix help witness
Fix the `repmgr witness --help` command where at the "Unregister" section the message shown was
```
"witness register" unregisters a witness node.
```
instead of
```
"witness unregister" unregisters a witness node.
```

GitHub #676.
2020-11-09 13:34:08 +09:00
Ian Barwick
8543c0bcf6 standby clone: emit pg_basebackup command in --dry-run mode 2020-11-04 12:00:42 +09:00
Ian Barwick
674c06d01c Decouple extension version check from binary version
Until now the extension version has always moved in lock-step
with the binary version, but that doesn't always need to be
the case, so make it possible to have an extension version
which does not match the binary version.
2020-10-30 14:42:58 +09:00
Ian Barwick
970d7a136f Fix return value of pg_reload_conf() database utility function
Would always return "false", but as the value wasn't used anywhere,
the issue was inconsequential.

However while we're at it, actually check the return value in the
two places it's called, to help diagnose any issues in the unlikely
event they occur.

Per issue reported via GitHub PR #671 from user duzhgg.
2020-10-30 14:25:11 +09:00
Ian Barwick
7bde686796 standby clone: handle missing "postgresql.auto.conf"
In PostgreSQL 12 and later we need to append replication configuration
to "postgresql.auto.conf" to guarantee it will be read last, and hence
override any preceding replication configuration which may be haunting
the configuration files.

We've been assuming that "postgresql.auto.conf" will always be present,
but at least one corner case has been observed where that was not the
case on the node being cloned from. Moreover it's perfectly acceptable
that this file does not exist (it will be recreated the next time
ALTER SYSTEM is executed), so we should be prepared to handle that case.

In passing, improve handling of more unlikely errors which might be
encountered when processing "postgresql.auto.conf".
2020-10-30 12:25:03 +09:00
Ian Barwick
ab1447aeca Standardize code style 2020-10-30 11:06:15 +09:00
Ian Barwick
293e37688f config: fix parsing of "replication_type"
This is a legacy parameter which can currently only contain one value,
"physical" (the default).

It can be safely omitted.

Addresses GitHub #672.
2020-10-30 10:14:04 +09:00
Ian Barwick
96718151a6 doc: update README
- remove partial sentence
- remove links to very dated blog entries
2020-10-27 13:58:07 +09:00
Ian Barwick
65ffe51bb4 doc: update README
Link to release notes as a simple way of providing the latest release
information.
2020-10-27 13:52:19 +09:00
Ian Barwick
b6d0288a82 Finalize release date 2020-10-22 21:23:50 +09:00
Ian Barwick
f888407ad8 Additional fix to upgrade script
Drop old "repl_events" table.
2020-10-22 21:22:52 +09:00
Ian Barwick
1512c7b761 Fix extension script for unpackaged upgrades to 5.2
Apparently "ALTER TABLE" (which we were using to convert the
"repl_events" table) does not mark the table as being part of the
extension. Instead, we need to create the new table and copy the
data, as is done with the other tables.
2020-10-22 21:22:47 +09:00
Ian Barwick
8877d4d508 doc: add missing "unpackaged" reference 2020-10-22 21:22:43 +09:00
Ian Barwick
f18b2e900d standby clone: improve Barman source server check
Use "remote_command()" to execute the remote psql command, and
provide the -X option to psql to ensure it doesn't read ~/.psqlrc.
2020-10-22 21:22:04 +09:00
Ian Barwick
5c4aa1856c doc: update README 2020-10-22 21:20:17 +09:00
Ian Barwick
091a2df167 doc: update release notes 2020-10-20 14:09:44 +09:00
Ian Barwick
17a1732eb0 Bump master branch to 5.3dev
Also update the minimum version check to PostgreSQL 9.4.
2020-10-20 13:41:49 +09:00
Ian Barwick
397e0ed5be Silence potential compiler complaint
*We* know the target buffer is sufficiently sized to accept the
source string, but the compiler doesn't.
2020-10-20 09:51:49 +09:00
Ian Barwick
8f3994b071 doc: update "repmgr standby clone" reference
Clarify which replication configuration parameters will be written
for which PostgreSQL version.
2020-10-20 09:35:22 +09:00
Ian Barwick
f7c232b393 Only write "recovery_target_timeline" for PostgreSQL 11 and earlier
"recovery_target_timeline" defaults to "latest" from PostgreSQL 12
(see core commit 2dedf4d9) so no need to write it explicitly.
2020-10-20 09:18:29 +09:00
Ian Barwick
ac2feba380 Improve capture of pg_rewind stderr output
As it seems redirecting stderr to stdin (2>&1) when executing
system commands results in a SIGPIPE (141) return code, making
it impossible to determine the actual return code, redirect
stderr to a temporary file and collate the output from that.

There are possibly better ways of doing this which could
be revisited at a future date.
2020-10-15 14:01:18 +09:00
Ian Barwick
725e9f9851 Remove more unused code 2020-10-15 11:03:18 +09:00
Ian Barwick
00bf4d61fa Remove unused code 2020-10-15 10:54:18 +09:00
Ian Barwick
338c4d3f8a node rejoin: rename variable for clarity 2020-10-14 17:57:20 +09:00
Ian Barwick
250c6291df node rejoin: fix Pg13+ "standby.signal" handling with pg_rewind 2020-10-14 17:51:57 +09:00
Ian Barwick
773159a9e8 standby clone: move check for --waldir pg_basebackup option
When cloning from Barman, and --no-upstream-connection was supplied,
the server version number will not be available at this point in the
code. It will however later be extracted from the Barman metadata,
so move the check for the --waldir pg_basebackup option to after
this point.

Also add an explicit check that a server version number has been
obtained (and fall back to extracting it from the cloned data
directory), as subsequent operations depend on knowing this to
be performed correctly.
2020-10-13 14:27:46 +09:00
Ian Barwick
5f986bc981 node rejoin: handle unclean shutdown in Pg13
From PostgreSQL 13, pg_rewind will automatically handle an unclean
shutdown itself, so as long as --force-rewind was provided, so there
is no need to fail with an error.

Note that pg_rewind handles the unclean shutdown by starting PostgreSQL
in single user mode, which it does before performing any checks as
to whether a rewind is actually necessary.

However pg_rewind doesn't take into account the possible presence
of a standby.signal file, so we remove that and recreate it after
pg_rewind was executed.
2020-10-13 10:18:55 +09:00
Ian Barwick
d62743ddf4 Make repmgr metadata tables dumpable
This makes it easier to extract data for troubleshooting.
2020-10-12 10:02:52 +09:00
Ian Barwick
b195547525 Remove hack to create pre-9.4 monitoring history table
The pg_lsn datatype was introduced in PostgreSQL 9.4, and we no
longer need to support earlier versions.
2020-10-12 09:32:37 +09:00
Ian Barwick
758c18985c node rejoin: better document unrecoverable situation
If two diverged nodes are on the same timeline, currently there's
no way of establishing the divergence point and pg_rewind
is ineffective.

Clarify the log messages to make this clearer.
2020-10-08 21:09:51 +09:00
Ian Barwick
7969dc4800 Enable "node rejoin" to join a target with a lower timeline
This has been possible since PostgreSQL 9.6, but the node rejoin/follow
check did not consider this possibility.
2020-10-08 16:51:16 +09:00
Ian Barwick
0fc8c6c79c Add some break statements to silence compiler warnings 2020-10-08 13:10:00 +09:00
Ian Barwick
e7acb6809b standby clone: improve error logging
When executing "repmgr standby clone" in Barman mode, and --waldir
is set in pg_basebackup options, properly report an error if the
target WAL directory could not be created or is not empty.
2020-10-08 10:46:20 +09:00
Ian Barwick
4b524c52b6 standby clone: honour --waldir setting when cloning from Barman
By setting --waldir in "pg_basebackup_options", standbys cloned using
pg_basebackup would have their WAL directory set to the specified
location and symlinked from the data directory.

This commit causes repmgr to honour that setting even when cloning
from Barman.
2020-10-07 15:13:52 +09:00
Ian Barwick
b3b9281253 Parse pg_basebackup option --waldir/--xlogdir 2020-10-07 15:13:50 +09:00
Ian Barwick
679cfe0852 doc: update release notes
Note PostgreSQL 13 support as a general feature.
2020-10-06 14:17:16 +09:00
Ian Barwick
e10d9fd393 EXPERIMENTAL: synchronise try_primary_reconnect()'s reconnection loop
Per proposal in GitHub #662, this patch attempts to synchronise each
repmgrd's primary reconnection attempts to prevent potential race
conditions. This relies on each node's clock being correcly
synchronised.

Currently this change is experimental and is not enabled by default.
It can be enabled by setting the repmgr.conf parameter
"reconnect_loop_sync".
2020-10-06 13:35:49 +09:00
Ian Barwick
467d19bcd4 Use atoll() to parse system_identifier on 32bit systems
Addresses issue in GitHub #665.
2020-10-06 09:44:31 +09:00
Ian Barwick
be244e2155 Fix typo
s/paremeter/parameter/
2020-10-05 17:06:52 +09:00
Ian Barwick
42283bf344 repmgrd: check local connection after promoting local node
In theory the local connection should not be affected by the node's
promotion. However we're handing over control to an external command
which is usually just "repmgr standby promote", but could potentially
be a user-defined script with unknowable side effects. So it's
better to be safe than sorry.
2020-10-05 16:50:41 +09:00
Ian Barwick
5b254a1be9 repmgrd: add parameter "failover_delay"
This parameter is not documented and intended for use during testing.
It should not be used in production.
2020-10-05 16:43:06 +09:00
Ian Barwick
9aaf7d79a2 standby switchover: in Pg13 and later, promotion overrides paused WAL replay
Preventing a switchover in this case no longer makes sense, so we apply
the checks to PostgreSQL 12 and earlier only.
2020-09-30 15:15:11 +09:00
Ian Barwick
e86c035242 standby promote: in Pg13 and later, promotion overrides paused WAL replay
Aborting in this case no longer makes sense, so we apply the checks
to PostgreSQL 12 and earlier only.
2020-09-30 15:15:07 +09:00
Ian Barwick
73d2088a85 standby follow: don't restart server (PostgreSQL 13 and later)
As of PostgreSQL 13, changes to the fundamental replication
configuration can be applied with a simple SIGHUP, no restart
required.

In case the old behaviour is desired, i.e. a full restart to apply
the configuration changes, the new configuration parameter
"standby_follow_restart" can be set. This parameter has no effect
in PostgreSQL 12 and earlier.
2020-09-29 17:53:51 +09:00
Ian Barwick
48f95f9a39 Fix typo in comment 2020-09-29 15:26:28 +09:00
Ian Barwick
ce229beff8 repmgrd: add configuration option "always_promote"
In certain corner cases, it's possible repmgrd may end up monitoring
a standby which was a former primary, but the node record has not
yet been updated.

Previously repmgrd would abort the promotion with a cryptic message
about being unable to find a node record for node_id -1 (the
default value for an unknown node id).

This commit addes a new configuration option "always_promote", which
determines whether repmgrd should promote the node in this case.
The default is "false", to effectively maintain the existing behaviour.

Logging output has also been improved to make it clearer what has
happened when this situation occurs.
2020-09-29 14:18:00 +09:00
Ian Barwick
16eeae700c repmgrd: minor log message tweak 2020-09-29 10:23:31 +09:00
Ian Barwick
70061c51aa Further improve handling of possible pg_control read errors
Builds on changes in commit 147f454, and ensures appropriate
action is taken if a value cannot be read from pg_control.
2020-09-28 13:59:34 +09:00
houzj.fnst
3ffeffbd8b Remove redundant condition
GitHub #655.
2020-09-28 13:08:18 +09:00
Ian Barwick
147f454d32 Minor sanity check for control file extraction functions
If the control file couldn't be parsed for whatever reason, return
the default value for the requested parameter.

It'd be better to have the caller pass in a pointer to the parameter
and have the function return bool so the caller doesn't assume the
control file was read successfully. This is important for handling
DBState, where no "value unknown" default is available.
2020-09-28 10:47:56 +09:00
Ian Barwick
26b5664741 repmgr: enable "primary unregister --force" to unregister an active primary
The primary must have no registered standby nodes.

Also document usage when unregistering a primary node which is actually
running as a standby.
2020-09-23 15:12:19 +09:00
Ian Barwick
cb86180f4f doc: document include directives 2020-09-18 16:27:52 +09:00
Ian Barwick
1f3e098104 Add option "--dump-config"
This is initially intended for verifying the configuration parsing
mechanism and is currently undocumented.
2020-09-18 15:12:22 +09:00
Ian Barwick
4670515285 config: fix parsing of event_notifications list 2020-09-18 14:36:56 +09:00
Ian Barwick
bccc2673b6 doc: update compatibility matrix 2020-09-18 11:40:47 +09:00
Ian Barwick
158008c5c5 doc: update release notes 2020-09-18 11:29:07 +09:00
Ian Barwick
5f3d1cdeb6 doc: note removal of PostgreSQL 9.3 support 2020-09-17 16:05:16 +09:00
Ian Barwick
82515a9733 doc: document new parameters for "failover_validation_command" 2020-09-17 15:48:18 +09:00
Stanislav Paskalev
73e8373337 Add %v, %u and %t parameters to "failover_validation_command"
These indicate:
 - the number of visible nodes sharing the current upstream
 - the number of nodes on the current upstream
 - the total number of nodes in the entire repmgr cluster.

This allows the failover_validation_command to be used to perform
more thorough validations, including cross-referencing external
cluster management state (e.g. if managed by kubernetes).

GitHub #651.
2020-09-17 15:48:12 +09:00
Ian Barwick
f1bdb09512 doc: note existing pg_rewind corner-case bug 2020-09-15 14:21:14 +09:00
Ian Barwick
028e3ab48d doc: rearrange "repmgr node rejoin" reference for clarity
The <important> section looked like an actual subsection, so convert
that and the following example section into <refsect2> sections.
2020-09-15 13:42:18 +09:00
Ian Barwick
b5b7d635ad doc: fix "release-current" tag 2020-09-04 15:12:33 +09:00
Ian Barwick
146654bf0e Clarify code comment 2020-09-04 15:10:54 +09:00
Ian Barwick
4c3aed2573 rsync: exclude log/pg_log directory depending on PostgreSQL version
This is more for completeness as the data source here is Barman, which
shouldn't contain log files anyway.
2020-09-04 15:03:27 +09:00
Ian Barwick
3945314e65 Remove PostgreSQL 9.3 support
PostgreSQL 9.3 community support ended in November 2018.
2020-09-04 11:37:12 +09:00
Ian Barwick
f4938a4a42 standby clone: tweak --help output wording 2020-09-03 10:41:04 +09:00
Ian Barwick
9a836b3c04 Add option --verify-backup
This causes pg_verifybackup to be executed immediately after
pg_basebackup completes.

PostreSQL 13 and later.
2020-09-03 10:40:32 +09:00
Ian Barwick
c8e52e486f Have make_pg_path() output to a PQexpBuffer
Calling functions are all using one anyway, so there's no point keeping
static buffers around.
2020-09-02 15:30:57 +09:00
Ian Barwick
1f7ac843fd Consolidate role availability checking code 2020-09-01 14:37:33 +09:00
Ian Barwick
8d57d7e001 is_downstream_node_attached(): avoid false negative
If the provided connection does not have sufficient permission to read
"pg_stat_replication.state", and there is an entry for the node in
"pg_stat_replication", assume it's connected. Finer-grained detection
requires additional user permissions, nothing we can do about that.
2020-09-01 14:28:40 +09:00
Ian Barwick
13e7c679cd Minor coding style fixes 2020-09-01 13:35:13 +09:00
Ian Barwick
466590af28 Fix comment 2020-09-01 13:23:46 +09:00
Ian Barwick
a88c80248c repmgrd: minor tweaks to witness node synchronisation
Explicitly roll back if any operation fails, and add debugging output
to track elapsed time between synchronisation intervals.
2020-09-01 09:58:14 +09:00
Ian Barwick
1131e3aad2 PostgreSQL 13: support "wal_keep_size"
Renamed from "wal_keep_segments" in core commit f5dff459.
2020-08-31 17:18:41 +09:00
Ian Barwick
0630d9644e Improve replication connection check
Previously the check verifying that a node has connected to its upstream
merely assumed the presence of a record in pg_stat_replication indicates
a successful replication connection. However the record may contain a
state other than "streaming", typically "startup" (which will occur when
a node has diverged from its upstream and will therefore never
transition to "streaming"), which needs to be taken into account when
considering the state of the replication connection to avoid false
positives.
2020-08-27 16:09:25 +09:00
Ian Barwick
c50a2d049c doc: note use of wildcards in .pgpass file 2020-08-19 10:32:34 +09:00
Ian Barwick
20100f5aaa docs: link to PostgreSQL roadmap 2020-08-06 09:50:23 +09:00
Ian Barwick
2d20c110bf doc: update "repmgr witness register" description
Add missing "Options" section.
2020-08-06 09:50:19 +09:00
Ian Barwick
aed0045c3a docs: reformat additonal config file upgrade notes into a new section
It's easier to link to the information that way.
2020-08-06 09:50:16 +09:00
Martín Marqués
cd81046c26 doc: add two notes on section related to configuration files
Add notes to the documention mentioning that after postgres or repmgr
upgrades (postgres major upgrades), there are some changes that need
to be taken care of.

Signed-off-by: Martín Marqués <martin.marques@2ndquadrant.com>
2020-08-06 09:50:11 +09:00
Ian Barwick
fb32284cdc remove superfluous debugging output 2020-08-06 09:05:55 +09:00
Ian Barwick
893044f1e9 Add missing pfree() calls 2020-07-16 11:08:20 +09:00
Ian Barwick
271d407c7c doc: update sample configuration file
Clarify parameters for recovery_min_apply_delay
2020-07-16 11:07:49 +09:00
Ian Barwick
1d0103ca44 cluster matrix/crosscheck: improve text mode output formatting
Previously these actions were hard-wired to assume node IDs would only
ever have two digits at most.

Refactor to use the same table generation code as other actions, which
properly handles variable column sizes.
2020-07-06 13:52:28 +09:00
Ian Barwick
51d56684a7 node status: clarify "archive_mode" message on standbys
"archive_mode = 'always'" available from PostgreSQL 9.5.
2020-07-06 10:21:00 +09:00
Ian Barwick
4d88f177a7 doc: clarify "node rejoin" usage
Emphasize that conninfo must be provided for a running node.
2020-07-06 09:55:06 +09:00
Ian Barwick
de3f0802b4 Update source comments to clarify data directory modifications 2020-06-19 13:51:00 +09:00
Ian Barwick
2985b9d91f Remove vestiges of deprecated "--node" option
The option was never actually set anywhere.

By removing it, readline will now produce a reasoanably helpful message
in the offchance it is provided, e.g.:

   option '--node=foo' is ambiguous; possibilities: '--node-id' '--node-name'
2020-06-10 13:11:22 +09:00
Ian Barwick
300e11eb76 Rearrange some command line option handling definitions for clarity 2020-06-10 13:02:13 +09:00
Ian Barwick
53546b1c88 node rejoin: remove unneeded PQfinish() 2020-06-10 10:36:55 +09:00
Ian Barwick
547bbb06d8 doc: note downstream node (dis)connection monitoring in more places 2020-06-09 16:21:36 +09:00
Ian Barwick
0d0ffc675c standby clone: add a strategic Assert 2020-06-09 14:31:49 +09:00
Ian Barwick
11dc923a20 standby clone: minor code cleanup 2020-06-09 14:31:44 +09:00
Ian Barwick
e97319f01d Fix typo in comment 2020-06-09 14:31:40 +09:00
Ian Barwick
db1cb1433f Rename the TablespaceDataListCell element "f" to "fptr" for clarity
And add a few more comments to make it clearer what's going on.
2020-06-09 14:31:36 +09:00
Ian Barwick
c1428a3ecd standby clone: fixes for Barman tablespace handling.
repmgr creates a file with a list of tablespace files to fetch from
Barman, however the file may not actually have been flushed to disk
at the point the rsync operation was executed, so may be incomplete
or empty.

Also fix handling of tablespace remapping.

Addresses GitHub #650.
2020-06-09 10:52:10 +09:00
Ian Barwick
fc568a9101 run_file_backup(): fix comments
Explicitly document use-case for this function, and fix a comment
which probably got munged by pg_indent.
2020-06-08 12:45:38 +09:00
Ian Barwick
e65738c989 Explicitly unset search path when connecting to database 2020-05-22 16:11:55 +09:00
Ian Barwick
aaea24b58b repmgrd: log reconnection of paired connection 2020-05-22 14:21:17 +09:00
Ian Barwick
d75a35a788 repmgrd: clarify why node is not configured for automatic failover 2020-05-22 11:21:48 +09:00
Ian Barwick
8233560629 repmgrd: ensure cascaded standby reconnects to primary
If the primary connection went away, and the upstream is not the
primary, attempt to reconnect if the monitoring update fails.

If the upstream is the primary, the reconnection will happen on
the next connection check.
2020-05-22 11:11:58 +09:00
Ian Barwick
cf60844c45 repmgrd: ensure primary connection is reset if same as upstream
Addresses GitHub #633.
2020-05-22 11:11:54 +09:00
Ian Barwick
a0d3fae7ab standby register: ensure location field is compared during record check 2020-05-21 14:35:03 +09:00
Ian Barwick
f05978e2e1 doc: update example log output to match current code 2020-05-15 10:33:47 +09:00
Ian Barwick
b7475792e7 configuration: add maximum nesting depth
As with ff4771ab, this is the same behaviour as core PostgreSQL.
2020-05-14 16:27:35 +09:00
Ian Barwick
5c16e94672 configuration: clean up unneeded code and comments 2020-05-14 16:27:22 +09:00
Ian Barwick
ff4771ab02 configuration: reject direct recursion
Ensure a configuration file can't include itself.

This is the same behaviour as core PostgreSQL.
2020-05-14 15:32:04 +09:00
Ian Barwick
d59cadd5f6 Remove old configuration handling code
This expunges two large and cumbersome sets of if/else statements and
the T_CONFIGURATION_OPTIONS_INITIALIZER macro, all of which needed to
be kept in sync when adding/modifying configuration file parameters.
2020-05-14 11:57:16 +09:00
Ian Barwick
04aee7b406 Set defaults before loading configuration file 2020-05-14 11:57:07 +09:00
Ian Barwick
029164a817 Make configuration default value usage more consistent 2020-05-14 11:57:04 +09:00
Ian Barwick
3dde8f1386 "retire" old configuration handling code 2020-05-14 11:57:00 +09:00
Ian Barwick
94fbf76b2e be quiet, griping compiler! 2020-05-14 11:56:56 +09:00
Ian Barwick
4a1855fabe Place configuration settings struct in separate file 2020-05-14 11:56:45 +09:00
Ian Barwick
d79d4c50b2 handle tablespace mapping 2020-05-14 11:56:42 +09:00
Ian Barwick
2071fa8c7e Initial implementation of an iterable configuration item list
This implements storing the configuration file parameter definitions in
an iterable list. This will replace the existing way of populating the
configuration struct, which is a long and cumbersome if/else structure,
and will make it possible to later dump the imported configuration.
2020-05-14 11:56:38 +09:00
Ian Barwick
9945a3a4a8 Handle "include_dir" 2020-05-14 11:56:35 +09:00
Ian Barwick
0df0db1281 Handle "include_if_exists" 2020-05-14 11:56:30 +09:00
Ian Barwick
682ec9184a Handle "include" 2020-05-14 11:56:26 +09:00
Ian Barwick
fdc6f61257 Pass base configuration file directory to configuration parser
If provided, the parser will use this to process include directives
with unqualified filenames.
2020-05-14 11:56:23 +09:00
Ian Barwick
f5018e42f3 Initial refactoring of configuration file parsing
Have the configuration file parsing routine itself open the respective
configuration file, rather than passing a file pointer from the original
caller. This is required for handling include directives, which we'll
want to do for sanity-checking the PostgreSQL configuration on a freshly
cloned, unstarted standby.
2020-05-14 11:56:19 +09:00
Ian Barwick
26689871dc Update filename in comment 2020-05-14 10:50:36 +09:00
Ian Barwick
a863dc7f6c repmgrd: additional check for the upstream connection
It's possible the upstream server was intermittently unavailable in
the interval between checks, invalidating the upstream connection.
With check types "ping" and "connection", the connection would not be
restored, so if the availability check was successful, additionally
verify the upstream connection and restore if necessary.

Addresses GitHub #633.
2020-05-14 10:26:57 +09:00
Ian Barwick
9b6fe6858a doc: update repmgr.conf.sample
Was missing "query" option for "connection_check_type".
2020-05-12 17:05:22 +09:00
Ian Barwick
2f667116d8 repmgrd: include node name in log output
Missed in commit fd52df0.
2020-05-12 15:31:47 +09:00
Ian Barwick
8ee4fac5bb repmgrd: minor refactoring of try_primary_reconnect() 2020-05-12 14:52:14 +09:00
Ian Barwick
bb56387aaa repmgrd: consolidate connection closing code
PQfinish() should only be called on local PGconn pointers which
will not be reused.
2020-05-12 14:48:39 +09:00
Ian Barwick
5d00094936 repmgrd: ensure "close_connection()" always called after connection failure 2020-05-12 14:41:33 +09:00
Ian Barwick
ebdfdc530d repmgrd: ensure PQfinish() always executed on failed connections in NodeInfoLists
clear_node_info_list() will clean up any remaining active connections,
but we need to ensure all failed connections are cleaned up at the point
of failure to prevent leaks.

Per report in GitHub #643.
2020-05-12 14:22:08 +09:00
Ian Barwick
e5d3285d02 repmgrd: remove redundant log message 2020-05-11 16:59:32 +09:00
Ian Barwick
fd52df0fab repmgrd: include node name in log output in more places
Still a few places where only the node ID was reported, but it's always
useful to have the node name as well.
2020-05-11 16:55:31 +09:00
Ian Barwick
1b5ad743b5 standby clone: explicitly set closed connection pointers to NULL
We omitted to do this with the connections used when checking the system
identifier, which means libpq calls by the teardown function using the
pointer risk using unallocated memory.

Addresses issue reported in GitHub #644.
2020-05-11 13:52:10 +09:00
Ian Barwick
389c0ab9c0 Clarify use of function parameter 2020-05-11 13:37:42 +09:00
Ian Barwick
72dfe28e81 doc: clarify usage of "-f /etc/repmgr.conf" in examples 2020-05-08 10:22:52 +09:00
Ian Barwick
bc566f7a42 standby check: ignore upstream/downstream connections if node is witness
Per report in GitHub #641.
2020-05-08 09:37:30 +09:00
Ian Barwick
d1ab6ce28b standby clone: emit warning, not error if server is 9.3 and tablespace_mapping provided 2020-05-07 10:23:07 +09:00
Ian Barwick
bcc284cac9 Refactor configuration file reload handling
Rather than parse the configuration file into a new structure and
copy changed values from that into the main structure, we'll copy
the existing structure before parsing the changed configuration
file directly into the nmain structure, and revert using the copy
if any issues are encountered.

This is necessary as preparation for further reworking of the
configuration file structure handling. It also makes the reload
idempotent.

While we're at it, make some general improvements to the reload
handling, particularly:

 - improve logging to show "before" and "after" values
 - collate change notifications and only display if no errors
   were found
 - remove unnecessary double-logging of errors
 - various bugfixes
2020-05-05 15:29:07 +09:00
Ian Barwick
d37513312a Move the main configfile structure into configfile.c
This is required for a later refactoring of the configuration file
handling.
2020-05-05 14:43:55 +09:00
Ian Barwick
3ca642fee1 repmgrd: log receipt of SIGHUP at log level NOTICE
PostgreSQL itself logs it at log level LOG, which we don't have,
but NOTICE seems reasonable, especially as we log SIGTERM as that.
2020-05-05 13:41:23 +09:00
Ian Barwick
be8e5b45fa Add utility function validate_conninfo_string() 2020-05-05 13:41:18 +09:00
Ian Barwick
5ee4540640 Fix typo in comment 2020-05-01 12:13:06 +09:00
Ian Barwick
6507a374f7 doc: update legacy upgrade procedure
From PostgreSQL 13, the "CREATE EXTENSION ... FROM" syntax is no longer
available. It's unlikely at this point that someone will find themselves
with a PostgreSQL 13 database and the legacy repmgr schema, but we'll
cover all bases just in case.
2020-05-01 10:27:33 +09:00
Ian Barwick
c884f21a58 Tidy up log message 2020-04-28 14:23:39 +09:00
Ian Barwick
11e1b7a2c5 Check function return values in modify_auto_conf() 2020-04-27 14:26:04 +09:00
Ian Barwick
d0c5dffe91 standby clone: explicitly log that replication slots not in use
Helps with diagnosing output.
2020-04-27 13:57:18 +09:00
Ian Barwick
38b3447bd3 Add repmgr home page to --help output
Per PostgreSQL commit 1933ae629e7b706c6c23673a381e778819db307d it seems
to be all the rage these days.
2020-04-24 09:41:56 +09:00
Ian Barwick
3200c8c4e4 doc: clarify usage of the "passfile" parameter. 2020-04-23 15:03:40 +09:00
Ian Barwick
971309c830 Fix parsing of database connection check results in "standby clone" 2020-04-23 13:19:20 +09:00
Ian Barwick
1628bfb846 Update references to "recovery.conf" in _do_create_replication_conf() 2020-04-23 11:42:13 +09:00
Ian Barwick
8adcb1348d repmgrd: improve logging of promote_command failure
- log failure *before* we check if the primary has reappeared
- log the error code
2020-04-21 15:02:15 +09:00
Ian Barwick
025e66ea46 standby switchover: check superuser connection on demotion candidate
Add a sanity check that rempgr, when remotely executed on the demotion
candidate, is able to connect as superuser. If not, emit a diagnostic
command as a hint.
2020-04-21 11:25:01 +09:00
Ian Barwick
4e48301d78 standby switchover: note database name for superuser connections
It's useful to have a confirmation of which database repmgr is trying
to connect to when the -S/--superuser connection is provided.

It will always be the database defined in the repmgr.conf "conninfo"
parameter, but having the name available is useful when e.g.
troubleshooting issues with .pgpass configuration.
2020-04-20 16:49:47 +09:00
Ian Barwick
f8b214f721 doc: have Makefile clean up generated html files 2020-04-20 15:40:13 +09:00
Ian Barwick
96acd3f915 doc: clarify .pgpass usage with -S/--superuser option 2020-04-20 15:34:29 +09:00
Ian Barwick
c1584d587c doc: remove DEBUG output from example 2020-04-20 12:14:47 +09:00
Ian Barwick
2f26a02b5c doc: clarify usage of -F/--force with "standby promote"
Per GitHub #632.
2020-04-20 12:11:49 +09:00
Ian Barwick
cb2fb53556 Fix debug logging
Per GitHub #630.
2020-04-20 11:07:51 +09:00
Ian Barwick
e1953742a1 doc: note additional diagnostic options provided by "node check" 2020-04-17 11:53:56 +09:00
Ian Barwick
97d83bd443 standby switchover: add hint for diagnosing remote DB connection failure
Output a command, which when excuted on the local node (promotion
candidate) will attempt to remotely connect to the demotion candidate
and display both the connection message encountered and the connection
parameters used.

This is useful for corner-cases where the connection normally succeeds if a
particular environment variable (e.g. PGPORT) is normally set, but is
not set in the environment where SSH is executed.
2020-04-17 11:20:02 +09:00
Ian Barwick
45e96f21a5 node check: add option --db-connection
This is intended for diagnostic purposes, primarily when diagnosing
the connection parameters used when repmgr is being executed on a
remote node.
2020-04-15 17:48:23 +09:00
Ian Barwick
9df1731fb8 doc: update release notes 2020-04-15 14:50:51 +09:00
Ian Barwick
cfd35852b7 standby switchover: improve archive check error handling
Explicitly log if a database connection failure caused the check
to fail.

It's unlikely this situation will be encountered, as the data directory
check will already have run and checked for connection failure, however
there's a small chance the connection could fail between checks.
2020-04-15 14:08:33 +09:00
Ian Barwick
32dde4eaaf standby switchover: improve directory check failure handling
It's possible that the remote data directory check will fail if e.g.
connection configuration is not consistent across all nodes. This
modification ensures a database error connection is reported, rather
than a spurios issue with the data directory configuration.
2020-04-15 14:08:29 +09:00
Ian Barwick
78f89a4d47 node check: report connection error if --optformat provided
The --optformat option is intended for use when repmgr is being invoked
remotely by another repmgr instance, typically during a switchover
operation.

Previously no output was returned if the local repmgr was unable to
connect to its local PostgreSQL instance, which made diagnosing
various corner-case problems trickier than it should be.
2020-04-15 14:08:25 +09:00
Ian Barwick
410dd40526 standby switchover: standardize log message 2020-04-15 10:24:44 +09:00
Ian Barwick
3d85d8f5ff doc: update link to Debian package archive
See also https://www.df7cb.de/blog/2020/apt-archive.postgresql.org.html
2020-04-14 12:32:59 +09:00
Ian Barwick
d20711c267 Update Makefile for 5.2dev 2020-04-13 17:49:58 +09:00
Ian Barwick
e4a7da0132 Add upgrade route for repmgr 3.x to repmgr 5.1
The removal of some extensions functions means it's not possible to
follow the conventional incremental upgrade path; instead we'll
create a script for direct upgrades to 5.1.
2020-04-13 17:45:19 +09:00
Ian Barwick
4f0e8a503a doc: fix typo in 5.1.0 release section ID 2020-04-13 17:17:06 +09:00
Ian Barwick
c39289d570 doc: finalize release notes 2020-04-13 17:17:01 +09:00
Ian Barwick
662b603770 doc: update release notes 2020-04-13 17:16:55 +09:00
Ian Barwick
fa4f37ddb9 Bump master branch to 5.2dev 2020-04-08 14:22:51 +09:00
Ian Barwick
599bab590a Create temporary pg.auto.conf file with the same permissions as the original
Commit 0574279 set the file permissions to 0600 rather than the user's
umask, but if initdb was executed with -g/--allow-group-access, the
file is maintained with 0640, so we'll just maintain the existing
permssions.
2020-04-07 13:29:59 +09:00
Ian Barwick
cd80f265ac standby clone: warn about missing pg_rewind prerequisites
These are not essential for cloning a standby, but useful to warn
as early as possible in case the user is intending to use pg_rewind.
2020-04-06 15:37:37 +09:00
Ian Barwick
09f0be8ceb Minor log output fixes 2020-04-06 13:19:58 +09:00
Ian Barwick
59159dede7 Ensure next release is 5.1, not 5.1.0 2020-04-03 14:57:17 +09:00
Ian Barwick
780453e168 repmgrd: clarify log messages
Display the identity of the node question in the meassges fixed
in commit 8a27c89; this makes it easier to diagnose log output.
2020-04-03 13:02:49 +09:00
Tom Janson
8a27c89d18 repmgrd: fix inverted log message
Warning is emitted when the node in question is in recovery.
2020-04-03 12:39:36 +09:00
Ian Barwick
0a2091d5d3 repmgrd: handle new primary notification during failover check
It's possible a repmgrd instance might still be in the primary check
phase while a primary has already been promoted. Therefore it's
necessary to check for new primary notifications here, so we can
follow a new primary as quickly as possible.
2020-04-02 15:45:14 +09:00
Ian Barwick
447054a630 standby promote: in --dry-run mode, display promote command which will be used
For PostgreSQL 12 and later, explicitly note whether repmgr user has
execution permissions on the pg_promote() function.
2020-04-02 12:37:32 +09:00
Ian Barwick
d998cab3d0 doc: add note about granting permissions on pg_promote() 2020-04-02 11:32:02 +09:00
Ian Barwick
7f460c88bf doc: update "node check" examples
Also add example output for a standby.
2020-03-31 11:09:00 +09:00
Ian Barwick
e59da2d74e node check: display upstream info before downstream info
It makes more sense that way.
2020-03-31 11:08:28 +09:00
Ian Barwick
bffb8fa11b node check: handle --upstream option when node is primary 2020-03-31 10:49:30 +09:00
Ian Barwick
d9cb38c7f0 node check: add --upstream option
We have a --downstream option to check for attached nodes, but it
would be useful to have a corresponding --upstream option too.

A following patch will adapt the behaviour of this option when executed
on the primary node.
2020-03-30 17:54:52 +09:00
Ian Barwick
f3258c5002 cluster cleanup: explicitly log vacuum operation 2020-03-26 11:38:51 +09:00
Ian Barwick
5d92c99bb9 standby switchover: warn if no superuser connection available 2020-03-26 11:18:04 +09:00
Ian Barwick
6895916914 node service: explicitly note the node identity where CHECKPOINT issued
This output is logged during "standby switchover", so it's useful to be
aware of which node the activity is being performed on.
2020-03-25 14:00:55 +09:00
Ian Barwick
e64349e4da standby switchover: accept -S/--superuser option 2020-03-25 14:00:51 +09:00
Ian Barwick
2e9bc31c8c Consolidate code for establishing a superuser connection 2020-03-25 11:02:31 +09:00
Ian Barwick
325e3ea541 Update "repmgr node" help output 2020-03-25 09:37:49 +09:00
Ian Barwick
2b06f2d1ae node service: enable provision of the -S/--superuser option
This is required to be able to execute a CHECKPOINT if the normal
repmgr user is not a superuser.
2020-03-24 17:25:34 +09:00
Ian Barwick
304c1391cc node action: don't attempt to issue a CHECKPOINT as non-superuser
Raise a warning instead.
2020-03-24 17:25:27 +09:00
Ian Barwick
b09631b3bc doc: clarify pg_promote() usage 2020-03-24 15:40:26 +09:00
Ian Barwick
e561ddc8d3 node check: accept -S/--superuser option
This is mainly useful for the --data-directory-config option, which
requires permission to read pg_settings to verify that the data
directory configured in "repmgr.conf" matches the data directory
actually in use.

If pg_settings read permission is not available, repmgr will fall
back to a simple check that the data directory configured in
"repmgr.conf" is a valid PostgreSQL directory. This is not entirely
foolproof, as it's possible PostgreSQL could be using a different
data directory.
2020-03-23 17:14:04 +09:00
Ian Barwick
06f0e5e94f Minor error message output tweak 2020-03-23 16:30:00 +09:00
Ian Barwick
12adb5e0d1 Add warning if --superuser option provided when it won't be used
Currently the only place this option is relevant is "standby clone".
2020-03-23 15:28:22 +09:00
Ian Barwick
b691a1bd10 doc: minor fixes to pg_upgrade notes 2020-03-20 17:24:41 +09:00
Ian Barwick
dd35c22033 doc: add note about pg_upgrade and standbys 2020-03-20 17:22:15 +09:00
Ian Barwick
ddde31b14e doc: update section about passwords when cloning standbys
Reference new password management section and remove duplicate
info.
2020-03-18 17:24:39 +09:00
Ian Barwick
09a78111f6 doc: add note about alternative passfile locations 2020-03-18 17:08:54 +09:00
Ian Barwick
76cea52755 doc: add section about password management
This is briefly covered in the section about cloning, but is hard to
find.
2020-03-18 17:08:49 +09:00
Ian Barwick
57ba3ef19a doc: clarify database user permission requirements 2020-03-10 14:26:27 +09:00
Ian Barwick
0ddc9b8bbf doc: move database permission configuration to separate file 2020-03-10 14:26:23 +09:00
Ian Barwick
5722c0a582 doc: fix typo 2020-03-06 17:41:19 +09:00
Ian Barwick
eb346ac6ae Simplify configuration parsing code
No need to check for empty parameters; this is something left over
from the original configuration file parsing. Since converting
to use the PostgreSQL-based configuration file parsing, it is
redundant.
2020-03-06 16:27:37 +09:00
Ian Barwick
0bc0a28378 standby promote: enable "service_promote_command" in PostgreSQL 12
This enables the promote command generated internally by repmgr to
be overridden if desired, in the same way as for PostgreSQL 11 and
earlier.
2020-03-06 13:21:30 +09:00
Ian Barwick
fb5ce720f3 standby promote: fall back to "pg_ctl promote" if necessary
From PostgreSQL 12, the SQL-level function "pg_promote()" can be used
to promote a PostgreSQL instance, however usage is restricted to
superusers and users to whom explicit execution permission for this
function has been granted.

Therefore, if execution permission is not available, fall back to
"pg_ctl promote".
2020-03-06 12:53:37 +09:00
Ian Barwick
7c96afc6fb Move user information database functions into their own section
Code reorganisation for easier location of functions.
2020-03-06 12:53:34 +09:00
Ian Barwick
6559258b53 doc: update release notes 2020-03-05 17:24:24 +09:00
Ian Barwick
9de31428f1 Consolidate replication connection code
In a few places, replication connections are generated from the
parameters used by existing connections. This has resulted in a
number of similar blocks of code which do more-or-less the same
thing almost but not quite identically. In two cases, the code
omitted to set "dbname=replication", which can cause problems
in some contexts.

These code blocks have now been consolidated into standardized
functions.

This also resolves the issue addressed by GitHub #619.
2020-03-05 17:21:37 +09:00
Ian Barwick
10304a1a3b doc: update release notes 2020-03-04 17:21:31 +09:00
Ian Barwick
63aac64938 standby switchover: fetch remote repmgr version number 2020-03-04 17:21:27 +09:00
Ian Barwick
8f6058c676 standby switchover: check replication configuration file ownership
Within a PostgreSQL data directory, all files should have the same
ownership as the data directory itself. PostgreSQL itself expects
this, and ownership of files by another user is likely to cause
problems.

In PostgreSQL 11 or earlier, if "recovery.conf" cannot be moved
by PostgreSQL (because e.g. it is owned by root), it will not be
possible to promote the standby to primary.

In PostgreSQL 12 and later, if "postgresql.auto.conf" on the demotion
candidate (current primary) has incorrect ownership (e.g. owned by
root), repmgr will very likely not be able to modify this file and
write the replication configuration required for the node to rejoin
the cluster as a standby.

Checks added to catch both cases before a switchover is executed.
2020-03-04 17:21:22 +09:00
Ian Barwick
194b6d0948 Minor code simplification 2020-03-03 15:27:45 +09:00
Ian Barwick
c6dfe53f03 cluster show: update code comment listing supported options 2020-03-02 16:03:48 +09:00
Ian Barwick
e218422eca standby clone: fix references to "recovery.conf" for Pg 12 and later
"standby clone --recovery-conf-only" still mentioned "recovery.conf" in a
couple of places; change that to the more generic "replication configuration"
for Pg 12 and later.
2020-02-27 12:20:09 +09:00
Ian Barwick
e02e3dae29 doc: update "repmgr cluster show" output example 2020-02-26 16:02:08 +09:00
Ian Barwick
6ef722956b cluster show: show unreachable node's upstream name as uncertain 2020-02-25 16:50:45 +09:00
Ian Barwick
cebb1249aa Convert printed "WARNING" messages to logging output
In a couple of places ("cluster show" and "service status") we printed
connection status errors as a "WARNING" to stdout, followed by a log
HINT, but the latter was ineffective unless the configured log
level happened to match the level of the most recently emitted log
line (which will most likely be DEBUG).

Convert the printed WARNING lines to an actual log WARNING, to make the
behaviour of this output behave as expected.
2020-02-25 15:25:59 +09:00
Ian Barwick
51a7c31833 doc: update "repmgr cluster show" examples 2020-02-25 12:22:19 +09:00
Ian Barwick
76af2d9e08 cluster show: don't display witness node timeline ID
The witness node is not part of the replication cluster, so its timeline
ID is not of any relevance.
2020-02-25 10:33:54 +09:00
Ian Barwick
3b03edebb6 cluster show: correct timeline column length calculation
Unlikely to have made a difference unless abnormally long priority
or timeline values exist.
2020-02-25 09:55:41 +09:00
Ian Barwick
eaee7145f6 repmgrd: improve logging
Note node name and type when logging primary node visibility.
2020-02-24 15:33:03 +09:00
Ian Barwick
2bb89d252b doc: a witness server is also relevant for primary visibility consensus checks
Clarify documentation and example to make it clear that a witness
server, if present, is also used for primary visibility consensus
checks.
2020-02-24 15:25:15 +09:00
Ian Barwick
e782f2d949 repmgrd: improve logging
For easier log analysis, state which node is the current primary.
2020-02-20 13:06:41 +09:00
Ian Barwick
5d058dc371 doc: link to latest blog article from README 2020-02-19 09:30:57 +09:00
Ian Barwick
089b3ecb8b doc: note PostgreSQL 9.4 EOL 2020-02-14 11:17:06 +09:00
Ian Barwick
b4af80fdec Add optional check for unsupported future PostgreSQL releases
This is for backbranches to prevent them running against newer
PostgreSQL versions with which they are not compatible, for example
4.4.x with PostgreSQL 12 and later.
2020-02-14 10:43:19 +09:00
laixiong
cb7bbda021 standby switchover: check remote's registered repmgr.conf
Check the demotion candidate's registered repmgr.conf file can be found.

If the configuration file has been deleted or moved, previously the
resulting error message would have been a confusing reference to
an incorrectly configured data directory; by explicitly checking for the
expected configuration file, we can make troubleshooting easier.

Original patch by laixiong <yin.zhb@gmail.com> (GitHub #615), modified
by Ian Barwick.
2020-02-05 15:56:57 +09:00
Ian Barwick
9cf4616af1 standby switchover: mark successful if standby attaches later
Handle corner case where standby (demotion candidate) doesn't
attach during the main check cycle, but does at the final check,
where we'll want to mark the operation as successful.
2020-02-05 14:29:30 +09:00
Ian Barwick
6f01c54620 repmgr: improve "standby switchover" completion checks
There were some corner cases where "repmgr standby switchover"
would erroneously report a successful switchover, even if the
demotion candidate had not reattached to the promotion candidate.

Also improve the logging in various places to make it clearer
what is happening on which node.
2020-02-04 15:38:10 +09:00
Ian Barwick
7ed0a99d70 Make code to check standby join status available globally
This makes it possible to check the standby join status from another
node, e.g. the promotion candidate during a switchover operation.
2020-02-04 12:52:55 +09:00
Ian Barwick
e2a362a171 "node rejoin": check for available replication slots on the rejoin target
"standby follow" did this already, but "node rejoin" didn't.
2020-02-03 17:03:20 +09:00
Ian Barwick
cd7f36a6fd Add general check function "check_replication_slots_available()"
Make the code previously only used by "standby follow" generally
available - we'll want to use this from "node rejoin" as well.

While we're at it, when reporting failure due to lack of free
replication slots, report the current value of "max_replication_slots".
2020-02-03 16:43:55 +09:00
Ian Barwick
ab9c84c655 Report error code on follow/rejoin failure due to non-available slot
Previously, if "repmgr standby follow" or "repmgr node rejoin" failed
due to a replication slot not being available, no error code was
returned.
2020-02-03 15:03:31 +09:00
Ian Barwick
0141bc2be7 standby switchover: display "shutdown_check_timeout" value in --dry-run mode
It's useful to be aware of this setting.
2020-01-30 10:30:18 +09:00
Ian Barwick
4d6cff6c42 doc: link to latest blog article 2020-01-30 10:24:12 +09:00
Ian Barwick
84b824d86a Add missing values to action_name() 2020-01-29 15:32:40 +09:00
Ian Barwick
a7689ecd78 standby switchover: fix repmgr execution confirmation in --dry-run mode
Inexplicably, "localhost" was hard-coded, rather than the remote host
name.
2020-01-29 14:04:37 +09:00
Ian Barwick
ef30892250 standby switchover: improve wording of pending archive file messages 2020-01-28 13:40:59 +09:00
Ian Barwick
3ae6691d34 doc: minor clarifications to Debian package info 2020-01-24 10:36:46 +09:00
Ian Barwick
bd8eb82fb9 doc: update repository links to https 2020-01-24 10:29:40 +09:00
Ian Barwick
4d4ed3bcd6 Remove BDR 2.x support
The BDR 2.x support was conceptual only and was never used in
production. As BDR 2.x will be EOL'd shortly, there is no risk it will
be needed.
2020-01-16 09:52:42 +09:00
Ian Barwick
7fdf2f1778 Update copyright notices to 2020 2020-01-13 14:06:20 +09:00
Ian Barwick
46222cc0ae doc: note availability of RHEL 8 packages 2020-01-07 09:44:47 +09:00
Renaud Fortier
afa88f0514 Update repmgr.conf.sample
Add empty single quotes to promote_command and follow_command
2019-12-16 12:27:59 +09:00
Ian Barwick
647c0c879e repmgrd: fix configuration file reload handling
Usually repmgrd requires the parameters "promote_command" and
"follow_command" to be present in the configuration file. These are
not required if "failover=manual", but the configuration sanity check
following receipt of SIGHUP was not checking that.

Addresses issue reported in GitHub #614.
2019-12-16 11:40:05 +09:00
Ian Barwick
3f5d2f6ee9 standby follow: don't attempt to delete slot if new upstream is same as current
An attempt will be made to delete an existing replication slot on the
old upstream node (this is important during e.g. a switchover operation
or when attaching a cascaded standby to a new upstream). However if the
standby is currently attached to the follow target node anyway, the
replication slot should never be deleted.
2019-12-10 15:56:00 +09:00
Ian Barwick
ab6e5ceab3 doc: add reference to "ssh_options"
This is listed in "repmgr.conf.sample" but not the main documentation.
2019-11-25 10:17:31 +09:00
Ian Barwick
eb1d5c4e93 doc: link PgBouncer fencing document from main docs 2019-11-21 09:53:53 +09:00
Ian Barwick
b3c09c48bf doc: document "tablespace_mapping" parameter.
This was previously only mentioned in "repmgr.conf.sample".
2019-11-20 16:52:35 +09:00
Ian Barwick
e2ffeac67d doc: add missing single quotes in repmgr.conf.sample 2019-11-20 15:13:12 +09:00
Ian Barwick
4ed72eb901 Minor formatting fix 2019-11-20 15:13:01 +09:00
Ian Barwick
f158e35c13 Make variable local to code block 2019-11-20 10:13:55 +09:00
Ian Barwick
21475b9c70 doc: update pgbouncer fencing example
Add "--log-to-file" to "repmgr standby promote", per recommended practice.
2019-11-19 21:57:17 +09:00
Ian Barwick
95ee576052 doc: fix minor punctuation typo 2019-11-11 15:52:15 +09:00
Ian Barwick
ac753c2ba1 doc: ensure various repmgr.conf values are quoted appropriately 2019-11-08 11:54:31 +09:00
Ian Barwick
ce85ba6df5 doc: update repmgr.conf sample
Convert recovery.conf references to generic configuration descriptions,
and fix spacing.
2019-11-08 11:54:27 +09:00
Ian Barwick
c3aba173ea doc: clarify Barman configuation
Per confusion noted in GitHub #602.
2019-11-07 14:26:57 +09:00
Ian Barwick
93acdcfda2 doc: add single quotes to "barman_config" example.
Mandatory from repmgr 5.x.
2019-11-07 14:23:04 +09:00
Ian Barwick
25fb24eee4 Minor cleanup in repmgr-client.c 2019-10-30 16:58:30 +09:00
Ian Barwick
220ec7fc96 Minimize user permissions requirements for replication slots
Enable operations which create or drop replication slots to be carried
out with the minimum necessary user permissions, i.e. a user with the
REPLICATION attribute.

This can be the repmgr user, or a dedicated replication user.
In the latter case, if the dedicated replication user is only
permitted to make replication connections, the streaming
replication protocol is used to create/drop slots.

Implements part of GitHub #536.
2019-10-30 15:51:15 +09:00
Ian Barwick
1a9bcddccd standby clone: fix typo in log message 2019-10-28 14:08:48 +09:00
Ian Barwick
f0693271d3 Clean up replication slot creation/deletion functions 2019-10-25 14:31:11 +09:00
Ian Barwick
c23162e787 doc: note superuser requirement for "repmgr primary register" 2019-10-25 12:43:39 +09:00
Ian Barwick
b8f323af5a primary register: improve debug log output 2019-10-25 12:43:39 +09:00
Ian Barwick
63217e436a doc: note permission requirements for "repmgr standby (promote|switchover)
Per issues noted in GitHub #595.
2019-10-25 12:43:39 +09:00
Ian Barwick
45b9002e5b Modify function "is_replication_role()" to reference "pg_roles"
"pg_authid" is restricted to superusers.
2019-10-24 16:57:50 +09:00
Ian Barwick
52f9cd3bae Rename "_do_create_recovery_conf()" to "_do_create_replication_conf()"
As of PostgreSQL 12, the functionality is no longer specific to the
recovery.conf file.
2019-10-24 15:12:39 +09:00
Ian Barwick
cc540a54e5 Add functions for slot creation via the streaming replication protocol 2019-10-24 10:05:32 +09:00
Ian Barwick
9083f26990 Clarify usage of log_db_error() function 2019-10-24 10:04:15 +09:00
Ian Barwick
5405ae7100 doc: note which repmgr versions are supported in the compatibility matrix 2019-10-24 09:46:28 +09:00
Ian Barwick
aa2674e284 Fix typo in placeholder date 2019-10-24 09:45:12 +09:00
Ian Barwick
b007d5ed4b doc: update README
Link to compatibility matrix, support section.
2019-10-24 09:42:23 +09:00
Ian Barwick
63ddc2d39e Let _establish_db_connection() work with replication connections
Previously this was limited to establish_db_connection_by_params().
2019-10-23 14:45:44 +09:00
Ian Barwick
9976e646cd doc: update README 2019-10-23 13:45:34 +09:00
Ian Barwick
dc11330d58 Rename replication slot create/drop functions
Append "_sql" to the respective function names, as we'll later be
creating equivalent functions which use the replication protocol
so need a way to distinguish between them.
2019-10-23 13:43:09 +09:00
Ian Barwick
be494f0d5f standby clone: minimize requirement to check upstream data directory location
repmgr has always insisted on determining the upstream's data directory
location, which requires superuser permissions (or from PostgreSQL 10,
membership of the default role "pg_read_all_settings").

Knowledge of the data directory location was required to implement rsync
cloning (now deprecated), but with pg_basebackup the minimum permission
requirement is now only a normal user with access to the repmgr metadata
and a user with replication permissions. The ability to determine the
data directory location is only required if the user specifies the
--copy-external-config-files option, which needs to be able to determine
the data directory to work out which configuration files are located
outside it.

This patch makes it possible to clone a standby with minimum
permissions, with appropriate checks for available permissions if
--copy-external-config-files is provided.

Implements part of GitHub #536 and addresses issue raised in #586.
2019-10-23 10:46:40 +09:00
Ian Barwick
d7fd55be99 Update HISTORY 2019-10-18 16:47:28 +09:00
Ian Barwick
0574279ccb Ensure postgresql.auto.conf is created with correct permissions 2019-10-18 16:45:46 +09:00
Ian Barwick
b74f965f54 standby clone: rename --recovery-conf-only to --replication-conf-only
A more generic option name to cover pre- and post-Pg12 replication
configuration methods.

--recovery-conf-only is retained as an alias for backwards
compatibility.
2019-10-18 14:44:57 +09:00
Ian Barwick
b9e360d5b8 Tweak "repmgr standby --help" output not to mention recovery.conf
Use the more generic "replication configuration" to cover Pg12
and later.
2019-10-18 14:09:54 +09:00
Ian Barwick
047249e980 doc: expand section about requesting support 2019-10-18 11:58:13 +09:00
Ian Barwick
14f46b076e doc: add link to blog entry about Pg12 replication configuration changes 2019-10-18 11:57:52 +09:00
Ian Barwick
52abe309df Add function is_replication_role() 2019-10-17 17:13:18 +09:00
Ian Barwick
f45b9d7024 Call check_93_config() directly from check_upstream_config() 2019-10-16 16:57:53 +09:00
Ian Barwick
de67fa2441 standby clone: simplify data directory check
Now we no longer care about the upstream's data directory, and
normally expect to find the data directory in repmgr.conf, we
can just exit with an error in the corner case that no repmgr.conf
is provided and no data directory specified with -D/--pgdata.
2019-10-16 16:06:26 +09:00
Ian Barwick
5f6d970fd9 standby clone: update code comment
Follow-up to 0dce03a
2019-10-16 15:45:20 +09:00
Ian Barwick
0dce03a5f8 standby clone: don't query upstream's data directory
In early repmgr versions, this used to be a requirement for cloning
via rsync, and/or as a fallback location if the user didn't supply
a data directory to clone into. However as rsync cloning has been
deprecated, and the data directory must be specified in repmgr.conf,
this is no longer required, and removing it simplifies user privilege
requirements.

Note that it is still possible to explicitly provide a target data
directory with -D/--pgdata, though this is primarily useful for
the niche use case where repmgr is used as a convenience tool to
clone a node which is not intended to become part of a repmgr
cluster.

This is part of the implementation of GitHub #536 for the minimizing
of user privilege requirements.
2019-10-16 13:21:29 +09:00
Ian Barwick
5d81e03d2d Bump master branch to 5.1dev 2019-10-16 11:04:37 +09:00
Ian Barwick
fdb61a1dea Change version number from 5.0 to 5.0.0
Previous initial "major" releases were two-element only (e.g. 4.4);
beginning from repmgr 5 we want to ensure all version numbers have
three elements, for general consistency, including the generation
of package names.
2019-10-16 10:45:54 +09:00
Ian Barwick
8a38188c47 doc: split notes about PostgreSQL 9.3 and 9.4 support into a new subsection 2019-10-15 10:47:12 +09:00
Ian Barwick
5dcca6b053 doc: add note about 4.x development policy 2019-10-15 10:47:09 +09:00
Ian Barwick
a0591afb1e doc: add repmgr 5.0 release date 2019-10-15 10:29:52 +09:00
Ian Barwick
af1c889bc3 Bump version to 5.0 2019-10-14 15:10:40 +09:00
Ian Barwick
2304584679 Fix handling of upstream node change check
repmgrd has a check to see if the upstream node has unexpectedly
changed, e.g. if the repmgrd service is paused and the PostgreSQL
instance has been pointed to another node.

However this check was relying on the node record on the local node
being up-to-date, which may not be the case immediately after a
failover, when the node is still replaying records updated prior
to the node's own record being updated. In this case it will
mistakenly assume the node is following the original primary
and attempt to restart monitoring, which will fail as the original
primary is no longer available.

To prevent this, we check against the node's record on the upstream
node.

Addresses issue noted in GitHub #587 and #588.
2019-10-14 12:28:04 +09:00
Ian Barwick
4aaa24a5f8 Update configuration file conversion script
Ensure output is quoted.
2019-10-08 10:59:20 +09:00
Ian Barwick
ea29af2e68 Remove mistakenly added file 2019-10-08 10:33:27 +09:00
Ian Barwick
7053ed5b51 doc: update links to Barman documentation 2019-10-08 10:30:41 +09:00
Ian Barwick
a845d7126d doc: minor updates to "repmgr standby clone" reference
- remove references to repmgr 4.0.4 (present because feature
  was added in a minor release, but that's a long time ago)
- note configuration is appended to postgresql.auto.conf
2019-10-08 10:21:26 +09:00
Ian Barwick
1c317059cd doc: clarify use of --recovery-conf-only 2019-10-08 10:03:44 +09:00
Ian Barwick
dcf5bfb649 doc: fix minor formatting error 2019-10-08 09:48:04 +09:00
Ian Barwick
dbd3d34c89 doc; update repmgr.conf.sample
Note new PostgreSQL-style parsing and add link to documentation.
2019-10-07 18:28:16 +09:00
Ian Barwick
f3c3320a9c doc: update examples in quickstart guide 2019-10-07 18:27:38 +09:00
Ian Barwick
cfc5bde219 doc: update repmgr.conf samples in Barman section
From repmgr 5.x we really need to quote all the things.
2019-10-07 12:05:26 +09:00
Ian Barwick
ea57269569 doc: improve instructions for cloning from Barman 2019-10-07 11:56:40 +09:00
Ian Barwick
b885337abc Minor code formatting fix 2019-10-07 10:48:35 +09:00
Ian Barwick
e8b5b92893 doc: improve Barman standby clone example 2019-10-03 15:52:32 +09:00
Ian Barwick
02bdcf657f doc: add link to FAQ section about 3rd party package compatibilty 2019-10-03 15:23:57 +09:00
Ian Barwick
405f70f769 doc: clarify barman-cli package usage
As of Barman 2.8, the barman-cli package has been merged with the core
Barman code, so is only requires an explicit mention for Barman 2.0 ~ 2.7.
2019-10-03 14:35:45 +09:00
Ian Barwick
577ca35de5 doc: remove reference to Barman 1.x.
Barman 1.x is very outdated and should no longer be used anyway.
2019-10-03 14:25:17 +09:00
Martín Marqués
a557f2d69e Typo in the documentation of the repmgrd configuration
Signed-off-by: Martín Marqués <martin.marques@2ndquadrant.com>
2019-10-01 09:44:30 -03:00
Ian Barwick
1196821457 doc: update FAQ
Note pg_monitor default role as well, and link to relevant section
in the PostgreSQL documentation.
2019-10-01 10:29:44 +09:00
Ian Barwick
c1d464f3da doc: add FAQ entry about 3rd-party PostgreSQL packages 2019-10-01 10:07:25 +09:00
Ian Barwick
4646bbc289 doc: standardize doc formatting
Indent with two spaces instead of one.
2019-10-01 09:44:04 +09:00
Ian Barwick
bb9a0c2297 doc: update FAQ
Add note about repmgr 5 in the "What's the difference between the repmgr
versions?" item.
2019-10-01 09:41:49 +09:00
Ian Barwick
1ed8b1067a Prevent use of backend string functions
From PostgreSQL 12, port.h forcibly redefines printf() et al to use
the versions defined by PostgreSQL (pg_printf() et al). As this
causes linking issues in build environments which build pre-Pg12
versions against Pg12's libpq, ensure relevant macros defined
in port.h are undefined.
2019-09-26 12:47:51 +09:00
Ian Barwick
a502b2cf96 Move function parse_repmgr_version() to a more appropriate location 2019-09-24 13:14:03 +09:00
Ian Barwick
8e6d111f32 Refactor remote_command() function
Use dynamic rather than fixed buffer to generate the command string.
2019-09-24 13:14:03 +09:00
Ian Barwick
50d4cee877 doc: link to GitHub release page 2019-09-24 11:37:25 +09:00
Ian Barwick
db99e98236 doc: note flex required for source builds
From 5.0 onwards.
2019-09-24 11:34:24 +09:00
Ian Barwick
10f00b8822 repmgr: pass explicitly provided log level when executing repmgr remotely
This makes it possible to return log output when executing repmgr
remotely at a different level to the one defined in the remote
repmgr's repmgr.conf.

This is particularly useful when DEBUG output is required.
2019-09-17 15:38:43 +09:00
Ian Barwick
98e96f4375 doc: clarify configuration file changes 2019-09-17 13:01:03 +09:00
Ian Barwick
8489fd061f doc: update release notes 2019-09-17 11:19:05 +09:00
Ian Barwick
56aae22b6c doc: update release notes 2019-09-17 11:00:04 +09:00
Ian Barwick
bce039f336 doc: add clarifications to "Standby disconnection on failover" 2019-09-05 18:00:56 +09:00
Ian Barwick
19190153a0 doc: clarify prerequisites for executing the "repmgr service" commands
Note node accessibility requirements on each command's reference
page.
2019-08-30 12:07:37 +09:00
Ian Barwick
b1c6418e8d doc: expand "see also" links for "repmgr (service|daemon)" commands 2019-08-30 11:51:32 +09:00
Ian Barwick
12491c6aa1 doc: add note about starting/stopping repmgrd on individual nodes 2019-08-30 11:51:11 +09:00
Ian Barwick
d5b806eeff Fix pg_control handling for PostgreSQL 12
"FullTransactionId" is not present in earlier versions, so we'll
have to #ifdef that out for those.

We should probably add more elegant checks to ensure that repmgr
is being executed against the PostgreSQL version it was built against.
In a normal production environment that will be the case as the
matching package will have been installed, so version mismatches
don't usually occur.

Note that while currently most aspects of the repmgr client are
compatible across PostgreSQL versions, the repmgrd code is very
version specific, so version specificity is a given anyway.
2019-08-29 17:22:01 +09:00
Ian Barwick
37bfe6ee4f Have "make clean" remove "repmgr_version.h" 2019-08-29 17:17:33 +09:00
Ian Barwick
97c21ed907 doc: update package examples
Use recent version numbers where appropriate.
2019-08-29 15:57:49 +09:00
Ian Barwick
3ea47522cd doc: clarify "repmgr daemon (start|stop)" purpose 2019-08-28 16:28:29 +09:00
Ian Barwick
935be3d669 doc: update example PostgreSQL version references to Pg12 2019-08-28 15:52:14 +09:00
Ian Barwick
494444869d doc: updates for repmgr 5.x and PostgreSQL 12 2019-08-28 15:33:01 +09:00
Ian Barwick
677a94513e repmgr: note that --dry-run is not effective with "repmgr service status" 2019-08-28 15:14:35 +09:00
Ian Barwick
931da14df1 Rename some "repmgr daemon ..." commands to "repmgr service ..."
"repmgr daemon" can be interpreted to mean the commands affect the local
daemon process only. Rename the commands which affect the entire cluster
to "repmgr service ...".

The "repmgr daemon ..." form of the affected commands is retained for backwards
 compatibility.
2019-08-28 14:58:11 +09:00
Ian Barwick
3e812f6e91 repmgrd: always emit NOTICE when attempting to follow a new primary
Previously, if a standby's repmgrd was looping in degraded monitoring
mode looking for a new primary to follow, once a new primary was
detected the follow command would be executed without any prior
logging at non-DEBUG log levels.
2019-08-26 16:02:41 +09:00
Ian Barwick
ffc7b7817b doc: update HISTORY
Note PostgreSQL support.
2019-08-22 15:42:29 +09:00
Ian Barwick
fb6352735a The next major release will be 5.0.
4.5 was a placeholder release number in case a major release was required
prior to the release of Pg12.
2019-08-22 15:15:56 +09:00
Ian Barwick
f122c44a77 Fix debugging output 2019-08-21 15:52:08 +09:00
Ian Barwick
b4e6922a26 doc: add further note about configuration file changes 2019-08-20 16:36:58 +09:00
Ian Barwick
6e200d32a4 doc: add note about max_wal_senders in Pg12 and later 2019-08-20 11:17:36 +09:00
Ian Barwick
507b27c05d Mark set_repmgrd_pid() as "RETURNS NULL ON NULL INPUT"
When unsetting the PID, we'll want to set the pidfile to NULL rather
than an empty string.
2019-08-19 20:15:30 +09:00
Ian Barwick
28f4536372 repmgrd: fix pidfile handling at shutdown 2019-08-19 17:55:18 +09:00
Ian Barwick
2ec761a979 doc: update "repmgr standby clone" reference for PostgreSQL 12
Mainly replace "recovery.conf" with the more generic "replication
configuration".
2019-08-19 10:40:42 +09:00
Ian Barwick
b5225a2662 Support --create-recovery-conf in Pg12 2019-08-19 10:40:38 +09:00
Ian Barwick
d5ed38f573 Make "standby follow" work in Pg12 2019-08-19 10:40:35 +09:00
Ian Barwick
2a37e28304 write standby.signal 2019-08-19 10:40:31 +09:00
Ian Barwick
9eb6ce52b4 Write replication configuration for Pg12 and later 2019-08-19 10:40:27 +09:00
Ian Barwick
9e072c6773 Update code comment with list of options for "standby clone" 2019-08-15 18:11:47 +09:00
Ian Barwick
72daa38baa durable_rename() only available externally from Pg10 2019-08-14 20:28:05 +09:00
Ian Barwick
f5044465cb Add function to safely modify postgresql.auto.conf
This is required for PostgreSQL 12 and later.
2019-08-14 16:57:42 +09:00
Ian Barwick
4ebc43fd63 Clean up variable usage in do_node_status()
Variable with the same name existed both at function level and within
local code blocks.
2019-08-14 14:15:41 +09:00
Ian Barwick
a1775237d4 Update comment
Deprecated command line option --data-dir was removed in commit 5ca0b57,
but a comment still referred to it.
2019-08-14 14:12:09 +09:00
Ian Barwick
94ba635811 Define our own PG_AUTOCONF_FILENAME 2019-08-13 16:48:44 +09:00
Ian Barwick
c0f3990973 Use appendPQExpBufferStr where appropriate 2019-08-13 16:32:40 +09:00
Ian Barwick
d0f5ee1851 doc: mention not to use --siblings-follow in the repmgrd promote command
This is noted on the "repmgr standby promote" page but needs repeating
on the repmgrd configuration page.
2019-08-13 11:49:52 +09:00
Ian Barwick
75c0987e79 repmgrd: emit node name when reporting follow target attach error
This is consistent with other error messages.
2019-08-13 11:02:52 +09:00
Ian Barwick
68be86349b Add function to parse version string returned by "repmgr --version" 2019-08-08 13:47:19 +09:00
Ian Barwick
666c6f5140 "standby clone": improve error messages related to extension status
Previously repmgr would emit the "repmgr extension not found on source node"
which depending on context is somewhat misleading, as it may exist
but not be installed, or the user may be attempting to clone from the
wrong database.
2019-08-07 16:41:27 +09:00
Ian Barwick
3df65d0eb3 Simplify pg_has_role() call
Specifying CURRENT_USER is superfluous here.
2019-08-07 14:43:56 +09:00
Ian Barwick
38b373e6df "node check": check role membership when trying to read pg_settings
From PostgreSQL 10, a member of the default roles "pg_monitor" and/or
"pg_read_all_settings" can read pg_settings without requiring superuser
privileges.

Previously, a hint was being emitted about making the repmgr user a
member of one of those groups, but no check for membership was being
made, meaning the check could only be run by a superuser.
2019-08-07 14:26:48 +09:00
Ian Barwick
10870503d1 Add missing field in init_replication_info()
"upstream_node_id" was not being initialised.
2019-08-06 21:24:37 +09:00
Ian Barwick
5ca0b57d0c Remove command-line options deprecated since repmgr 3.3
The following options have long since been deprecated, and any attempt
to use them results only in a warning that they are no longer valid:

  --data-dir
  --no-conninfo-password
  --recovery-min-apply-delay
2019-08-05 16:26:12 +09:00
Ian Barwick
7d20aea606 Fix typo in comment 2019-08-01 15:20:44 +09:00
Ian Barwick
424d92e311 doc: fix typo 2019-08-01 14:14:37 +09:00
Ian Barwick
8d55cab25e Convert configuration file parsing to use flex
Previously, repmgr was using a very simple ad-hoc string-based parser,
which had various limitations and allowed configuration files to be
created in a way which could cause confusion and/or unexpected
behaviour.

For example, it accepted strings enclosed in single quotes, but treated
strings enclosed in double quotes literally. A node_name defined thusly:

    node_name="somenode"

would result in the literal value '"somenode"' being used, which could
lead to unobvious errors along the lines of:

    no record found for ""somenode""

The configuration file parser has been adapted from the one used by
PostgreSQL itself, so behaves more-or-less identically (though some
functions such as file inclusion are not supported in repmgr).

This makes configuration parsing more robust and consistent;
additionally, error reporting will be more precise.

Note this does mean that some repmgr.conf items previously accepted
as valid by repmgr will now be rejected; in particular this includes
strings containing spaces which are not enclosed in single quotes.
2019-08-01 10:17:20 +09:00
Ian Barwick
ab7e527af8 More sed tweakage 2019-07-26 21:25:16 +09:00
Ian Barwick
9274fdc6ba Use more portable sed invocation
Works on FreeBSD too.
2019-07-26 20:13:15 +09:00
Ian Barwick
018394faa2 Define PG_ACTUAL_VERSION_NUM
Due to [insert reason here], in the Debian package build process (and
only there), when building frontend code PG_VERSION_NUM appears to be
from the newest libpq-dev version installed, and does not necessarily
match the version of the server the code is being built against.

To work around this distribution-specific package build issue, we'll
define our own substitution variable which is taken from the value
provided in Makefile.global.
2019-07-26 18:12:07 +09:00
Ian Barwick
532a5207e2 More portable usage of sed in Makefile 2019-07-26 18:08:16 +09:00
Ian Barwick
5bf9605286 Revert "Convert configuration file parsing to use flex"
This reverts commit c6ca183247.

Backing out this patch for now as the Debian build system doesn't
seem to like it, even though it builds just fine on Debian itself.
2019-07-18 10:19:18 +09:00
Ian Barwick
215f4bb9d9 doc: add note about parallel restore from Barman 2019-07-18 09:23:09 +09:00
Ian Barwick
75a381ed27 doc: add reminder to update release date in version header 2019-07-09 11:37:50 +09:00
Ian Barwick
a26b7e29a0 Add release date placeholder 2019-07-09 11:33:09 +09:00
Ian Barwick
d09214b83d doc: define entity &releasedate;
This should be used wherever we need to show the latest release
date.

Don't use this in the release notes however, as it will be easy to
forget to update it when adding notes for a new release.
2019-07-09 11:32:43 +09:00
Ian Barwick
822abbbe5b doc: update compatibility matrix
Use &repmgrversion; entity to generate the current version number and
prevent document bitrot.

Also define a "release-current" ID attribute for ease of linking to
the current release notes.

Per notification from the mailing list.
2019-07-09 11:07:04 +09:00
Ian Barwick
d51704e272 doc: update release notes 2019-07-04 11:21:37 +09:00
Ian Barwick
c6ca183247 Convert configuration file parsing to use flex
Previously, repmgr was using a very simple ad-hoc string-based parser,
which had various limitations and allowed configuration files to be
created in a way which could cause confusion and/or unexpected
behaviour.

For example, it accepted strings enclosed in single quotes, but treated
strings enclosed in double quotes literally. A node_name defined thusly:

    node_name="somenode"

would result in the literal value '"somenode"' being used, which could
lead to unobvious errors along the lines of:

    no record found for ""somenode""

The configuration file parser has been adapted from the one used by
PostgreSQL itself, so behaves more-or-less identically (though some
functions such as file inclusion are not supported in repmgr).

This makes configuration parsing more robust and consistent;
additionally, error reporting will be more precise.

Note this does mean that some repmgr.conf items previously accepted
as valid by repmgr will now be rejected; in particular this includes
strings containing spaces which are not enclosed in single quotes.
2019-07-03 12:18:01 +09:00
Ian Barwick
b125628f7b doc: update release notes
Finalize release date.
2019-06-26 15:57:42 +09:00
Ian Barwick
cd550fcd5c doc: clean up release notes
Remove tabs.
2019-06-14 16:53:45 +09:00
Ian Barwick
b6dc8af6c7 doc: fix typo 2019-06-12 16:28:28 +09:00
Ian Barwick
09979eaa91 note that "standby follow" requires a primary to be available
While it's technically possible to have a standby follow another
standby while the primary is not available, repmgr will not be able
to update its metadata, which will cause Confusion and Chaos.

Update the documentation to make this clear, and provide a more helpful
error message if this situation occurs. The operation previously
failed anyway, but with an unhelpful message about not being able to
find a node record.
2019-06-11 15:14:17 +09:00
Ian Barwick
3469152314 doc: document optional configuration settings 2019-06-10 14:08:34 +09:00
Ian Barwick
3bf308509f doc: add missing space 2019-06-10 09:02:11 +09:00
Ian Barwick
01852f7e3a doc: improve repmgr.conf settings documentation 2019-06-07 12:48:36 +09:00
Ian Barwick
36a09a5c4b doc: improve configuration documentation 2019-06-07 12:16:04 +09:00
Ian Barwick
7180e2bed7 Canonicalize the data directory path when parsing the configuration file
This ensures the provided path matches the path PostgreSQL reports as its
data directory.
2019-06-07 09:48:01 +09:00
Ian Barwick
6aca764d5e Fix extension version number query 2019-06-06 12:46:12 +09:00
Ian Barwick
341421f8e0 standby follow: remove some ineffective code
For some reason we were taking the trouble to extract an appliction_name
from the local node's conninfo, but this was being subsequently overwritten
with the node name (which is what we want anyway).
2019-06-06 12:12:33 +09:00
Ian Barwick
f5d29f6591 doc: update release notes 2019-06-06 11:30:30 +09:00
Ian Barwick
c0ea5ffa04 Ensure parsed value of --upstream-conninfo is written to recovery.conf
Previously it was being parsed (a step which ensures any "application_name"
set by the caller is changed to the node name), but the original string
was being copied to "primary_conninfo" anyway.
2019-06-06 11:30:24 +09:00
Ian Barwick
aa44c8abf1 Add .sql extension files for 4.5 2019-06-04 15:58:22 +09:00
Ian Barwick
456a95f159 Bump master branch to 4.5dev
Note that the next release is intended to be 5.0 to coincide with the
release of PostgreSQL 12; 4.5 is currently a placeholder in case we
need to push out a feature release before then.
2019-06-04 14:26:48 +09:00
Ian Barwick
703a483e81 Remove redundant comment in .sql files 2019-06-04 13:46:10 +09:00
Ian Barwick
d893ce227b repmgrd: optionally exclude/include witness server from child node checks 2019-06-03 16:04:54 +09:00
Ian Barwick
e8731f8159 doc: update child node monitoring documentation 2019-06-03 16:04:51 +09:00
Ian Barwick
20d710e34c doc: update filename referenced in code comment 2019-06-03 15:30:02 +09:00
Ian Barwick
7e8710b1e9 doc: remove redundant entity definitions 2019-06-03 15:29:08 +09:00
Ian Barwick
19e8387d8f doc: remove mistakenly committed .sgml file 2019-05-30 19:58:06 +09:00
Ian Barwick
b5ff2ec120 repmgrd: update log text 2019-05-30 16:08:04 +09:00
Ian Barwick
0a4072b8f7 witness (un)register: add event details
Also create an actual event notification for both actions, rather
than just creating the event record.

This is presumably an oversight from the original conversion to
repmgr4 which no-one has noticed before.
2019-05-30 14:41:10 +09:00
Ian Barwick
d4df0055c9 repmgr: use --compact (not --terse) in "cluster events" to hide details column
This is consistent with usage elsewhere.

"--terse" is intended to reduce logging noise.
2019-05-30 14:19:37 +09:00
Ian Barwick
06a83247c9 repmgrd: note node type when logging child node dis/re-connections 2019-05-30 14:06:54 +09:00
Ian Barwick
a6ea1d0fda repmgrd: fix witness node disconnection monitoring 2019-05-30 11:51:50 +09:00
Ian Barwick
9a0994856a doc: note witness node behaviour in child node monitoring 2019-05-30 11:50:31 +09:00
Ian Barwick
45e17223b9 Update variable/field names relating to pg_basebackup's -X option
Now the "xlog nomenclature" Pg versions are fading into the past,
rename things related to handling pg_basebackup's -X option
(was: --xlog-method, now: --wal-method) to start with "wal_"
rather than "xlog_".

This is a cosmetic change for code clarity.
2019-05-30 09:32:06 +09:00
Ian Barwick
9085ca46a8 doc: update release notes 2019-05-28 15:38:19 +09:00
Ian Barwick
9114299223 Tweak log output if attempted to register witness on primary cluster 2019-05-28 14:58:32 +09:00
John Naylor
519df66197 Disallow witness on primary cluster 2019-05-28 14:40:15 +09:00
Ian Barwick
d1e708454f Fix fwrite() result check 2019-05-28 14:37:36 +09:00
Ian Barwick
d54f0d66fb Free palloc'd StringInfoData data 2019-05-28 13:04:44 +09:00
Ian Barwick
c153e2fc02 standby clone: improve --dry-run output
Log positive check results as an additional confirmation that the
upstream configuration appears to be correct.
2019-05-28 00:54:39 +09:00
Ian Barwick
44a39760a1 standby clone: improve source node replication connection check
Previously, the check was attempting to make replication connections
to the source node, and if these were failing, inferring that
insufficient walsenders were available.

However it's quite likely that the connections are refused due to
insufficient user connection permissions. So before performing
the connection check, query the number of potentially available
walsenders on the source node and compare it with the number
required (either 1 or 2) - if insufficient, exit with error and
hint about increasing "max_wal_senders".

Once we've established sufficient walsenders are available, inability
to connect is most likely related to permissions issues on the source
node.
2019-05-28 00:11:53 +09:00
Ian Barwick
b959f771c1 Improve naming/usage of node record variables in "standby clone"
Make it clearer we're dealing with the upstream node record.

Also avoid "overloading" the upstream record when checking for an
existing record with the same node name; this was not technically
a problem but mildly confusing when reading the code.
2019-05-27 23:39:49 +09:00
Ian Barwick
c560dfbbce cluster show: display timeline ID
This helps provide a better picture of the state of the cluster, i.e.
making it more obvious whether there's been a timeline divergence.

This also provides infrastructure for further improvements in cluster
status display and diagnosis.

Note this is only available in PostgreSQL 9.6 and later as it relies
on the SQL functions for interrogating pg_control, which can be executed
remotely. As PostgreSQL 9.5 will shortly be the only community-supported
version without these functions, it's not worth the effort of trying
to duplicate their functionality.
2019-05-27 09:39:19 +09:00
Ian Barwick
df6d160d2e Reformat REPMGR_NODE_COLUMNS macros for readability 2019-05-24 16:39:02 +09:00
Ian Barwick
14b805d650 Makefile: improve documentation targets
- add documentation targets to main Makefile
- ensure clean/maintainer-clean remove all generated documentation files
2019-05-24 14:15:54 +09:00
Ian Barwick
1d46261c24 doc: update appendix "Installing old package versions"
Move legacy 3.x package info to separate section.
2019-05-24 10:03:38 +09:00
Ian Barwick
8ead0042ad Miscellaneous comment and logging cleanup1 2019-05-23 09:31:46 +09:00
Ian Barwick
2bce1b371c doc: fold putative 4.3.1 release notes into 4.4 2019-05-23 09:03:18 +09:00
Ian Barwick
3c8bab97d8 Fix variable declarations 2019-05-22 17:26:34 +09:00
Ian Barwick
c9e85996f5 repmgr: prevent a standby being cloned from a witness server
Previously repmgr would happily clone from whatever server
it found at the provided source server address. We should
ensure that a standby can only be cloned from a node which
is part of the main replication cluster.

This check fetches a list of nodes from the source server,
connects to the first non-witness server it finds, and
compares the system identifiers of the source node and the
node it has connected to. If there is a mismatch, then the
source server is clearly not part of the main replication
cluster, and is most likely the witness server.
2019-05-22 16:52:25 +09:00
Ian Barwick
fa66e72c2f repmgrd: count witness server as child node for connection monitoring purposes
As the witness server does not, by definition, ever have an entry in pg_stat_replication,
we need to check its "attached" status by connecting to the witness server itself
and querying the reported upstream node ID (which should be set by the witness
server repmgrd). If this matches the current primary node ID, we count it as attached.
2019-05-21 15:19:41 +09:00
Ian Barwick
e6195edbca cluster show: warn if unable to connect to witness's upstream
Fix also applies to "daemon status".
2019-05-21 12:35:49 +09:00
Ian Barwick
2326c384c0 cluster show: fix upstream check for witnesses
Fix also applies to "daemon status"
2019-05-21 12:28:32 +09:00
Ian Barwick
074769a090 doc: remove copypasta error 2019-05-20 15:40:03 +09:00
Ian Barwick
10425d6967 doc: rename file endings from .sgml to .xml
As they are now XML files. In PostgreSQL itself they remain with
the .sgml suffix for backwards compatibility, but that's not
important for us.
2019-05-20 15:38:40 +09:00
Ian Barwick
cbaa890a22 doc: document "primary_visibility_consensus" 2019-05-17 14:55:51 +09:00
Ian Barwick
24e1108dba doc: fix incorrect case 2019-05-17 11:15:24 +09:00
Ian Barwick
f03e012c99 cluster show/daemon status: report if node not attached to advertised upstream 2019-05-14 16:15:03 +09:00
Ian Barwick
dd78a16006 Change return type of is_downstream_node_attached() from bool to NodeAttached
This enables us to better determine whether a node is definitively
attached, definitively not attached, or if it was not possible to
determine the attached state.
2019-05-14 15:57:20 +09:00
Ian Barwick
7599afce8b doc: mention minimum PostgreSQL version for building repmgr docs
As-is, it won't build against PostgreSQL 9.4 or earlier, but as 9.4
will be removed from community support later this year, it's not
so critical.
2019-05-14 14:26:03 +09:00
Ian Barwick
8587539adb Fix command line sanity check 2019-05-14 13:27:00 +09:00
Ian Barwick
fca033fb9d cluster show/daemon status: report upstream node mismatches
When showing node information, check if the node's copy of its
record shows a different upstream to the one expected according
to the node where the command is executed.

This helps visualise situations where the cluster is in an
unexpected state, and provide a better idea of the actual state.

For example, if a cluster has divided somehow and a set of nodes are
following a new primary, when running "cluster show" etc., repmgr
will now show the name of the primary those nodes are actually
following, rather than the now outdated node name recorded
on the other side of the split. A warning will also be issued
about the situation.
2019-05-14 13:11:31 +09:00
Ian Barwick
ae44012383 Minor code fixes to "cluster show"/"daemon status" formatting 2019-05-14 11:36:59 +09:00
Ian Barwick
b938f10206 repmgr client: mark some options as deprecated 2019-05-13 15:45:34 +09:00
Ian Barwick
0af732e88f doc: tweaks for PDF generation 2019-05-13 15:42:51 +09:00
Ian Barwick
1d36e34dfd doc: use "--wal-method" as the standard option
and note it's "--xlog-method" for 9.6 and earlier. This matches
practice elsewhere in the documentation.
2019-05-13 09:31:53 +09:00
Ian Barwick
d8e4c54ea4 "standby switchover": add "--repmgrd-force-unpause"
Implements GitHub #559.
2019-05-10 16:04:07 +09:00
Ian Barwick
d43b40c5c6 doc: enable creation of PDF files 2019-05-10 10:50:49 +09:00
Ian Barwick
ecf4bdb431 doc: fix typos in source install instructions
s/llib/lib/g
2019-05-10 10:28:52 +09:00
Ian Barwick
9d7a3e24af doc: tweak Makefile 2019-05-10 10:25:07 +09:00
Ian Barwick
6684822274 doc: update documentation build instructions
Also add an item in the release notes
2019-05-10 10:10:14 +09:00
Ian Barwick
edf3aa6687 doc: restore original stylesheet for now 2019-05-09 16:24:41 +09:00
Ian Barwick
255623004c doc: update link to PostgreSQL documentation 2019-05-09 16:24:37 +09:00
Ian Barwick
04a6bf86f2 doc: update documentation build instructions 2019-05-09 16:24:30 +09:00
Ian Barwick
3804c95019 doc: (re)add single page HTML generation 2019-05-09 16:24:26 +09:00
Ian Barwick
409eb47e2a doc: convert documentation to DocBook XML
This brings the repmgr documentation build system in line with that
used by the main PostgreSQL project, and removed the restriction
that documentation must be built against PostgreSQL 9.6 or earlier.

Main formatting changes are:

 - convert empty-element tags (mainly <xref/>)
 - put <indexterm> sections in the correct location
 - correct usage of various entities.
2019-05-09 16:24:21 +09:00
Ian Barwick
1a6f7e979d doc: update release notes 2019-05-07 17:23:03 +09:00
Ian Barwick
6f8fa45604 doc: update release notes 2019-05-07 15:49:54 +09:00
Ian Barwick
5e03627e6c doc: update release notes 2019-05-07 15:29:56 +09:00
Ian Barwick
1c13e57c8b doc: update release notes 2019-05-07 15:27:13 +09:00
Ian Barwick
02245a0014 repmgrd: add missing PQfinish() calls 2019-05-02 18:50:21 +09:00
Ian Barwick
4b37562444 Make it clearer that a witness node counts as a "sibling node"
It's not attached to the primary per-se, but needs to know what
the current primary is in order to correctly synchronise its
copy of the metadata.

Per GitHub #560.
2019-05-02 14:22:53 +09:00
Ian Barwick
8da355eb3f doc: update release notes 2019-05-02 14:00:07 +09:00
Ian Barwick
b8fa71257a doc: update "repmgr standby promote" documentation
Document new "--siblings-follow" option.
2019-05-02 12:06:08 +09:00
Ian Barwick
fed09ecaae standby promote: have former siblings follow new primary 2019-05-02 12:04:49 +09:00
Ian Barwick
98d09f83b5 standby (promote|switchover): improve --dry-run functionality
Continue checks as far as possible.
2019-05-02 12:04:43 +09:00
Ian Barwick
7bbe938e19 Separate promotion candidate walsender/slot checks into discrete functions
For use by "standby promote" as well as "standby follow"
2019-05-02 12:04:40 +09:00
Ian Barwick
63c7f758c3 Remove unneeded server version number variables
No need to pass these around.
2019-05-02 12:04:33 +09:00
Ian Barwick
b9f07f6a91 standby promote: use variable name "local_conn" for the local connection handle
This is consistent with usage in other functions, and makes it easier to
differentiate between the local node connection and the primary connection.
2019-05-02 12:04:26 +09:00
Ian Barwick
e4615b4666 Refactor code for executing --siblings-follow
This will enable provision of "--siblings-follow" to "repmgr standby promote"
2019-05-02 12:04:15 +09:00
Ian Barwick
dbeffbf29a doc: define entity for repmgrd 2019-05-01 10:36:54 +09:00
Ian Barwick
4d1e11533e doc: add missing space in example output 2019-05-01 10:14:18 +09:00
Ian Barwick
52905f1eb3 Standardize on "ID: %i" when logging node IDs
Previously there was a mix of "id:", "node id:", "node ID:" and "node_id:".
2019-04-30 17:07:33 +09:00
Ian Barwick
6c3b4c0db8 Remove unused line 2019-04-30 15:53:24 +09:00
Ian Barwick
89a7261483 Always quote node names in log messages 2019-04-30 15:52:56 +09:00
Frantisek Holop
d7de0a64e0 doc: bit too many e.g.'s
PR #565.
2019-04-30 10:47:45 +09:00
Frantisek Holop
531c4d9853 doc: promote -> follow
PR #565
2019-04-30 10:43:15 +09:00
Ian Barwick
356fe2e640 Fix "repmgr daemon status --csv" output 2019-04-29 20:52:27 +09:00
Ian Barwick
e32acda8c0 standby switchover: ignore nodes which are unreachable and marked as inactive
Previously "repmgr standby switchover" would abort if any node was unreachable,
as that means it was unable to check if repmgrd is running.

However if the node has been marked as inactive in the repmgr metadata, it's
reasonable to assume the node is no longer part of the replication cluster
and does not need to be checked.
2019-04-29 14:35:49 +09:00
Ian Barwick
5f10e68f31 emit warning if "--siblings-follow" provided out-of-context 2019-04-29 14:12:22 +09:00
Ian Barwick
87910a5448 repmgrd: improve logging of sibling node's upstream info
If the sibling node has already been promoted (for whatever
reason, e.g. "repmgr standby promote" was executed manually)
and has exited recovery, the upstream node ID will normally
be reported as "-1", which is correct, but looks confusing in
the logs.

We now only report the upstream node ID if the sibling node
is still in recovery, *or* if it has exited recovery but is
still reporting an extant node ID.
2019-04-29 13:51:17 +09:00
Ian Barwick
ec6266e375 doc: list caveats when monitoring child node disconnection 2019-04-25 17:52:14 +09:00
Ian Barwick
2082a8d3f3 Consolidate some code 2019-04-25 16:04:40 +09:00
Ian Barwick
c8d52bab6d cluster show: fix thinko introduced in commit 9fe2fa2 2019-04-25 15:46:07 +09:00
Ian Barwick
dbbf35ded1 Update HISTORY 2019-04-25 14:59:33 +09:00
Ian Barwick
9fe2fa2daf daemon status: make output more like that of "cluster show"
In particular make any issues with unexpected server state more
obvious.
2019-04-25 14:45:41 +09:00
Ian Barwick
da24896fd5 doc: add child node monitoring example 2019-04-24 16:04:47 +09:00
Ian Barwick
c092ce60a7 doc: document "child_node..." configuration parameters 2019-04-24 14:48:38 +09:00
Ian Barwick
090493ebc9 doc: document "child_node" events 2019-04-24 13:19:00 +09:00
Ian Barwick
8d80267ab1 doc: update "repmgr primary register" output 2019-04-24 13:18:31 +09:00
Ian Barwick
3231b5034d Remove temporary debugging log output 2019-04-24 13:17:52 +09:00
Ian Barwick
5a9175c740 Clarify hints about updating the repmgr extension 2019-04-24 11:37:31 +09:00
Ian Barwick
58b33fb411 Clarify a couple of code comments 2019-04-24 10:55:53 +09:00
Ian Barwick
3129da221e "primary register": ensure --force works if another primary is registered but not running 2019-04-23 16:54:07 +09:00
Ian Barwick
6cbf436bf8 Don't execute "child_nodes_disconnect_command" when repmgrd paused 2019-04-23 14:08:13 +09:00
Ian Barwick
5a90513878 repmgrd: monitor standbys attached to primary
This functionality enables repmgrd (when running on the primary) to
monitor connected child nodes. It will log connections and disconnections
and generate events.

Additionally, repmgrd can execute a custom script if the number of connected
child nodes falls below a configurable threshold. This script can be used
e.g. to "fence" the primary following a failover situation where a new primary
has been promoted and all standbys are now child nodes of that primary.
2019-04-22 16:18:52 +09:00
Ian Barwick
64c4cb81d5 Update pg_control processing for PostgreSQL 12 2019-04-18 09:31:33 +09:00
Ian Barwick
3115face28 doc: add note about when a PostgreSQL restart is required
Per query in GitHub #564.
2019-04-17 09:43:35 +09:00
Ian Barwick
80f66e87c9 Improve string handling during configuration file reload 2019-04-16 11:20:41 +09:00
Ian Barwick
ad28cf95bd standby register: add upstream node ID in event details 2019-04-16 11:01:22 +09:00
Ian Barwick
a0c6cb602f repmgrd: remove duplicate function definition 2019-04-16 10:53:05 +09:00
Ian Barwick
27803f93ff repmgrd: always unset upstream node ID when monitoring a primary 2019-04-12 12:26:39 +09:00
Ian Barwick
1a344d488a Use sizeof() consistently 2019-04-11 23:07:58 +09:00
Ian Barwick
46d17d0933 repmgrd: fix log output 2019-04-11 16:29:08 +09:00
Ian Barwick
6b79e08706 repmgrd: add addiitonal log output in do_election() 2019-04-11 15:46:20 +09:00
Ian Barwick
cd6a55c7cb repmgrd: improve primary visibility consensus check
Exclude sibling nodes which report they're following a different
node. This shouldn't happen, but could.
2019-04-11 15:46:14 +09:00
Ian Barwick
008bd00a59 repmgrd: store upstream node ID in shared memory 2019-04-11 15:46:09 +09:00
Ian Barwick
5a8741199f repmgrd: exclude witness server from followability check 2019-04-11 11:19:12 +09:00
Ian Barwick
dd454a8374 Miscellaneous string handling cleanup
This is mainly to prevent effectively spurious truncation warnings
in recent GCC versions.
2019-04-10 16:18:56 +09:00
Ian Barwick
a9b56d9833 Fix hint message
s/UPGRADE/UPDATE
2019-04-10 12:08:26 +09:00
Ian Barwick
ef47589c6b standby clone: always ensure directory is created with correct permissions
In Barman mode, if there is an existing, populated data directory, and
the "--force" option is provided, the entire directory was being deleted,
and later recreated as part of the rsync process, but with the default
permissions.

Fix this by recreating the data directory with the correct permissions
after deleting it.
2019-04-09 10:58:27 +09:00
Ian Barwick
77b9887d61 standby clone: improve --dry-run behaviour in barman mode
- emit additional informational output
- ensure that provision of --force does not result in an existing
  data directory being modified in any way
2019-04-08 15:12:22 +09:00
Ian Barwick
7631c60933 doc: update release notes 2019-04-08 11:27:25 +09:00
Ian Barwick
a8d560860d Ensure BDR-specific code only runs on BDR 2.x
The BDR support in repmgr is for a specific BDR 2.x use case, and
is not suitable for more recent BDR versions.
2019-04-05 14:37:49 +09:00
Ian Barwick
c338bc9c5e doc: add note about BDR replication type in sample config 2019-04-05 14:37:49 +09:00
Ian Barwick
3c8e42ff15 doc: emphasise that BDR2 support is for BDR2 only 2019-04-05 10:53:23 +09:00
Ian Barwick
be9c6d5fc6 Use correct sizeof() argument in a couple of strncpy calls
Source and destination buffers are however the same length in both cases.

Per GitHub #561.
2019-04-04 10:58:00 +09:00
Ian Barwick
55e79bd0b7 doc: update 4.3 release notes 2019-04-03 15:08:35 +09:00
Ian Barwick
8970a72be9 doc: update README
Link to current documentation version
2019-04-03 11:12:48 +09:00
Ian Barwick
7791abb8f7 doc: add a link to the current documentation from the contents page 2019-04-03 10:54:18 +09:00
Ian Barwick
602e06a8f4 doc: finalize 4.3 release notes 2019-04-02 14:42:06 +09:00
Ian Barwick
84f4c6c979 doc: note that --siblings-follow will become default in a future release 2019-04-02 11:04:36 +09:00
Ian Barwick
67e977592c standby switchover: list nodes which will remain attatched to the old primary
If --siblings-follow is not supplied, list all nodes which repmgr considers
to be siblings (this will include the witness server, if in use), and
which will remain attached to the old primary.
2019-04-02 10:46:59 +09:00
Ian Barwick
b1cd7e7edf doc: update quickstart guide
Improve sample PostgreSQL replication configuration, including
links to the PostgreSQL documentation for each configuration item.

Also set "max_replication_slots" to the same value as "max_wal_senders"
to ensure the sample configuration will work regardless of whether
replication slots are in use, though we do still encourage careful
reading of the comments in the sample configuration and the documentation
in general.
2019-04-02 09:27:37 +09:00
Ian Barwick
a564f365c1 Fix default return value in alter_system_int() 2019-04-01 14:50:19 +09:00
Ian Barwick
799ac6d453 Add is_server_available_quiet()
For use in cases where the caller collates node availability information
and doesn't want to prematurely emit log output.
2019-04-01 12:27:30 +09:00
Ian Barwick
57c0ccd477 Improve copying of strings from database results
Where feasible, specify the maximum string length via sizeof(), and
use snprintf() in place of strncpy().
2019-04-01 11:19:58 +09:00
Ian Barwick
aef8e31897 Bump master branch to 4.4dev 2019-03-28 17:24:36 +09:00
Ian Barwick
3d4b81ba2a Handle unhandled error situation in enable_wal_receiver() 2019-03-28 14:52:16 +09:00
Ian Barwick
98d924685b Updae BDR repmgrd to handle node_name as a max 63 char string
Follow-up from commit 1953ec7.
2019-03-28 14:32:52 +09:00
Ian Barwick
79613af8d0 Handle potential NULL return from string_skip_prefix() 2019-03-28 12:45:53 +09:00
Ian Barwick
5e9f202c9a Add missing break 2019-03-28 12:44:50 +09:00
Ian Barwick
e44c048ae2 Update code comment 2019-03-28 12:44:30 +09:00
Ian Barwick
bb42d8cba6 Fix calculation of maximum filename length 2019-03-28 12:40:29 +09:00
Ian Barwick
9d5afeebbc Remove logically dead code 2019-03-28 12:35:41 +09:00
Ian Barwick
fe822a9eea Prevent potential file descriptor resource leak 2019-03-28 12:29:10 +09:00
Ian Barwick
03cd5a6028 Put closedir call in correct location 2019-03-28 12:08:42 +09:00
Ian Barwick
1e1c596446 Add various missing close() calls 2019-03-28 11:32:25 +09:00
Ian Barwick
d43975eb5f Use correct argument for sizeof() 2019-03-28 11:02:50 +09:00
Ian Barwick
ece20f4831 Cast "int" to "long long" 2019-03-28 11:02:25 +09:00
Ian Barwick
e23f5afc5f doc: note valid characters for "node_name"
"node_name" will be used as "application_name", so should only contain
characters valid for that; see:

    https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-APPLICATION-NAME

Not yet enforced.
2019-03-28 10:53:43 +09:00
Ian Barwick
ba1f05ece9 Restrict "node_name" to maximum 63 characters
In "recovery.conf", the configuration parameter "node_name" is used
as the "application_name" value, which will be truncated by PostgreSQL
to 63 characters (NAMEDATALEN - 1).

repmgr sometimes needs to be able to extract the application name from
pg_stat_replication to determine if a node is connected (e.g. when
executing "repmgr standby register"), so the comparison will fail
if "node_name" exceeds 63 characters.
2019-03-28 10:37:57 +09:00
Ian Barwick
73ad689390 standby register: fail if --upstream-node-id is the local node ID 2019-03-27 14:22:55 +09:00
Ian Barwick
e9ece34aeb log_db_error(): fix formatted message handling 2019-03-27 11:00:31 +09:00
Ian Barwick
9dd2f30c72 Use sizeof(buf) rather than hard-coding value 2019-03-27 10:43:49 +09:00
Ian Barwick
9164d3931b repmgrd: clean up PQExpBuffer handling
Unless the PQExpBuffer is required for the duration of the function,
ensure it's always a variable local to the relevant code block. This
mitigates the risk of accidentally accessing a generically named
PQExpBuffer which hasn't been initialised or was previously terminated.
2019-03-26 13:15:25 +09:00
Ian Barwick
801ed2b0c8 repmgrd: don't terminate uninitialized PQExpBuffer 2019-03-26 11:35:45 +09:00
Ian Barwick
e490f35223 doc: fix syntax 2019-03-22 15:43:55 +09:00
Ian Barwick
ec873b0119 doc: update release notes 2019-03-22 15:43:49 +09:00
Ian Barwick
539861cb58 repmgrd: during failover, check if a node was already promoted
Previously, repmgrd assumed that during a failover, there would not
already be another primary node. However it's possible a node was
promoted manually. While this is not a desirable situation, it's
conceivable this could happen in the wild, so we should check for
it and react accordingly.

Also sanity-check that the follow target can actually be followed.

Addresses issue raised in GitHub #420.
2019-03-22 14:06:41 +09:00
Ian Barwick
6f0f338968 standby follow: set replication user when connecting to local node 2019-03-21 16:43:39 +09:00
Ian Barwick
bd26eb3025 standby switchover: don't attempt to pause repmgrd on unreachable nodes 2019-03-21 13:48:59 +09:00
Ian Barwick
9b089b7401 doc: add note about compiling against Pg11 and later with the --with-llvm option 2019-03-21 10:30:00 +09:00
Ian Barwick
314a1e8f4f use a constant to denote unknown replication lag 2019-03-20 17:26:04 +09:00
Ian Barwick
7204a0faf4 doc: consolidate witness server documentation 2019-03-20 16:31:52 +09:00
Ian Barwick
5e775cef16 doc: various improvements to repmgrd documentation 2019-03-20 16:10:03 +09:00
Ian Barwick
7d0caefaee Fix logging related to "connection_check_type"
Also log the selected type at repmgrd startup.
2019-03-20 11:58:18 +09:00
Ian Barwick
7434cc0b8e repmgrd: improve witness node monitoring
Mainly fix a couple of places where "standby" was hard-coded into a log
message which can apply either to a witness or a standby.
2019-03-20 11:47:36 +09:00
Ian Barwick
b84d98fe81 Explictly log PQping() failures 2019-03-20 11:47:32 +09:00
Ian Barwick
46efe57cd0 Improve database connection failure logging
Log the output of PQerrorStatus() in a couple of places where it was missing.

Additionally, always log the output of PQerrorStatus() starting with a blank
line, otherwise the first line looks like it was emitted by repmgr, and
it's harder to scan the error message.

Before:

    [2019-03-20 11:24:15] [DETAIL] could not connect to server: Connection refused
            Is the server running on host "localhost" (::1) and accepting
            TCP/IP connections on port 5501?
    could not connect to server: Connection refused
            Is the server running on host "localhost" (127.0.0.1) and accepting
            TCP/IP connections on port 5501?

After:

    [2019-03-20 11:27:21] [DETAIL]
    could not connect to server: Connection refused
            Is the server running on host "localhost" (::1) and accepting
            TCP/IP connections on port 5501?
    could not connect to server: Connection refused
            Is the server running on host "localhost" (127.0.0.1) and accepting
            TCP/IP connections on port 5501?
2019-03-20 11:47:28 +09:00
Ian Barwick
426759ca8e check_primary_status(): handle case where recovery type unknown 2019-03-18 16:16:54 +09:00
Ian Barwick
39df55c39c Check node recovery type before attempting to write an event record
In some corner cases (e.g. immediately after a switchover) where
the current primary has not yet been determined, the provided connection
might not be writeable. This prevents error messages such as
"cannot execute INSERT in a read-only transaction" generating unnecessary
noise in the logs.
2019-03-18 15:26:16 +09:00
Ian Barwick
f54ff85cfa Remove outdated comment
This was only relevant for repmgr3 and earlier; in repmgr4 the schema
is hard-coded.
2019-03-18 15:19:11 +09:00
Ian Barwick
8ab51c2ae3 Refactor check_primary_status()
Reduce nested if/else branching, and improve documentation.
2019-03-18 15:01:21 +09:00
Ian Barwick
43f28f4097 Clarify calls to check_primary_status()
Use a constant rather than a magic number to indicate non-provision
of elapsed degraded monitoring time.
2019-03-18 14:21:34 +09:00
Ian Barwick
0940185f49 doc: clarify "cluster show" error codes 2019-03-18 10:49:38 +09:00
John Naylor
4f9fc56871 Fix assorted Makefile bugs
1. The target additional-maintainer-clean was misspelled as
maintainer-additional-clean.

2. Add add missing clean targets, in particular sysutils.o, config.h,
repmgr_version.h, and Makefile.global. While at it, use a wildcard
for obj files.

3. Don't delete configure.

4. Remove generated file doc/version.sgml from the repo.

5. Have maintainer-clean recurse to the doc directory.
2019-03-15 16:29:31 +09:00
Ian Barwick
fbdf9617fa doc: update repmgrd example output 2019-03-15 15:43:11 +09:00
Ian Barwick
dfb92df05f doc: miscellaenous cleanup 2019-03-15 14:39:37 +09:00
Ian Barwick
9dd87dd5ce doc: add explanation of the configuration file format 2019-03-15 14:02:42 +09:00
Ian Barwick
a2df69512a doc: update "connection_check_type" descriptions 2019-03-14 15:44:59 +09:00
Ian Barwick
c2206b007a repmgrd: optionally check upstream availability through connection attempts 2019-03-14 15:44:53 +09:00
John Naylor
e06d3de444 Correct some doc typos 2019-03-14 11:58:31 +08:00
Ian Barwick
9d056b2f72 doc: expand "standby_disconnect_on_failover" documentation 2019-03-14 12:08:13 +09:00
Ian Barwick
19bf4d7434 Count witness and zero-priority nodes in visibility check 2019-03-14 11:17:51 +09:00
Ian Barwick
56d9f5b856 Ensure witness node sets last upstream seen time 2019-03-14 10:53:47 +09:00
Ian Barwick
c1d6753081 doc: fix option name typo 2019-03-14 09:32:06 +09:00
Ian Barwick
2b59b4894a doc: expand "failover_validate_command" documentation 2019-03-13 21:10:03 +09:00
Ian Barwick
c3c58df7b9 repmgrd: improve logging output when executing "failover_validate_command" 2019-03-13 21:07:26 +09:00
Ian Barwick
0e2f3e563a doc: various updates 2019-03-13 16:55:32 +09:00
Ian Barwick
8c4421d110 doc: merge repmgrd witness server description into failover section 2019-03-13 16:12:17 +09:00
Ian Barwick
69cb3f1e82 doc: merge repmgrd split network handling description into failover section 2019-03-13 16:12:14 +09:00
Ian Barwick
960acfeb3c doc: merge repmgrd monitoring description into operating section 2019-03-13 16:12:11 +09:00
Ian Barwick
a8d50a5b98 doc: merge repmgrd degraded monitoring description into operation section 2019-03-13 16:12:06 +09:00
Ian Barwick
11e5993bf5 doc: merge repmgrd notes into operation documentation 2019-03-13 16:12:03 +09:00
Ian Barwick
09861a5604 doc: merge repmgrd pause documentation into overview 2019-03-13 16:11:59 +09:00
Ian Barwick
89bba77d4d doc: initial repmgrd doc refactoring 2019-03-13 16:11:55 +09:00
Ian Barwick
dd6ece326f doc: update repmgrd configuration documentation 2019-03-13 13:34:08 +09:00
Ian Barwick
573d027db6 repmgrd: various minor logging improvements 2019-03-13 11:27:17 +09:00
Ian Barwick
1afb41647b repmgrd: remove global variable
Make the "sibling_nodes" local, and pass by reference where relevant.
2019-03-12 17:12:23 +09:00
Ian Barwick
fc397f25f6 repmgrd: enable election rerun
If "failover_validation_command" is set, and the command returns an error,
rerun the election.

There is a pause between reruns to avoid "churn"; the length of this pause
is controlled by the configuration parameter "election_rerun_interval".
2019-03-12 17:12:19 +09:00
Ian Barwick
99923f5ffc Remove redundant struct allocation 2019-03-11 19:06:07 +09:00
Ian Barwick
b9cdcd55e7 doc: update list of reloadable repmgrd configuration options 2019-03-11 16:18:10 +09:00
Ian Barwick
db87ff46fd doc: document "failover_validation_command" 2019-03-11 15:02:33 +09:00
Ian Barwick
2a8f8d8400 doc: expand repmgrd configuration section 2019-03-11 14:50:33 +09:00
Ian Barwick
4ef706c2ca Execute "failover_validation_command" when only one standby exists 2019-03-08 12:19:37 +09:00
Ian Barwick
663c2e75b4 Make "failover_validation_command" reloadable 2019-03-08 09:27:19 +09:00
Ian Barwick
db0d71c6a7 Initial implementation of "failover_validation_command" 2019-03-08 08:49:15 +09:00
Ian Barwick
6f4f56dd8c Make recently added configuration options reloadable 2019-03-07 10:58:25 +09:00
Ian Barwick
33fefd9f52 Add configuration option "primary_visibility_consensus"
This determines whether repmgrd should continue with a failover if
one or more nodes report they can still see the standby.
2019-03-07 10:41:42 +09:00
Ian Barwick
a3f90d2bba Add configuration option "sibling_nodes_disconnect_timeout"
This controls the maximum length of time in seconds that repmgrd will
wait for other standbys to disconnect their WAL receivers in a failover
situation.

This setting is only used when "standby_disconnect_on_failover" is set to "true".
2019-03-06 15:56:21 +09:00
Ian Barwick
2ed044c358 Reset "wal_retrieve_retry_interval" for all nodes 2019-03-06 15:55:03 +09:00
Ian Barwick
9823978f41 repmgrd: don't wait for WAL receiver to reconnect during failover
If the WAL receiver has been temporarily disabled, we don't want to
wait for it to start up as it may not be able to at that point; we do
however need to reset "wal_retrieve_retry_interval".
2019-03-06 15:54:56 +09:00
Ian Barwick
ae8171e461 Improve logging/sanity checking for "node control" options 2019-03-06 15:54:30 +09:00
Ian Barwick
1f8f64d57c Improve logging when disabling/enabling WAL receiver
Also check action is being run on node which is in recovery.
2019-03-06 15:54:26 +09:00
Ian Barwick
13c650fa83 Check for WAL receiver start up 2019-03-06 15:54:23 +09:00
Ian Barwick
f85b4cd98e Log warning if "standby_disconnect_on_failover" used on pre-9.5
"standby_disconnect_on_failover" requires availability of "wal_retrieve_retry_interval",
which is available from PostgreSQL 9.5.

9.4 will fall out of community support this year, so it doesn't seem
productive at this point to do anything more than put the onus on the user
to read the documentation and heed any warning messages in the logs.
2019-03-06 15:54:15 +09:00
Ian Barwick
1615353f48 repmgrd: optionally disconnect WAL receivers during failover
This is intended to ensure that all nodes have a constant LSN while
making the failover decision.

This feature is experimental and needs to be explicitly enabled with the
configuration file option "standby_disconnect_on_failover".

Note enabling this option will result in a delay in the failover decision
until the WAL receiver is disconnected on all nodes.
2019-03-06 15:53:57 +09:00
Ian Barwick
dd04ebb809 repmgrd: handle reconnect to restarted server when using "connection" checks 2019-03-06 14:54:05 +09:00
Ian Barwick
b4dcda37a1 *_transaction() functions: log error message text as DETAIL
Per behaviour elsewhere.
2019-03-06 12:12:47 +09:00
Ian Barwick
63f7ad546e repmgrd: add option "connection_check_type"
This enable selection of the method repmgrd uses to check whether the upstream
node is available. Possible values are:

 - "ping" (default): uses PQping() to check server availability
 - "connection":  executes a query on the connection to check server
   availability (similar to repmgr3.x).
2019-03-06 12:09:54 +09:00
Ian Barwick
4f83111033 repmgrd: ignore invalid "upstream_last_seen" value 2019-03-05 11:00:29 +09:00
Ian Barwick
92103c5338 Use appendPQExpBufferStr where approrpriate 2019-03-01 16:42:00 +09:00
Ian Barwick
4b89cbd98d Rename "..._primary_last_seen" functions to "..._upstream_last_seen"
As that better reflects what they do.
2019-02-28 15:36:55 +09:00
Ian Barwick
0330fa6e62 daemon status: with csv output, show repmgrd status as unknown where appropriate
Previously, if PostgreSQL was not running on the node, repmgrd and
pause status were shown as "0", implying their status was known.

This brings the csv output in line with the human-readable output,
which displays "n/a" in this case.
2019-02-28 12:27:39 +09:00
Ian Barwick
4006f8af3c doc: upate release notes 2019-02-28 10:01:51 +09:00
Ian Barwick
b1875a8d91 Split command execution functions into separate library
These may need to be executed by repmgrd.
2019-02-27 14:41:17 +09:00
Ian Barwick
5c2264eb8d Update .gitignore
Ignore artefacts from failed patch application.
2019-02-27 13:02:30 +09:00
Ian Barwick
a6c16541c2 doc: tweak wording in event notification documentation 2019-02-27 13:01:19 +09:00
Ian Barwick
790a1cc492 repmgrd: add additional logging during a failover operation 2019-02-27 11:46:05 +09:00
Ian Barwick
067ed82931 Remove unneeded debugging output 2019-02-26 21:16:11 +09:00
Ian Barwick
59f32d74df doc: update introductory blurb 2019-02-26 15:16:46 +09:00
Ian Barwick
0578053875 standby clone: check upstream connections after data copy operation
With long-running copy operations, it's possible the connection(s) to
the primary/source server may go away for some reason, so recheck
their availability before attempting to reuse.
2019-02-26 14:37:05 +09:00
John Naylor
897e3bee14 Doc fix: PostgreSQL 9.4 is no longer considered recent 2019-02-24 12:44:10 +07:00
John Naylor
4e414d2ea0 Fix typo 2019-02-24 10:50:09 +07:00
Ian Barwick
ea36609159 Add some missing query error logging 2019-02-23 16:54:07 +09:00
Ian Barwick
0c68018631 repmgrd: log details of nodes which can see primary
If a failover is cancelled because other nodes can still see the primary,
log the identies of those nodes.
2019-02-23 15:55:06 +09:00
Ian Barwick
b72c894db4 repmgrd: during failover, check if other nodes have seen the primary
In a situation where only some standbys are cut off from the primary,
a failover would result in a split brain/split cluster situation,
as it's likely one of the cut-off standbys will promote itself, and
other cut-off standbys (but not all standbys) will follow it.

To prevent this happening, interrogate the other sibiling nodes to
check whether they've seen the primary within a reasonably short interval;
if this is the case, do not take any failover action.

This feature is experimental.
2019-02-23 13:03:22 +09:00
166 changed files with 25647 additions and 12006 deletions

77
.github/workflows/sonarqube-scan.yml vendored Normal file
View File

@@ -0,0 +1,77 @@
###
# Foundation-security SonarQube workflow
# version: 2.1
###
name: Foundation-Security/SonarQube Scan
on:
push:
tags:
- "**"
branches:
- "*main*"
- "*master*"
- "*STABLE*"
pull_request:
types: [opened, synchronize, reopened]
branches:
- "**"
workflow_dispatch:
inputs:
ref:
description: "Branch to scan"
required: true
default: "main"
jobs:
SonarQube-Scan:
name: SonarQube Scan Job
if: ${{ github.actor != 'dependabot[bot]' }}
permissions:
id-token: write
contents: read
runs-on: ubuntu-22.04
steps:
- name: Checkout source repository for dispatch runs
id: checkout-source-dispatch
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v4
with:
repository: ${{ github.repository }}
ref: ${{ inputs.ref }}
path: source
token: ${{ secrets.GH_SLONIK }}
- name: Checkout source repository for non-dispatch runs
id: checkout-source
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
with:
repository: ${{ github.repository }}
ref: ${{ github.ref }}
path: source
token: ${{ secrets.GH_SLONIK }}
- name: Checkout foundation-security repository
id: checkout-foundation-security
uses: actions/checkout@v4
with:
repository: EnterpriseDB/foundation-security
ref: v2
path: foundation-security
token: ${{ secrets.GH_SLONIK }}
- name: SonarQube Scan
id: call-sq-composite
uses: ./foundation-security/actions/sonarqube
with:
github-token: ${{ secrets.GH_SLONIK }}
github-ref: ${{ github.ref_name }}
sonarqube-url: ${{ vars.SQ_URL }}
sonarqube-token: ${{ secrets.SONARQUBE_TOKEN }}
project-name: ${{ github.event.repository.name }}
pull-request-key: ${{ github.event.number }}
pull-request-branch: ${{ github.head_ref }}
pull-request-base-branch: ${{ github.base_ref }}
foundation-security-sonarqube-token: ${{ secrets.FOUNDATION_SECURITY_SONARQUBE_TOKEN }}
cloudsmith-token: ${{ secrets.CLOUDSMITH_READ_ALL }}

5
.gitignore vendored
View File

@@ -42,8 +42,6 @@ lib*.pc
/regression.diffs /regression.diffs
/regression.out /regression.out
/doc/Makefile
# other # other
/.lineno /.lineno
*.dSYM *.dSYM
@@ -55,3 +53,6 @@ repmgr
repmgrd repmgrd
repmgr4 repmgr4
repmgrd4 repmgrd4
# generated files
configfile-scan.c

View File

@@ -2,7 +2,7 @@ License and Contributions
========================= =========================
`repmgr` is licensed under the GPL v3. All of its code and documentation is `repmgr` is licensed under the GPL v3. All of its code and documentation is
Copyright 2010-2019, 2ndQuadrant Limited. See the files COPYRIGHT and LICENSE for Copyright 2010-2021, EnterpriseDB Corporation. See the files COPYRIGHT and LICENSE for
details. details.
The development of repmgr has primarily been sponsored by 2ndQuadrant customers. The development of repmgr has primarily been sponsored by 2ndQuadrant customers.
@@ -12,10 +12,10 @@ which has received funding from the European Union's Seventh Framework Programme
(FP7/2007-2013) under grant agreement 258862. (FP7/2007-2013) under grant agreement 258862.
Contributions to `repmgr` are welcome, and will be listed in the file `CREDITS`. Contributions to `repmgr` are welcome, and will be listed in the file `CREDITS`.
2ndQuadrant Limited requires that any contributions provide a copyright EnterpriseDB Corporation requires that any contributions provide a copyright
assignment and a disclaimer of any work-for-hire ownership claims from the assignment and a disclaimer of any work-for-hire ownership claims from the
employer of the developer. This lets us make sure that all of the repmgr employer of the developer. This lets us make sure that all of the repmgr
distribution remains free code. Please contact info@2ndQuadrant.com for a distribution remains free code. Please contact info@enterprise.com for a
copy of the relevant Copyright Assignment Form. copy of the relevant Copyright Assignment Form.
Code style Code style

View File

@@ -1,4 +1,4 @@
Copyright (c) 2010-2019, 2ndQuadrant Limited Copyright (c) 2010-2021, EnterpriseDB Corporation
All rights reserved. All rights reserved.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify

2
FAQ.md
View File

@@ -5,6 +5,6 @@ The repmgr 4 FAQ is located here: [repmgr FAQ (Frequently Asked Questions)](http
The repmgr 3.x FAQ can be found here: The repmgr 3.x FAQ can be found here:
https://github.com/2ndQuadrant/repmgr/blob/REL3_3_STABLE/FAQ.md https://github.com/EnterpriseDB/repmgr/blob/REL3_3_STABLE/FAQ.md
Note that repmgr 3.x is no longer supported. Note that repmgr 3.x is no longer supported.

140
HISTORY
View File

@@ -1,6 +1,140 @@
4.3.1 2019-12-?? 5.4.1 2023-??-??
repmgr: ensure an existing replication slot is not deleted if the repmgrd: ensure witness node metadata is updated (Ian)
follow target is the node's current upstream (Ian)
5.4.0 2023-03-16
Support cloning replicas using pg-backup-api
5.3.3 2022-10-17
Support for PostgreSQL added
repmgrd: ensure event notification script is called for event
"repmgrd_upstream_disconnect"; GitHub #760 (Ian)
5.3.2 2022-05-25
standby clone: don't error out if unable to determine cluster size (Ian)
node check: fix --downstream --nagios output; GitHub #749 (Ian)
repmgrd: ensure witness node marked active (hslightdb)
repmgrd: improve walsender disable check (Ian)
general: ensure replication slots can be dropped by a
replication-only user (Ian)
5.3.1 2022-02-15
repmgrd: fixes for potential connection leaks (hslightdb)
repmgr: fix upgrade path from repmgr 4.2 and 4.3 to repmgr 5.3 (Ian)
5.3.0 2021-10-12
standby switchover: improve handling of node rejoin failure (Ian)
repmgrd: prefix all shared library functions with "repmgr_" to
minimize the risk of clashes with other shared libraries (Ian)
repmgrd: at startup, if node record is marked as "inactive", attempt
to set it to "active" (Ian)
standby clone: set "slot_name" in node record if required (Ian)
node rejoin: emit rejoin target note information as NOTICE (Ian)
repmgrd: ensure short option "-s" is accepted (Ian)
5.2.1 2020-12-07
config: fix parsing of "replication_type"; GitHub #672 (Ian)
standby clone: handle missing "postgresql.auto.conf" (Ian)
standby clone: add option --recovery-min-apply-delay (Ian)
standby clone: fix data directory permissions handling for
PostgreSQL 11 and later (Ian)
repmgrd: prevent termination when local node not available and
standby_disconnect_on_failover; GitHub #675 (Ian)
repmgrd: ensure reconnect_interval" is correctly handled;
GitHub #673 (Ian)
5.2.0 2020-10-22
general: add support for PostgreSQL 13 (Ian)
general: remove support for PostgreSQL 9.3 (Ian)
config: add support for file inclusion directives (Ian)
repmgr: "primary unregister --force" will unregister an active primary
with no registered standby nodes (Ian)
repmgr: add option --verify-backup to "standby clone" (Ian)
repmgr: "standby clone" honours --waldir option if set in
"pg_basebackup_options" (Ian)
repmgr: add option --db-connection to "node check" (Ian)
repmgr: report database connection error if the --optformat option was
provided to "node check" (Ian)
repmgr: improve "node rejoin" checks (Ian)
repmgr: enable "node rejoin" to join a target with a lower timeline (Ian)
repmgr: support pg_rewind's automatic crash recovery in Pg13 and later (Ian)
repmgr: improve output formatting for cluster matrix/crosscheck (Ian)
repmgr: improve database connection failure error checking on the
demotion candidate during "standby switchover" (Ian)
repmgr: make repmgr metadata tables dumpable (Ian)
repmgr: fix issue with tablespace mapping when cloning from Barman;
GitHub #650 (Ian)
repmgr: improve handling of pg_control read errors (Ian)
repmgrd: add additional optional parameters to "failover_validation command"
(spaskalev; GitHub #651)
repmgrd: ensure primary connection is reset if same as upstream;
GitHub #633 (Ian)
5.1.0 2020-04-13
repmgr: remove BDR 2.x support
repmgr: don't query upstream's data directory (Ian)
repmgr: rename --recovery-conf-only to --replication-conf-only (Ian)
repmgr: ensure postgresql.auto.conf is created with correct permissions (Ian)
repmgr: minimize requirement to check upstream data directory location
during "standby clone" (Ian)
repmgr: warn about missing pg_rewind prerequisites when executing
"standby clone" (Ian)
repmgr: add --upstream option to "node check"
repmgr: report error code on follow/rejoin failure due to non-available
replication slot (Ian)
repmgr: ensure "node rejoin" checks for available replication slots (Ian)
repmgr: improve "standby switchover" completion checks (Ian)
repmgr: add replication configuration file ownership check to
"standby switchover" (Ian)
repmgr: check the demotion candidate's registered repmgr.conf file can
be found (laixiong; GitHub 615)
repmgr: consolidate replication connection code (Ian)
repmgr: check permissions for "pg_promote()" and fall back to pg_ctl
if necessary (Ian)
repmgr: in --dry-run mode, display promote command which will be used (Ian)
repmgr: enable "service_promote_command" in PostgreSQL 12 (Ian)
repmgr: accept option -S/--superuser for "node check"; GitHub #612 (Ian)
5.0 2019-10-15
general: add PostgreSQL 12 support (Ian)
general: parse configuration file using flex (Ian)
repmgr: rename "repmgr daemon ..." commands to "repmgr service ..." (Ian)
repmgr: improve data directory check (Ian)
repmgr: improve extension check during "standby clone" (Ian)
repmgr: pass provided log level when executing repmgr remotely (Ian)
repmgrd: fix handling of upstream node change check (Ian)
4.4 2019-06-27
repmgr: improve "daemon status" output (Ian)
repmgr: add "--siblings-follow" option to "standby promote" (Ian)
repmgr: add "--repmgrd-force-unpause" option to "standby switchover" (Ian)
repmgr: fix data directory permissions issue in barman mode where
an existing directory is being overwritten (Ian)
repmgr: improve "--dry-run" behaviour for "standby promote" and
"standby switchover" (Ian)
repmgr: when running "standby clone" with the "--upstream-conninfo" option
ensure that "application_name" is set correctly in "primary_conninfo" (Ian)
repmgr: ensure "--dry-run" together with --force when running "standby clone"
in barman mode does not modify an existing data directory (Ian)
repmgr: improve "--dry-run" output when running "standby clone" in
basebackup mode (Ian)
repmgr: improve upstream walsender checks when running "standby clone" (Ian)
repmgr: display node timeline ID in "cluster show" output (Ian)
repmgr: in "cluster show" and "daemon status", show upstream node name
as reported by each individual node (Ian)
repmgr: in "cluster show" and "daemon status", check if a node is attached
to its advertised upstream node
repmgr: use --compact rather than --terse option in "cluster event" (Ian)
repmgr: prevent a standby being cloned from a witness server (Ian)
repmgr: prevent a witness server being registered on the cluster primary (John)
repmgr: ensure BDR2-specific functionality cannot be used on
BDR3 and later (Ian)
repmgr: canonicalize the data directory path (Ian)
repmgr: note that "standby follow" requires a primary to be available (Ian)
repmgrd: monitor standbys attached to primary (Ian)
repmgrd: add "primary visibility consensus" functionality (Ian)
repmgrd: fix memory leak which occurs while the monitored PostgreSQL
node is not running (Ian)
general: documentation converted to DocBook XML format (Ian)
4.3 2019-04-02 4.3 2019-04-02
repmgr: add "daemon (start|stop)" command; GitHub #528 (Ian) repmgr: add "daemon (start|stop)" command; GitHub #528 (Ian)

View File

@@ -2,6 +2,7 @@
# Makefile.global.in # Makefile.global.in
# @configure_input@ # @configure_input@
# Can only be built using pgxs # Can only be built using pgxs
USE_PGXS=1 USE_PGXS=1
@@ -14,14 +15,26 @@ ifeq ($(vpath_build),yes)
VPATH := $(repmgr_abs_srcdir)/$(repmgr_subdir) VPATH := $(repmgr_abs_srcdir)/$(repmgr_subdir)
USE_VPATH :=$(VPATH) USE_VPATH :=$(VPATH)
endif endif
SED=@SED@
GIT_WORK_TREE=${repmgr_abs_srcdir} GIT_WORK_TREE=${repmgr_abs_srcdir}
GIT_DIR=${repmgr_abs_srcdir}/.git GIT_DIR=${repmgr_abs_srcdir}/.git
export GIT_DIR export GIT_DIR
export GIT_WORK_TREE export GIT_WORK_TREE
PG_LDFLAGS=-lcurl -ljson-c
include $(PGXS) include $(PGXS)
-include ${repmgr_abs_srcdir}/Makefile.custom -include ${repmgr_abs_srcdir}/Makefile.custom
REPMGR_VERSION=$(shell awk '/^\#define REPMGR_VERSION / { print $3; }' ${repmgr_abs_srcdir}/repmgr_version.h.in | cut -d '"' -f 2) REPMGR_VERSION=$(shell awk '/^\#define REPMGR_VERSION / { print $3; }' ${repmgr_abs_srcdir}/repmgr_version.h.in | cut -d '"' -f 2)
REPMGR_RELEASE_DATE=$(shell awk '/^\#define REPMGR_RELEASE_DATE / { print $3; }' ${repmgr_abs_srcdir}/repmgr_version.h.in | cut -d '"' -f 2)
FLEX = flex
##########################################################################
#
# Global targets and rules
%.c: %.l
$(FLEX) $(FLEXFLAGS) -o'$@' $<

View File

@@ -11,13 +11,28 @@ EXTENSION = repmgr
DATA = \ DATA = \
repmgr--unpackaged--4.0.sql \ repmgr--unpackaged--4.0.sql \
repmgr--unpackaged--5.1.sql \
repmgr--unpackaged--5.2.sql \
repmgr--unpackaged--5.3.sql \
repmgr--4.0.sql \ repmgr--4.0.sql \
repmgr--4.0--4.1.sql \ repmgr--4.0--4.1.sql \
repmgr--4.1.sql \ repmgr--4.1.sql \
repmgr--4.1--4.2.sql \ repmgr--4.1--4.2.sql \
repmgr--4.2.sql \ repmgr--4.2.sql \
repmgr--4.2--4.3.sql \ repmgr--4.2--4.3.sql \
repmgr--4.3.sql repmgr--4.3.sql \
repmgr--4.3--4.4.sql \
repmgr--4.4.sql \
repmgr--4.4--5.0.sql \
repmgr--5.0.sql \
repmgr--5.0--5.1.sql \
repmgr--5.1.sql \
repmgr--5.1--5.2.sql \
repmgr--5.2.sql \
repmgr--5.2--5.3.sql \
repmgr--5.3.sql \
repmgr--5.3--5.4.sql \
repmgr--5.4.sql
REGRESS = repmgr_extension REGRESS = repmgr_extension
@@ -49,13 +64,19 @@ $(info Building against PostgreSQL $(MAJORVERSION))
REPMGR_CLIENT_OBJS = repmgr-client.o \ REPMGR_CLIENT_OBJS = repmgr-client.o \
repmgr-action-primary.o repmgr-action-standby.o repmgr-action-witness.o \ repmgr-action-primary.o repmgr-action-standby.o repmgr-action-witness.o \
repmgr-action-bdr.o repmgr-action-cluster.o repmgr-action-node.o repmgr-action-daemon.o \ repmgr-action-cluster.o repmgr-action-node.o repmgr-action-service.o repmgr-action-daemon.o \
configfile.o log.o strutil.o controldata.o dirutil.o compat.o dbutils.o sysutils.o configdata.o configfile.o configfile-scan.o log.o strutil.o controldata.o dirutil.o compat.o \
REPMGRD_OBJS = repmgrd.o repmgrd-physical.o repmgrd-bdr.o configfile.o log.o dbutils.o strutil.o controldata.o compat.o sysutils.o dbutils.o sysutils.o pgbackupapi.o
REPMGRD_OBJS = repmgrd.o repmgrd-physical.o configdata.o configfile.o configfile-scan.o log.o \
dbutils.o strutil.o controldata.o compat.o sysutils.o
DATE=$(shell date "+%Y-%m-%d") DATE=$(shell date "+%Y-%m-%d")
repmgr_version.h: repmgr_version.h.in repmgr_version.h: repmgr_version.h.in
sed '0,/REPMGR_VERSION_DATE/s,\(REPMGR_VERSION_DATE\).*,\1 "$(DATE)",' $< >$@ $(SED) -E 's/REPMGR_VERSION_DATE.*""/REPMGR_VERSION_DATE "$(DATE)"/' $< >$@; \
$(SED) -i -E 's/PG_ACTUAL_VERSION_NUM/PG_ACTUAL_VERSION_NUM $(VERSION_NUM)/' $@
configfile-scan.c: configfile-scan.l
$(REPMGR_CLIENT_OBJS): repmgr-client.h repmgr_version.h $(REPMGR_CLIENT_OBJS): repmgr-client.h repmgr_version.h
@@ -75,10 +96,19 @@ Makefile: Makefile.in config.status configure
Makefile.global: Makefile.global.in config.status configure Makefile.global: Makefile.global.in config.status configure
./config.status $@ ./config.status $@
doc: doc: repmgr_version.h
$(MAKE) -C doc all $(MAKE) -C doc html
install-doc: doc-repmgr.html: repmgr_version.h
$(MAKE) -C doc repmgr.html
doc-repmgr-A4.pdf: repmgr_version.h
$(MAKE) -C doc repmgr-A4.pdf
doc-repmgr-US.pdf: repmgr_version.h
$(MAKE) -C doc repmgr-US.pdf
install-doc: doc
$(MAKE) -C doc install $(MAKE) -C doc install
clean: additional-clean clean: additional-clean
@@ -87,6 +117,8 @@ maintainer-clean: additional-maintainer-clean
additional-clean: additional-clean:
rm -f *.o rm -f *.o
rm -f repmgr_version.h
$(MAKE) -C doc clean
additional-maintainer-clean: clean additional-maintainer-clean: clean
$(MAKE) -C doc maintainer-clean $(MAKE) -C doc maintainer-clean
@@ -109,3 +141,4 @@ installdirs-scripts:
.PHONY: installdirs-scripts .PHONY: installdirs-scripts
endif endif
.PHONY: doc doc-repmgr.html doc-repmgr-A4.pdf doc-repmgr-US.pdf install-doc

View File

@@ -7,32 +7,23 @@ replication capabilities with utilities to set up standby servers, monitor
replication, and perform administrative tasks such as failover or switchover replication, and perform administrative tasks such as failover or switchover
operations. operations.
`repmgr 4` is a complete rewrite of the existing `repmgr` codebase, allowing The most recent `repmgr` version (5.3.2) supports all PostgreSQL versions from
the use of all of the latest features in PostgreSQL replication. 9.5 to 15. PostgreSQL 9.4 is also supported, with some restrictions.
PostgreSQL 11, 10, 9.6 and 9.5 are fully supported.
PostgreSQL 9.4 and 9.3 are supported, with some restrictions.
`repmgr` is distributed under the GNU GPL 3 and maintained by 2ndQuadrant.
### BDR support
`repmgr 4` supports monitoring of a two-node BDR 2.0 cluster on PostgreSQL 9.6
only. Note that BDR 2.0 is not publicly available; please contact 2ndQuadrant
for details.
`repmgr` is distributed under the GNU GPL 3 and maintained by EnterpriseDB.
Documentation Documentation
------------- -------------
The main `repmgr` documentation is available here: The full `repmgr` documentation is available here:
> [repmgr documentation](https://repmgr.org/docs/current/index.html) > [repmgr documentation](https://repmgr.org/docs/current/index.html)
The `README` file for `repmgr` 3.x is available here: Versions
--------
> https://github.com/2ndQuadrant/repmgr/blob/REL3_3_STABLE/README.md
For an overview of `repmgr` versions and PostgreSQL compatibility, see the
[repmgr compatibility matrix](https://repmgr.org/docs/current/install-requirements.html#INSTALL-COMPATIBILITY-MATRIX).
Files Files
------ ------
@@ -49,18 +40,17 @@ Directories
- `contrib/`: additional utilities - `contrib/`: additional utilities
- `doc/`: DocBook-based documentation files - `doc/`: DocBook-based documentation files
- `expected/`: expected regression test output - `expected/`: expected regression test output
- `scripts/`: example scripts
- `sql/`: regression test input - `sql/`: regression test input
Support and Assistance Support and Assistance
---------------------- ----------------------
2ndQuadrant provides 24x7 production support for `repmgr`, including EnterpriseDB provides 24x7 production support for `repmgr`, including
configuration assistance, installation verification and training for configuration assistance, installation verification and training for
running a robust replication cluster. For further details see: running a robust replication cluster. For further details see:
* https://2ndquadrant.com/en/support/ * [EDB Support Services](https://www.enterprisedb.com/support/postgresql-support-overview-get-the-most-out-of-postgresql)
There is a mailing list/forum to discuss contributions or issues: There is a mailing list/forum to discuss contributions or issues:
@@ -70,25 +60,15 @@ The IRC channel #repmgr is registered with freenode.
Please report bugs and other issues to: Please report bugs and other issues to:
* https://github.com/2ndQuadrant/repmgr * https://github.com/EnterpriseDB/repmgr
Further information is available at https://repmgr.org/ Further information is available at https://repmgr.org/
We'd love to hear from you about how you use repmgr. Case studies and We'd love to hear from you about how you use repmgr. Case studies and
news are always welcome. Send us an email at info@2ndQuadrant.com, or news are always welcome.
send a postcard to
repmgr
c/o 2ndQuadrant
7200 The Quorum
Oxford Business Park North
Oxford
OX4 2JZ
United Kingdom
Thanks from the repmgr core team. Thanks from the repmgr core team.
* Ian Barwick
* Jaime Casanova * Jaime Casanova
* Abhijit Menon-Sen * Abhijit Menon-Sen
* Simon Riggs * Simon Riggs
@@ -98,7 +78,6 @@ Further reading
--------------- ---------------
* [repmgr documentation](https://repmgr.org/docs/current/index.html) * [repmgr documentation](https://repmgr.org/docs/current/index.html)
* https://blog.2ndquadrant.com/repmgr-3-2-is-here-barman-support-brand-new-high-availability-features/ * [How to Automate PostgreSQL 12 Replication and Failover with repmgr - Part 1](https://www.2ndquadrant.com/en/blog/how-to-automate-postgresql-12-replication-and-failover-with-repmgr-part-1/)
* https://blog.2ndquadrant.com/improvements-in-repmgr-3-1-4/ * [How to Automate PostgreSQL 12 Replication and Failover with repmgr - Part 2](https://www.2ndquadrant.com/en/blog/how-to-automate-postgresql-12-replication-and-failover-with-repmgr-part-2/)
* https://blog.2ndquadrant.com/managing-useful-clusters-repmgr/ * [How to implement repmgr for PostgreSQL automatic failover](https://www.enterprisedb.com/postgres-tutorials/how-implement-repmgr-postgresql-automatic-failover)
* https://blog.2ndquadrant.com/easier_postgresql_90_clusters/

View File

@@ -1,7 +1,7 @@
TODO TODO
==== ====
This file contains a list of improvements which are desireable and/or have This file contains a list of improvements which are desirable and/or have
been requested, and which we aim to address/implement when time and resources been requested, and which we aim to address/implement when time and resources
permit. permit.
@@ -17,4 +17,4 @@ repmgrd nodes to prevent unintended failover; this is obviously inconvenient.
We'll need to implement some way of notifying each repmgrd to suspend automatic We'll need to implement some way of notifying each repmgrd to suspend automatic
failover until further notice. failover until further notice.
Requested in GitHub #410 ( https://github.com/2ndQuadrant/repmgr/issues/410 ) Requested in GitHub #410 ( https://github.com/EnterpriseDB/repmgr/issues/410 )

View File

@@ -6,7 +6,7 @@
* supported PostgreSQL versions. They're unlikely to change but * supported PostgreSQL versions. They're unlikely to change but
* it would be worth keeping an eye on them for any fixes/improvements. * it would be worth keeping an eye on them for any fixes/improvements.
* *
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) EnterpriseDB Corporation, 2010-2021
* *
* Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California

View File

@@ -1,6 +1,6 @@
/* /*
* compat.h * compat.h
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) EnterpriseDB Corporation, 2010-2021
* *
* Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California

986
configdata.c Normal file
View File

@@ -0,0 +1,986 @@
/*
* configdata.c - contains structs with parsed configuration data
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "repmgr.h"
#include "configfile.h"
/*
* Parsed configuration settings are stored here
*/
t_configuration_options config_file_options;
/*
* Configuration settings are defined here
*/
struct ConfigFileSetting config_file_settings[] =
{
/* ================
* node information
* ================
*/
/* node_id */
{
"node_id",
CONFIG_INT,
{ .intptr = &config_file_options.node_id },
{ .intdefault = UNKNOWN_NODE_ID },
{ .intminval = MIN_NODE_ID },
{},
{}
},
/* node_name */
{
"node_name",
CONFIG_STRING,
{ .strptr = config_file_options.node_name },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.node_name) },
{}
},
/* conninfo */
{
"conninfo",
CONFIG_STRING,
{ .strptr = config_file_options.conninfo },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.conninfo) },
{}
},
/* replication_user */
{
"replication_user",
CONFIG_STRING,
{ .strptr = config_file_options.replication_user },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.replication_user) },
{}
},
/* data_directory */
{
"data_directory",
CONFIG_STRING,
{ .strptr = config_file_options.data_directory },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.data_directory) },
{ .postprocess_func = &repmgr_canonicalize_path }
},
/* config_directory */
{
"config_directory",
CONFIG_STRING,
{ .strptr = config_file_options.config_directory },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.config_directory) },
{ .postprocess_func = &repmgr_canonicalize_path }
},
/* pg_bindir */
{
"pg_bindir",
CONFIG_STRING,
{ .strptr = config_file_options.pg_bindir },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.pg_bindir) },
{ .postprocess_func = &repmgr_canonicalize_path }
},
/* repmgr_bindir */
{
"repmgr_bindir",
CONFIG_STRING,
{ .strptr = config_file_options.repmgr_bindir },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.repmgr_bindir) },
{ .postprocess_func = &repmgr_canonicalize_path }
},
/* replication_type */
{
"replication_type",
CONFIG_REPLICATION_TYPE,
{ .replicationtypeptr = &config_file_options.replication_type },
{ .replicationtypedefault = DEFAULT_REPLICATION_TYPE },
{},
{},
{}
},
/* ================
* logging settings
* ================
*/
/*
* log_level
* NOTE: the default for "log_level" is set in log.c and does not need
* to be initialised here
*/
{
"log_level",
CONFIG_STRING,
{ .strptr = config_file_options.log_level },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.log_level) },
{}
},
/* log_facility */
{
"log_facility",
CONFIG_STRING,
{ .strptr = config_file_options.log_facility },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.log_facility) },
{}
},
/* log_file */
{
"log_file",
CONFIG_STRING,
{ .strptr = config_file_options.log_file },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.log_file) },
{ .postprocess_func = &repmgr_canonicalize_path }
},
/* log_status_interval */
{
"log_status_interval",
CONFIG_INT,
{ .intptr = &config_file_options.log_status_interval },
{ .intdefault = DEFAULT_LOG_STATUS_INTERVAL, },
{ .intminval = 0 },
{},
{}
},
/* ======================
* standby clone settings
* ======================
*/
/* use_replication_slots */
{
"use_replication_slots",
CONFIG_BOOL,
{ .boolptr = &config_file_options.use_replication_slots },
{ .booldefault = DEFAULT_USE_REPLICATION_SLOTS },
{},
{},
{}
},
/* pg_basebackup_options */
{
"pg_basebackup_options",
CONFIG_STRING,
{ .strptr = config_file_options.pg_basebackup_options },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.pg_basebackup_options) },
{}
},
/* restore_command */
{
"restore_command",
CONFIG_STRING,
{ .strptr = config_file_options.restore_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.restore_command) },
{}
},
/* tablespace_mapping */
{
"tablespace_mapping",
CONFIG_TABLESPACE_MAPPING,
{ .tablespacemappingptr = &config_file_options.tablespace_mapping },
{},
{},
{},
{}
},
/* recovery_min_apply_delay */
{
"recovery_min_apply_delay",
CONFIG_STRING,
{ .strptr = config_file_options.recovery_min_apply_delay },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.recovery_min_apply_delay) },
{
.process_func = &parse_time_unit_parameter,
.providedptr = &config_file_options.recovery_min_apply_delay_provided
}
},
/* archive_cleanup_command */
{
"archive_cleanup_command",
CONFIG_STRING,
{ .strptr = config_file_options.archive_cleanup_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.archive_cleanup_command) },
{}
},
/* use_primary_conninfo_password */
{
"use_primary_conninfo_password",
CONFIG_BOOL,
{ .boolptr = &config_file_options.use_primary_conninfo_password },
{ .booldefault = DEFAULT_USE_PRIMARY_CONNINFO_PASSWORD },
{},
{},
{}
},
/* passfile */
{
"passfile",
CONFIG_STRING,
{ .strptr = config_file_options.passfile },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.passfile) },
{}
},
/* ======================
* standby clone settings
* ======================
*/
/* promote_check_timeout */
{
"promote_check_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.promote_check_timeout },
{ .intdefault = DEFAULT_PROMOTE_CHECK_TIMEOUT },
{ .intminval = 1 },
{},
{}
},
/* promote_check_interval */
{
"promote_check_interval",
CONFIG_INT,
{ .intptr = &config_file_options.promote_check_interval },
{ .intdefault = DEFAULT_PROMOTE_CHECK_INTERVAL },
{ .intminval = 1 },
{},
{}
},
/* pg_backupapi_backup_id*/
{
"pg_backupapi_backup_id",
CONFIG_STRING,
{ .strptr = config_file_options.pg_backupapi_backup_id },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_backup_id) },
{}
},
/* pg_backupapi_host*/
{
"pg_backupapi_host",
CONFIG_STRING,
{ .strptr = config_file_options.pg_backupapi_host },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_host) },
{}
},
/* pg_backupapi_node_name */
{
"pg_backupapi_node_name",
CONFIG_STRING,
{ .strptr = config_file_options.pg_backupapi_node_name },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_node_name) },
{}
},
/* pg_backupapi_remote_ssh_command */
{
"pg_backupapi_remote_ssh_command",
CONFIG_STRING,
{ .strptr = config_file_options.pg_backupapi_remote_ssh_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_remote_ssh_command) },
{}
},
/* =======================
* standby follow settings
* =======================
*/
/* primary_follow_timeout */
{
"primary_follow_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.primary_follow_timeout },
{ .intdefault = DEFAULT_PRIMARY_FOLLOW_TIMEOUT, },
{ .intminval = 1 },
{},
{}
},
/* standby_follow_timeout */
{
"standby_follow_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.standby_follow_timeout },
{ .intdefault = DEFAULT_STANDBY_FOLLOW_TIMEOUT },
{ .intminval = 1 },
{},
{}
},
/* standby_follow_restart */
{
"standby_follow_restart",
CONFIG_BOOL,
{ .boolptr = &config_file_options.standby_follow_restart },
{ .booldefault = DEFAULT_STANDBY_FOLLOW_RESTART },
{},
{},
{}
},
/* ===========================
* standby switchover settings
* ===========================
*/
/* shutdown_check_timeout */
{
"shutdown_check_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.shutdown_check_timeout },
{ .intdefault = DEFAULT_SHUTDOWN_CHECK_TIMEOUT },
{ .intminval = 1 },
{},
{}
},
/* standby_reconnect_timeout */
{
"standby_reconnect_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.standby_reconnect_timeout },
{ .intdefault = DEFAULT_STANDBY_RECONNECT_TIMEOUT },
{ .intminval = 1 },
{},
{}
},
/* wal_receive_check_timeout */
{
"wal_receive_check_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.wal_receive_check_timeout },
{ .intdefault = DEFAULT_WAL_RECEIVE_CHECK_TIMEOUT },
{ .intminval = 1 },
{},
{}
},
/* ====================
* node rejoin settings
* ====================
*/
/* node_rejoin_timeout */
{
"node_rejoin_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.node_rejoin_timeout },
{ .intdefault = DEFAULT_NODE_REJOIN_TIMEOUT },
{ .intminval = 1 },
{},
{}
},
/* ===================
* node check settings
* ===================
*/
/* archive_ready_warning */
{
"archive_ready_warning",
CONFIG_INT,
{ .intptr = &config_file_options.archive_ready_warning },
{ .intdefault = DEFAULT_ARCHIVE_READY_WARNING },
{ .intminval = 1 },
{},
{}
},
/* archive_ready_critical */
{
"archive_ready_critical",
CONFIG_INT,
{ .intptr = &config_file_options.archive_ready_critical },
{ .intdefault = DEFAULT_ARCHIVE_READY_CRITICAL },
{ .intminval = 1 },
{},
{}
},
/* replication_lag_warning */
{
"replication_lag_warning",
CONFIG_INT,
{ .intptr = &config_file_options.replication_lag_warning },
{ .intdefault = DEFAULT_REPLICATION_LAG_WARNING },
{ .intminval = 1 },
{},
{}
},
/* replication_lag_critical */
{
"replication_lag_critical",
CONFIG_INT,
{ .intptr = &config_file_options.replication_lag_critical },
{ .intdefault = DEFAULT_REPLICATION_LAG_CRITICAL },
{ .intminval = 1 },
{},
{}
},
/* ================
* witness settings
* ================
*/
/* witness_sync_interval */
{
"witness_sync_interval",
CONFIG_INT,
{ .intptr = &config_file_options.witness_sync_interval },
{ .intdefault = DEFAULT_WITNESS_SYNC_INTERVAL },
{ .intminval = 1 },
{},
{}
},
/* ================
* repmgrd settings
* ================
*/
/* failover */
{
"failover",
CONFIG_FAILOVER_MODE,
{ .failovermodeptr = &config_file_options.failover },
{ .failovermodedefault = FAILOVER_MANUAL },
{},
{},
{}
},
/* location */
{
"location",
CONFIG_STRING,
{ .strptr = config_file_options.location },
{ .strdefault = DEFAULT_LOCATION },
{},
{ .strmaxlen = sizeof(config_file_options.location) },
{}
},
/* priority */
{
"priority",
CONFIG_INT,
{ .intptr = &config_file_options.priority },
{ .intdefault = DEFAULT_PRIORITY, },
{ .intminval = 0 },
{},
{}
},
/* promote_command */
{
"promote_command",
CONFIG_STRING,
{ .strptr = config_file_options.promote_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.promote_command) },
{}
},
/* follow_command */
{
"follow_command",
CONFIG_STRING,
{ .strptr = config_file_options.follow_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.follow_command) },
{}
},
/* monitor_interval_secs */
{
"monitor_interval_secs",
CONFIG_INT,
{ .intptr = &config_file_options.monitor_interval_secs },
{ .intdefault = DEFAULT_MONITORING_INTERVAL },
{ .intminval = 1 },
{},
{}
},
/* reconnect_attempts */
{
"reconnect_attempts",
CONFIG_INT,
{ .intptr = &config_file_options.reconnect_attempts },
{ .intdefault = DEFAULT_RECONNECTION_ATTEMPTS },
{ .intminval = 0 },
{},
{}
},
/* reconnect_interval */
{
"reconnect_interval",
CONFIG_INT,
{ .intptr = &config_file_options.reconnect_interval },
{ .intdefault = DEFAULT_RECONNECTION_INTERVAL },
{ .intminval = 0 },
{},
{}
},
/* monitoring_history */
{
"monitoring_history",
CONFIG_BOOL,
{ .boolptr = &config_file_options.monitoring_history },
{ .booldefault = DEFAULT_MONITORING_HISTORY },
{},
{},
{}
},
/* degraded_monitoring_timeout */
{
"degraded_monitoring_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.degraded_monitoring_timeout },
{ .intdefault = DEFAULT_DEGRADED_MONITORING_TIMEOUT },
{ .intminval = -1 },
{},
{}
},
/* async_query_timeout */
{
"async_query_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.async_query_timeout },
{ .intdefault = DEFAULT_ASYNC_QUERY_TIMEOUT },
{ .intminval = 0 },
{},
{}
},
/* primary_notification_timeout */
{
"primary_notification_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.primary_notification_timeout },
{ .intdefault = DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT },
{ .intminval = 0 },
{},
{}
},
/* repmgrd_standby_startup_timeout */
{
"repmgrd_standby_startup_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.repmgrd_standby_startup_timeout },
{ .intdefault = DEFAULT_REPMGRD_STANDBY_STARTUP_TIMEOUT },
{ .intminval = 0 },
{},
{}
},
/* repmgrd_pid_file */
{
"repmgrd_pid_file",
CONFIG_STRING,
{ .strptr = config_file_options.repmgrd_pid_file },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.repmgrd_pid_file) },
{ .postprocess_func = &repmgr_canonicalize_path }
},
/* repmgrd_exit_on_inactive_node */
{
"repmgrd_exit_on_inactive_node",
CONFIG_BOOL,
{ .boolptr = &config_file_options.repmgrd_exit_on_inactive_node},
{ .booldefault = DEFAULT_REPMGRD_EXIT_ON_INACTIVE_NODE },
{},
{},
{}
},
/* standby_disconnect_on_failover */
{
"standby_disconnect_on_failover",
CONFIG_BOOL,
{ .boolptr = &config_file_options.standby_disconnect_on_failover },
{ .booldefault = DEFAULT_STANDBY_DISCONNECT_ON_FAILOVER },
{},
{},
{}
},
/* sibling_nodes_disconnect_timeout */
{
"sibling_nodes_disconnect_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.sibling_nodes_disconnect_timeout },
{ .intdefault = DEFAULT_SIBLING_NODES_DISCONNECT_TIMEOUT },
{ .intminval = 0 },
{},
{}
},
/* connection_check_type */
{
"connection_check_type",
CONFIG_CONNECTION_CHECK_TYPE,
{ .checktypeptr = &config_file_options.connection_check_type },
{ .checktypedefault = DEFAULT_CONNECTION_CHECK_TYPE },
{},
{},
{}
},
/* primary_visibility_consensus */
{
"primary_visibility_consensus",
CONFIG_BOOL,
{ .boolptr = &config_file_options.primary_visibility_consensus },
{ .booldefault = DEFAULT_PRIMARY_VISIBILITY_CONSENSUS },
{},
{},
{}
},
/* always_promote */
{
"always_promote",
CONFIG_BOOL,
{ .boolptr = &config_file_options.always_promote },
{ .booldefault = DEFAULT_ALWAYS_PROMOTE },
{},
{},
{}
},
/* failover_validation_command */
{
"failover_validation_command",
CONFIG_STRING,
{ .strptr = config_file_options.failover_validation_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.failover_validation_command) },
{}
},
/* election_rerun_interval */
{
"election_rerun_interval",
CONFIG_INT,
{ .intptr = &config_file_options.election_rerun_interval },
{ .intdefault = DEFAULT_ELECTION_RERUN_INTERVAL },
{ .intminval = 1 },
{},
{}
},
/* child_nodes_check_interval */
{
"child_nodes_check_interval",
CONFIG_INT,
{ .intptr = &config_file_options.child_nodes_check_interval },
{ .intdefault = DEFAULT_CHILD_NODES_CHECK_INTERVAL },
{ .intminval = 1 },
{},
{}
},
/* child_nodes_disconnect_min_count */
{
"child_nodes_disconnect_min_count",
CONFIG_INT,
{ .intptr = &config_file_options.child_nodes_disconnect_min_count },
{ .intdefault = DEFAULT_CHILD_NODES_DISCONNECT_MIN_COUNT },
{ .intminval = -1 },
{},
{}
},
/* child_nodes_connected_min_count */
{
"child_nodes_connected_min_count",
CONFIG_INT,
{ .intptr = &config_file_options.child_nodes_connected_min_count },
{ .intdefault = DEFAULT_CHILD_NODES_CONNECTED_MIN_COUNT},
{ .intminval = -1 },
{},
{}
},
/* child_nodes_connected_include_witness */
{
"child_nodes_connected_include_witness",
CONFIG_BOOL,
{ .boolptr = &config_file_options.child_nodes_connected_include_witness },
{ .booldefault = DEFAULT_CHILD_NODES_CONNECTED_INCLUDE_WITNESS },
{},
{},
{}
},
/* child_nodes_disconnect_timeout */
{
"child_nodes_disconnect_timeout",
CONFIG_INT,
{ .intptr = &config_file_options.child_nodes_disconnect_timeout },
{ .intdefault = DEFAULT_CHILD_NODES_DISCONNECT_TIMEOUT },
{ .intminval = 0 },
{},
{}
},
/* child_nodes_disconnect_command */
{
"child_nodes_disconnect_command",
CONFIG_STRING,
{ .strptr = config_file_options.child_nodes_disconnect_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.child_nodes_disconnect_command) },
{}
},
/* ================
* service settings
* ================
*/
/* pg_ctl_options */
{
"pg_ctl_options",
CONFIG_STRING,
{ .strptr = config_file_options.pg_ctl_options },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.pg_ctl_options) },
{}
},
/* service_start_command */
{
"service_start_command",
CONFIG_STRING,
{ .strptr = config_file_options.service_start_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.service_start_command) },
{}
},
/* service_stop_command */
{
"service_stop_command",
CONFIG_STRING,
{ .strptr = config_file_options.service_stop_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.service_stop_command) },
{}
},
/* service_restart_command */
{
"service_restart_command",
CONFIG_STRING,
{ .strptr = config_file_options.service_restart_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.service_restart_command) },
{}
},
/* service_reload_command */
{
"service_reload_command",
CONFIG_STRING,
{ .strptr = config_file_options.service_reload_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.service_reload_command) },
{}
},
/* service_promote_command */
{
"service_promote_command",
CONFIG_STRING,
{ .strptr = config_file_options.service_promote_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.service_promote_command) },
{}
},
/* ========================
* repmgrd service settings
* ========================
*/
/* repmgrd_service_start_command */
{
"repmgrd_service_start_command",
CONFIG_STRING,
{ .strptr = config_file_options.repmgrd_service_start_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.repmgrd_service_start_command) },
{}
},
/* repmgrd_service_stop_command */
{
"repmgrd_service_stop_command",
CONFIG_STRING,
{ .strptr = config_file_options.repmgrd_service_stop_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.repmgrd_service_stop_command) },
{}
},
/* ===========================
* event notification settings
* ===========================
*/
/* event_notification_command */
{
"event_notification_command",
CONFIG_STRING,
{ .strptr = config_file_options.event_notification_command },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.event_notification_command) },
{}
},
{
"event_notifications",
CONFIG_EVENT_NOTIFICATION_LIST,
{ .notificationlistptr = &config_file_options.event_notifications },
{},
{},
{},
{}
},
/* ===============
* barman settings
* ===============
*/
/* barman_host */
{
"barman_host",
CONFIG_STRING,
{ .strptr = config_file_options.barman_host },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.barman_host) },
{}
},
/* barman_server */
{
"barman_server",
CONFIG_STRING,
{ .strptr = config_file_options.barman_server },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.barman_server) },
{}
},
/* barman_config */
{
"barman_config",
CONFIG_STRING,
{ .strptr = config_file_options.barman_config },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.barman_config) },
{}
},
/* ==================
* rsync/ssh settings
* ==================
*/
/* rsync_options */
{
"rsync_options",
CONFIG_STRING,
{ .strptr = config_file_options.rsync_options },
{ .strdefault = "" },
{},
{ .strmaxlen = sizeof(config_file_options.rsync_options) },
{}
},
/* ssh_options */
{
"ssh_options",
CONFIG_STRING,
{ .strptr = config_file_options.ssh_options },
{ .strdefault = DEFAULT_SSH_OPTIONS },
{},
{ .strmaxlen = sizeof(config_file_options.ssh_options) },
{}
},
/* ==================================
* undocumented experimental settings
* ==================================
*/
/* reconnect_loop_sync */
{
"reconnect_loop_sync",
CONFIG_BOOL,
{ .boolptr = &config_file_options.reconnect_loop_sync },
{ .booldefault = false },
{},
{},
{}
},
/* ==========================
* undocumented test settings
* ==========================
*/
/* promote_delay */
{
"promote_delay",
CONFIG_INT,
{ .intptr = &config_file_options.promote_delay },
{ .intdefault = 0 },
{ .intminval = 1 },
{},
{}
},
/* failover_delay */
{
"failover_delay",
CONFIG_INT,
{ .intptr = &config_file_options.failover_delay },
{ .intdefault = 0 },
{ .intminval = 1 },
{},
{}
},
{
"connection_check_query",
CONFIG_STRING,
{ .strptr = config_file_options.connection_check_query },
{ .strdefault = "SELECT 1" },
{},
{ .strmaxlen = sizeof(config_file_options.connection_check_query) },
{}
},
/* End-of-list marker */
{
NULL, CONFIG_INT, {}, {}, {}, {}, {}
}
};

644
configfile-scan.l Normal file
View File

@@ -0,0 +1,644 @@
/*
* Scanner for the configuration file
*/
%{
#include <setjmp.h>
#include <sys/stat.h>
#include <dirent.h>
#include "repmgr.h"
#include "configfile.h"
/*
* flex emits a yy_fatal_error() function that it calls in response to
* critical errors like malloc failure, file I/O errors, and detection of
* internal inconsistency. That function prints a message and calls exit().
* Mutate it to instead call our handler, which jumps out of the parser.
*/
#undef fprintf
#define fprintf(file, fmt, msg) CONF_flex_fatal(msg)
enum
{
CONF_ID = 1,
CONF_STRING = 2,
CONF_INTEGER = 3,
CONF_REAL = 4,
CONF_EQUALS = 5,
CONF_UNQUOTED_STRING = 6,
CONF_QUALIFIED_ID = 7,
CONF_EOL = 99,
CONF_ERROR = 100
};
static unsigned int ConfigFileLineno;
static const char *CONF_flex_fatal_errmsg;
static sigjmp_buf *CONF_flex_fatal_jmp;
static char *CONF_scanstr(const char *s);
static int CONF_flex_fatal(const char *msg);
static bool ProcessConfigFile(const char *base_dir, const char *config_file, const char *calling_file, bool strict, int depth, KeyValueList *contents, ItemList *error_list, ItemList *warning_list);
static bool ProcessConfigFp(FILE *fp, const char *config_file, const char *calling_file, int depth, const char *base_dir, KeyValueList *contents, ItemList *error_list, ItemList *warning_list);
static bool ProcessConfigDirectory(const char *base_dir, const char *includedir, const char *calling_file, int depth, KeyValueList *contents, ItemList *error_list, ItemList *warning_list);
static char *AbsoluteConfigLocation(const char *base_dir, const char *location, const char *calling_file);
%}
%option 8bit
%option never-interactive
%option nodefault
%option noinput
%option nounput
%option noyywrap
%option warn
%option prefix="CONF_yy"
SIGN ("-"|"+")
DIGIT [0-9]
HEXDIGIT [0-9a-fA-F]
UNIT_LETTER [a-zA-Z]
INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+){UNIT_LETTER}*
EXPONENT [Ee]{SIGN}?{DIGIT}+
REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}?
LETTER [A-Za-z_\200-\377]
LETTER_OR_DIGIT [A-Za-z_0-9\200-\377]
ID {LETTER}{LETTER_OR_DIGIT}*
QUALIFIED_ID {ID}"."{ID}
UNQUOTED_STRING {LETTER}({LETTER_OR_DIGIT}|[-._:/])*
STRING \'([^'\\\n]|\\.|\'\')*\'
%%
\n ConfigFileLineno++; return CONF_EOL;
[ \t\r]+ /* eat whitespace */
#.* /* eat comment (.* matches anything until newline) */
{ID} return CONF_ID;
{QUALIFIED_ID} return CONF_QUALIFIED_ID;
{STRING} return CONF_STRING;
{UNQUOTED_STRING} return CONF_UNQUOTED_STRING;
{INTEGER} return CONF_INTEGER;
{REAL} return CONF_REAL;
= return CONF_EQUALS;
. return CONF_ERROR;
%%
extern bool
ProcessRepmgrConfigFile(const char *config_file, const char *base_dir, ItemList *error_list, ItemList *warning_list)
{
return ProcessConfigFile(base_dir, config_file, NULL, true, 0, NULL, error_list, warning_list);
}
extern bool
ProcessPostgresConfigFile(const char *config_file, const char *base_dir, bool strict, KeyValueList *contents, ItemList *error_list, ItemList *warning_list)
{
return ProcessConfigFile(base_dir, config_file, NULL, strict, 0, contents, error_list, warning_list);
}
static bool
ProcessConfigFile(const char *base_dir, const char *config_file, const char *calling_file, bool strict, int depth, KeyValueList *contents, ItemList *error_list, ItemList *warning_list)
{
char *abs_path;
bool success = true;
FILE *fp;
/*
* Reject file name that is all-blank (including empty), as that leads to
* confusion --- we'd try to read the containing directory as a file.
*/
if (strspn(config_file, " \t\r\n") == strlen(config_file))
{
return false;
}
/*
* Reject too-deep include nesting depth. This is just a safety check to
* avoid dumping core due to stack overflow if an include file loops back
* to itself. The maximum nesting depth is pretty arbitrary.
*/
if (depth > 10)
{
item_list_append_format(error_list,
_("could not open configuration file \"%s\": maximum nesting depth exceeded"),
config_file);
return false;
}
abs_path = AbsoluteConfigLocation(base_dir, config_file, calling_file);
/* Reject direct recursion */
if (calling_file && strcmp(abs_path, calling_file) == 0)
{
item_list_append_format(error_list,
_("configuration file recursion in \"%s\""),
calling_file);
pfree(abs_path);
return false;
}
fp = fopen(abs_path, "r");
if (!fp)
{
if (strict == false)
{
item_list_append_format(error_list,
"skipping configuration file \"%s\"",
abs_path);
}
else
{
item_list_append_format(error_list,
"could not open configuration file \"%s\": %s",
abs_path,
strerror(errno));
success = false;
}
}
else
{
success = ProcessConfigFp(fp, abs_path, calling_file, depth + 1, base_dir, contents, error_list, warning_list);
}
free(abs_path);
return success;
}
static bool
ProcessConfigFp(FILE *fp, const char *config_file, const char *calling_file, int depth, const char *base_dir, KeyValueList *contents, ItemList *error_list, ItemList *warning_list)
{
volatile bool OK = true;
volatile YY_BUFFER_STATE lex_buffer = NULL;
sigjmp_buf flex_fatal_jmp;
int errorcount;
int token;
if (sigsetjmp(flex_fatal_jmp, 1) == 0)
{
CONF_flex_fatal_jmp = &flex_fatal_jmp;
}
else
{
/*
* Regain control after a fatal, internal flex error. It may have
* corrupted parser state. Consequently, abandon the file, but trust
* that the state remains sane enough for yy_delete_buffer().
*/
item_list_append_format(error_list,
"%s at file \"%s\" line %u",
CONF_flex_fatal_errmsg, config_file, ConfigFileLineno);
OK = false;
goto cleanup;
}
/*
* Parse
*/
ConfigFileLineno = 1;
errorcount = 0;
lex_buffer = yy_create_buffer(fp, YY_BUF_SIZE);
yy_switch_to_buffer(lex_buffer);
/* This loop iterates once per logical line */
while ((token = yylex()))
{
char *opt_name = NULL;
char *opt_value = NULL;
if (token == CONF_EOL) /* empty or comment line */
continue;
/* first token on line is option name */
if (token != CONF_ID && token != CONF_QUALIFIED_ID)
goto parse_error;
opt_name = pstrdup(yytext);
/* next we have an optional equal sign; discard if present */
token = yylex();
if (token == CONF_EQUALS)
token = yylex();
/* now we must have the option value */
if (token != CONF_ID &&
token != CONF_STRING &&
token != CONF_INTEGER &&
token != CONF_REAL &&
token != CONF_UNQUOTED_STRING)
goto parse_error;
if (token == CONF_STRING) /* strip quotes and escapes */
opt_value = CONF_scanstr(yytext);
else
opt_value = pstrdup(yytext);
/* now we'd like an end of line, or possibly EOF */
token = yylex();
if (token != CONF_EOL)
{
if (token != 0)
goto parse_error;
/* treat EOF like \n for line numbering purposes, cf bug 4752 */
ConfigFileLineno++;
}
/* Handle include files */
if (base_dir != NULL && strcasecmp(opt_name, "include_dir") == 0)
{
/*
* An include_dir directive isn't a variable and should be
* processed immediately.
*/
if (!ProcessConfigDirectory(base_dir, opt_value, config_file,
depth + 1, contents,
error_list, warning_list))
OK = false;
yy_switch_to_buffer(lex_buffer);
pfree(opt_name);
pfree(opt_value);
}
else if (base_dir != NULL && strcasecmp(opt_name, "include_if_exists") == 0)
{
if (!ProcessConfigFile(base_dir, opt_value, config_file,
false, depth + 1, contents,
error_list, warning_list))
OK = false;
yy_switch_to_buffer(lex_buffer);
pfree(opt_name);
pfree(opt_value);
}
else if (base_dir != NULL && strcasecmp(opt_name, "include") == 0)
{
if (!ProcessConfigFile(base_dir, opt_value, config_file,
true, depth + 1, contents,
error_list, warning_list))
OK = false;
yy_switch_to_buffer(lex_buffer);
pfree(opt_name);
pfree(opt_value);
}
else
{
/* OK, process the option name and value */
if (contents != NULL)
{
key_value_list_replace_or_set(contents,
opt_name,
opt_value);
}
else
{
parse_configuration_item(error_list,
warning_list,
opt_name,
opt_value);
}
}
/* break out of loop if read EOF, else loop for next line */
if (token == 0)
break;
continue;
parse_error:
/* release storage if we allocated any on this line */
if (opt_name)
pfree(opt_name);
if (opt_value)
pfree(opt_value);
/* report the error */
if (token == CONF_EOL || token == 0)
{
item_list_append_format(error_list,
_("syntax error in file \"%s\" line %u, near end of line"),
config_file, ConfigFileLineno - 1);
}
else
{
item_list_append_format(error_list,
_("syntax error in file \"%s\" line %u, near token \"%s\""),
config_file, ConfigFileLineno, yytext);
}
OK = false;
errorcount++;
/*
* To avoid producing too much noise when fed a totally bogus file,
* give up after 100 syntax errors per file (an arbitrary number).
* Also, if we're only logging the errors at DEBUG level anyway, might
* as well give up immediately. (This prevents postmaster children
* from bloating the logs with duplicate complaints.)
*/
if (errorcount >= 100)
{
fprintf(stderr,
_("too many syntax errors found, abandoning file \"%s\"\n"),
config_file);
break;
}
/* resync to next end-of-line or EOF */
while (token != CONF_EOL && token != 0)
token = yylex();
/* break out of loop on EOF */
if (token == 0)
break;
}
cleanup:
yy_delete_buffer(lex_buffer);
return OK;
}
/*
* Read and parse all config files in a subdirectory in alphabetical order
*
* includedir is the absolute or relative path to the subdirectory to scan.
*
* See ProcessConfigFp for further details.
*/
static bool
ProcessConfigDirectory(const char *base_dir, const char *includedir, const char *calling_file, int depth, KeyValueList *contents, ItemList *error_list, ItemList *warning_list)
{
char *directory;
DIR *d;
struct dirent *de;
char **filenames;
int num_filenames;
int size_filenames;
bool status;
/*
* Reject directory name that is all-blank (including empty), as that
* leads to confusion --- we'd read the containing directory, typically
* resulting in recursive inclusion of the same file(s).
*/
if (strspn(includedir, " \t\r\n") == strlen(includedir))
{
item_list_append_format(error_list,
_("empty configuration directory name: \"%s\""),
includedir);
return false;
}
directory = AbsoluteConfigLocation(base_dir, includedir, calling_file);
d = opendir(directory);
if (d == NULL)
{
item_list_append_format(error_list,
_("could not open configuration directory \"%s\": %s"),
directory,
strerror(errno));
status = false;
goto cleanup;
}
/*
* Read the directory and put the filenames in an array, so we can sort
* them prior to processing the contents.
*/
size_filenames = 32;
filenames = (char **) palloc(size_filenames * sizeof(char *));
num_filenames = 0;
while ((de = readdir(d)) != NULL)
{
struct stat st;
char filename[MAXPGPATH];
/*
* Only parse files with names ending in ".conf". Explicitly reject
* files starting with ".". This excludes things like "." and "..",
* as well as typical hidden files, backup files, and editor debris.
*/
if (strlen(de->d_name) < 6)
continue;
if (de->d_name[0] == '.')
continue;
if (strcmp(de->d_name + strlen(de->d_name) - 5, ".conf") != 0)
continue;
join_path_components(filename, directory, de->d_name);
canonicalize_path(filename);
if (stat(filename, &st) == 0)
{
if (!S_ISDIR(st.st_mode))
{
/* Add file to array, increasing its size in blocks of 32 */
if (num_filenames >= size_filenames)
{
size_filenames += 32;
filenames = (char **) repalloc(filenames,
size_filenames * sizeof(char *));
}
filenames[num_filenames] = pstrdup(filename);
num_filenames++;
}
}
else
{
/*
* stat does not care about permissions, so the most likely reason
* a file can't be accessed now is if it was removed between the
* directory listing and now.
*/
item_list_append_format(error_list,
_("could not stat file \"%s\": %s"),
filename, strerror(errno));
status = false;
goto cleanup;
}
}
if (num_filenames > 0)
{
int i;
qsort(filenames, num_filenames, sizeof(char *), pg_qsort_strcmp);
for (i = 0; i < num_filenames; i++)
{
if (!ProcessConfigFile(base_dir, filenames[i], calling_file,
true, depth, contents,
error_list, warning_list))
{
status = false;
goto cleanup;
}
}
}
status = true;
cleanup:
if (d)
closedir(d);
pfree(directory);
return status;
}
/*
* scanstr
*
* Strip the quotes surrounding the given string, and collapse any embedded
* '' sequences and backslash escapes.
*
* the string returned is palloc'd and should eventually be pfree'd by the
* caller.
*/
static char *
CONF_scanstr(const char *s)
{
char *newStr;
int len,
i,
j;
Assert(s != NULL && s[0] == '\'');
len = strlen(s);
Assert(s != NULL);
Assert(len >= 2);
Assert(s[len - 1] == '\'');
/* Skip the leading quote; we'll handle the trailing quote below */
s++, len--;
/* Since len still includes trailing quote, this is enough space */
newStr = palloc(len);
for (i = 0, j = 0; i < len; i++)
{
if (s[i] == '\\')
{
i++;
switch (s[i])
{
case 'b':
newStr[j] = '\b';
break;
case 'f':
newStr[j] = '\f';
break;
case 'n':
newStr[j] = '\n';
break;
case 'r':
newStr[j] = '\r';
break;
case 't':
newStr[j] = '\t';
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
{
int k;
long octVal = 0;
for (k = 0;
s[i + k] >= '0' && s[i + k] <= '7' && k < 3;
k++)
octVal = (octVal << 3) + (s[i + k] - '0');
i += k - 1;
newStr[j] = ((char) octVal);
}
break;
default:
newStr[j] = s[i];
break;
} /* switch */
}
else if (s[i] == '\'' && s[i + 1] == '\'')
{
/* doubled quote becomes just one quote */
newStr[j] = s[++i];
}
else
newStr[j] = s[i];
j++;
}
/* We copied the ending quote to newStr, so replace with \0 */
Assert(j > 0 && j <= len);
newStr[--j] = '\0';
return newStr;
}
/*
* Given a configuration file or directory location that may be a relative
* path, return an absolute one. We consider the location to be relative to
* the directory holding the calling file, or to DataDir if no calling file.
*/
static char *
AbsoluteConfigLocation(const char *base_dir, const char *location, const char *calling_file)
{
char abs_path[MAXPGPATH];
if (is_absolute_path(location))
return strdup(location);
if (calling_file != NULL)
{
strlcpy(abs_path, calling_file, sizeof(abs_path));
get_parent_directory(abs_path);
join_path_components(abs_path, abs_path, location);
canonicalize_path(abs_path);
}
else if (base_dir != NULL)
{
join_path_components(abs_path, base_dir, location);
canonicalize_path(abs_path);
}
else
{
strlcpy(abs_path, location, sizeof(abs_path));
}
return strdup(abs_path);
}
/*
* Flex fatal errors bring us here. Stash the error message and jump back to
* ParseConfigFp(). Assume all msg arguments point to string constants; this
* holds for flex 2.5.31 (earliest we support) and flex 2.5.35 (latest as of
* this writing). Otherwise, we would need to copy the message.
*
* We return "int" since this takes the place of calls to fprintf().
*/
static int
CONF_flex_fatal(const char *msg)
{
CONF_flex_fatal_errmsg = msg;
siglongjmp(*CONF_flex_fatal_jmp, 1);
return 0; /* keep compiler quiet */
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/* /*
* configfile.h * configfile.h
* *
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) EnterpriseDB Corporation, 2010-2021
* *
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@@ -28,6 +28,12 @@
/* magic number for use in t_recovery_conf */ /* magic number for use in t_recovery_conf */
#define TARGET_TIMELINE_LATEST 0 #define TARGET_TIMELINE_LATEST 0
/*
* This is defined in src/include/utils.h, however it's not practical
* to include that from a frontend application.
*/
#define PG_AUTOCONF_FILENAME "postgresql.auto.conf"
extern bool config_file_found; extern bool config_file_found;
extern char config_file_path[MAXPGPATH]; extern char config_file_path[MAXPGPATH];
@@ -44,6 +50,11 @@ typedef enum
CHECK_CONNECTION CHECK_CONNECTION
} ConnectionCheckType; } ConnectionCheckType;
typedef enum
{
REPLICATION_TYPE_PHYSICAL
} ReplicationType;
typedef struct EventNotificationListCell typedef struct EventNotificationListCell
{ {
struct EventNotificationListCell *next; struct EventNotificationListCell *next;
@@ -72,6 +83,58 @@ typedef struct TablespaceList
} TablespaceList; } TablespaceList;
typedef enum
{
CONFIG_BOOL,
CONFIG_INT,
CONFIG_STRING,
CONFIG_FAILOVER_MODE,
CONFIG_CONNECTION_CHECK_TYPE,
CONFIG_EVENT_NOTIFICATION_LIST,
CONFIG_TABLESPACE_MAPPING,
CONFIG_REPLICATION_TYPE
} ConfigItemType;
typedef struct ConfigFileSetting
{
const char *name;
ConfigItemType type;
union
{
int *intptr;
char *strptr;
bool *boolptr;
failover_mode_opt *failovermodeptr;
ConnectionCheckType *checktypeptr;
EventNotificationList *notificationlistptr;
TablespaceList *tablespacemappingptr;
ReplicationType *replicationtypeptr;
} val;
union {
int intdefault;
const char *strdefault;
bool booldefault;
failover_mode_opt failovermodedefault;
ConnectionCheckType checktypedefault;
ReplicationType replicationtypedefault;
} defval;
union {
int intminval;
} minval;
union {
int strmaxlen;
} maxval;
struct {
void (*process_func)(const char *, const char *, char *, ItemList *errors);
void (*postprocess_func)(const char *, const char *, char *, ItemList *errors);
bool *providedptr;
} process;
} ConfigFileSetting;
/* Declare the main configfile structure for client applications */
extern ConfigFileSetting config_file_settings[];
typedef struct typedef struct
{ {
/* node information */ /* node information */
@@ -83,12 +146,12 @@ typedef struct
char config_directory[MAXPGPATH]; char config_directory[MAXPGPATH];
char pg_bindir[MAXPGPATH]; char pg_bindir[MAXPGPATH];
char repmgr_bindir[MAXPGPATH]; char repmgr_bindir[MAXPGPATH];
int replication_type; ReplicationType replication_type;
/* log settings */ /* log settings */
char log_level[MAXLEN]; char log_level[MAXLEN];
char log_facility[MAXLEN]; char log_facility[MAXLEN];
char log_file[MAXLEN]; char log_file[MAXPGPATH];
int log_status_interval; int log_status_interval;
/* standby clone settings */ /* standby clone settings */
@@ -101,6 +164,10 @@ typedef struct
char archive_cleanup_command[MAXLEN]; char archive_cleanup_command[MAXLEN];
bool use_primary_conninfo_password; bool use_primary_conninfo_password;
char passfile[MAXPGPATH]; char passfile[MAXPGPATH];
char pg_backupapi_backup_id[NAMEDATALEN];
char pg_backupapi_host[NAMEDATALEN];
char pg_backupapi_node_name[NAMEDATALEN];
char pg_backupapi_remote_ssh_command[MAXLEN];
/* standby promote settings */ /* standby promote settings */
int promote_check_timeout; int promote_check_timeout;
@@ -109,6 +176,7 @@ typedef struct
/* standby follow settings */ /* standby follow settings */
int primary_follow_timeout; int primary_follow_timeout;
int standby_follow_timeout; int standby_follow_timeout;
bool standby_follow_restart;
/* standby switchover settings */ /* standby switchover settings */
int shutdown_check_timeout; int shutdown_check_timeout;
@@ -142,16 +210,20 @@ typedef struct
int primary_notification_timeout; int primary_notification_timeout;
int repmgrd_standby_startup_timeout; int repmgrd_standby_startup_timeout;
char repmgrd_pid_file[MAXPGPATH]; char repmgrd_pid_file[MAXPGPATH];
bool repmgrd_exit_on_inactive_node;
bool standby_disconnect_on_failover; bool standby_disconnect_on_failover;
int sibling_nodes_disconnect_timeout; int sibling_nodes_disconnect_timeout;
ConnectionCheckType connection_check_type; ConnectionCheckType connection_check_type;
bool primary_visibility_consensus; bool primary_visibility_consensus;
bool always_promote;
char failover_validation_command[MAXPGPATH]; char failover_validation_command[MAXPGPATH];
int election_rerun_interval; int election_rerun_interval;
int child_nodes_check_interval;
/* BDR settings */ int child_nodes_disconnect_min_count;
bool bdr_local_monitoring_only; int child_nodes_connected_min_count;
bool bdr_recovery_timeout; bool child_nodes_connected_include_witness;
int child_nodes_disconnect_timeout;
char child_nodes_disconnect_command[MAXPGPATH];
/* service settings */ /* service settings */
char pg_ctl_options[MAXLEN]; char pg_ctl_options[MAXLEN];
@@ -179,74 +251,35 @@ typedef struct
char rsync_options[MAXLEN]; char rsync_options[MAXLEN];
char ssh_options[MAXLEN]; char ssh_options[MAXLEN];
/* undocumented test settings */ /*
* undocumented settings
*
* These settings are for testing or experimental features
* and may be changed without notice.
*/
/* experimental settings */
bool reconnect_loop_sync;
/* test settings */
int promote_delay; int promote_delay;
int failover_delay;
char connection_check_query[MAXLEN];
} t_configuration_options; } t_configuration_options;
/*
* The following will initialize the structure with a minimal set of options;
* actual defaults are set in parse_config() before parsing the configuration file
*/
#define T_CONFIGURATION_OPTIONS_INITIALIZER { \
/* node information */ \
UNKNOWN_NODE_ID, "", "", "", "", "", "", "", REPLICATION_TYPE_PHYSICAL, \
/* log settings */ \
"", "", "", DEFAULT_LOG_STATUS_INTERVAL, \
/* standby clone settings */ \
false, "", "", { NULL, NULL }, "", false, "", false, "", \
/* standby promote settings */ \
DEFAULT_PROMOTE_CHECK_TIMEOUT, DEFAULT_PROMOTE_CHECK_INTERVAL, \
/* standby follow settings */ \
DEFAULT_PRIMARY_FOLLOW_TIMEOUT, \
DEFAULT_STANDBY_FOLLOW_TIMEOUT, \
/* standby switchover settings */ \
DEFAULT_SHUTDOWN_CHECK_TIMEOUT, \
DEFAULT_STANDBY_RECONNECT_TIMEOUT, \
DEFAULT_WAL_RECEIVE_CHECK_TIMEOUT, \
/* node rejoin settings */ \
DEFAULT_NODE_REJOIN_TIMEOUT, \
/* node check settings */ \
DEFAULT_ARCHIVE_READY_WARNING, DEFAULT_ARCHIVE_READY_CRITICAL, \
DEFAULT_REPLICATION_LAG_WARNING, DEFAULT_REPLICATION_LAG_CRITICAL, \
/* witness settings */ \
DEFAULT_WITNESS_SYNC_INTERVAL, \
/* repmgrd settings */ \
FAILOVER_MANUAL, DEFAULT_LOCATION, DEFAULT_PRIORITY, "", "", \
DEFAULT_MONITORING_INTERVAL, \
DEFAULT_RECONNECTION_ATTEMPTS, \
DEFAULT_RECONNECTION_INTERVAL, \
false, -1, \
DEFAULT_ASYNC_QUERY_TIMEOUT, \
DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT, \
-1, "", false, DEFAULT_SIBLING_NODES_DISCONNECT_TIMEOUT, \
CHECK_PING, true, "", DEFAULT_ELECTION_RERUN_INTERVAL, \
/* BDR settings */ \
false, DEFAULT_BDR_RECOVERY_TIMEOUT, \
/* service settings */ \
"", "", "", "", "", "", \
/* repmgrd service settings */ \
"", "", \
/* event notification settings */ \
"", "", { NULL, NULL }, \
/* barman settings */ \
"", "", "", \
/* rsync/ssh settings */ \
"", "", \
/* undocumented test settings */ \
0 \
}
/* Declare the main configfile structure for client applications */
extern t_configuration_options config_file_options;
typedef struct typedef struct
{ {
char slot[MAXLEN]; char slot[MAXLEN];
char xlog_method[MAXLEN]; char wal_method[MAXLEN];
char waldir[MAXPGPATH];
bool no_slot; /* from PostgreSQL 10 */ bool no_slot; /* from PostgreSQL 10 */
} t_basebackup_options; } t_basebackup_options;
#define T_BASEBACKUP_OPTIONS_INITIALIZER { "", "", false } #define T_BASEBACKUP_OPTIONS_INITIALIZER { "", "", "", false }
typedef enum typedef enum
@@ -303,8 +336,11 @@ typedef struct
void set_progname(const char *argv0); void set_progname(const char *argv0);
const char *progname(void); const char *progname(void);
void load_config(const char *config_file, bool verbose, bool terse, t_configuration_options *options, char *argv0); void load_config(const char *config_file, bool verbose, bool terse, char *argv0);
bool reload_config(t_configuration_options *orig_options, t_server_type server_type); bool reload_config(t_server_type server_type);
void dump_config(void);
void parse_configuration_item(ItemList *error_list, ItemList *warning_list, const char *name, const char *value);
bool parse_recovery_conf(const char *data_dir, t_recovery_conf *conf); bool parse_recovery_conf(const char *data_dir, t_recovery_conf *conf);
@@ -317,6 +353,9 @@ int repmgr_atoi(const char *s,
ItemList *error_list, ItemList *error_list,
int minval); int minval);
void parse_time_unit_parameter(const char *name, const char *value, char *dest, ItemList *errors);
void repmgr_canonicalize_path(const char *name, const char *value, char *config_item, ItemList *errors);
bool parse_pg_basebackup_options(const char *pg_basebackup_options, bool parse_pg_basebackup_options(const char *pg_basebackup_options,
t_basebackup_options *backup_options, t_basebackup_options *backup_options,
int server_version_num, int server_version_num,
@@ -324,11 +363,21 @@ bool parse_pg_basebackup_options(const char *pg_basebackup_options,
int parse_output_to_argv(const char *string, char ***argv_array); int parse_output_to_argv(const char *string, char ***argv_array);
void free_parsed_argv(char ***argv_array); void free_parsed_argv(char ***argv_array);
const char *format_failover_mode(failover_mode_opt failover);
/* called by repmgr-client and repmgrd */ /* called by repmgr-client and repmgrd */
void exit_with_cli_errors(ItemList *error_list, const char *repmgr_command); void exit_with_cli_errors(ItemList *error_list, const char *repmgr_command);
void print_item_list(ItemList *item_list); void print_item_list(ItemList *item_list);
const char *print_replication_type(ReplicationType type);
const char *print_connection_check_type(ConnectionCheckType type); const char *print_connection_check_type(ConnectionCheckType type);
char *print_event_notification_list(EventNotificationList *list);
char *print_tablespace_mapping(TablespaceList *tablespacemappingptr);
extern bool modify_auto_conf(const char *data_dir, KeyValueList *items);
extern bool ProcessRepmgrConfigFile(const char *config_file, const char *base_dir, ItemList *error_list, ItemList *warning_list);
extern bool ProcessPostgresConfigFile(const char *config_file, const char *base_dir, bool strict, KeyValueList *contents, ItemList *error_list, ItemList *warning_list);
#endif /* _REPMGR_CONFIGFILE_H_ */ #endif /* _REPMGR_CONFIGFILE_H_ */

163
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for repmgr 4.3. # Generated by GNU Autoconf 2.69 for repmgr 5.4.0.
# #
# Report bugs to <repmgr@googlegroups.com>. # Report bugs to <repmgr@googlegroups.com>.
# #
@@ -11,7 +11,7 @@
# This configure script is free software; the Free Software Foundation # This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it. # gives unlimited permission to copy, distribute and modify it.
# #
# Copyright (c) 2010-2019, 2ndQuadrant Ltd. # Copyright (c) 2010-2021, EnterpriseDB Corporation
## -------------------- ## ## -------------------- ##
## M4sh Initialization. ## ## M4sh Initialization. ##
## -------------------- ## ## -------------------- ##
@@ -582,13 +582,16 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='repmgr' PACKAGE_NAME='repmgr'
PACKAGE_TARNAME='repmgr' PACKAGE_TARNAME='repmgr'
PACKAGE_VERSION='4.3' PACKAGE_VERSION='5.4.0'
PACKAGE_STRING='repmgr 4.3' PACKAGE_STRING='repmgr 5.4.0'
PACKAGE_BUGREPORT='repmgr@googlegroups.com' PACKAGE_BUGREPORT='repmgr@googlegroups.com'
PACKAGE_URL='https://repmgr.org/' PACKAGE_URL='https://repmgr.org/'
ac_subst_vars='LTLIBOBJS ac_subst_vars='LTLIBOBJS
LIBOBJS LIBOBJS
HAVE_SED
HAVE_GSED
HAVE_GNUSED
vpath_build vpath_build
SED SED
PG_CONFIG PG_CONFIG
@@ -1178,7 +1181,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures repmgr 4.3 to adapt to many kinds of systems. \`configure' configures repmgr 5.4.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1239,7 +1242,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of repmgr 4.3:";; short | recursive ) echo "Configuration of repmgr 5.4.0:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1313,14 +1316,14 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
repmgr configure 4.3 repmgr configure 5.4.0
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it. gives unlimited permission to copy, distribute and modify it.
Copyright (c) 2010-2019, 2ndQuadrant Ltd. Copyright (c) 2010-2021, EnterpriseDB Corporation
_ACEOF _ACEOF
exit exit
fi fi
@@ -1332,7 +1335,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by repmgr $as_me 4.3, which was It was created by repmgr $as_me 5.4.0, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@@ -1808,11 +1811,11 @@ fi
pgac_pg_config_version=$($PG_CONFIG --version 2>/dev/null) pgac_pg_config_version=$($PG_CONFIG --version 2>/dev/null)
major_version_num=$(echo "$pgac_pg_config_version"| major_version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^PostgreSQL \([0-9]\{1,2\}\).*$/\1/') $SED -e 's/^[^0-9]\+ \([0-9]\{1,2\}\).*$/\1/')
if test "$major_version_num" -lt '10'; then if test "$major_version_num" -lt '10'; then
version_num=$(echo "$pgac_pg_config_version"| version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^PostgreSQL \([0-9]*\)\.\([0-9]*\)\([a-zA-Z0-9.]*\)$/\1.\2/') $SED -e 's/^[^0-9]\+ \([0-9]*\)\.\([0-9]*\)\([a-zA-Z0-9.]*\)$/\1.\2/')
if test -z "$version_num"; then if test -z "$version_num"; then
as_fn_error $? "could not detect the PostgreSQL version, wrong or broken pg_config?" "$LINENO" 5 as_fn_error $? "could not detect the PostgreSQL version, wrong or broken pg_config?" "$LINENO" 5
@@ -1821,12 +1824,12 @@ if test "$major_version_num" -lt '10'; then
version_num_int=$(echo "$version_num"| version_num_int=$(echo "$version_num"|
$SED -e 's/^\([0-9]*\)\.\([0-9]*\)$/\1\2/') $SED -e 's/^\([0-9]*\)\.\([0-9]*\)$/\1\2/')
if test "$version_num_int" -lt '93'; then if test "$version_num_int" -lt '94'; then
as_fn_error $? "repmgr is not compatible with detected PostgreSQL version: $version_num" "$LINENO" 5 as_fn_error $? "repmgr is not compatible with detected PostgreSQL version: $version_num" "$LINENO" 5
fi fi
else else
version_num=$(echo "$pgac_pg_config_version"| version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^PostgreSQL \(.\+\)$/\1/') $SED -e 's/^[^0-9]\+ \(.\+\)$/\1/')
if test -z "$version_num"; then if test -z "$version_num"; then
as_fn_error $? "could not detect the PostgreSQL version, wrong or broken pg_config?" "$LINENO" 5 as_fn_error $? "could not detect the PostgreSQL version, wrong or broken pg_config?" "$LINENO" 5
@@ -1847,12 +1850,137 @@ else
fi fi
# Extract the first word of "gnused", so it can be a program name with args.
set dummy gnused; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_HAVE_GNUSED+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$HAVE_GNUSED"; then
ac_cv_prog_HAVE_GNUSED="$HAVE_GNUSED" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_HAVE_GNUSED="yes"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
test -z "$ac_cv_prog_HAVE_GNUSED" && ac_cv_prog_HAVE_GNUSED="no"
fi
fi
HAVE_GNUSED=$ac_cv_prog_HAVE_GNUSED
if test -n "$HAVE_GNUSED"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_GNUSED" >&5
$as_echo "$HAVE_GNUSED" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
# Extract the first word of "gsed", so it can be a program name with args.
set dummy gsed; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_HAVE_GSED+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$HAVE_GSED"; then
ac_cv_prog_HAVE_GSED="$HAVE_GSED" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_HAVE_GSED="yes"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
test -z "$ac_cv_prog_HAVE_GSED" && ac_cv_prog_HAVE_GSED="no"
fi
fi
HAVE_GSED=$ac_cv_prog_HAVE_GSED
if test -n "$HAVE_GSED"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_GSED" >&5
$as_echo "$HAVE_GSED" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
# Extract the first word of "sed", so it can be a program name with args.
set dummy sed; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_HAVE_SED+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$HAVE_SED"; then
ac_cv_prog_HAVE_SED="$HAVE_SED" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_HAVE_SED="yes"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
test -z "$ac_cv_prog_HAVE_SED" && ac_cv_prog_HAVE_SED="no"
fi
fi
HAVE_SED=$ac_cv_prog_HAVE_SED
if test -n "$HAVE_SED"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_SED" >&5
$as_echo "$HAVE_SED" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "$HAVE_GNUSED" = yes; then
SED=gnused
else
if test "$HAVE_GSED" = yes; then
SED=gsed
else
SED=sed
fi
fi
ac_config_files="$ac_config_files Makefile" ac_config_files="$ac_config_files Makefile"
ac_config_files="$ac_config_files Makefile.global" ac_config_files="$ac_config_files Makefile.global"
ac_config_files="$ac_config_files doc/Makefile"
cat >confcache <<\_ACEOF cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure # This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure # tests run on this system so they can be shared between configure
@@ -2359,7 +2487,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by repmgr $as_me 4.3, which was This file was extended by repmgr $as_me 5.4.0, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -2422,7 +2550,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
repmgr config.status 4.3 repmgr config.status 5.4.0
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"
@@ -2546,7 +2674,6 @@ do
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"Makefile.global") CONFIG_FILES="$CONFIG_FILES Makefile.global" ;; "Makefile.global") CONFIG_FILES="$CONFIG_FILES Makefile.global" ;;
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac esac

View File

@@ -1,6 +1,6 @@
AC_INIT([repmgr], [4.3], [repmgr@googlegroups.com], [repmgr], [https://repmgr.org/]) AC_INIT([repmgr], [5.4.0], [repmgr@googlegroups.com], [repmgr], [https://repmgr.org/])
AC_COPYRIGHT([Copyright (c) 2010-2019, 2ndQuadrant Ltd.]) AC_COPYRIGHT([Copyright (c) 2010-2021, EnterpriseDB Corporation])
AC_CONFIG_HEADER(config.h) AC_CONFIG_HEADER(config.h)
@@ -19,11 +19,11 @@ fi
pgac_pg_config_version=$($PG_CONFIG --version 2>/dev/null) pgac_pg_config_version=$($PG_CONFIG --version 2>/dev/null)
major_version_num=$(echo "$pgac_pg_config_version"| major_version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^PostgreSQL \([[0-9]]\{1,2\}\).*$/\1/') $SED -e 's/^[[^0-9]]\+ \([[0-9]]\{1,2\}\).*$/\1/')
if test "$major_version_num" -lt '10'; then if test "$major_version_num" -lt '10'; then
version_num=$(echo "$pgac_pg_config_version"| version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^PostgreSQL \([[0-9]]*\)\.\([[0-9]]*\)\([[a-zA-Z0-9.]]*\)$/\1.\2/') $SED -e 's/^[[^0-9]]\+ \([[0-9]]*\)\.\([[0-9]]*\)\([[a-zA-Z0-9.]]*\)$/\1.\2/')
if test -z "$version_num"; then if test -z "$version_num"; then
AC_MSG_ERROR([could not detect the PostgreSQL version, wrong or broken pg_config?]) AC_MSG_ERROR([could not detect the PostgreSQL version, wrong or broken pg_config?])
@@ -32,12 +32,12 @@ if test "$major_version_num" -lt '10'; then
version_num_int=$(echo "$version_num"| version_num_int=$(echo "$version_num"|
$SED -e 's/^\([[0-9]]*\)\.\([[0-9]]*\)$/\1\2/') $SED -e 's/^\([[0-9]]*\)\.\([[0-9]]*\)$/\1\2/')
if test "$version_num_int" -lt '93'; then if test "$version_num_int" -lt '94'; then
AC_MSG_ERROR([repmgr is not compatible with detected PostgreSQL version: $version_num]) AC_MSG_ERROR([repmgr is not compatible with detected PostgreSQL version: $version_num])
fi fi
else else
version_num=$(echo "$pgac_pg_config_version"| version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^PostgreSQL \(.\+\)$/\1/') $SED -e 's/^[[^0-9]]\+ \(.\+\)$/\1/')
if test -z "$version_num"; then if test -z "$version_num"; then
AC_MSG_ERROR([could not detect the PostgreSQL version, wrong or broken pg_config?]) AC_MSG_ERROR([could not detect the PostgreSQL version, wrong or broken pg_config?])
@@ -57,8 +57,43 @@ else
fi fi
AC_SUBST(vpath_build) AC_SUBST(vpath_build)
AC_CHECK_PROG(HAVE_GNUSED,gnused,yes,no)
AC_CHECK_PROG(HAVE_GSED,gsed,yes,no)
AC_CHECK_PROG(HAVE_SED,sed,yes,no)
AC_CHECK_PROG(HAVE_FLEX,flex,yes,no)
if test "$HAVE_GNUSED" = yes; then
SED=gnused
else
if test "$HAVE_GSED" = yes; then
SED=gsed
else
SED=sed
fi
fi
AC_SUBST(SED)
AS_IF([test x"$HAVE_FLEX" != x"yes"], AC_MSG_ERROR([flex should be installed first]))
#Checking libraries
GENERIC_LIB_FAILED_MSG="library should be installed"
AC_CHECK_LIB(selinux, is_selinux_enabled, [],
[AC_MSG_ERROR(['selinux' $GENERIC_LIB_FAILED_MSG])])
AC_CHECK_LIB(lz4, LZ4_compress_default, [],
[AC_MSG_ERROR(['Z4' $GENERIC_LIB_FAILED_MSG])])
AC_CHECK_LIB(xslt, xsltCleanupGlobals, [],
[AC_MSG_ERROR(['xslt' $GENERIC_LIB_FAILED_MSG])])
AC_CHECK_LIB(pam, pam_start, [],
[AC_MSG_ERROR(['pam' $GENERIC_LIB_FAILED_MSG])])
AC_CHECK_LIB(gssapi_krb5, gss_init_sec_context, [],
[AC_MSG_ERROR([gssapi_krb5 $GENERIC_LIB_FAILED_MSG])])
AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([Makefile.global]) AC_CONFIG_FILES([Makefile.global])
AC_CONFIG_FILES([doc/Makefile])
AC_OUTPUT AC_OUTPUT

View File

@@ -73,7 +73,16 @@ while(<$fh>) {
if ($param eq 'data_directory') { if ($param eq 'data_directory') {
$data_directory_found = 1; $data_directory_found = 1;
} }
push @outp, $line;
# Don't quote numbers
if ($value =~ /^\d+$/) {
push @outp, sprintf(q|%s=%s|, $param, $value);
}
# Quote everything else
else {
$value =~ s/'/''/g;
push @outp, sprintf(q|%s='%s'|, $param, $value);
}
} }
} }
@@ -83,6 +92,6 @@ print join("\n", @outp);
print "\n"; print "\n";
if ($data_directory_found == 0) { if ($data_directory_found == 0) {
print "data_directory=\n"; print "data_directory=''\n";
} }

View File

@@ -2,11 +2,11 @@
* controldata.c - functions for reading the pg_control file * controldata.c - functions for reading the pg_control file
* *
* The functions provided here enable repmgr to read a pg_control file * The functions provided here enable repmgr to read a pg_control file
* in a version-indepent way, even if the PostgreSQL instance is not * in a version-independent way, even if the PostgreSQL instance is not
* running. For that reason we can't use on the pg_control_*() functions * running. For that reason we can't use on the pg_control_*() functions
* provided in PostgreSQL 9.6 and later. * provided in PostgreSQL 9.6 and later.
* *
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) EnterpriseDB Corporation, 2010-2021
* *
* Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
@@ -90,7 +90,9 @@ get_system_identifier(const char *data_directory)
uint64 system_identifier = UNKNOWN_SYSTEM_IDENTIFIER; uint64 system_identifier = UNKNOWN_SYSTEM_IDENTIFIER;
control_file_info = get_controlfile(data_directory); control_file_info = get_controlfile(data_directory);
system_identifier = control_file_info->system_identifier;
if (control_file_info->control_file_processed == true)
system_identifier = control_file_info->system_identifier;
pfree(control_file_info); pfree(control_file_info);
@@ -98,19 +100,21 @@ get_system_identifier(const char *data_directory)
} }
DBState bool
get_db_state(const char *data_directory) get_db_state(const char *data_directory, DBState *state)
{ {
ControlFileInfo *control_file_info = NULL; ControlFileInfo *control_file_info = NULL;
DBState state; bool control_file_processed;
control_file_info = get_controlfile(data_directory); control_file_info = get_controlfile(data_directory);
control_file_processed = control_file_info->control_file_processed;
state = control_file_info->state; if (control_file_processed == true)
*state = control_file_info->state;
pfree(control_file_info); pfree(control_file_info);
return state; return control_file_processed;
} }
@@ -122,7 +126,8 @@ get_latest_checkpoint_location(const char *data_directory)
control_file_info = get_controlfile(data_directory); control_file_info = get_controlfile(data_directory);
checkPoint = control_file_info->checkPoint; if (control_file_info->control_file_processed == true)
checkPoint = control_file_info->checkPoint;
pfree(control_file_info); pfree(control_file_info);
@@ -134,11 +139,12 @@ int
get_data_checksum_version(const char *data_directory) get_data_checksum_version(const char *data_directory)
{ {
ControlFileInfo *control_file_info = NULL; ControlFileInfo *control_file_info = NULL;
int data_checksum_version = -1; int data_checksum_version = UNKNOWN_DATA_CHECKSUM_VERSION;
control_file_info = get_controlfile(data_directory); control_file_info = get_controlfile(data_directory);
data_checksum_version = (int) control_file_info->data_checksum_version; if (control_file_info->control_file_processed == true)
data_checksum_version = (int) control_file_info->data_checksum_version;
pfree(control_file_info); pfree(control_file_info);
@@ -277,8 +283,19 @@ get_controlfile(const char *DataDir)
return control_file_info; return control_file_info;
} }
if (version_num >= 120000)
if (version_num >= 90500) {
#if PG_ACTUAL_VERSION_NUM >= 120000
expected_size = sizeof(ControlFileData12);
ControlFileDataPtr = palloc0(expected_size);
#endif
}
else if (version_num >= 110000)
{
expected_size = sizeof(ControlFileData11);
ControlFileDataPtr = palloc0(expected_size);
}
else if (version_num >= 90500)
{ {
expected_size = sizeof(ControlFileData95); expected_size = sizeof(ControlFileData95);
ControlFileDataPtr = palloc0(expected_size); ControlFileDataPtr = palloc0(expected_size);
@@ -288,12 +305,6 @@ get_controlfile(const char *DataDir)
expected_size = sizeof(ControlFileData94); expected_size = sizeof(ControlFileData94);
ControlFileDataPtr = palloc0(expected_size); ControlFileDataPtr = palloc0(expected_size);
} }
else if (version_num >= 90300)
{
expected_size = sizeof(ControlFileData93);
ControlFileDataPtr = palloc0(expected_size);
}
if (read(fd, ControlFileDataPtr, expected_size) != expected_size) if (read(fd, ControlFileDataPtr, expected_size) != expected_size)
{ {
@@ -310,7 +321,23 @@ get_controlfile(const char *DataDir)
control_file_info->control_file_processed = true; control_file_info->control_file_processed = true;
if (version_num >= 110000) if (version_num >= 120000)
{
#if PG_ACTUAL_VERSION_NUM >= 120000
ControlFileData12 *ptr = (struct ControlFileData12 *)ControlFileDataPtr;
control_file_info->system_identifier = ptr->system_identifier;
control_file_info->state = ptr->state;
control_file_info->checkPoint = ptr->checkPoint;
control_file_info->data_checksum_version = ptr->data_checksum_version;
control_file_info->timeline = ptr->checkPointCopy.ThisTimeLineID;
control_file_info->minRecoveryPointTLI = ptr->minRecoveryPointTLI;
control_file_info->minRecoveryPoint = ptr->minRecoveryPoint;
#else
fprintf(stderr, "ERROR: please use a repmgr version built for PostgreSQL 12 or later\n");
exit(ERR_BAD_CONFIG);
#endif
}
else if (version_num >= 110000)
{ {
ControlFileData11 *ptr = (struct ControlFileData11 *)ControlFileDataPtr; ControlFileData11 *ptr = (struct ControlFileData11 *)ControlFileDataPtr;
control_file_info->system_identifier = ptr->system_identifier; control_file_info->system_identifier = ptr->system_identifier;
@@ -343,17 +370,6 @@ get_controlfile(const char *DataDir)
control_file_info->minRecoveryPointTLI = ptr->minRecoveryPointTLI; control_file_info->minRecoveryPointTLI = ptr->minRecoveryPointTLI;
control_file_info->minRecoveryPoint = ptr->minRecoveryPoint; control_file_info->minRecoveryPoint = ptr->minRecoveryPoint;
} }
else if (version_num >= 90300)
{
ControlFileData93 *ptr = (struct ControlFileData93 *)ControlFileDataPtr;
control_file_info->system_identifier = ptr->system_identifier;
control_file_info->state = ptr->state;
control_file_info->checkPoint = ptr->checkPoint;
control_file_info->data_checksum_version = ptr->data_checksum_version;
control_file_info->timeline = ptr->checkPointCopy.ThisTimeLineID;
control_file_info->minRecoveryPointTLI = ptr->minRecoveryPointTLI;
control_file_info->minRecoveryPoint = ptr->minRecoveryPoint;
}
pfree(ControlFileDataPtr); pfree(ControlFileDataPtr);

View File

@@ -1,6 +1,6 @@
/* /*
* controldata.h * controldata.h
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) EnterpriseDB Corporation, 2010-2021
* *
* Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
@@ -12,6 +12,7 @@
#include "postgres_fe.h" #include "postgres_fe.h"
#include "catalog/pg_control.h" #include "catalog/pg_control.h"
#define MAX_VERSION_STRING 24 #define MAX_VERSION_STRING 24
/* /*
* A simplified representation of pg_control containing only those fields * A simplified representation of pg_control containing only those fields
@@ -30,9 +31,7 @@ typedef struct
} ControlFileInfo; } ControlFileInfo;
typedef struct CheckPoint94
/* Same for 9.3, 9.4 */
typedef struct CheckPoint93
{ {
XLogRecPtr redo; /* next RecPtr available when we began to XLogRecPtr redo; /* next RecPtr available when we began to
* create CheckPoint (i.e. REDO start point) */ * create CheckPoint (i.e. REDO start point) */
@@ -52,10 +51,10 @@ typedef struct CheckPoint93
pg_time_t time; /* time stamp of checkpoint */ pg_time_t time; /* time stamp of checkpoint */
TransactionId oldestActiveXid; TransactionId oldestActiveXid;
} CheckPoint93; } CheckPoint94;
/* Same for 9.5, 9.6, 10, HEAD */ /* Same for 9.5, 9.6, 10, 11 */
typedef struct CheckPoint95 typedef struct CheckPoint95
{ {
XLogRecPtr redo; /* next RecPtr available when we began to XLogRecPtr redo; /* next RecPtr available when we began to
@@ -83,66 +82,51 @@ typedef struct CheckPoint95
} CheckPoint95; } CheckPoint95;
typedef struct ControlFileData93 #if PG_ACTUAL_VERSION_NUM >= 120000
{
uint64 system_identifier;
uint32 pg_control_version; /* PG_CONTROL_VERSION */
uint32 catalog_version_no; /* see catversion.h */
DBState state; /* see enum above */
pg_time_t time; /* time stamp of last pg_control update */
XLogRecPtr checkPoint; /* last check point record ptr */
XLogRecPtr prevCheckPoint; /* previous check point record ptr */
CheckPoint93 checkPointCopy; /* copy of last check point record */
XLogRecPtr unloggedLSN; /* current fake LSN value, for unlogged rels */
XLogRecPtr minRecoveryPoint;
TimeLineID minRecoveryPointTLI;
XLogRecPtr backupStartPoint;
XLogRecPtr backupEndPoint;
bool backupEndRequired;
int wal_level;
int MaxConnections;
int max_prepared_xacts;
int max_locks_per_xact;
uint32 maxAlign; /* alignment requirement for tuples */
double floatFormat; /* constant 1234567.0 */
uint32 blcksz; /* data block size for this DB */
uint32 relseg_size; /* blocks per segment of large relation */
uint32 xlog_blcksz; /* block size within WAL files */
uint32 xlog_seg_size; /* size of each WAL segment */
uint32 nameDataLen; /* catalog name field width */
uint32 indexMaxKeys; /* max number of columns in an index */
uint32 toast_max_chunk_size; /* chunk size in TOAST tables */
/* flag indicating internal format of timestamp, interval, time */
bool enableIntTimes; /* int64 storage enabled? */
/* flags indicating pass-by-value status of various types */
bool float4ByVal; /* float4 pass-by-value? */
bool float8ByVal; /* float8, int8, etc pass-by-value? */
/* Are data pages protected by checksums? Zero if no checksum version */
uint32 data_checksum_version;
} ControlFileData93;
/* /*
* Following field added since 9.3: * Following fields removed in PostgreSQL 12;
* *
* int max_worker_processes; * uint32 nextXidEpoch;
* TransactionId nextXid;
*
* and replaced by:
*
* FullTransactionId nextFullXid;
*/ */
typedef struct CheckPoint12
{
XLogRecPtr redo; /* next RecPtr available when we began to
* create CheckPoint (i.e. REDO start point) */
TimeLineID ThisTimeLineID; /* current TLI */
TimeLineID PrevTimeLineID; /* previous TLI, if this record begins a new
* timeline (equals ThisTimeLineID otherwise) */
bool fullPageWrites; /* current full_page_writes */
FullTransactionId nextFullXid; /* next free full transaction ID */
Oid nextOid; /* next free OID */
MultiXactId nextMulti; /* next free MultiXactId */
MultiXactOffset nextMultiOffset; /* next free MultiXact offset */
TransactionId oldestXid; /* cluster-wide minimum datfrozenxid */
Oid oldestXidDB; /* database with minimum datfrozenxid */
MultiXactId oldestMulti; /* cluster-wide minimum datminmxid */
Oid oldestMultiDB; /* database with minimum datminmxid */
pg_time_t time; /* time stamp of checkpoint */
TransactionId oldestCommitTsXid; /* oldest Xid with valid commit
* timestamp */
TransactionId newestCommitTsXid; /* newest Xid with valid commit
* timestamp */
/*
* Oldest XID still running. This is only needed to initialize hot standby
* mode from an online checkpoint, so we only bother calculating this for
* online checkpoints and only when wal_level is replica. Otherwise it's
* set to InvalidTransactionId.
*/
TransactionId oldestActiveXid;
} CheckPoint12;
#endif
typedef struct ControlFileData94 typedef struct ControlFileData94
{ {
uint64 system_identifier; uint64 system_identifier;
@@ -155,7 +139,7 @@ typedef struct ControlFileData94
XLogRecPtr checkPoint; /* last check point record ptr */ XLogRecPtr checkPoint; /* last check point record ptr */
XLogRecPtr prevCheckPoint; /* previous check point record ptr */ XLogRecPtr prevCheckPoint; /* previous check point record ptr */
CheckPoint93 checkPointCopy; /* copy of last check point record */ CheckPoint94 checkPointCopy; /* copy of last check point record */
XLogRecPtr unloggedLSN; /* current fake LSN value, for unlogged rels */ XLogRecPtr unloggedLSN; /* current fake LSN value, for unlogged rels */
@@ -333,8 +317,67 @@ typedef struct ControlFileData11
} ControlFileData11; } ControlFileData11;
#if PG_ACTUAL_VERSION_NUM >= 120000
/*
* Following field added in Pg12:
*
* int max_wal_senders;
*/
typedef struct ControlFileData12
{
uint64 system_identifier;
uint32 pg_control_version; /* PG_CONTROL_VERSION */
uint32 catalog_version_no; /* see catversion.h */
DBState state; /* see enum above */
pg_time_t time; /* time stamp of last pg_control update */
XLogRecPtr checkPoint; /* last check point record ptr */
CheckPoint12 checkPointCopy; /* copy of last check point record */
XLogRecPtr unloggedLSN; /* current fake LSN value, for unlogged rels */
XLogRecPtr minRecoveryPoint;
TimeLineID minRecoveryPointTLI;
XLogRecPtr backupStartPoint;
XLogRecPtr backupEndPoint;
bool backupEndRequired;
int wal_level;
bool wal_log_hints;
int MaxConnections;
int max_worker_processes;
int max_wal_senders;
int max_prepared_xacts;
int max_locks_per_xact;
bool track_commit_timestamp;
uint32 maxAlign; /* alignment requirement for tuples */
double floatFormat; /* constant 1234567.0 */
uint32 blcksz; /* data block size for this DB */
uint32 relseg_size; /* blocks per segment of large relation */
uint32 xlog_blcksz; /* block size within WAL files */
uint32 xlog_seg_size; /* size of each WAL segment */
uint32 nameDataLen; /* catalog name field width */
uint32 indexMaxKeys; /* max number of columns in an index */
uint32 toast_max_chunk_size; /* chunk size in TOAST tables */
uint32 loblksize; /* chunk size in pg_largeobject */
bool float4ByVal; /* float4 pass-by-value? */
bool float8ByVal; /* float8, int8, etc pass-by-value? */
uint32 data_checksum_version;
} ControlFileData12;
#endif
extern int get_pg_version(const char *data_directory, char *version_string); extern int get_pg_version(const char *data_directory, char *version_string);
extern DBState get_db_state(const char *data_directory); extern bool get_db_state(const char *data_directory, DBState *state);
extern const char *describe_db_state(DBState state); extern const char *describe_db_state(DBState state);
extern int get_data_checksum_version(const char *data_directory); extern int get_data_checksum_version(const char *data_directory);
extern uint64 get_system_identifier(const char *data_directory); extern uint64 get_system_identifier(const char *data_directory);

2003
dbutils.c

File diff suppressed because it is too large Load Diff

204
dbutils.h
View File

@@ -1,7 +1,7 @@
/* /*
* dbutils.h * dbutils.h
* *
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) EnterpriseDB Corporation, 2010-2021
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -29,9 +29,35 @@
#include "strutil.h" #include "strutil.h"
#include "voting.h" #include "voting.h"
#define REPMGR_NODES_COLUMNS "n.node_id, n.type, n.upstream_node_id, n.node_name, n.conninfo, n.repluser, n.slot_name, n.location, n.priority, n.active, n.config_file, '' AS upstream_node_name " #define REPMGR_NODES_COLUMNS \
#define BDR2_NODES_COLUMNS "node_sysid, node_timeline, node_dboid, node_name, node_local_dsn, ''" "n.node_id, " \
#define BDR3_NODES_COLUMNS "ns.node_id, 0, 0, ns.node_name, ns.interface_connstr, ns.peer_state_name" "n.type, " \
"n.upstream_node_id, " \
"n.node_name, " \
"n.conninfo, " \
"n.repluser, " \
"n.slot_name, " \
"n.location, " \
"n.priority, " \
"n.active, " \
"n.config_file, " \
"'' AS upstream_node_name, " \
"NULL AS attached "
#define REPMGR_NODES_COLUMNS_WITH_UPSTREAM \
"n.node_id, " \
"n.type, " \
"n.upstream_node_id, " \
"n.node_name, " \
"n.conninfo, " \
"n.repluser, " \
"n.slot_name, " \
"n.location, " \
"n.priority, " \
"n.active, "\
"n.config_file, " \
"un.node_name AS upstream_node_name, " \
"NULL AS attached "
#define ERRBUFF_SIZE 512 #define ERRBUFF_SIZE 512
@@ -41,8 +67,7 @@ typedef enum
UNKNOWN = 0, UNKNOWN = 0,
PRIMARY, PRIMARY,
STANDBY, STANDBY,
WITNESS, WITNESS
BDR
} t_server_type; } t_server_type;
typedef enum typedef enum
@@ -92,9 +117,23 @@ typedef enum
CONN_ERROR CONN_ERROR
} ConnectionStatus; } ConnectionStatus;
typedef enum
{
/* unable to query "pg_stat_replication" or other error */
NODE_ATTACHED_UNKNOWN = -1,
/* node has record in "pg_stat_replication" and state is not "streaming" */
NODE_ATTACHED,
/* node has record in "pg_stat_replication" but state is not "streaming" */
NODE_NOT_ATTACHED,
/* node has no record in "pg_stat_replication" */
NODE_DETACHED
} NodeAttached;
typedef enum typedef enum
{ {
SLOT_UNKNOWN = -1, SLOT_UNKNOWN = -1,
SLOT_NOT_FOUND,
SLOT_NOT_PHYSICAL,
SLOT_INACTIVE, SLOT_INACTIVE,
SLOT_ACTIVE SLOT_ACTIVE
} ReplSlotStatus; } ReplSlotStatus;
@@ -107,6 +146,7 @@ typedef enum
} BackupState; } BackupState;
/* /*
* Struct to store extension version information * Struct to store extension version information
*/ */
@@ -125,8 +165,29 @@ typedef struct s_extension_versions {
UNKNOWN_SERVER_VERSION_NUM \ UNKNOWN_SERVER_VERSION_NUM \
} }
typedef struct
{
char current_timestamp[MAXLEN];
bool in_recovery;
TimeLineID timeline_id;
char timeline_id_str[MAXLEN];
XLogRecPtr last_wal_receive_lsn;
XLogRecPtr last_wal_replay_lsn;
char last_xact_replay_timestamp[MAXLEN];
int replication_lag_time;
bool receiving_streamed_wal;
bool wal_replay_paused;
int upstream_last_seen;
int upstream_node_id;
} ReplInfo;
/* /*
* Struct to store node information * Struct to store node information.
*
* The first section represents the contents of the "repmgr.nodes"
* table; subsequent section contain information collated in
* various contexts.
*/ */
typedef struct s_node_info typedef struct s_node_info
{ {
@@ -152,7 +213,7 @@ typedef struct s_node_info
/* for ad-hoc use e.g. when working with a list of nodes */ /* for ad-hoc use e.g. when working with a list of nodes */
char details[MAXLEN]; char details[MAXLEN];
bool reachable; bool reachable;
bool attached; NodeAttached attached;
/* various statistics */ /* various statistics */
int max_wal_senders; int max_wal_senders;
int attached_wal_receivers; int attached_wal_receivers;
@@ -160,6 +221,8 @@ typedef struct s_node_info
int total_replication_slots; int total_replication_slots;
int active_replication_slots; int active_replication_slots;
int inactive_replication_slots; int inactive_replication_slots;
/* replication info */
ReplInfo *replication_info;
} t_node_info; } t_node_info;
@@ -186,7 +249,8 @@ typedef struct s_node_info
/* for ad-hoc use e.g. when working with a list of nodes */ \ /* for ad-hoc use e.g. when working with a list of nodes */ \
"", true, true, \ "", true, true, \
/* various statistics */ \ /* various statistics */ \
-1, -1, -1, -1, -1, -1 \ -1, -1, -1, -1, -1, -1, \
NULL \
} }
@@ -262,56 +326,6 @@ typedef struct s_connection_user
#define T_CONNECTION_USER_INITIALIZER { "", false } #define T_CONNECTION_USER_INITIALIZER { "", false }
/* represents an entry in bdr.bdr_nodes */
typedef struct s_bdr_node_info
{
char node_sysid[MAXLEN];
uint32 node_timeline;
uint32 node_dboid;
char node_name[MAXLEN];
char node_local_dsn[MAXLEN];
char peer_state_name[MAXLEN];
} t_bdr_node_info;
#define T_BDR_NODE_INFO_INITIALIZER { \
"", InvalidOid, InvalidOid, \
"", "", "" \
}
/* structs to store a list of BDR node records */
typedef struct BdrNodeInfoListCell
{
struct BdrNodeInfoListCell *next;
t_bdr_node_info *node_info;
} BdrNodeInfoListCell;
typedef struct BdrNodeInfoList
{
BdrNodeInfoListCell *head;
BdrNodeInfoListCell *tail;
int node_count;
} BdrNodeInfoList;
#define T_BDR_NODE_INFO_LIST_INITIALIZER { \
NULL, \
NULL, \
0 \
}
typedef struct
{
char current_timestamp[MAXLEN];
bool in_recovery;
XLogRecPtr last_wal_receive_lsn;
XLogRecPtr last_wal_replay_lsn;
char last_xact_replay_timestamp[MAXLEN];
int replication_lag_time;
bool receiving_streamed_wal;
bool wal_replay_paused;
int upstream_last_seen;
} ReplInfo;
typedef struct typedef struct
{ {
char filepath[MAXPGPATH]; char filepath[MAXPGPATH];
@@ -321,6 +335,7 @@ typedef struct
#define T_CONFIGFILE_INFO_INITIALIZER { "", "", false } #define T_CONFIGFILE_INFO_INITIALIZER { "", "", false }
typedef struct typedef struct
{ {
int size; int size;
@@ -330,6 +345,7 @@ typedef struct
#define T_CONFIGFILE_LIST_INITIALIZER { 0, 0, NULL } #define T_CONFIGFILE_LIST_INITIALIZER { 0, 0, NULL }
typedef struct typedef struct
{ {
uint64 system_identifier; uint64 system_identifier;
@@ -369,10 +385,6 @@ typedef struct RepmgrdInfo {
/* utility functions */ /* utility functions */
XLogRecPtr parse_lsn(const char *str); XLogRecPtr parse_lsn(const char *str);
extern void
wrap_ddl_query(PQExpBufferData *query_buf, int replication_type, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
bool atobool(const char *value); bool atobool(const char *value);
/* connection functions */ /* connection functions */
@@ -381,12 +393,19 @@ PGconn *establish_db_connection(const char *conninfo,
PGconn *establish_db_connection_quiet(const char *conninfo); PGconn *establish_db_connection_quiet(const char *conninfo);
PGconn *establish_db_connection_by_params(t_conninfo_param_list *param_list, PGconn *establish_db_connection_by_params(t_conninfo_param_list *param_list,
const bool exit_on_error); const bool exit_on_error);
PGconn *establish_db_connection_with_replacement_param(const char *conninfo,
const char *param,
const char *value,
const bool exit_on_error);
PGconn *establish_replication_connection_from_conn(PGconn *conn, const char *repluser);
PGconn *establish_replication_connection_from_conninfo(const char *conninfo, const char *repluser);
PGconn *establish_primary_db_connection(PGconn *conn, PGconn *establish_primary_db_connection(PGconn *conn,
const bool exit_on_error); const bool exit_on_error);
PGconn *get_primary_connection(PGconn *standby_conn, int *primary_id, char *primary_conninfo_out); PGconn *get_primary_connection(PGconn *standby_conn, int *primary_id, char *primary_conninfo_out);
PGconn *get_primary_connection_quiet(PGconn *standby_conn, int *primary_id, char *primary_conninfo_out); PGconn *get_primary_connection_quiet(PGconn *standby_conn, int *primary_id, char *primary_conninfo_out);
PGconn *duplicate_connection(PGconn *conn, const char *user, bool replication);
bool is_superuser_connection(PGconn *conn, t_connection_user *userinfo);
void close_connection(PGconn **conn); void close_connection(PGconn **conn);
/* conninfo manipulation functions */ /* conninfo manipulation functions */
@@ -399,6 +418,7 @@ void conn_to_param_list(PGconn *conn, t_conninfo_param_list *param_list);
void param_set(t_conninfo_param_list *param_list, const char *param, const char *value); void param_set(t_conninfo_param_list *param_list, const char *param, const char *value);
void param_set_ine(t_conninfo_param_list *param_list, const char *param, const char *value); void param_set_ine(t_conninfo_param_list *param_list, const char *param, const char *value);
char *param_get(t_conninfo_param_list *param_list, const char *param); char *param_get(t_conninfo_param_list *param_list, const char *param);
bool validate_conninfo_string(const char *conninfo_str, char **errmsg);
bool parse_conninfo_string(const char *conninfo_str, t_conninfo_param_list *param_list, char **errmsg, bool ignore_local_params); bool parse_conninfo_string(const char *conninfo_str, t_conninfo_param_list *param_list, char **errmsg, bool ignore_local_params);
char *param_list_to_string(t_conninfo_param_list *param_list); char *param_list_to_string(t_conninfo_param_list *param_list);
char *normalize_conninfo_string(const char *conninfo_str); char *normalize_conninfo_string(const char *conninfo_str);
@@ -414,8 +434,9 @@ bool rollback_transaction(PGconn *conn);
bool set_config(PGconn *conn, const char *config_param, const char *config_value); bool set_config(PGconn *conn, const char *config_param, const char *config_value);
bool set_config_bool(PGconn *conn, const char *config_param, bool state); bool set_config_bool(PGconn *conn, const char *config_param, bool state);
int guc_set(PGconn *conn, const char *parameter, const char *op, const char *value); int guc_set(PGconn *conn, const char *parameter, const char *op, const char *value);
int guc_set_typed(PGconn *conn, const char *parameter, const char *op, const char *value, const char *datatype);
bool get_pg_setting(PGconn *conn, const char *setting, char *output); bool get_pg_setting(PGconn *conn, const char *setting, char *output);
bool get_pg_setting_bool(PGconn *conn, const char *setting, bool *output);
bool get_pg_setting_int(PGconn *conn, const char *setting, int *output);
bool alter_system_int(PGconn *conn, const char *name, int value); bool alter_system_int(PGconn *conn, const char *name, int value);
bool pg_reload_conf(PGconn *conn); bool pg_reload_conf(PGconn *conn);
@@ -427,7 +448,16 @@ RecoveryType get_recovery_type(PGconn *conn);
int get_primary_node_id(PGconn *conn); int get_primary_node_id(PGconn *conn);
int get_ready_archive_files(PGconn *conn, const char *data_directory); int get_ready_archive_files(PGconn *conn, const char *data_directory);
bool identify_system(PGconn *repl_conn, t_system_identification *identification); bool identify_system(PGconn *repl_conn, t_system_identification *identification);
uint64 system_identifier(PGconn *conn);
TimeLineHistoryEntry *get_timeline_history(PGconn *repl_conn, TimeLineID tli); TimeLineHistoryEntry *get_timeline_history(PGconn *repl_conn, TimeLineID tli);
pid_t get_wal_receiver_pid(PGconn *conn);
/* user/role information functions */
bool can_execute_pg_promote(PGconn *conn);
bool can_disable_walsender(PGconn *conn);
bool connection_has_pg_monitor_role(PGconn *conn, const char *subrole);
bool is_replication_role(PGconn *conn, char *rolname);
bool is_superuser_connection(PGconn *conn, t_connection_user *userinfo);
/* repmgrd shared memory functions */ /* repmgrd shared memory functions */
bool repmgrd_set_local_node_id(PGconn *conn, int local_node_id); bool repmgrd_set_local_node_id(PGconn *conn, int local_node_id);
@@ -439,7 +469,8 @@ pid_t repmgrd_get_pid(PGconn *conn);
bool repmgrd_is_running(PGconn *conn); bool repmgrd_is_running(PGconn *conn);
bool repmgrd_is_paused(PGconn *conn); bool repmgrd_is_paused(PGconn *conn);
bool repmgrd_pause(PGconn *conn, bool pause); bool repmgrd_pause(PGconn *conn, bool pause);
pid_t get_wal_receiver_pid(PGconn *conn); int repmgrd_get_upstream_node_id(PGconn *conn);
bool repmgrd_set_upstream_node_id(PGconn *conn, int node_id);
/* extension functions */ /* extension functions */
ExtensionStatus get_repmgr_extension_status(PGconn *conn, t_extension_versions *extversions); ExtensionStatus get_repmgr_extension_status(PGconn *conn, t_extension_versions *extversions);
@@ -466,8 +497,10 @@ bool get_local_node_record(PGconn *conn, int node_id, t_node_info *node_info);
bool get_primary_node_record(PGconn *conn, t_node_info *node_info); bool get_primary_node_record(PGconn *conn, t_node_info *node_info);
bool get_all_node_records(PGconn *conn, NodeInfoList *node_list); bool get_all_node_records(PGconn *conn, NodeInfoList *node_list);
bool get_all_nodes_count(PGconn *conn, int *count);
void get_downstream_node_records(PGconn *conn, int node_id, NodeInfoList *nodes); void get_downstream_node_records(PGconn *conn, int node_id, NodeInfoList *nodes);
void get_active_sibling_node_records(PGconn *conn, int node_id, int upstream_node_id, NodeInfoList *node_list); void get_active_sibling_node_records(PGconn *conn, int node_id, int upstream_node_id, NodeInfoList *node_list);
bool get_child_nodes(PGconn *conn, int node_id, NodeInfoList *node_list);
void get_node_records_by_priority(PGconn *conn, NodeInfoList *node_list); void get_node_records_by_priority(PGconn *conn, NodeInfoList *node_list);
bool get_all_node_records_with_upstream(PGconn *conn, NodeInfoList *node_list); bool get_all_node_records_with_upstream(PGconn *conn, NodeInfoList *node_list);
bool get_downstream_nodes_with_missing_slot(PGconn *conn, int this_node_id, NodeInfoList *noede_list); bool get_downstream_nodes_with_missing_slot(PGconn *conn, int this_node_id, NodeInfoList *noede_list);
@@ -503,10 +536,14 @@ PGresult *get_event_records(PGconn *conn, int node_id, const char *node_name,
/* replication slot functions */ /* replication slot functions */
void create_slot_name(char *slot_name, int node_id); void create_slot_name(char *slot_name, int node_id);
bool create_replication_slot(PGconn *conn, char *slot_name, PQExpBufferData *error_msg);
bool drop_replication_slot(PGconn *conn, char *slot_name); bool create_replication_slot_sql(PGconn *conn, char *slot_name, PQExpBufferData *error_msg);
bool create_replication_slot_replprot(PGconn *conn, PGconn *repl_conn, char *slot_name, PQExpBufferData *error_msg);
bool drop_replication_slot_sql(PGconn *conn, char *slot_name);
bool drop_replication_slot_replprot(PGconn *repl_conn, char *slot_name);
RecordStatus get_slot_record(PGconn *conn, char *slot_name, t_replication_slot *record); RecordStatus get_slot_record(PGconn *conn, char *slot_name, t_replication_slot *record);
int get_free_replication_slot_count(PGconn *conn); int get_free_replication_slot_count(PGconn *conn, int *max_replication_slots);
int get_inactive_replication_slots(PGconn *conn, KeyValueList *list); int get_inactive_replication_slots(PGconn *conn, KeyValueList *list);
/* tablespace functions */ /* tablespace functions */
@@ -558,32 +595,17 @@ XLogRecPtr get_last_wal_receive_location(PGconn *conn);
void init_replication_info(ReplInfo *replication_info); void init_replication_info(ReplInfo *replication_info);
bool get_replication_info(PGconn *conn, t_server_type node_type, ReplInfo *replication_info); bool get_replication_info(PGconn *conn, t_server_type node_type, ReplInfo *replication_info);
int get_replication_lag_seconds(PGconn *conn); int get_replication_lag_seconds(PGconn *conn);
TimeLineID get_node_timeline(PGconn *conn, char *timeline_id_str);
void get_node_replication_stats(PGconn *conn, t_node_info *node_info); void get_node_replication_stats(PGconn *conn, t_node_info *node_info);
bool is_downstream_node_attached(PGconn *conn, char *node_name); NodeAttached is_downstream_node_attached(PGconn *conn, char *node_name, char **node_state);
void set_upstream_last_seen(PGconn *conn); NodeAttached is_downstream_node_attached_quiet(PGconn *conn, char *node_name, char **node_state);
void set_upstream_last_seen(PGconn *conn, int upstream_node_id);
int get_upstream_last_seen(PGconn *conn, t_server_type node_type); int get_upstream_last_seen(PGconn *conn, t_server_type node_type);
bool is_wal_replay_paused(PGconn *conn, bool check_pending_wal); bool is_wal_replay_paused(PGconn *conn, bool check_pending_wal);
/* BDR functions */ /* repmgrd status functions */
int get_bdr_version_num(void); CheckStatus get_repmgrd_status(PGconn *conn);
void get_all_bdr_node_records(PGconn *conn, BdrNodeInfoList *node_list);
RecordStatus get_bdr_node_record_by_name(PGconn *conn, const char *node_name, t_bdr_node_info *node_info);
bool is_bdr_db(PGconn *conn, PQExpBufferData *output);
bool is_bdr_db_quiet(PGconn *conn);
bool is_active_bdr_node(PGconn *conn, const char *node_name);
bool is_bdr_repmgr(PGconn *conn);
char *get_default_bdr_replication_set(PGconn *conn);
bool is_table_in_bdr_replication_set(PGconn *conn, const char *tablename, const char *set);
bool add_table_to_bdr_replication_set(PGconn *conn, const char *tablename, const char *set);
void add_extension_tables_to_bdr_replication_set(PGconn *conn);
bool bdr_node_name_matches(PGconn *conn, const char *node_name, PQExpBufferData *bdr_local_node_name);
ReplSlotStatus get_bdr_node_replication_slot_status(PGconn *conn, const char *node_name);
void get_bdr_other_node_name(PGconn *conn, int node_id, char *name_buf);
bool am_bdr_failover_handler(PGconn *conn, int node_id);
void unset_bdr_failover_handler(PGconn *conn);
bool bdr_node_has_repmgr_set(PGconn *conn, const char *node_name);
bool bdr_node_set_repmgr_set(PGconn *conn, const char *node_name);
/* miscellaneous debugging functions */ /* miscellaneous debugging functions */
const char *print_node_status(NodeStatus node_status); const char *print_node_status(NodeStatus node_status);

View File

@@ -3,7 +3,7 @@
* dirmod.c * dirmod.c
* directory handling functions * directory handling functions
* *
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) EnterpriseDB Corporation, 2010-2021
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -109,9 +109,56 @@ create_dir(const char *path)
bool bool
set_dir_permissions(const char *path) set_dir_permissions(const char *path, int server_version_num)
{ {
return (chmod(path, 0700) != 0) ? false : true; struct stat stat_buf;
bool no_group_access =
(server_version_num != UNKNOWN_SERVER_VERSION_NUM) &&
(server_version_num < 110000);
/*
* At this point the path should exist, so this check is very
* much just-in-case.
*/
if (stat(path, &stat_buf) != 0)
{
if (errno == ENOENT)
{
log_warning(_("directory \"%s\" does not exist"), path);
}
else
{
log_warning(_("could not read permissions of directory \"%s\""),
path);
log_detail("%s", strerror(errno));
}
return false;
}
/*
* If mode is not 0700 or 0750, attempt to change.
*/
if ((no_group_access == true && (stat_buf.st_mode & (S_IRWXG | S_IRWXO)))
|| (no_group_access == false && (stat_buf.st_mode & (S_IWGRP | S_IRWXO))))
{
/*
* Currently we default to 0700.
* There is no facility to override this directly,
* but the user can manually create the directory with
* the desired permissions.
*/
if (chmod(path, 0700) != 0) {
log_error(_("unable to change permissions of directory \"%s\""), path);
log_detail("%s", strerror(errno));
return false;
}
return true;
}
/* Leave as-is */
return true;
} }
@@ -158,7 +205,7 @@ mkdir_p(char *path, mode_t omode)
/* /*
* POSIX 1003.2: For each dir operand that does not name an * POSIX 1003.2: For each dir operand that does not name an
* existing directory, effects equivalent to those caused by the * existing directory, effects equivalent to those caused by the
* following command shall occcur: * following command shall occur:
* *
* mkdir -p -m $(umask -S),u+wx $(dirname dir) && mkdir [-m mode] * mkdir -p -m $(umask -S),u+wx $(dirname dir) && mkdir [-m mode]
* dir * dir
@@ -242,7 +289,7 @@ is_pg_running(const char *path)
{ {
/* /*
* No PID file - PostgreSQL shouldn't be running. From 9.3 (the * No PID file - PostgreSQL shouldn't be running. From 9.3 (the
* earliesty version we care about) removal of the PID file will * earliest version we care about) removal of the PID file will
* cause the postmaster to shut down, so it's highly unlikely * cause the postmaster to shut down, so it's highly unlikely
* that PostgreSQL will still be running. * that PostgreSQL will still be running.
*/ */
@@ -303,7 +350,7 @@ create_pg_dir(const char *path, bool force)
switch (check_dir(path)) switch (check_dir(path))
{ {
case DIR_NOENT: case DIR_NOENT:
/* directory does not exist, attempt to create it */ /* Directory does not exist, attempt to create it. */
log_info(_("creating directory \"%s\"..."), path); log_info(_("creating directory \"%s\"..."), path);
if (!create_dir(path)) if (!create_dir(path))
@@ -314,14 +361,23 @@ create_pg_dir(const char *path, bool force)
} }
break; break;
case DIR_EMPTY: case DIR_EMPTY:
/* exists but empty, fix permissions and use it */ /*
* Directory exists but empty, fix permissions and use it.
*
* Note that at this point the caller might not know the server
* version number, so in this case "set_dir_permissions()" will
* accept 0750 as a valid setting. As this is invalid in Pg10 and
* earlier, the caller should call "set_dir_permissions()" again
* when it has the number.
*
* We need to do the permissions check here in any case to catch
* fatal permissions early.
*/
log_info(_("checking and correcting permissions on existing directory \"%s\""), log_info(_("checking and correcting permissions on existing directory \"%s\""),
path); path);
if (!set_dir_permissions(path)) if (!set_dir_permissions(path, UNKNOWN_SERVER_VERSION_NUM))
{ {
log_error(_("unable to change permissions of directory \"%s\""), path);
log_detail("%s", strerror(errno));
return false; return false;
} }
break; break;

View File

@@ -1,6 +1,6 @@
/* /*
* dirutil.h * dirutil.h
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) EnterpriseDB Corporation, 2010-2021
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -35,7 +35,7 @@ typedef enum
} PgDirState; } PgDirState;
extern int mkdir_p(char *path, mode_t omode); extern int mkdir_p(char *path, mode_t omode);
extern bool set_dir_permissions(const char *path); extern bool set_dir_permissions(const char *path, int server_version_num);
extern DataDirState check_dir(const char *path); extern DataDirState check_dir(const char *path);
extern bool create_dir(const char *path); extern bool create_dir(const char *path);

8
doc/.gitignore vendored
View File

@@ -1,7 +1,9 @@
HTML.index HTML.index
bookindex.sgml bookindex.xml
html-stamp html-stamp
html/ html/
nochunks.dsl
repmgr.html repmgr.html
version.sgml version.xml
*.fo
*.pdf
*.sgml

104
doc/Makefile Normal file
View File

@@ -0,0 +1,104 @@
# Make "html" the default target, since that is what most people tend
# to want to use.
html:
all: html
subdir = doc
repmgr_top_builddir = ..
include $(repmgr_top_builddir)/Makefile.global
XMLINCLUDE = --path .
ifndef XMLLINT
XMLLINT = $(missing) xmllint
endif
ifndef XSLTPROC
XSLTPROC = $(missing) xsltproc
endif
ifndef FOP
FOP = $(missing) fop
endif
override XSLTPROCFLAGS += --stringparam repmgr.version '$(REPMGR_VERSION)'
GENERATED_XML = version.xml
ALLXML := $(wildcard $(srcdir)/*.xml) $(GENERATED_XML)
version.xml: $(repmgr_top_builddir)/repmgr_version.h
{ \
echo "<!ENTITY repmgrversion \"$(REPMGR_VERSION)\">"; \
echo "<!ENTITY releasedate \"$(REPMGR_RELEASE_DATE)\">"; \
} > $@
##
## HTML
##
html: html-stamp
html-stamp: stylesheet.xsl repmgr.xml $(ALLXML)
$(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
$(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_FLAGS) $(wordlist 1,2,$^)
cp $(srcdir)/stylesheet.css $(srcdir)/website-docs.css html/
touch $@
# single-page HTML
repmgr.html: stylesheet-html-nochunk.xsl repmgr.xml $(ALLXML)
$(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
$(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_FLAGS) -o $@ $(wordlist 1,2,$^)
zip: html
cp -r html repmgr-docs-$(REPMGR_VERSION)
zip -r repmgr-docs-$(REPMGR_VERSION).zip repmgr-docs-$(REPMGR_VERSION)
rm -rf repmgr-docs-$(REPMGR_VERSION)
##
## Print
##
repmgr.pdf:
$(error Invalid target; use repmgr-A4.pdf or repmgr-US.pdf as targets)
# Standard paper size
repmgr-A4.fo: stylesheet-fo.xsl repmgr.xml $(ALLXML)
$(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
$(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) --stringparam paper.type A4 -o $@ $(wordlist 1,2,$^)
repmgr-A4.pdf: repmgr-A4.fo
$(FOP) -fo $< -pdf $@
# North American paper size
repmgr-US.fo: stylesheet-fo.xsl repmgr.xml $(ALLXML)
$(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
$(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) --stringparam paper.type USletter -o $@ $(wordlist 1,2,$^)
repmgr-US.pdf: repmgr-US.fo
$(FOP) -fo $< -pdf $@
install: html
@$(MKDIR_P) $(DESTDIR)$(docdir)/$(docmoduledir)/repmgr
@$(INSTALL_DATA) $(wildcard html/*.html) $(wildcard html/*.css) $(DESTDIR)$(docdir)/$(docmoduledir)/repmgr
@echo Installed docs to $(DESTDIR)$(docdir)/$(docmoduledir)/repmgr
clean:
rm -f html-stamp
rm -f HTML.index $(GENERATED_XML)
rm -f repmgr.html
rm -f repmgr-A4.pdf
rm -f repmgr-US.pdf
rm -f *.fo
rm -f html/*
maintainer-clean:
rm -rf html
.PHONY: html

View File

@@ -1,76 +0,0 @@
repmgr_subdir = doc
repmgr_top_builddir = ..
include $(repmgr_top_builddir)/Makefile.global
ifndef JADE
JADE = $(missing) jade
endif
SGMLINCLUDE = -D . -D ${srcdir}
SPFLAGS += -wall -wno-unused-param -wno-empty -wfully-tagged
JADE.html.call = $(JADE) $(JADEFLAGS) $(SPFLAGS) $(SGMLINCLUDE) $(CATALOG) -t sgml -i output-html
ALLSGML := $(wildcard $(srcdir)/*.sgml)
# to build bookindex
ALMOSTALLSGML := $(filter-out %bookindex.sgml,$(ALLSGML))
GENERATED_SGML = version.sgml bookindex.sgml
Makefile: Makefile.in
cd $(repmgr_top_builddir) && ./config.status doc/Makefile
all: html
html: html-stamp
html-stamp: repmgr.sgml $(ALLSGML) $(GENERATED_SGML) stylesheet.dsl website-docs.css
$(MKDIR_P) html
$(JADE.html.call) -d stylesheet.dsl -i include-index $<
cp $(srcdir)/stylesheet.css $(srcdir)/website-docs.css html/
touch $@
repmgr.html: repmgr.sgml $(ALLSGML) $(GENERATED_SGML) stylesheet.dsl website-docs.css
sed '/html-index-filename/a\
(define nochunks #t)' <stylesheet.dsl >nochunks.dsl
$(JADE.html.call) -d nochunks.dsl -i include-index $< >repmgr.html
version.sgml: ${repmgr_top_builddir}/repmgr_version.h
{ \
echo "<!ENTITY repmgrversion \"$(REPMGR_VERSION)\">"; \
} > $@
HTML.index: repmgr.sgml $(ALMOSTALLSGML) stylesheet.dsl
@$(MKDIR_P) html
$(JADE.html.call) -d stylesheet.dsl -V html-index $<
website-docs.css:
@$(MKDIR_P) html
curl http://www.postgresql.org/media/css/docs.css > ${srcdir}/website-docs.css
bookindex.sgml: HTML.index
ifdef COLLATEINDEX
LC_ALL=C $(PERL) $(COLLATEINDEX) -f -g -i 'bookindex' -o $@ $<
else
@$(missing) collateindex.pl $< $@
endif
clean:
rm -f html-stamp
rm -f HTML.index $(GENERATED_SGML)
maintainer-clean:
rm -rf html
rm -f Makefile
zip: html
cp -r html repmgr-docs-$(REPMGR_VERSION)
zip -r repmgr-docs-$(REPMGR_VERSION).zip repmgr-docs-$(REPMGR_VERSION)
rm -rf repmgr-docs-$(REPMGR_VERSION)
install: html
@$(MKDIR_P) $(DESTDIR)$(docdir)/$(docmoduledir)/repmgr
@$(INSTALL_DATA) $(wildcard html/*.html) $(wildcard html/*.css) $(DESTDIR)$(docdir)/$(docmoduledir)/repmgr
@echo Installed docs to $(DESTDIR)$(docdir)/$(docmoduledir)/repmgr
.PHONY: html all

View File

@@ -1,438 +0,0 @@
<appendix id="appendix-faq" xreflabel="FAQ">
<indexterm>
<primary>FAQ (Frequently Asked Questions)</primary>
</indexterm>
<title>FAQ (Frequently Asked Questions)</title>
<sect1 id="faq-general" xreflabel="General">
<title>General</title>
<sect2 id="faq-xrepmgr-version-diff" xreflabel="Version differences">
<title>What's the difference between the repmgr versions?</title>
<para>
&repmgr; 4 is a complete rewrite of the existing &repmgr; code base
and implements &repmgr; as a PostgreSQL extension. It
supports all PostgreSQL versions from 9.3 (although some &repmgr;
features are not available for PostgreSQL 9.3 and 9.4).
</para>
<para>
&repmgr; 3.x builds on the improved replication facilities added
in PostgreSQL 9.3, as well as improved automated failover support
via <application>repmgrd</application>, and is not compatible with PostgreSQL 9.2
and earlier. We recommend upgrading to &repmgr; 4, as the &repmgr; 3.x
series is no longer maintained.
</para>
<para>
&repmgr; 2.x supports PostgreSQL 9.0 ~ 9.3. While it is compatible
with PostgreSQL 9.3, we recommend using repmgr 4.x. &repmgr; 2.x is
no longer maintained.
</para>
<para>
See also <link linkend="install-compatibility-matrix">&repmgr; compatibility matrix</link>
and <link linkend="faq-upgrade-repmgr">Should I upgrade &repmgr;?</link>.
</para>
</sect2>
<sect2 id="faq-replication-slots-advantage" xreflabel="Advantages of replication slots">
<title>What's the advantage of using replication slots?</title>
<para>
Replication slots, introduced in PostgreSQL 9.4, ensure that the
primary server will retain WAL files until they have been consumed
by all standby servers. This means standby servers should never
fail due to not being able to retrieve required WAL files from the
primary.
</para>
<para>
However this does mean that if a standby is no longer connected to the
primary, the presence of the replication slot will cause WAL files
to be retained indefinitely, and eventually lead to disk space
exhaustion.
</para>
<tip>
<para>
2ndQuadrant's recommended configuration is to configure
<ulink url="https://www.pgbarman.org/">Barman</ulink> as a fallback
source of WAL files, rather than maintain replication slots for
each standby. See also: <link linkend="cloning-from-barman-restore-command">Using Barman as a WAL file source</link>.
</para>
</tip>
</sect2>
<sect2 id="faq-replication-slots-number" xreflabel="Number of replication slots">
<title>How many replication slots should I define in <varname>max_replication_slots</varname>?</title>
<para>
Normally at least same number as the number of standbys which will connect
to the node. Note that changes to <varname>max_replication_slots</varname> require a server
restart to take effect, and as there is no particular penalty for unused
replication slots, setting a higher figure will make adding new nodes
easier.
</para>
</sect2>
<sect2 id="faq-hash-index" xreflabel="Hash indexes">
<title>Does &repmgr; support hash indexes?</title>
<para>
Before PostgreSQL 10, hash indexes were not WAL logged and are therefore not suitable
for use in streaming replication in PostgreSQL 9.6 and earlier. See the
<ulink url="https://www.postgresql.org/docs/9.6/sql-createindex.html#AEN80279">PostgreSQL documentation</ulink>
for details.
</para>
<para>
From PostgreSQL 10, this restriction has been lifted and hash indexes can be used
in a streaming replication cluster.
</para>
</sect2>
<sect2 id="faq-upgrades" xreflabel="Upgrading PostgreSQL with repmgr">
<title>Can &repmgr; assist with upgrading a PostgreSQL cluster?</title>
<para>
For <emphasis>minor</emphasis> version upgrades, e.g. from 9.6.7 to 9.6.8, a common
approach is to upgrade a standby to the latest version, perform a
<link linkend="performing-switchover">switchover</link> promoting it to a primary,
then upgrade the former primary.
</para>
<para>
For <emphasis>major</emphasis> version upgrades (e.g. from PostgreSQL 9.6 to PostgreSQL 10),
the traditional approach is to "reseed" a cluster by upgrading a single
node with <ulink url="https://www.postgresql.org/docs/current/pgupgrade.html">pg_upgrade</ulink>
and recloning standbys from this.
</para>
<para>
To minimize downtime during major upgrades from PostgreSQL 9.4 and later,
<ulink url="https://www.2ndquadrant.com/en/resources/pglogical/">pglogical</ulink>
can be used to set up a parallel cluster using the newer PostgreSQL version,
which can be kept in sync with the existing production cluster until the
new cluster is ready to be put into production.
</para>
</sect2>
<sect2 id="faq-libdir-repmgr-error">
<title>What does this error mean: <literal>ERROR: could not access file "$libdir/repmgr"</literal>?</title>
<para>
It means the &repmgr; extension code is not installed in the
PostgreSQL application directory. This typically happens when using PostgreSQL
packages provided by a third-party vendor, which often have different
filesystem layouts.
</para>
<para>
Either use PostgreSQL packages provided by the community or 2ndQuadrant; if this
is not possible, contact your vendor for assistance.
</para>
</sect2>
<sect2 id="faq-old-packages">
<title>How can I obtain old versions of &repmgr; packages?</title>
<para>
See appendix <xref linkend="packages-old-versions"> for details.
</para>
</sect2>
<sect2 id="faq-repmgr-required-for-replication">
<title>Is &repmgr; required for streaming replication?</title>
<para>
No.
</para>
<para>
&repmgr; (together with <application>repmgrd</application>) assists with
<emphasis>managing</emphasis> replication. It does not actually perform replication, which
is part of the core PostgreSQL functionality.
</para>
</sect2>
<sect2 id="faq-what-if-repmgr-uninstalled">
<title>Will replication stop working if &repmgr; is uninstalled?</title>
<para>
No. See preceding question.
</para>
</sect2>
<sect2 id="faq-version-mix">
<title>Does it matter if different &repmgr; versions are present in the replication cluster?</title>
<para>
Yes. If different &quot;major&quot; &repmgr; versions (e.g. 3.3.x and 4.1.x) are present,
&repmgr; (in particular <application>repmgrd</application>)
may not run, or run properly, or in the worst case (if different <application>repmgrd</application>
versions are running and there are differences in the failover implementation) break
your replication cluster.
</para>
<para>
If different &quot;minor&quot; &repmgr; versions (e.g. 4.1.1 and 4.1.6) are installed,
&repmgr; will function, but we strongly recommend always running the same version
to ensure there are no unexpected suprises, e.g. a newer version behaving slightly
differently to the older version.
</para>
<para>
See also <link linkend="faq-upgrade-repmgr">Should I upgrade &repmgr;?</link>.
</para>
</sect2>
<sect2 id="faq-upgrade-repmgr">
<title>Should I upgrade &repmgr;?</title>
<para>
Yes.
</para>
<para>
We don't release new versions for fun, you know. Upgrading may require a little effort,
but running an older &repmgr; version with bugs which have since been fixed may end up
costing you more effort. The same applies to PostgreSQL itself.
</para>
</sect2>
<sect2 id="faq-repmgr-conf-data-directory">
<title>Why do I need to specify the data directory location in repmgr.conf?</title>
<para>
In some circumstances &repmgr; may need to access a PostgreSQL data
directory while the PostgreSQL server is not running, e.g. to confirm
it shut down cleanly during a <link linkend="performing-switchover">switchover</link>.
</para>
<para>
Additionally, this provides support when using &repmgr; on PostgreSQL 9.6 and
earlier, where the <literal>repmgr</literal> user is not a superuser; in that
case the <literal>repmgr</literal> user will not be able to access the
<literal>data_directory</literal> configuration setting, access to which is restricted
to superusers. (In PostgreSQL 10 and later, non-superusers can be added to the
group <option>pg_read_all_settings</option> which will enable them to read this setting).
</para>
</sect2>
</sect1>
<sect1 id="faq-repmgr" xreflabel="repmgr">
<title><command>repmgr</command></title>
<sect2 id="faq-register-existing-node" xreflabel="registering an existing node">
<title>Can I register an existing PostgreSQL server with repmgr?</title>
<para>
Yes, any existing PostgreSQL server which is part of the same replication
cluster can be registered with &repmgr;. There's no requirement for a
standby to have been cloned using &repmgr;.
</para>
</sect2>
<sect2 id="faq-repmgr-clone-other-source" >
<title>Can I use a standby not cloned by &repmgr; as a &repmgr; node?</title>
<para>
For a standby which has been manually cloned or recovered from an external
backup manager such as Barman, the command
<command><link linkend="repmgr-standby-clone">repmgr standby clone --recovery-conf-only</link></command>
can be used to create the correct <filename>recovery.conf</filename> file for
use with &repmgr; (and will create a replication slot if required). Once this has been done,
<link linkend="repmgr-standby-register">register the node</link> as usual.
</para>
</sect2>
<sect2 id="faq-repmgr-recovery-conf" >
<title>What does &repmgr; write in <filename>recovery.conf</filename>, and what options can be set there?</title>
<para>
See section <link linkend="repmgr-standby-clone-recovery-conf">Customising recovery.conf</link>.
</para>
</sect2>
<sect2 id="faq-repmgr-failed-primary-standby" xreflabel="Reintegrate a failed primary as a standby">
<title>How can a failed primary be re-added as a standby?</title>
<para>
This is a two-stage process. First, the failed primary's data directory
must be re-synced with the current primary; secondly the failed primary
needs to be re-registered as a standby.
</para>
<para>
It's possible to use <command>pg_rewind</command> to re-synchronise the existing data
directory, which will usually be much
faster than re-cloning the server. However <command>pg_rewind</command> can only
be used if PostgreSQL either has <varname>wal_log_hints</varname> enabled, or
data checksums were enabled when the cluster was initialized.
</para>
<para>
Note that <command>pg_rewind</command> is available as part of the core PostgreSQL
distribution from PostgreSQL 9.5, and as a third-party utility for PostgreSQL 9.3 and 9.4.
</para>
<para>
&repmgr; provides the command <command>repmgr node rejoin</command> which can
optionally execute <command>pg_rewind</command>; see the <xref linkend="repmgr-node-rejoin">
documentation for details, in particular the section <xref linkend="repmgr-node-rejoin-pg-rewind">.
</para>
<para>
If <command>pg_rewind</command> cannot be used, then the data directory will need
to be re-cloned from scratch.
</para>
</sect2>
<sect2 id="faq-repmgr-check-configuration" xreflabel="Check PostgreSQL configuration">
<title>Is there an easy way to check my primary server is correctly configured for use with &repmgr;?</title>
<para>
Execute <command><link linkend="repmgr-standby-clone">repmgr standby clone</link></command>
with the <literal>--dry-run</literal> option; this will report any configuration problems
which need to be rectified.
</para>
</sect2>
<sect2 id="faq-repmgr-clone-skip-config-files" xreflabel="">
<title>When cloning a standby, how can I get &repmgr; to copy
<filename>postgresql.conf</filename> and <filename>pg_hba.conf</filename> from the PostgreSQL configuration
directory in <filename>/etc</filename>?</title>
<para>
Use the command line option <literal>--copy-external-config-files</literal>. For more details
see <xref linkend="repmgr-standby-clone-config-file-copying">.
</para>
</sect2>
<sect2 id="faq-repmgr-shared-preload-libaries-no-repmgrd" xreflabel="shared_preload_libraries without repmgrd">
<title>Do I need to include <literal>shared_preload_libraries = 'repmgr'</literal>
in <filename>postgresql.conf</filename> if I'm not using <application>repmgrd</application>?</title>
<para>
No, the <literal>repmgr</literal> shared library is only needed when running <application>repmgrd</application>.
If you later decide to run <application>repmgrd</application>, you just need to add
<literal>shared_preload_libraries = 'repmgr'</literal> and restart PostgreSQL.
</para>
</sect2>
<sect2 id="faq-repmgr-permissions" xreflabel="Replication permission problems">
<title>I've provided replication permission for the <literal>repmgr</literal> user in <filename>pg_hba.conf</filename>
but <command>repmgr</command>/<application>repmgrd</application> complains it can't connect to the server... Why?</title>
<para>
<command>repmgr</command> and <application>repmgrd</application> need to be able to connect to the repmgr database
with a normal connection to query metadata. The <literal>replication</literal> connection
permission is for PostgreSQL's streaming replication (and doesn't necessarily need to be the <literal>repmgr</literal> user).
</para>
</sect2>
<sect2 id="faq-repmgr-clone-provide-primary-conninfo" xreflabel="Providing primary connection parameters">
<title>When cloning a standby, why do I need to provide the connection parameters
for the primary server on the command line, not in the configuration file?</title>
<para>
Cloning a standby is a one-time action; the role of the server being cloned
from could change, so fixing it in the configuration file would create
confusion. If &repmgr; needs to establish a connection to the primary
server, it can retrieve this from the <literal>repmgr.nodes</literal> table on the local
node, and if necessary scan the replication cluster until it locates the active primary.
</para>
</sect2>
<sect2 id="faq-repmgr-clone-waldir-xlogdir" xreflabel="Providing a custom WAL directory">
<title>When cloning a standby, how do I ensure the WAL files are placed in a custom directory?</title>
<para>
Provide the option <literal>--waldir</literal> (<literal>--xlogdir</literal> in PostgreSQL 9.6
and earlier) with the absolute path to the WAL directory in <varname>pg_basebackup_options</varname>.
For more details see <xref linkend="cloning-advanced-pg-basebackup-options">.
</para>
</sect2>
<sect2 id="faq-repmgr-events-no-fkey" xreflabel="No foreign key on node_id in repmgr.events">
<title>Why is there no foreign key on the <literal>node_id</literal> column in the <literal>repmgr.events</literal>
table?</title>
<para>
Under some circumstances event notifications can be generated for servers
which have not yet been registered; it's also useful to retain a record
of events which includes servers removed from the replication cluster
which no longer have an entry in the <literal>repmgr.nodes</literal> table.
</para>
</sect2>
<sect2 id="faq-repmgr-recovery-conf-quoted-values" xreflabel="Quoted values in recovery.conf">
<title>Why are some values in <filename>recovery.conf</filename> surrounded by pairs of single quotes?</title>
<para>
This is to ensure that user-supplied values which are written as parameter values in <filename>recovery.conf</filename>
are escaped correctly and do not cause errors when <filename>recovery.conf</filename> is parsed.
</para>
<para>
The escaping is performed by an internal PostgreSQL routine, which leaves strings consisting
of digits and alphabetical characters only as-is, but wraps everything else in pairs of single quotes,
even if the string does not contain any characters which need escaping.
</para>
</sect2>
</sect1>
<sect1 id="faq-repmgrd" xreflabel="repmgrd">
<title><application>repmgrd</application></title>
<sect2 id="faq-repmgrd-prevent-promotion" xreflabel="Prevent standby from being promoted to primary">
<title>How can I prevent a node from ever being promoted to primary?</title>
<para>
In <filename>repmgr.conf</filename>, set its priority to a value of <literal>0</literal>; apply the changed setting with
<command><link linkend="repmgr-standby-register">repmgr standby register --force</link></command>.
</para>
<para>
Additionally, if <varname>failover</varname> is set to <literal>manual</literal>, the node will never
be considered as a promotion candidate.
</para>
</sect2>
<sect2 id="faq-repmgrd-delayed-standby" xreflabel="Delayed standby support">
<title>Does <application>repmgrd</application> support delayed standbys?</title>
<para>
<application>repmgrd</application> can monitor delayed standbys - those set up with
<varname>recovery_min_apply_delay</varname> set to a non-zero value
in <filename>recovery.conf</filename> - but as it's not currently possible
to directly examine the value applied to the standby, <application>repmgrd</application>
may not be able to properly evaluate the node as a promotion candidate.
</para>
<para>
We recommend that delayed standbys are explicitly excluded from promotion
by setting <varname>priority</varname> to <literal>0</literal> in
<filename>repmgr.conf</filename>.
</para>
<para>
Note that after registering a delayed standby, <application>repmgrd</application> will only start
once the metadata added in the primary node has been replicated.
</para>
</sect2>
<sect2 id="faq-repmgrd-logfile-rotate" xreflabel="repmgrd logfile rotation">
<title>How can I get <application>repmgrd</application> to rotate its logfile?</title>
<para>
Configure your system's <literal>logrotate</literal> service to do this; see <xref linkend="repmgrd-log-rotation">.
</para>
</sect2>
<sect2 id="faq-repmgrd-recloned-no-start" xreflabel="repmgrd not restarting after node cloned">
<title>I've recloned a failed primary as a standby, but <application>repmgrd</application> refuses to start?</title>
<para>
Check you registered the standby after recloning. If unregistered, the standby
cannot be considered as a promotion candidate even if <varname>failover</varname> is set to
<literal>automatic</literal>, which is probably not what you want. <application>repmgrd</application> will start if
<varname>failover</varname> is set to <literal>manual</literal> so the node's replication status can still
be monitored, if desired.
</para>
</sect2>
<sect2 id="faq-repmgrd-pg-bindir" xreflabel="repmgrd does not apply pg_bindir to promote_command or follow_command">
<title>
<application>repmgrd</application> ignores pg_bindir when executing <varname>promote_command</varname> or <varname>follow_command</varname>
</title>
<para>
<varname>promote_command</varname> or <varname>follow_command</varname> can be user-defined scripts,
so &repmgr; will not apply <option>pg_bindir</option> even if excuting &repmgr;. Always provide the full
path; see <xref linkend="repmgrd-automatic-failover-configuration"> for more details.
</para>
</sect2>
<sect2 id="faq-repmgrd-startup-no-upstream" xreflabel="repmgrd does not start if upstream node is not running">
<title>
<application>repmgrd</application> aborts startup with the error "<literal>upstream node must be running before repmgrd can start</literal>"
</title>
<para>
<application>repmgrd</application> does this to avoid starting up on a replication cluster
which is not in a healthy state. If the upstream is unavailable, <application>repmgrd</application>
may initiate a failover immediately after starting up, which could have unintended side-effects,
particularly if <application>repmgrd</application> is not running on other nodes.
</para>
<para>
In particular, it's possible that the node's local copy of the <literal>repmgr.nodes</literal> copy
is out-of-date, which may lead to incorrect failover behaviour.
</para>
<para>
The onus is therefore on the adminstrator to manually set the cluster to a stable, healthy state before
starting <application>repmgrd</application>.
</para>
</sect2>
</sect1>
</appendix>

488
doc/appendix-faq.xml Normal file
View File

@@ -0,0 +1,488 @@
<appendix id="appendix-faq" xreflabel="FAQ">
<title>FAQ (Frequently Asked Questions)</title>
<indexterm>
<primary>FAQ (Frequently Asked Questions)</primary>
</indexterm>
<sect1 id="faq-general" xreflabel="General">
<title>General</title>
<sect2 id="faq-xrepmgr-version-diff" xreflabel="Version differences">
<title>What's the difference between the repmgr versions?</title>
<para>
&repmgr; 4 is a complete rewrite of the previous &repmgr; code base
and implements &repmgr; as a PostgreSQL extension. It
supports all PostgreSQL versions from 9.3 (although some &repmgr;
features are not available for PostgreSQL 9.3 and 9.4).
</para>
<note>
<para>
&repmgr; 5 is fundamentally the same code base as &repmgr; 4, but provides
support for the revised replication configuration mechanism in PostgreSQL 12.
</para>
<para>
Support for PostgreSQL 9.3 is no longer available from &repmgr; 5.2.
</para>
</note>
<para>
&repmgr; 3.x builds on the improved replication facilities added
in PostgreSQL 9.3, as well as improved automated failover support
via &repmgrd;, and is not compatible with PostgreSQL 9.2
and earlier. We recommend upgrading to &repmgr; 4, as the &repmgr; 3.x
series is no longer maintained.
</para>
<para>
&repmgr; 2.x supports PostgreSQL 9.0 ~ 9.3. While it is compatible
with PostgreSQL 9.3, we recommend using repmgr 4.x. &repmgr; 2.x is
no longer maintained.
</para>
<para>
See also <link linkend="install-compatibility-matrix">&repmgr; compatibility matrix</link>
and <link linkend="faq-upgrade-repmgr">Should I upgrade &repmgr;?</link>.
</para>
</sect2>
<sect2 id="faq-replication-slots-advantage" xreflabel="Advantages of replication slots">
<title>What's the advantage of using replication slots?</title>
<para>
Replication slots, introduced in PostgreSQL 9.4, ensure that the
primary server will retain WAL files until they have been consumed
by all standby servers. This means standby servers should never
fail due to not being able to retrieve required WAL files from the
primary.
</para>
<para>
However this does mean that if a standby is no longer connected to the
primary, the presence of the replication slot will cause WAL files
to be retained indefinitely, and eventually lead to disk space
exhaustion.
</para>
<tip>
<para>
Our recommended configuration is to configure
<ulink url="https://www.pgbarman.org/">Barman</ulink> as a fallback
source of WAL files, rather than maintain replication slots for
each standby. See also: <link linkend="cloning-from-barman-restore-command">Using Barman as a WAL file source</link>.
</para>
</tip>
</sect2>
<sect2 id="faq-replication-slots-number" xreflabel="Number of replication slots">
<title>How many replication slots should I define in <varname>max_replication_slots</varname>?</title>
<para>
Normally at least same number as the number of standbys which will connect
to the node. Note that changes to <varname>max_replication_slots</varname> require a server
restart to take effect, and as there is no particular penalty for unused
replication slots, setting a higher figure will make adding new nodes
easier.
</para>
</sect2>
<sect2 id="faq-hash-index" xreflabel="Hash indexes">
<title>Does &repmgr; support hash indexes?</title>
<para>
Before PostgreSQL 10, hash indexes were not WAL logged and are therefore not suitable
for use in streaming replication in PostgreSQL 9.6 and earlier. See the
<ulink url="https://www.postgresql.org/docs/9.6/sql-createindex.html#AEN80279">PostgreSQL documentation</ulink>
for details.
</para>
<para>
From PostgreSQL 10, this restriction has been lifted and hash indexes can be used
in a streaming replication cluster.
</para>
</sect2>
<sect2 id="faq-upgrades" xreflabel="Upgrading PostgreSQL with repmgr">
<title>Can &repmgr; assist with upgrading a PostgreSQL cluster?</title>
<para>
For <emphasis>minor</emphasis> version upgrades, e.g. from 9.6.7 to 9.6.8, a common
approach is to upgrade a standby to the latest version, perform a
<link linkend="performing-switchover">switchover</link> promoting it to a primary,
then upgrade the former primary.
</para>
<para>
For <emphasis>major</emphasis> version upgrades (e.g. from PostgreSQL 9.6 to PostgreSQL 10),
the traditional approach is to "reseed" a cluster by upgrading a single
node with <ulink url="https://www.postgresql.org/docs/current/pgupgrade.html">pg_upgrade</ulink>
and recloning standbys from this.
</para>
<para>
To minimize downtime during major upgrades from PostgreSQL 9.4 and later,
<ulink url="https://www.2ndquadrant.com/en/resources/pglogical/">pglogical</ulink>
can be used to set up a parallel cluster using the newer PostgreSQL version,
which can be kept in sync with the existing production cluster until the
new cluster is ready to be put into production.
</para>
</sect2>
<sect2 id="faq-libdir-repmgr-error">
<title>What does this error mean: <literal>ERROR: could not access file "$libdir/repmgr"</literal>?</title>
<para>
It means the &repmgr; extension code is not installed in the
PostgreSQL application directory. This typically happens when using PostgreSQL
packages provided by a third-party vendor, which often have different
filesystem layouts.
</para>
<para>
Either use PostgreSQL packages provided by the community or EnterpriseDB; if this
is not possible, contact your vendor for assistance.
</para>
</sect2>
<sect2 id="faq-old-packages">
<title>How can I obtain old versions of &repmgr; packages?</title>
<para>
See appendix <xref linkend="packages-old-versions"/> for details.
</para>
</sect2>
<sect2 id="faq-repmgr-required-for-replication">
<title>Is &repmgr; required for streaming replication?</title>
<para>
No.
</para>
<para>
&repmgr; (together with &repmgrd;) assists with
<emphasis>managing</emphasis> replication. It does not actually perform replication, which
is part of the core PostgreSQL functionality.
</para>
</sect2>
<sect2 id="faq-what-if-repmgr-uninstalled">
<title>Will replication stop working if &repmgr; is uninstalled?</title>
<para>
No. See preceding question.
</para>
</sect2>
<sect2 id="faq-version-mix">
<title>Does it matter if different &repmgr; versions are present in the replication cluster?</title>
<para>
Yes. If different &quot;major&quot; &repmgr; versions (e.g. 3.3.x and 4.1.x) are present,
&repmgr; (in particular &repmgrd;)
may not run, or run properly, or in the worst case (if different &repmgrd;
versions are running and there are differences in the failover implementation) break
your replication cluster.
</para>
<para>
If different &quot;minor&quot; &repmgr; versions (e.g. 4.1.1 and 4.1.6) are installed,
&repmgr; will function, but we strongly recommend always running the same version
to ensure there are no unexpected surprises, e.g. a newer version behaving slightly
differently to the older version.
</para>
<para>
See also <link linkend="faq-upgrade-repmgr">Should I upgrade &repmgr;?</link>.
</para>
</sect2>
<sect2 id="faq-upgrade-repmgr">
<title>Should I upgrade &repmgr;?</title>
<para>
Yes.
</para>
<para>
We don't release new versions for fun, you know. Upgrading may require a little effort,
but running an older &repmgr; version with bugs which have since been fixed may end up
costing you more effort. The same applies to PostgreSQL itself.
</para>
</sect2>
<sect2 id="faq-repmgr-conf-data-directory">
<title>Why do I need to specify the data directory location in repmgr.conf?</title>
<para>
In some circumstances &repmgr; may need to access a PostgreSQL data
directory while the PostgreSQL server is not running, e.g. to confirm
it shut down cleanly during a <link linkend="performing-switchover">switchover</link>.
</para>
<para>
Additionally, this provides support when using &repmgr; on PostgreSQL 9.6 and
earlier, where the <literal>repmgr</literal> user is not a superuser; in that
case the <literal>repmgr</literal> user will not be able to access the
<literal>data_directory</literal> configuration setting, access to which is restricted
to superusers.
</para>
<para>
In PostgreSQL 10 and later, non-superusers can be added to the
<ulink url="https://www.postgresql.org/docs/current/default-roles.html">default role</ulink>
<option>pg_read_all_settings</option> (or the meta-role <option>pg_monitor</option>)
which will enable them to read this setting.
</para>
</sect2>
<sect2 id="faq-third-party-packages" xreflabel="Compatibility with third party vendor packages">
<title>Are &repmgr; packages compatible with <literal>$third_party_vendor</literal>'s packages?</title>
<para>
&repmgr; packages provided by EnterpriseDB are compatible with the community-provided PostgreSQL
packages and specified software provided by EnterpriseDB.
</para>
<para>
A number of other vendors provide their own versions of PostgreSQL packages, often with different
package naming schemes and/or file locations.
</para>
<para>
We cannot guarantee that &repmgr; packages will be compatible with these packages.
It may be possible to override package dependencies (e.g. <literal>rpm --nodeps</literal>
for CentOS-based systems or <literal>dpkg --force-depends</literal> for Debian-based systems).
</para>
</sect2>
</sect1>
<sect1 id="faq-repmgr" xreflabel="repmgr">
<title><command>repmgr</command></title>
<sect2 id="faq-register-existing-node" xreflabel="registering an existing node">
<title>Can I register an existing PostgreSQL server with repmgr?</title>
<para>
Yes, any existing PostgreSQL server which is part of the same replication
cluster can be registered with &repmgr;. There's no requirement for a
standby to have been cloned using &repmgr;.
</para>
</sect2>
<sect2 id="faq-repmgr-clone-other-source" >
<title>Can I use a standby not cloned by &repmgr; as a &repmgr; node?</title>
<para>
For a standby which has been manually cloned or recovered from an external
backup manager such as Barman, the command
<command><link linkend="repmgr-standby-clone">repmgr standby clone --replication-conf-only</link></command>
can be used to create the correct replication configuration file for
use with &repmgr; (and will create a replication slot if required). Once this has been done,
<link linkend="repmgr-standby-register">register the node</link> as usual.
</para>
</sect2>
<sect2 id="faq-repmgr-recovery-conf" >
<title>What does &repmgr; write in the replication configuration, and what options can be set there?</title>
<para>
See section <link linkend="repmgr-standby-clone-recovery-conf">Customising replication configuration</link>.
</para>
</sect2>
<sect2 id="faq-repmgr-failed-primary-standby" xreflabel="Reintegrate a failed primary as a standby">
<title>How can a failed primary be re-added as a standby?</title>
<para>
This is a two-stage process. First, the failed primary's data directory
must be re-synced with the current primary; secondly the failed primary
needs to be re-registered as a standby.
</para>
<para>
It's possible to use <command>pg_rewind</command> to re-synchronise the existing data
directory, which will usually be much
faster than re-cloning the server. However <command>pg_rewind</command> can only
be used if PostgreSQL either has <varname>wal_log_hints</varname> enabled, or
data checksums were enabled when the cluster was initialized.
</para>
<para>
Note that <command>pg_rewind</command> is available as part of the core PostgreSQL
distribution from PostgreSQL 9.5, and as a third-party utility for PostgreSQL 9.3 and 9.4.
</para>
<para>
&repmgr; provides the command <command>repmgr node rejoin</command> which can
optionally execute <command>pg_rewind</command>; see the <xref linkend="repmgr-node-rejoin"/>
documentation for details, in particular the section <xref linkend="repmgr-node-rejoin-pg-rewind"/>.
</para>
<para>
If <command>pg_rewind</command> cannot be used, then the data directory will need
to be re-cloned from scratch.
</para>
</sect2>
<sect2 id="faq-repmgr-check-configuration" xreflabel="Check PostgreSQL configuration">
<title>Is there an easy way to check my primary server is correctly configured for use with &repmgr;?</title>
<para>
Execute <command><link linkend="repmgr-standby-clone">repmgr standby clone</link></command>
with the <literal>--dry-run</literal> option; this will report any configuration problems
which need to be rectified.
</para>
</sect2>
<sect2 id="faq-repmgr-clone-skip-config-files" xreflabel="">
<title>When cloning a standby, how can I get &repmgr; to copy
<filename>postgresql.conf</filename> and <filename>pg_hba.conf</filename> from the PostgreSQL configuration
directory in <filename>/etc</filename>?</title>
<para>
Use the command line option <literal>--copy-external-config-files</literal>. For more details
see <xref linkend="repmgr-standby-clone-config-file-copying"/>.
</para>
</sect2>
<sect2 id="faq-repmgr-shared-preload-libraries-no-repmgrd" xreflabel="shared_preload_libraries without repmgrd">
<title>Do I need to include <literal>shared_preload_libraries = 'repmgr'</literal>
in <filename>postgresql.conf</filename> if I'm not using &repmgrd;?</title>
<para>
No, the <literal>repmgr</literal> shared library is only needed when running &repmgrd;.
If you later decide to run &repmgrd;, you just need to add
<literal>shared_preload_libraries = 'repmgr'</literal> and restart PostgreSQL.
</para>
</sect2>
<sect2 id="faq-repmgr-permissions" xreflabel="Replication permission problems">
<title>I've provided replication permission for the <literal>repmgr</literal> user in <filename>pg_hba.conf</filename>
but <command>repmgr</command>/&repmgrd; complains it can't connect to the server... Why?</title>
<para>
<command>repmgr</command> and &repmgrd; need to be able to connect to the repmgr database
with a normal connection to query metadata. The <literal>replication</literal> connection
permission is for PostgreSQL's streaming replication (and doesn't necessarily need to be the <literal>repmgr</literal> user).
</para>
</sect2>
<sect2 id="faq-repmgr-clone-provide-primary-conninfo" xreflabel="Providing primary connection parameters">
<title>When cloning a standby, why do I need to provide the connection parameters
for the primary server on the command line, not in the configuration file?</title>
<para>
Cloning a standby is a one-time action; the role of the server being cloned
from could change, so fixing it in the configuration file would create
confusion. If &repmgr; needs to establish a connection to the primary
server, it can retrieve this from the <literal>repmgr.nodes</literal> table on the local
node, and if necessary scan the replication cluster until it locates the active primary.
</para>
</sect2>
<sect2 id="faq-repmgr-clone-waldir-xlogdir" xreflabel="Providing a custom WAL directory">
<title>When cloning a standby, how do I ensure the WAL files are placed in a custom directory?</title>
<para>
Provide the option <literal>--waldir</literal> (<literal>--xlogdir</literal> in PostgreSQL 9.6
and earlier) with the absolute path to the WAL directory in <varname>pg_basebackup_options</varname>.
For more details see <xref linkend="cloning-advanced-pg-basebackup-options"/>.
</para>
<para>
In &repmgr; 5.2 and later, this setting will also be honoured when cloning from Barman.
</para>
</sect2>
<sect2 id="faq-repmgr-events-no-fkey" xreflabel="No foreign key on node_id in repmgr.events">
<title>Why is there no foreign key on the <literal>node_id</literal> column in the <literal>repmgr.events</literal>
table?</title>
<para>
Under some circumstances event notifications can be generated for servers
which have not yet been registered; it's also useful to retain a record
of events which includes servers removed from the replication cluster
which no longer have an entry in the <literal>repmgr.nodes</literal> table.
</para>
</sect2>
<sect2 id="faq-repmgr-recovery-conf-quoted-values" xreflabel="Quoted values in replication.conf">
<title>Why are some values in <filename>recovery.conf</filename> (PostgreSQL 11 and earlier) surrounded by pairs of single quotes?</title>
<para>
This is to ensure that user-supplied values which are written as parameter values in <filename>recovery.conf</filename>
are escaped correctly and do not cause errors when the file is parsed.
</para>
<para>
The escaping is performed by an internal PostgreSQL routine, which leaves strings consisting
of digits and alphabetical characters only as-is, but wraps everything else in pairs of single quotes,
even if the string does not contain any characters which need escaping.
</para>
</sect2>
<sect2 id="faq-repmgr-exclude-metadata-from-dump" xreflabel="Excluding repmgr metadata from pg_dump output">
<title>How can I exclude &repmgr; metadata from <application>pg_dump</application> output?</title>
<para>
Beginning with &repmgr; 5.2, the metadata tables associated with the &repmgr; extension
(<literal>repmgr.nodes</literal>, <literal>repmgr.events</literal> and <literal>repmgr.monitoring_history</literal>)
have been marked as dumpable as they contain configuration and user-generated data.
</para>
<para>
To exclude these from <application>pg_dump</application> output, add the flag <option>--exclude-schema=repmgr</option>.
</para>
<para>
To exclude individual &repmgr; metadata tables from <application>pg_dump</application> output, add the flag
e.g. <option>--exclude-table=repmgr.monitoring_history</option>. This flag can be provided multiple times
to exclude individual tables,
</para>
</sect2>
</sect1>
<sect1 id="faq-repmgrd" xreflabel="repmgrd">
<title>&repmgrd;</title>
<sect2 id="faq-repmgrd-prevent-promotion" xreflabel="Prevent standby from being promoted to primary">
<title>How can I prevent a node from ever being promoted to primary?</title>
<para>
In <filename>repmgr.conf</filename>, set its priority to a value of <literal>0</literal>; apply the changed setting with
<command><link linkend="repmgr-standby-register">repmgr standby register --force</link></command>.
</para>
<para>
Additionally, if <varname>failover</varname> is set to <literal>manual</literal>, the node will never
be considered as a promotion candidate.
</para>
</sect2>
<sect2 id="faq-repmgrd-delayed-standby" xreflabel="Delayed standby support">
<title>Does &repmgrd; support delayed standbys?</title>
<para>
&repmgrd; can monitor delayed standbys - those set up with
<varname>recovery_min_apply_delay</varname> set to a non-zero value
in the replication configuration. However &repmgrd; does not currently
consider this setting, and therefore may not be able to properly evaluate
the node as a promotion candidate.
</para>
<para>
We recommend that delayed standbys are explicitly excluded from promotion
by setting <varname>priority</varname> to <literal>0</literal> in
<filename>repmgr.conf</filename>.
</para>
<para>
Note that after registering a delayed standby, &repmgrd; will only start
once the metadata added in the primary node has been replicated.
</para>
</sect2>
<sect2 id="faq-repmgrd-logfile-rotate" xreflabel="repmgrd logfile rotation">
<title>How can I get &repmgrd; to rotate its logfile?</title>
<para>
Configure your system's <literal>logrotate</literal> service to do this; see <xref linkend="repmgrd-log-rotation"/>.
</para>
</sect2>
<sect2 id="faq-repmgrd-recloned-no-start" xreflabel="repmgrd not restarting after node cloned">
<title>I've recloned a failed primary as a standby, but &repmgrd; refuses to start?</title>
<para>
Check you registered the standby after recloning. If unregistered, the standby
cannot be considered as a promotion candidate even if <varname>failover</varname> is set to
<literal>automatic</literal>, which is probably not what you want. &repmgrd; will start if
<varname>failover</varname> is set to <literal>manual</literal> so the node's replication status can still
be monitored, if desired.
</para>
</sect2>
<sect2 id="faq-repmgrd-pg-bindir" xreflabel="repmgrd does not apply pg_bindir to promote_command or follow_command">
<title>
&repmgrd; ignores pg_bindir when executing <varname>promote_command</varname> or <varname>follow_command</varname>
</title>
<para>
<varname>promote_command</varname> or <varname>follow_command</varname> can be user-defined scripts,
so &repmgr; will not apply <option>pg_bindir</option> even if executing &repmgr;. Always provide the full
path; see <xref linkend="repmgrd-automatic-failover-configuration"/> for more details.
</para>
</sect2>
<sect2 id="faq-repmgrd-startup-no-upstream" xreflabel="repmgrd does not start if upstream node is not running">
<title>
&repmgrd; aborts startup with the error "<literal>upstream node must be running before repmgrd can start</literal>"
</title>
<para>
&repmgrd; does this to avoid starting up on a replication cluster
which is not in a healthy state. If the upstream is unavailable, &repmgrd;
may initiate a failover immediately after starting up, which could have unintended side-effects,
particularly if &repmgrd; is not running on other nodes.
</para>
<para>
In particular, it's possible that the node's local copy of the <literal>repmgr.nodes</literal> copy
is out-of-date, which may lead to incorrect failover behaviour.
</para>
<para>
The onus is therefore on the administrator to manually set the cluster to a stable, healthy state before
starting &repmgrd;.
</para>
</sect2>
</sect1>
</appendix>

View File

@@ -1,9 +1,11 @@
<appendix id="appendix-packages" xreflabel="Package details"> <appendix id="appendix-packages" xreflabel="Package details">
<title>&repmgr; package details</title>
<indexterm> <indexterm>
<primary>packages</primary> <primary>packages</primary>
</indexterm> </indexterm>
<title>&repmgr; package details</title>
<para> <para>
This section provides technical details about various &repmgr; binary This section provides technical details about various &repmgr; binary
packages, such as location of the installed binaries and packages, such as location of the installed binaries and
@@ -48,19 +50,18 @@
<title>CentOS repositories</title> <title>CentOS repositories</title>
<para> <para>
&repmgr; packages are available from the public 2ndQuadrant repository, and also the &repmgr; packages are available from the public EDB repository, and also the
PostgreSQL community repository. The 2ndQuadrant repository is updated immediately PostgreSQL community repository. The EDB repository is updated immediately
after each after each &repmgr; release.
&repmgr; release.
</para> </para>
<table id="centos-2ndquadrant-repository"> <table id="centos-2ndquadrant-repository">
<title>2ndQuadrant public repository</title> <title>EDB public repository</title>
<tgroup cols="2"> <tgroup cols="2">
<tbody> <tbody>
<row> <row>
<entry>Repository URL:</entry> <entry>Repository URL:</entry>
<entry><ulink url="https://dl.2ndquadrant.com/">https://dl.2ndquadrant.com/</ulink></entry> <entry><ulink url="https://dl.enterprisedb.com/">https://dl.enterprisedb.com/</ulink></entry>
</row> </row>
<row> <row>
<entry>Repository documentation:</entry> <entry>Repository documentation:</entry>
@@ -120,7 +121,7 @@
<row> <row>
<entry>Package name example:</entry> <entry>Package name example:</entry>
<entry><filename>repmgr10-4.0.4-1.rhel7.x86_64</filename></entry> <entry><filename>repmgr11-4.4.0-1.rhel7.x86_64</filename></entry>
</row> </row>
<row> <row>
@@ -130,12 +131,12 @@
<row> <row>
<entry>Installation command:</entry> <entry>Installation command:</entry>
<entry><literal>yum install repmgr10</literal></entry> <entry><literal>yum install repmgr11</literal></entry>
</row> </row>
<row> <row>
<entry>Binary location:</entry> <entry>Binary location:</entry>
<entry><filename>/usr/pgsql-10/bin</filename></entry> <entry><filename>/usr/pgsql-11/bin</filename></entry>
</row> </row>
<row> <row>
@@ -145,22 +146,22 @@
<row> <row>
<entry>Configuration file location:</entry> <entry>Configuration file location:</entry>
<entry><filename>/etc/repmgr/10/repmgr.conf</filename></entry> <entry><filename>/etc/repmgr/11/repmgr.conf</filename></entry>
</row> </row>
<row> <row>
<entry>Data directory:</entry> <entry>Data directory:</entry>
<entry><filename>/var/lib/pgsql/10/data</filename></entry> <entry><filename>/var/lib/pgsql/11/data</filename></entry>
</row> </row>
<row> <row>
<entry>repmgrd service command:</entry> <entry>repmgrd service command:</entry>
<entry><command>systemctl [start|stop|restart|reload] repmgr10</command></entry> <entry><command>systemctl [start|stop|restart|reload] repmgr11</command></entry>
</row> </row>
<row> <row>
<entry>repmgrd service file location:</entry> <entry>repmgrd service file location:</entry>
<entry><filename>/usr/lib/systemd/system/repmgr10.service</filename></entry> <entry><filename>/usr/lib/systemd/system/repmgr11.service</filename></entry>
</row> </row>
<row> <row>
@@ -251,28 +252,22 @@
</indexterm> </indexterm>
<para> <para>
&repmgr; <literal>.deb</literal> packages are provided via the &repmgr; <literal>.deb</literal> packages are provided by EDB as well as the
PostgreSQL Community APT repository, and are available for each community-supported PostgreSQL Community APT repository, and are available for each community-supported
PostgreSQL version, currently supported Debian releases, and currently supported PostgreSQL version, currently supported Debian releases, and currently supported
Ubuntu LTS releases. Ubuntu LTS releases.
</para> </para>
<sect2 id="packages-apt-repository"> <sect2 id="packages-apt-repository">
<title>APT repository</title> <title>APT repositories</title>
<para>
&repmgr; packages are available from the PostgreSQL Community APT repository,
which is updated immediately after each &repmgr; release.
</para>
<table id="apt-2ndquadrant-repository"> <table id="apt-2ndquadrant-repository">
<title>2ndQuadrant public repository</title> <title>EDB public repository</title>
<tgroup cols="2"> <tgroup cols="2">
<tbody> <tbody>
<row> <row>
<entry>Repository URL:</entry> <entry>Repository URL:</entry>
<entry><ulink url="https://dl.2ndquadrant.com/">https://dl.2ndquadrant.com/</ulink></entry> <entry><ulink url="https://dl.enterprisedb.com/">https://dl.enterprisedb.com/</ulink></entry>
</row> </row>
<row> <row>
<entry>Repository documentation:</entry> <entry>Repository documentation:</entry>
@@ -289,7 +284,7 @@
<tbody> <tbody>
<row> <row>
<entry>Repository URL:</entry> <entry>Repository URL:</entry>
<entry><ulink url="http://apt.postgresql.org/">http://apt.postgresql.org/</ulink></entry> <entry><ulink url="https://apt.postgresql.org/">https://apt.postgresql.org/</ulink></entry>
</row> </row>
<row> <row>
<entry>Repository documentation:</entry> <entry>Repository documentation:</entry>
@@ -309,8 +304,8 @@
version number for your installation. version number for your installation.
</para> </para>
<para> <para>
See also <xref linkend="repmgrd-configuration-debian-ubuntu"> for some specifics related See also <xref linkend="repmgrd-configuration-debian-ubuntu"/> for some specifics related
to configuring the <application>repmgrd</application> daemon. to configuring the &repmgrd; daemon.
</para> </para>
<table id="debian-9-packages"> <table id="debian-9-packages">
@@ -321,7 +316,7 @@
<row> <row>
<entry>Package name example:</entry> <entry>Package name example:</entry>
<entry><filename>postgresql-10-repmgr</filename></entry> <entry><filename>postgresql-11-repmgr</filename></entry>
</row> </row>
<row> <row>
@@ -331,12 +326,12 @@
<row> <row>
<entry>Installation command:</entry> <entry>Installation command:</entry>
<entry><literal>apt-get install postgresql-10-repmgr</literal></entry> <entry><literal>apt-get install postgresql-11-repmgr</literal></entry>
</row> </row>
<row> <row>
<entry>Binary location:</entry> <entry>Binary location:</entry>
<entry><filename>/usr/lib/postgresql/10/bin</filename></entry> <entry><filename>/usr/lib/postgresql/11/bin</filename></entry>
</row> </row>
<row> <row>
@@ -351,12 +346,12 @@
<row> <row>
<entry>Data directory:</entry> <entry>Data directory:</entry>
<entry><filename>/var/lib/postgresql/10/main</filename></entry> <entry><filename>/var/lib/postgresql/11/main</filename></entry>
</row> </row>
<row> <row>
<entry>PostgreSQL service command:</entry> <entry>PostgreSQL service command:</entry>
<entry><command>systemctl [start|stop|restart|reload] postgresql@10-main</command></entry> <entry><command>systemctl [start|stop|restart|reload] postgresql@11-main</command></entry>
</row> </row>
@@ -380,11 +375,11 @@
</table> </table>
<note> <note>
<para> <para>
Instead of using the <application>systemd</application> service command directly, When using Debian packages, instead of using the <application>systemd</application> service
it's recommended to execute <command>pg_ctlcluster</command> (as <literal>root</literal>, command directly, it's recommended to execute <command>pg_ctlcluster</command>
either directly or via <command>sudo</command>), e.g.: (as <literal>root</literal>, either directly or via <command>sudo</command>), e.g.:
<programlisting> <programlisting>
<command>pg_ctlcluster 10 main [start|stop|restart|reload]</command></programlisting> <command>pg_ctlcluster 11 main [start|stop|restart|reload]</command></programlisting>
</para> </para>
<para> <para>
For pre-<application>systemd</application> systems, <command>pg_ctlcluster</command> For pre-<application>systemd</application> systems, <command>pg_ctlcluster</command>
@@ -402,11 +397,11 @@
</indexterm> </indexterm>
<indexterm> <indexterm>
<primary>packages</primary> <primary>packages</primary>
<secondary>snaphots</secondary> <secondary>snapshots</secondary>
</indexterm> </indexterm>
<para> <para>
For testing new features and bug fixes, from time to time 2ndQuadrant provides For testing new features and bug fixes, from time to time EDB provides
so-called &quot;snapshot packages&quot; via its public repository. These packages so-called &quot;snapshot packages&quot; via its public repository. These packages
are built from the &repmgr; source at a particular point in time, and are not formal are built from the &repmgr; source at a particular point in time, and are not formal
releases. releases.
@@ -418,22 +413,22 @@
</para> </para>
</note> </note>
<para> <para>
To install a snapshot package, it's necessary to install the 2ndQuadrant public snapshot repository, To install a snapshot package, it's necessary to install the EDB public snapshot repository,
following the instructions here: <ulink url="https://dl.2ndquadrant.com/default/release/site/">https://dl.2ndquadrant.com/default/release/site/</ulink> but replace <literal>release</literal> with <literal>snapshot</literal> following the instructions here: <ulink url="https://dl.enterprisedb.com/default/release/site/">https://dl.enterprisedb.com/default/release/site/</ulink> but replace <literal>release</literal> with <literal>snapshot</literal>
in the appropriate URL. in the appropriate URL.
</para> </para>
<para> <para>
For example, to install the snapshot RPM repository for PostgreSQL 9.6, execute (as <literal>root</literal>): For example, to install the snapshot RPM repository for PostgreSQL 9.6, execute (as <literal>root</literal>):
<programlisting> <programlisting>
curl https://dl.2ndquadrant.com/default/snapshot/get/9.6/rpm | bash</programlisting> curl https://dl.enterprisedb.com/default/snapshot/get/9.6/rpm | bash</programlisting>
or as a normal user with root sudo access: or as a normal user with root sudo access:
<programlisting> <programlisting>
curl https://dl.2ndquadrant.com/default/snapshot/get/9.6/rpm | sudo bash</programlisting> curl https://dl.enterprisedb.com/default/snapshot/get/9.6/rpm | sudo bash</programlisting>
</para> </para>
<para> <para>
Alternatively you can browse the repository here: Alternatively you can browse the repository here:
<ulink url="https://dl.2ndquadrant.com/default/snapshot/browse/">https://dl.2ndquadrant.com/default/snapshot/browse/</ulink>. <ulink url="https://dl.enterprisedb.com/default/snapshot/browse/">https://dl.enterprisedb.com/default/snapshot/browse/</ulink>.
</para> </para>
<para> <para>
Once the repository is installed, installing or updating &repmgr; will result in the latest snapshot Once the repository is installed, installing or updating &repmgr; will result in the latest snapshot
@@ -443,7 +438,7 @@ curl https://dl.2ndquadrant.com/default/snapshot/get/9.6/rpm | sudo bash</progra
The package name will be formatted like this: The package name will be formatted like this:
<programlisting> <programlisting>
repmgr96-4.1.1-0.0git320.g5113ab0.1.el7.x86_64.rpm</programlisting> repmgr96-4.1.1-0.0git320.g5113ab0.1.el7.x86_64.rpm</programlisting>
containg the snapshot build number (here: <literal>320</literal>) and the hash containing the snapshot build number (here: <literal>320</literal>) and the hash
of the <application>git</application> commit it was built from (here: <literal>g5113ab0</literal>). of the <application>git</application> commit it was built from (here: <literal>g5113ab0</literal>).
</para> </para>
@@ -475,7 +470,7 @@ repmgr96-4.1.1-0.0git320.g5113ab0.1.el7.x86_64.rpm</programlisting>
<title>Debian/Ubuntu</title> <title>Debian/Ubuntu</title>
<para> <para>
An archive of old packages (<literal>3.3.2</literal> and later) for Debian/Ubuntu-based systems is available here: An archive of old packages (<literal>3.3.2</literal> and later) for Debian/Ubuntu-based systems is available here:
<ulink url="http://atalia.postgresql.org/morgue/r/repmgr/">http://atalia.postgresql.org/morgue/r/repmgr/</ulink> <ulink url="https://apt-archive.postgresql.org/">https://apt-archive.postgresql.org/</ulink>
</para> </para>
</sect2> </sect2>
@@ -486,7 +481,7 @@ repmgr96-4.1.1-0.0git320.g5113ab0.1.el7.x86_64.rpm</programlisting>
Old versions can be located with e.g.: Old versions can be located with e.g.:
<programlisting> <programlisting>
yum --showduplicates list repmgr96</programlisting> yum --showduplicates list repmgr96</programlisting>
(substitute the appropriate package name; see <xref linkend="packages-centos">) and installed with: (substitute the appropriate package name; see <xref linkend="packages-centos"/>) and installed with:
<programlisting> <programlisting>
yum install {package_name}-{version}</programlisting> yum install {package_name}-{version}</programlisting>
where <literal>{package_name}</literal> is the base package name (e.g. <literal>repmgr96</literal>) where <literal>{package_name}</literal> is the base package name (e.g. <literal>repmgr96</literal>)
@@ -498,32 +493,6 @@ repmgr96-4.1.1-0.0git320.g5113ab0.1.el7.x86_64.rpm</programlisting>
yum install repmgr96-4.0.6-1.rhel6</programlisting> yum install repmgr96-4.0.6-1.rhel6</programlisting>
</para> </para>
<sect3 id="packages-old-versions-rhel-centos-repmgr3">
<title>repmgr 3 packages</title>
<para>
Old &repmgr; 3 RPM packages (<literal>3.2</literal> and later) can be retrieved from the
(deprecated) 2ndQuadrant repository at
<ulink url="http://packages.2ndquadrant.com/repmgr/yum/">http://packages.2ndquadrant.com/repmgr/yum/</ulink>
by installing the appropriate repository RPM:
</para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<ulink url="http://packages.2ndquadrant.com/repmgr/yum-repo-rpms/repmgr-fedora-1.0-1.noarch.rpm">http://packages.2ndquadrant.com/repmgr/yum-repo-rpms/repmgr-fedora-1.0-1.noarch.rpm</ulink>
</simpara>
</listitem>
<listitem>
<simpara>
<ulink url="http://packages.2ndquadrant.com/repmgr/yum-repo-rpms/repmgr-rhel-1.0-1.noarch.rpm">http://packages.2ndquadrant.com/repmgr/yum-repo-rpms/repmgr-rhel-1.0-1.noarch.rpm</ulink>
</simpara>
</listitem>
</itemizedlist>
</sect3>
</sect2> </sect2>
</sect1> </sect1>
@@ -550,13 +519,13 @@ repmgr96-4.1.1-0.0git320.g5113ab0.1.el7.x86_64.rpm</programlisting>
char package_conf_file[MAXPGPATH] = "";</programlisting> char package_conf_file[MAXPGPATH] = "";</programlisting>
</para> </para>
<para> <para>
See also: <xref linkend="configuration-file"> See also: <xref linkend="configuration-file"/>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
PID file location: the default <application>repmgrd</application> PID file PID file location: the default &repmgrd; PID file
location can be hard-coded by patching <varname>package_pid_file</varname> location can be hard-coded by patching <varname>package_pid_file</varname>
in <filename>repmgrd.c</filename>: in <filename>repmgrd.c</filename>:
<programlisting> <programlisting>
@@ -564,7 +533,7 @@ repmgr96-4.1.1-0.0git320.g5113ab0.1.el7.x86_64.rpm</programlisting>
char package_pid_file[MAXPGPATH] = "";</programlisting> char package_pid_file[MAXPGPATH] = "";</programlisting>
</para> </para>
<para> <para>
See also: <xref linkend="repmgrd-pid-file"> See also: <xref linkend="repmgrd-pid-file"/>
</para> </para>
</listitem> </listitem>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,26 @@
<appendix id="appendix-support" xreflabel="repmgr support"> <appendix id="appendix-support" xreflabel="repmgr support">
<title>&repmgr; support</title>
<indexterm> <indexterm>
<primary>support</primary> <primary>support</primary>
</indexterm> </indexterm>
<title>&repmgr; support</title>
<para> <para>
<ulink url="https://2ndquadrant.com/">2ndQuadrant</ulink> provides 24x7 <ulink url="https://www.enterprisedb.com/">EDB</ulink> provides 24x7
production support for &repmgr; and other PostgreSQL production support for &repmgr; and other PostgreSQL
products, including configuration assistance, installation products, including configuration assistance, installation
verification and training for running a robust replication cluster. verification and training for running a robust replication cluster.
</para> </para>
<para> <para>
For further details see: <ulink url="https://2ndquadrant.com/en/support/">https://2ndquadrant.com/en/support/</ulink> For further details see: <ulink url="https://www.enterprisedb.com/support/postgresql-support-overview-get-the-most-out-of-postgresql">Support Center</ulink>
</para> </para>
<para> <para>
A mailing list/forum is provided via Google groups to discuss contributions or issues: <ulink url="https://groups.google.com/group/repmgr">https://groups.google.com/group/repmgr</ulink>. A mailing list/forum is provided via Google groups to discuss contributions or issues: <ulink url="https://groups.google.com/group/repmgr">https://groups.google.com/group/repmgr</ulink>.
</para> </para>
<para> <para>
Please report bugs and other issues to: <ulink url="https://github.com/2ndQuadrant/repmgr">https://github.com/2ndQuadrant/repmgr</ulink>. Please report bugs and other issues to: <ulink url="https://github.com/EnterpriseDB/repmgr">https://github.com/EnterpriseDB/repmgr</ulink>.
</para> </para>
<important> <important>
@@ -28,18 +30,25 @@
</important> </important>
<sect1 id="appendix-support-reporting-issues" xreflabel="Reportins Issues"> <sect1 id="appendix-support-reporting-issues" xreflabel="Reportins Issues">
<title>Reporting Issues</title>
<indexterm> <indexterm>
<primary>support</primary> <primary>support</primary>
<secondary>reporting issues</secondary> <secondary>reporting issues</secondary>
</indexterm> </indexterm>
<title>Reporting Issues</title>
<para> <para>
When asking questions or reporting issues, it is extremely helpful if the following information is included: When asking questions or reporting issues, it is extremely helpful if the following information is included:
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
PostgreSQL version
</simpara>
</listitem>
<listitem> <listitem>
<simpara> <simpara>
&repmgr; version &repmgr; version
@@ -48,14 +57,14 @@
<listitem> <listitem>
<simpara> <simpara>
How was &repmgr installed? From source? From packages? If How was &repmgr; installed? From source? From packages? If
so from which repository? so from which repository?
</simpara> </simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara> <simpara>
<filename>repmpgr.conf</filename> files (suitably anonymized if necessary) <filename>repmgr.conf</filename> files (suitably anonymized if necessary)
</simpara> </simpara>
</listitem> </listitem>
@@ -65,9 +74,18 @@
</simpara> </simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara> <simpara>
PostgreSQL version PostgreSQL 11 and earlier: contents of the <filename>recovery.conf</filename> file
(suitably anonymized if necessary).
</simpara>
</listitem>
<listitem>
<simpara>
PostgreSQL 12 and later: contents of the <filename>postgresql.auto.conf</filename> file
(suitably anonymized if necessary), and whether or not the PostgreSQL data directory
contains the files <filename>standby.signal</filename> and/or <filename>recovery.signal</filename>.
</simpara> </simpara>
</listitem> </listitem>
@@ -80,15 +98,15 @@
the maximum level of logging output. the maximum level of logging output.
</para> </para>
<para> <para>
If issues are encountered with <application>repmgrd</application>, If issues are encountered with &repmgrd;,
please provide relevant extracts from the &repmgr; log files please provide relevant extracts from the &repmgr; log files
and if possible the PostgreSQL log itself. Please ensure these and if possible the PostgreSQL log itself. Please ensure these
logs do not contain any confidential data. logs do not contain any confidential data.
</para> </para>
<para> <para>
In all cases it is <emphasis>extremely</emphasis> useful to receive In all cases it is <emphasis>extremely</emphasis> useful to receive
information on how to reliably reproduce an issue with as much detail as as much detail as possible on how to reliably reproduce
possible. an issue.
</para> </para>
</sect1> </sect1>

View File

@@ -1,8 +0,0 @@
BDR failover with repmgrd
=========================
This document has been integrated into the main `repmgr` documentation
and is now located here:
> [BDR failover with repmgrd](https://repmgr.org/docs/current/repmgrd-bdr.html)

View File

@@ -2,6 +2,8 @@
<title>Cloning standbys</title> <title>Cloning standbys</title>
<sect1 id="cloning-from-barman" xreflabel="Cloning from Barman"> <sect1 id="cloning-from-barman" xreflabel="Cloning from Barman">
<title>Cloning a standby from Barman</title>
<indexterm> <indexterm>
<primary>cloning</primary> <primary>cloning</primary>
<secondary>from Barman</secondary> <secondary>from Barman</secondary>
@@ -11,10 +13,9 @@
<secondary>cloning a standby</secondary> <secondary>cloning a standby</secondary>
</indexterm> </indexterm>
<title>Cloning a standby from Barman</title>
<para> <para>
<xref linkend="repmgr-standby-clone"> can use <xref linkend="repmgr-standby-clone"/> can use
<ulink url="https://www.2ndquadrant.com/">2ndQuadrant</ulink>'s <ulink url="https://www.enterprisedb.com/">EDB</ulink>'s
<ulink url="https://www.pgbarman.org/">Barman</ulink> application <ulink url="https://www.pgbarman.org/">Barman</ulink> application
to clone a standby (and also as a fallback source for WAL files). to clone a standby (and also as a fallback source for WAL files).
</para> </para>
@@ -45,12 +46,32 @@
<para> <para>
WAL management on the primary becomes much easier as there's no need WAL management on the primary becomes much easier as there's no need
to use replication slots, and <varname>wal_keep_segments</varname> to use replication slots, and <varname>wal_keep_segments</varname>
(PostgreSQL 13 and later: <varname>wal_keep_size</varname>)
does not need to be set. does not need to be set.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<note>
<para>
Currently &repmgr;'s support for cloning from Barman is implemented by using
<productname>rsync</productname> to clone from the Barman server.
</para>
<para>
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.
</para>
<para>
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
<command><link linkend="repmgr-standby-clone">repmgr standby clone --replication-conf-only</link></command>.
</para>
</note>
<sect2 id="cloning-from-barman-prerequisites"> <sect2 id="cloning-from-barman-prerequisites">
<title>Prerequisites for cloning from Barman</title> <title>Prerequisites for cloning from Barman</title>
<para> <para>
@@ -59,8 +80,7 @@
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
<para> <para>
the <varname>barman_server</varname> setting in <filename>repmgr.conf</filename> is the same as the the Barman catalogue must include at least one valid backup for this server;
server configured in Barman;
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@@ -71,19 +91,90 @@
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
the <varname>restore_command</varname> setting in <filename>repmgr.conf</filename> is configured to the <varname>barman_server</varname> setting in <filename>repmgr.conf</filename> is the same as the
use a copy of the <command>barman-wal-restore</command> script shipped with the server configured in Barman.
<literal>barman-cli</literal> package (see section <xref linkend="cloning-from-barman-restore-command">
below).
</para>
</listitem>
<listitem>
<para>
the Barman catalogue includes at least one valid backup for this server.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para>
For example, assuming Barman is located on the host &quot;<literal>barmansrv</literal>&quot;
under the &quot;<literal>barman</literal>&quot; user account,
<filename>repmgr.conf</filename> should contain the following entries:
<programlisting>
barman_host='barman@barmansrv'
barman_server='pg'</programlisting>
</para>
<para>
Here <literal>pg</literal> corresponds to a section in Barman's configuration file for a specific
server backup configuration, which would look something like:
<programlisting>
[pg]
description = "Main cluster"
...
</programlisting>
</para>
<para>
More details on Barman configuration can be found in the
<ulink url="https://docs.pgbarman.org/">Barman documentation</ulink>'s
<ulink url="https://docs.pgbarman.org/#configuration">configuration section</ulink>.
</para>
<note>
<para>
To use a non-default Barman configuration file on the Barman server,
specify this in <filename>repmgr.conf</filename> with <filename>barman_config</filename>:
<programlisting>
barman_config='/path/to/barman.conf'</programlisting>
</para>
</note>
<para>
We also recommend configuring the <varname>restore_command</varname> setting in <filename>repmgr.conf</filename>
to use the <command>barman-wal-restore</command> script
(see section <xref linkend="cloning-from-barman-restore-command"/> below).
</para>
<tip>
<simpara>
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 <filename>~/.ssh/config</filename>
corresponding to the value of <varname>barman_host</varname> in
<filename>repmgr.conf</filename>. See the <literal>Host</literal>
section in <command>man 5 ssh_config</command> for more details.
</simpara>
</tip>
<para>
If you wish to place WAL files in a location outside the main
PostgreSQL data directory, set <option>--waldir</option>
(PostgreSQL 9.6 and earlier: <option>--xlogdir</option>) in
<option>pg_basebackup_options</option> to the target directory
(must be an absolute filepath). &repmgr; will create and
symlink to this directory in exactly the same way
<application>pg_basebackup</application> would.
</para>
<para>
It's now possible to clone a standby from Barman, e.g.:
<programlisting>
$ 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</programlisting>
</para>
<note> <note>
<simpara> <simpara>
Barman support is automatically enabled if <varname>barman_server</varname> Barman support is automatically enabled if <varname>barman_server</varname>
@@ -93,86 +184,155 @@
command line option. command line option.
</simpara> </simpara>
</note> </note>
<tip>
<simpara>
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 <filename>~/.ssh/config</filename>
corresponding to the value of<varname>barman_host</varname> in
<filename>repmgr.conf</filename>. See the <literal>Host</literal>
section in <command>man 5 ssh_config</command> for more details.
</simpara>
</tip>
<para>
It's now possible to clone a standby from Barman, e.g.:
<programlisting>
NOTICE: using configuration file "/etc/repmgr.conf"
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 upstream node
INFO: connected to source node, checking its state
INFO: successfully connected to source node
DETAIL: current installation size is 29 MB
NOTICE: retrieving backup from Barman...
receiving file list ...
(...)
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</programlisting>
</para>
</sect2> </sect2>
<sect2 id="cloning-from-barman-restore-command" xreflabel="Using Barman as a WAL file source"> <sect2 id="cloning-from-barman-restore-command" xreflabel="Using Barman as a WAL file source">
<indexterm> <title>Using Barman as a WAL file source</title>
<indexterm>
<primary>Barman</primary> <primary>Barman</primary>
<secondary>fetching archived WAL</secondary> <secondary>fetching archived WAL</secondary>
</indexterm> </indexterm>
<title>Using Barman as a WAL file source</title>
<para> <para>
As a fallback in case streaming replication is interrupted, PostgreSQL can optionally 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 retrieve WAL files from an archive, such as that provided by Barman. This is done by
setting <varname>restore_command</varname> in <filename>recovery.conf</filename> to setting <varname>restore_command</varname> in the replication configuration to
a valid shell command which can retrieve a specified WAL file from the archive. a valid shell command which can retrieve a specified WAL file from the archive.
</para> </para>
<para> <para>
<command>barman-wal-restore</command> is a Python script provided as part of the <literal>barman-cli</literal> <command>barman-wal-restore</command> is a Python script provided as part of the <literal>barman-cli</literal>
package (Barman 2.0 and later; for Barman 1.x the script is provided separately as package (Barman 2.0 ~ 2.7) or as part of the core Barman distribution (Barman 2.8 and later).
<command>barman-wal-restore.py</command>) which performs this function for Barman.
</para> </para>
<para> <para>
To use <command>barman-wal-restore</command> with &repmgr; To use <command>barman-wal-restore</command> with &repmgr;,
and assuming Barman is located on the <literal>barmansrv</literal> host assuming Barman is located on the host &quot;<literal>barmansrv</literal>&quot;
under the &quot;<literal>barman</literal>&quot; user account,
and that <command>barman-wal-restore</command> is located as an executable at and that <command>barman-wal-restore</command> is located as an executable at
<filename>/usr/bin/barman-wal-restore</filename>, <filename>/usr/bin/barman-wal-restore</filename>,
<filename>repmgr.conf</filename> should include the following lines: <filename>repmgr.conf</filename> should include the following lines:
<programlisting> <programlisting>
barman_host=barmansrv barman_host='barman@barmansrv'
barman_server=somedb barman_server='pg'
restore_command=/usr/bin/barman-wal-restore barmansrv somedb %f %p</programlisting> restore_command='/usr/bin/barman-wal-restore barmansrv pg %f %p'</programlisting>
</para> </para>
<note> <note>
<simpara> <simpara>
<command>barman-wal-restore</command> supports command line switches to <command>barman-wal-restore</command> supports command line switches to
control parallelism (<literal>--parallel=N</literal>) and compression ( control parallelism (<literal>--parallel=N</literal>) and compression
<literal>--bzip2</literal>, <literal>--gzip</literal>). (<literal>--bzip2</literal>, <literal>--gzip</literal>).
</simpara> </simpara>
</note> </note>
<note>
<para>
To use a non-default Barman configuration file on the Barman server,
specify this in <filename>repmgr.conf</filename> with <filename>barman_config</filename>:
<programlisting>
barman_config=/path/to/barman.conf</programlisting>
</para>
</note>
</sect2> </sect2>
<sect2 id="cloning-from-barman-pg_backupapi-mode" xreflabel="Using Barman through its API (pg-backup-api)">
<title>Using Barman through its API (pg-backup-api)</title>
<indexterm>
<primary>cloning</primary>
<secondary>pg-backup-api</secondary>
</indexterm>
<para>
You can find information on how to install and setup pg-backup-api in
<ulink url="https://www.enterprisedb.com/docs/supported-open-source/barman/pg-backup-api/">the pg-backup-api
documentation</ulink>.
</para>
<para>
This mode (`pg-backupapi`) was introduced in v5.4.0 as a way to further integrate with Barman letting Barman
handle the restore. This also reduces the ssh keys that need to share between the backup and postgres nodes.
As long as you have access to the API service by HTTP calls, you could perform recoveries right away.
You just need to instruct Barman through the API which backup you need and on which node the backup needs to
to be restored on.
</para>
<para>
In order to enable <literal>pg_backupapi mode</literal> support for <command>repmgr standby clone</command>,
you need the following lines in repmgr.conf:
<itemizedlist spacing="compact" mark="bullet">
<listitem><para>pg_backupapi_host: Where pg-backup-api is hosted</para></listitem>
<listitem><para>pg_backupapi_node_name: Name of the server as understood by Barman</para></listitem>
<listitem><para>pg_backupapi_remote_ssh_command: How Barman will be connecting as to the node</para></listitem>
<listitem><para>pg_backupapi_backup_id: ID of the existing backup you need to restore</para></listitem>
</itemizedlist>
This is an example of how repmgr.conf would look like:
<programlisting>
pg_backupapi_host = '192.168.122.154'
pg_backupapi_node_name = 'burrito'
pg_backupapi_remote_ssh_command = 'ssh john_doe@192.168.122.1'
pg_backupapi_backup_id = '20230223T093201'
</programlisting>
</para>
<para>
<literal>pg_backupapi_host</literal> is the variable name that enables this mode, and when you set it,
all the rest of the above variables are required. Also, remember that this service is just an interface
between Barman and repmgr, hence if something fails during a recovery, you should check Barman's logs upon
why the process couldn't finish properly.
</para>
<note>
<simpara>
Despite in Barman you can define shortcuts like "lastest" or "oldest", they are not supported for the
time being in pg-backup-api. These shortcuts will be supported in a future release.
</simpara>
</note>
<para>
This is a real example of repmgr's output cloning with the API. Note that during this operation, we stopped
the service for a little while and repmgr had to retry but that doesn't affect the final outcome. The primary
is listening on localhost's port 6001:
<programlisting>
$ repmgr -f ~/nodes/node_3/repmgr.conf standby clone -U repmgr -p 6001 -h localhost
NOTICE: destination directory "/home/mario/nodes/node_3/data" provided
INFO: Attempting to use `pg_backupapi` new restore mode
INFO: connecting to source node
DETAIL: connection string is: user=repmgr port=6001 host=localhost
DETAIL: current installation size is 8541 MB
DEBUG: 1 node records returned by source node
DEBUG: connecting to: "user=repmgr dbname=repmgr host=localhost port=6001 connect_timeout=2 fallback_application_name=repmgr options=-csearch_path="
DEBUG: upstream_node_id determined as 1
INFO: Attempting to use `pg_backupapi` new restore mode
INFO: replication slot usage not requested; no replication slot will be set up for this standby
NOTICE: starting backup (using pg_backupapi)...
INFO: Success creating the task: operation id '20230309T150647'
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
Incorrect reply received for that operation ID.
INFO: Retrying...
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status IN_PROGRESS
INFO: status DONE
NOTICE: standby clone (from pg_backupapi) complete
NOTICE: you can now start your PostgreSQL server
HINT: for example: pg_ctl -D /home/mario/nodes/node_3/data start
HINT: after starting the server, you need to register this standby with "repmgr standby register"
</programlisting>
</para>
</sect2> <!--END cloning-from-barman-pg_backupapi-mode !-->
</sect1> </sect1>
<sect1 id="cloning-replication-slots" xreflabel="Cloning and replication slots"> <sect1 id="cloning-replication-slots" xreflabel="Cloning and replication slots">
<title>Cloning and replication slots</title>
<indexterm> <indexterm>
<primary>cloning</primary> <primary>cloning</primary>
<secondary>replication slots</secondary> <secondary>replication slots</secondary>
@@ -182,13 +342,13 @@
<primary>replication slots</primary> <primary>replication slots</primary>
<secondary>cloning</secondary> <secondary>cloning</secondary>
</indexterm> </indexterm>
<title>Cloning and replication slots</title>
<para> <para>
Replication slots were introduced with PostgreSQL 9.4 and are designed to ensure 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 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 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 manage WAL file retention by estimating the number of WAL files that need to
be maintained on the primary using <varname>wal_keep_segments</varname>. be maintained on the primary using <varname>wal_keep_segments</varname>
(PostgreSQL 13 and later: <varname>wal_keep_size</varname>).
Do however be aware that if a standby is disconnected, WAL will continue to 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 accumulate on the primary until either the standby reconnects or the replication
slot is dropped. slot is dropped.
@@ -242,25 +402,27 @@
build up indefinitely, possibly leading to server failure. build up indefinitely, possibly leading to server failure.
</simpara> </simpara>
<simpara> <simpara>
As an alternative we recommend using 2ndQuadrant's <ulink url="https://www.pgbarman.org/">Barman</ulink>, As an alternative we recommend using EDB's <ulink url="https://www.pgbarman.org/">Barman</ulink>,
which offloads WAL management to a separate server, removing the requirement to use a replication 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 <xref linkend="cloning-from-barman"> slot for each individual standby to reserve WAL. See section <xref linkend="cloning-from-barman"/>
for more details on using &repmgr; together with Barman. for more details on using &repmgr; together with Barman.
</simpara> </simpara>
</tip> </tip>
</sect1> </sect1>
<sect1 id="cloning-cascading" xreflabel="Cloning and cascading replication"> <sect1 id="cloning-cascading" xreflabel="Cloning and cascading replication">
<title>Cloning and cascading replication</title>
<indexterm> <indexterm>
<primary>cloning</primary> <primary>cloning</primary>
<secondary>cascading replication</secondary> <secondary>cascading replication</secondary>
</indexterm> </indexterm>
<title>Cloning and cascading replication</title>
<para> <para>
Cascading replication, introduced with PostgreSQL 9.2, enables a standby server Cascading replication, introduced with PostgreSQL 9.2, enables a standby server
to replicate from another standby server rather than directly from the primary, to replicate from another standby server rather than directly from the primary,
meaning replication changes "cascade" down through a hierarchy of servers. This 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 can be used to reduce load on the primary and minimize bandwidth usage between
sites. For more details, see the sites. For more details, see the
<ulink url="https://www.postgresql.org/docs/current/warm-standby.html#CASCADING-REPLICATION"> <ulink url="https://www.postgresql.org/docs/current/warm-standby.html#CASCADING-REPLICATION">
PostgreSQL cascading replication documentation</ulink>. PostgreSQL cascading replication documentation</ulink>.
@@ -269,14 +431,14 @@
&repmgr; supports cascading replication. When cloning a standby, &repmgr; supports cascading replication. When cloning a standby,
set the command-line parameter <literal>--upstream-node-id</literal> to the set the command-line parameter <literal>--upstream-node-id</literal> to the
<varname>node_id</varname> of the server the standby should connect to, and <varname>node_id</varname> of the server the standby should connect to, and
&repmgr; will create <filename>recovery.conf</filename> to point to it. Note &repmgr; will create a replication configuration file to point to it. Note
that if <literal>--upstream-node-id</literal> is not explicitly provided, that if <literal>--upstream-node-id</literal> is not explicitly provided,
&repmgr; will set the standby's <filename>recovery.conf</filename> to &repmgr; will set the standby's replication configuration to
point to the primary node. point to the primary node.
</para> </para>
<para> <para>
To demonstrate cascading replication, first ensure you have a primary and standby To demonstrate cascading replication, first ensure you have a primary and standby
set up as shown in the <xref linkend="quickstart">. set up as shown in the <xref linkend="quickstart"/>.
Then create an additional standby server with <filename>repmgr.conf</filename> looking Then create an additional standby server with <filename>repmgr.conf</filename> looking
like this: like this:
<programlisting> <programlisting>
@@ -332,18 +494,18 @@
cluster, you may wish to clone a downstream standby whose upstream node 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 does not yet exist. In this case you can clone from the primary (or
another upstream node); provide the parameter <literal>--upstream-conninfo</literal> another upstream node); provide the parameter <literal>--upstream-conninfo</literal>
to explictly set the upstream's <varname>primary_conninfo</varname> string to explicitly set the upstream's <varname>primary_conninfo</varname> string
in <filename>recovery.conf</filename>. in the replication configuration.
</simpara> </simpara>
</tip> </tip>
</sect1> </sect1>
<sect1 id="cloning-advanced" xreflabel="Advanced cloning options"> <sect1 id="cloning-advanced" xreflabel="Advanced cloning options">
<title>Advanced cloning options</title>
<indexterm> <indexterm>
<primary>cloning</primary> <primary>cloning</primary>
<secondary>advanced options</secondary> <secondary>advanced options</secondary>
</indexterm> </indexterm>
<title>Advanced cloning options</title>
<sect2 id="cloning-advanced-pg-basebackup-options" xreflabel="pg_basebackup options when cloning a standby"> <sect2 id="cloning-advanced-pg-basebackup-options" xreflabel="pg_basebackup options when cloning a standby">
<title>pg_basebackup options when cloning a standby</title> <title>pg_basebackup options when cloning a standby</title>
@@ -365,7 +527,7 @@
<simpara> <simpara>
If <application>Barman</application> is set up for the cluster, it's possible to If <application>Barman</application> is set up for the cluster, it's possible to
clone the standby directly from Barman, without any impact on the server the standby clone the standby directly from Barman, without any impact on the server the standby
is being cloned from. For more details see <xref linkend="cloning-from-barman">. is being cloned from. For more details see <xref linkend="cloning-from-barman"/>.
</simpara> </simpara>
</tip> </tip>
<para> <para>
@@ -390,6 +552,13 @@
WAL directory. Any WALs generated during the cloning process will be copied here, and 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. a symlink will automatically be created from the main data directory.
</para> </para>
<tip>
<para>
The <literal>--waldir</literal> (<literal>--xlogdir</literal>) option,
if present in <varname>pg_basebackup_options</varname>, will be honoured by &repmgr;
when cloning from Barman (&repmgr; 5.2 and later).
</para>
</tip>
<para> <para>
See the <ulink url="https://www.postgresql.org/docs/current/app-pgbasebackup.html">PostgreSQL pg_basebackup documentation</ulink> See the <ulink url="https://www.postgresql.org/docs/current/app-pgbasebackup.html">PostgreSQL pg_basebackup documentation</ulink>
for more details of available options. for more details of available options.
@@ -410,10 +579,8 @@
<para> <para>
The recommended way to do this is to store the password in the <literal>postgres</literal> system The recommended way to do this is to store the password in the <literal>postgres</literal> system
user's <filename>~/.pgpass</filename> file. It's also possible to store the password in the user's <filename>~/.pgpass</filename> file. For more information on using the password file, see
environment variable <varname>PGPASSWORD</varname>, however this is not recommended for the documentation section <xref linkend="configuration-password-file"/>.
security reasons. For more details see the
<ulink url="https://www.postgresql.org/docs/current/libpq-pgpass.html">PostgreSQL password file documentation</ulink>.
</para> </para>
<note> <note>
@@ -427,26 +594,13 @@
</note> </note>
<para> <para>
If, for whatever reason, you wish to include the password in <filename>recovery.conf</filename>, If, for whatever reason, you wish to include the password in the replication configuration file,
set <varname>use_primary_conninfo_password</varname> to <literal>true</literal> in set <varname>use_primary_conninfo_password</varname> to <literal>true</literal> in
<filename>repmgr.conf</filename>. This will read a password set in <varname>PGPASSWORD</varname> <filename>repmgr.conf</filename>. This will read a password set in <varname>PGPASSWORD</varname>
(but not <filename>~/.pgpass</filename>) and place it into the <varname>primary_conninfo</varname> (but not <filename>~/.pgpass</filename>) and place it into the <varname>primary_conninfo</varname>
string in <filename>recovery.conf</filename>. Note that <varname>PGPASSWORD</varname> string in the replication configuration. Note that <varname>PGPASSWORD</varname>
will need to be set during any action which causes <filename>recovery.conf</filename> to be will need to be set during any action which causes the replication configuration file to be
rewritten, e.g. <xref linkend="repmgr-standby-follow">. rewritten, e.g. <xref linkend="repmgr-standby-follow"/>.
</para>
<para>
It is of course also possible to include the password value in the <varname>conninfo</varname>
string for each node, but this is obviously a security risk and should be avoided.
</para>
<para>
From PostgreSQL 9.6, <application>libpq</application> supports the <varname>passfile</varname>
parameter in connection strings, which can be used to specify a password file other than
the default <filename>~/.pgpass</filename>.
</para>
<para>
To have &repmgr; write a custom password file in <varname>primary_conninfo</varname>,
specify its location in <varname>passfile</varname> in <filename>repmgr.conf</filename>.
</para> </para>
</sect2> </sect2>
@@ -457,12 +611,40 @@
user (in addition to the user who manages the &repmgr; metadata). In this case, user (in addition to the user who manages the &repmgr; metadata). In this case,
the replication user should be set in <filename>repmgr.conf</filename> via the parameter the replication user should be set in <filename>repmgr.conf</filename> via the parameter
<varname>replication_user</varname>; &repmgr; will use this value when making <varname>replication_user</varname>; &repmgr; will use this value when making
replication connections and generating <filename>recovery.conf</filename>. This replication connections and generating the replication configuration. This
value will also be stored in the parameter <literal>repmgr.nodes</literal> value will also be stored in the parameter <literal>repmgr.nodes</literal>
table for each node; it no longer needs to be explicitly specified when table for each node; it no longer needs to be explicitly specified when
cloning a node or executing <xref linkend="repmgr-standby-follow">. cloning a node or executing <xref linkend="repmgr-standby-follow"/>.
</para> </para>
</sect2> </sect2>
<sect2 id="cloning-advanced-tablespace-mapping" xreflabel="Tablespace mapping">
<title>Tablespace mapping</title>
<indexterm>
<primary>tablespace mapping</primary>
</indexterm>
<para>
&repmgr; provides a <option>tablespace_mapping</option> configuration
file option, which will makes it possible to map the tablespace on the source node to
a different location on the local node.
</para>
<para>
To use this, add <option>tablespace_mapping</option> to <filename>repmgr.conf</filename>
like this:
<programlisting>
tablespace_mapping='/var/lib/pgsql/tblspc1=/data/pgsql/tblspc1'
</programlisting>
</para>
<para>
where the left-hand value represents the tablespace on the source node,
and the right-hand value represents the tablespace on the standby to be cloned.
</para>
<para>
This parameter can be provided multiple times.
</para>
</sect2>
</sect1> </sect1>

View File

@@ -1,4 +1,6 @@
<sect1 id="configuration-file-log-settings" xreflabel="log settings"> <sect1 id="configuration-file-log-settings" xreflabel="log settings">
<title>Log settings</title>
<indexterm> <indexterm>
<primary>repmgr.conf</primary> <primary>repmgr.conf</primary>
<secondary>log settings</secondary> <secondary>log settings</secondary>
@@ -7,10 +9,9 @@
<primary>log settings</primary> <primary>log settings</primary>
<secondary>configuration in repmgr.conf</secondary> <secondary>configuration in repmgr.conf</secondary>
</indexterm> </indexterm>
<title>Log settings</title>
<para> <para>
By default, &repmgr; and <application>repmgrd</application> write log output to By default, &repmgr; and &repmgrd; write log output to
<literal>STDERR</literal>. An alternative log destination can be specified <literal>STDERR</literal>. An alternative log destination can be specified
(either a file or <literal>syslog</literal>). (either a file or <literal>syslog</literal>).
</para> </para>
@@ -24,7 +25,7 @@
<para> <para>
This behaviour can be overriden with the command line option <option>--log-to-file</option>, This behaviour can be overriden with the command line option <option>--log-to-file</option>,
which will redirect all logging output to the configured log destination. This is recommended which will redirect all logging output to the configured log destination. This is recommended
when &repmgr; is executed by another application, particularly <application>repmgrd</application>, when &repmgr; is executed by another application, particularly &repmgrd;,
to enable log output generated by the &repmgr; application to be stored for later reference. to enable log output generated by the &repmgr; application to be stored for later reference.
</para> </para>
</note> </note>
@@ -32,12 +33,11 @@
<variablelist> <variablelist>
<varlistentry id="repmgr-conf-log-level" xreflabel="log_level"> <varlistentry id="repmgr-conf-log-level" xreflabel="log_level">
<term><varname>log_level</varname> (<type>string</type>) <term><varname>log_level</varname> (<type>string</type>)</term>
<listitem>
<indexterm> <indexterm>
<primary><varname>log_level</varname> configuration file parameter</primary> <primary><varname>log_level</varname> configuration file parameter</primary>
</indexterm> </indexterm>
</term>
<listitem>
<para> <para>
One of <option>DEBUG</option>, <option>INFO</option>, <option>NOTICE</option>, One of <option>DEBUG</option>, <option>INFO</option>, <option>NOTICE</option>,
<option>WARNING</option>, <option>ERROR</option>, <option>ALERT</option>, <option>CRIT</option> <option>WARNING</option>, <option>ERROR</option>, <option>ALERT</option>, <option>CRIT</option>
@@ -76,11 +76,11 @@
</term> </term>
<listitem> <listitem>
<para> <para>
If <xref linkend="repmgr-conf-log-facility"> is set to <option>STDERR</option>, log output If <xref linkend="repmgr-conf-log-facility"/> is set to <option>STDERR</option>, log output
can be redirected to the specified file. can be redirected to the specified file.
</para> </para>
<para> <para>
See <xref linkend="repmgrd-log-rotation"> for information on configuring log rotation. See <xref linkend="repmgrd-log-rotation"/> for information on configuring log rotation.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -93,12 +93,12 @@
</term> </term>
<listitem> <listitem>
<para> <para>
This setting causes <application>repmgrd</application> to emit a status log This setting causes &repmgrd; to emit a status log
line at the specified interval (in seconds, default <literal>300</literal>) line at the specified interval (in seconds, default <literal>300</literal>)
describing <application>repmgrd</application>'s current state, e.g.: describing &repmgrd;'s current state, e.g.:
</para> </para>
<programlisting> <programlisting>
[2018-07-12 00:47:32] [INFO] monitoring connection to upstream node "node1" (node ID: 1)</programlisting> [2018-07-12 00:47:32] [INFO] monitoring connection to upstream node "node1" (ID: 1)</programlisting>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@@ -0,0 +1,189 @@
<sect1 id="configuration-file-optional-settings" xreflabel="optional configuration file settings">
<title>Optional configuration file settings</title>
<indexterm>
<primary>repmgr.conf</primary>
<secondary>optional settings</secondary>
</indexterm>
<note>
<simpara>
This section documents a subset of optional configuration settings; for a full
and annotated view of all configuration options see the
<ulink url="https://raw.githubusercontent.com/EnterpriseDB/repmgr/master/repmgr.conf.sample">sample repmgr.conf file</ulink>
</simpara>
</note>
<variablelist>
<varlistentry id="repmgr-conf-config-directory" xreflabel="config_directory">
<term><varname>config_directory</varname> (<type>string</type>)
<indexterm>
<primary><varname>config_directory</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
If PostgreSQL configuration files are located outside the data
directory, specify the directory where the main
<filename>postgresql.conf</filename> file is located.
</para>
<para>
This enables explicit provision of an external configuration file
directory, which if set will be passed to <command>pg_ctl</command> as the
<option>-D</option> parameter. Otherwise <command>pg_ctl</command> will
default to using the data directory, which will cause some operations
to fail if the configuration files are not present there.
</para>
<note>
<para>
This is implemented primarily for feature completeness and for
development/testing purposes. Users who have installed &repmgr; from
a package should <emphasis>not</emphasis> rely on to stop/start/restart PostgreSQL,
instead they should set the appropriate <option>service_..._command</option>
for their operating system. For more details see
<xref linkend="configuration-file-service-commands"/>.
</para>
</note>
</listitem>
</varlistentry>
<varlistentry id="repmgr-conf-replication-user" xreflabel="replication_user">
<term><varname>replication_user</varname> (<type>string</type>)
<indexterm>
<primary><varname>replication_user</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
PostgreSQL user to make replication connections with.
If not set defaults, to the user defined in <xref linkend="repmgr-conf-conninfo"/>.
</para>
</listitem>
</varlistentry>
<varlistentry id="repmgr-conf-replication-type" xreflabel="replication_type">
<term><varname>replication_type</varname> (<type>string</type>)
<indexterm>
<primary><varname>replication_type</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
Must be <literal>physical</literal> (the default).
</para>
</listitem>
</varlistentry>
<varlistentry id="repmgr-conf-location" xreflabel="location">
<term><varname>location</varname> (<type>string</type>)
<indexterm>
<primary><varname>location</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
An arbitrary string defining the location of the node; this
is used during failover to check visibility of the
current primary node.
</para>
<para>
For more details see <xref linkend="repmgrd-network-split"/>.
</para>
</listitem>
</varlistentry>
<varlistentry id="repmgr-conf-use-replication-slots" xreflabel="use_replication_slots">
<term><varname>use_replication_slots</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>use_replication_slots</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
Whether to use physical replication slots.
</para>
<note>
<para>
When using replication slots,
<varname>max_replication_slots</varname> should be configured for
at least the number of standbys which will connect
to the primary.
</para>
</note>
</listitem>
</varlistentry>
<varlistentry id="repmgr-conf-ssh-options" xreflabel="ssh_options">
<term><varname>ssh_options</varname> (<type>string</type>)
<indexterm>
<primary><varname>ssh_options</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
Options to append to the <command>ssh</command> command when executed
by &repmgr;.
</para>
<para>
We recommend adding <literal>-q</literal> to suppress any superfluous
SSH chatter such as login banners, and also an explicit
<option>ConnectTimeout</option> value,
e.g.:
<programlisting>
ssh_options='-q -o ConnectTimeout=10'</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry id="repmgr-conf-pg-bindir" xreflabel="pg_bindir">
<term><varname>pg_bindir</varname> (<type>string</type>)
<indexterm>
<primary><varname>pg_bindir</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
Path to the PostgreSQL binary directory (location of <application>pg_ctl</application>,
<application>pg_basebackup</application> etc.). Only required
if these are not in the system <varname>PATH</varname>.
</para>
<tip>
<para>
When &repmgr; is executed via <application>SSH</application> (e.g. when running
<command><link linkend="repmgr-standby-switchover">repmgr standby switchover</link></command>,
<command><link linkend="repmgr-cluster-matrix">repmgr cluster matrix</link></command> or
<command><link linkend="repmgr-cluster-crosscheck">repmgr cluster crosscheck</link></command>,
or if it is executed as cronjob), a login shell will not be used and only the
default system <varname>PATH</varname> will be set. Therefore it's recommended to set
<varname>pg_bindir</varname> so &repmgr; can correctly invoke binaries on a remote
system and avoid potential path issues.
</para>
</tip>
<para>
Debian/Ubuntu users: you will probably need to set this to the directory where
<application>pg_ctl</application> is located, e.g. <filename>/usr/lib/postgresql/9.6/bin/</filename>.
</para>
<para>
<emphasis>NOTE</emphasis>: <varname>pg_bindir</varname> is only used when &repmgr; directly
executes PostgreSQL binaries; any user-defined scripts
<emphasis>must</emphasis> be specified with the full path.
</para>
</listitem>
</varlistentry>
</variablelist>
<tip>
<simpara>
See the <ulink url="https://raw.githubusercontent.com/EnterpriseDB/repmgr/master/repmgr.conf.sample">sample repmgr.conf file</ulink>
for a full and annotated view of all configuration options.
</simpara>
</tip>
</sect1>

View File

@@ -1,10 +1,12 @@
<sect1 id="configuration-file-settings" xreflabel="required configuration file settings"> <sect1 id="configuration-file-settings" xreflabel="required configuration file settings">
<title>Required configuration file settings</title>
<indexterm> <indexterm>
<primary>repmgr.conf</primary> <primary>repmgr.conf</primary>
<secondary>required settings</secondary> <secondary>required settings</secondary>
</indexterm> </indexterm>
<title>Required configuration file settings</title>
<para> <para>
Each <filename>repmgr.conf</filename> file must contain the following parameters: Each <filename>repmgr.conf</filename> file must contain the following parameters:
</para> </para>
@@ -60,7 +62,7 @@
</para> </para>
<para> <para>
For details on conninfo strings, see section <ulink For details on conninfo strings, see section <ulink
url="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING">Connection Strings</> url="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING">Connection Strings</ulink>
in the PosgreSQL documentation. in the PosgreSQL documentation.
</para> </para>
<para> <para>
@@ -69,18 +71,18 @@
string to determine the length of time which elapses before a network string to determine the length of time which elapses before a network
connection attempt is abandoned; for details see <ulink connection attempt is abandoned; for details see <ulink
url="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT"> url="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT">
the PostgreSQL documentation</>. the PostgreSQL documentation</ulink>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="repmgr-conf-data-directory" xreflabel="data_directory"> <varlistentry id="repmgr-conf-data-directory" xreflabel="data_directory">
<term><varname>data_directory</varname> (<type>string</type>) <term><varname>data_directory</varname> (<type>string</type>)</term>
<indexterm>
<primary><varname>data_directory</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem> <listitem>
<indexterm>
<primary><varname>data_directory</varname> configuration file parameter</primary>
</indexterm>
<para> <para>
The node's data directory. This is needed by repmgr The node's data directory. This is needed by repmgr
when performing operations when the PostgreSQL instance when performing operations when the PostgreSQL instance
@@ -94,33 +96,9 @@
</variablelist> </variablelist>
</para> </para>
<para> <para>
For a full list of annotated configuration items, see the file See <xref linkend="configuration-file-optional-settings"/> for further configuration options.
<ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink>. </para>
</para>
<para>
For <application>repmgrd</application>-specific settings, see <xref linkend="repmgrd-configuration">.
</para>
<note>
<para>
The following parameters in the configuration file can be overridden with
command line options:
<itemizedlist>
<listitem>
<simpara>
<literal>-L/--log-level</literal> overrides <literal>log_level</literal> in
<filename>repmgr.conf</filename>
</simpara>
</listitem>
<listitem>
<simpara>
<literal>-b/--pg_bindir</literal> overrides <literal>pg_bindir</literal> in
<filename>repmgr.conf</filename>
</simpara>
</listitem>
</itemizedlist>
</para>
</note>
</sect1> </sect1>

View File

@@ -1,4 +1,6 @@
<sect1 id="configuration-file-service-commands" xreflabel="service command settings"> <sect1 id="configuration-file-service-commands" xreflabel="service command settings">
<title>Service command settings</title>
<indexterm> <indexterm>
<primary>repmgr.conf</primary> <primary>repmgr.conf</primary>
<secondary>service command settings</secondary> <secondary>service command settings</secondary>
@@ -7,10 +9,9 @@
<primary>service command settings</primary> <primary>service command settings</primary>
<secondary>configuration in repmgr.conf</secondary> <secondary>configuration in repmgr.conf</secondary>
</indexterm> </indexterm>
<title>Service command settings</title>
<para> <para>
In some circumstances, &repmgr; (and <application>repmgrd</application>) need to In some circumstances, &repmgr; (and &repmgrd;) need to
be able to stop, start or restart PostgreSQL. &repmgr; commands which need to do this be able to stop, start or restart PostgreSQL. &repmgr; commands which need to do this
include <link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>, include <link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>,
<link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link> and <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link> and
@@ -26,7 +27,9 @@
<note> <note>
<para> <para>
If using <application>systemd</application>, ensure you have <varname>RemoveIPC</varname> set to <literal>off</literal>. If using <application>systemd</application>, ensure you have <varname>RemoveIPC</varname> set to <literal>off</literal>.
See the <ulink url="https://wiki.postgresql.org/wiki/Systemd">systemd</ulink> See the <ulink url="https://www.postgresql.org/docs/current/index.html">PostgreSQL documentation</ulink> section
<ulink url="https://www.postgresql.org/docs/current/kernel-resources.html#SYSTEMD-REMOVEIPC">systemd RemoveIPC</ulink>
and also the <ulink url="https://wiki.postgresql.org/wiki/Systemd">systemd</ulink>
entry in the <ulink url="https://wiki.postgresql.org/wiki/Main_Page">PostgreSQL wiki</ulink> for details. entry in the <ulink url="https://wiki.postgresql.org/wiki/Main_Page">PostgreSQL wiki</ulink> for details.
</para> </para>
</note> </note>
@@ -68,7 +71,7 @@
</para> </para>
<para> <para>
Do not confuse this with <varname>promote_command</varname>, which is used Do not confuse this with <varname>promote_command</varname>, which is used
by <application>repmgrd</application> to execute <xref linkend="repmgr-standby-promote">. by &repmgrd; to execute <xref linkend="repmgr-standby-promote"/>.
</para> </para>
</note> </note>

View File

@@ -1,120 +0,0 @@
<sect1 id="configuration-file" xreflabel="configuration file">
<indexterm>
<primary>repmgr.conf</primary>
</indexterm>
<indexterm>
<primary>configuration</primary>
<secondary>repmgr.conf</secondary>
</indexterm>
<title>Configuration file</title>
<para>
<application>repmgr</application> and <application>repmgrd</application>
use a common configuration file, by default called
<filename>repmgr.conf</filename> (although any name can be used if explicitly specified).
<filename>repmgr.conf</filename> must contain a number of required parameters, including
the database connection string for the local node and the location
of its data directory; other values will be inferred from defaults if
not explicitly supplied. See section <xref linkend="configuration-file-settings">
for more details.
</para>
<sect2 id="configuration-file-format" xreflabel="configuration file format">
<indexterm>
<primary>repmgr.conf</primary>
<secondary>format</secondary>
</indexterm>
<title>Configuration file format</title>
<para>
<filename>repmgr.conf</filename> is a plain text file with one parameter/value
combination per line.
</para>
<para>
Whitespace is insignificant (except within a quoted parameter value) and blank lines are ignored.
Hash marks (<literal>#</literal>) designate the remainder of the line as a comment.
Parameter values that are not simple identifiers or numbers should be single-quoted.
Note that single quote cannot be embedded in a parameter value.
</para>
<important>
<para>
&repmgr; will interpret double-quotes as being part of a string value; only use single quotes
to quote parameter values.
</para>
</important>
<para>
Example of a valid <filename>repmgr.conf</filename> file:
<programlisting>
# repmgr.conf
node_id=1
node_name= node1
conninfo ='host=node1 dbname=repmgr user=repmgr connect_timeout=2'
data_directory = /var/lib/pgsql/11/data</programlisting>
</para>
</sect2>
<sect2 id="configuration-file-location" xreflabel="configuration file location">
<indexterm>
<primary>repmgr.conf</primary>
<secondary>location</secondary>
</indexterm>
<title>Configuration file location</title>
<para>
The configuration file will be searched for in the following locations:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<para>a configuration file specified by the <literal>-f/--config-file</literal> command line option</para>
</listitem>
<listitem>
<para>
a location specified by the package maintainer (if <application>repmgr</application>
as installed from a package and the package maintainer has specified the configuration
file location)
</para>
</listitem>
<listitem>
<para><filename>repmgr.conf</filename> in the local directory</para>
</listitem>
<listitem>
<para><filename>/etc/repmgr.conf</filename></para>
</listitem>
<listitem>
<para>the directory reported by <application>pg_config --sysconfdir</application></para>
</listitem>
</itemizedlist>
</para>
<para>
Note that if a file is explicitly specified with <literal>-f/--config-file</literal>,
an error will be raised if it is not found or not readable, and no attempt will be made to
check default locations; this is to prevent <application>repmgr</application> unexpectedly
reading the wrong configuration file.
</para>
<note>
<para>
If providing the configuration file location with <literal>-f/--config-file</literal>,
avoid using a relative path, particularly when executing <xref linkend="repmgr-primary-register">
and <xref linkend="repmgr-standby-register">, as &repmgr; stores the configuration file location
in the repmgr metadata for use when &repmgr; is executed remotely (e.g. during
<xref linkend="repmgr-standby-switchover">). &repmgr; will attempt to convert the
a relative path into an absolute one, but this may not be the same as the path you
would explicitly provide (e.g. <filename>./repmgr.conf</filename> might be converted
to <filename>/path/to/./repmgr.conf</filename>, whereas you'd normally write
<filename>/path/to/repmgr.conf</filename>).
</para>
</note>
</sect2>
</sect1>

315
doc/configuration-file.xml Normal file
View File

@@ -0,0 +1,315 @@
<sect1 id="configuration-file" xreflabel="configuration file">
<title>Configuration file</title>
<indexterm>
<primary>repmgr.conf</primary>
</indexterm>
<indexterm>
<primary>configuration</primary>
<secondary>repmgr.conf</secondary>
</indexterm>
<para>
<application>repmgr</application> and &repmgrd;
use a common configuration file, by default called
<filename>repmgr.conf</filename> (although any name can be used if explicitly specified).
<filename>repmgr.conf</filename> must contain a number of required parameters, including
the database connection string for the local node and the location
of its data directory; other values will be inferred from defaults if
not explicitly supplied. See section <xref linkend="configuration-file-settings"/>
for more details.
</para>
<sect2 id="configuration-file-format" xreflabel="configuration file format">
<title>Configuration file format</title>
<indexterm>
<primary>repmgr.conf</primary>
<secondary>format</secondary>
</indexterm>
<para>
<filename>repmgr.conf</filename> is a plain text file with one parameter/value
combination per line.
</para>
<para>
Whitespace is insignificant (except within a quoted parameter value) and blank lines are ignored.
Hash marks (<literal>#</literal>) designate the remainder of the line as a comment.
Parameter values that are not simple identifiers or numbers should be single-quoted.
</para>
<para>
To embed a single quote in a parameter value, write either two quotes (preferred) or backslash-quote.
</para>
<para>
Example of a valid <filename>repmgr.conf</filename> file:
<programlisting>
# repmgr.conf
node_id=1
node_name= node1
conninfo ='host=node1 dbname=repmgr user=repmgr connect_timeout=2'
data_directory = '/var/lib/pgsql/12/data'</programlisting>
</para>
<note>
<para>
Beginning with <link linkend="release-5.0">repmgr 5.0</link>, configuration
file parsing has been tightened up and now matches the way PostgreSQL
itself parses configuration files.
</para>
<para>
This means <filename>repmgr.conf</filename> files used with earlier &repmgr;
versions may need slight modification before they can be used with &repmgr; 5
and later.
</para>
<para>
The main change is that &repmgr; requires most string values to be
enclosed in single quotes. For example, this was previously valid:
<programlisting>
conninfo=host=node1 user=repmgr dbname=repmgr connect_timeout=2</programlisting>
but must now be changed to:
<programlisting>
conninfo='host=node1 user=repmgr dbname=repmgr connect_timeout=2'</programlisting>
</para>
</note>
<sect3 id="configuration-file-include-directives" xreflabel="configuration file include directives">
<title>Configuration file include directives</title>
<indexterm>
<primary>repmgr.conf</primary>
<secondary>include directives</secondary>
</indexterm>
<para>
From &repmgr; 5.2, the configuration file can contain the following include directives:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<option>include</option>: include the specified file,
either as an absolute path or path relative to the current file
</simpara>
</listitem>
<listitem>
<simpara>
<option>include_if_exists</option>: include the specified file.
The file is specified as an absolute path or path relative to the current file.
However, if it does not exist, an error will not be raised.
</simpara>
</listitem>
<listitem>
<simpara>
<option>include_dir</option>: include files in the specified directory
which have the <filename>.conf</filename> suffix.
The directory is specified either as an absolute path or path
relative to the current file
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
These behave in exactly the same way as the PostgreSQL configuration file processing;
see the <ulink url="https://www.postgresql.org/docs/current/config-setting.html#CONFIG-INCLUDES">PostgreSQL documentation</ulink>
for additional details.
</para>
</sect3>
</sect2>
<sect2 id="configuration-file-items" xreflabel="configuration file items">
<title>Configuration file items</title>
<para>
The following sections document some sections of the configuration file:
<itemizedlist>
<listitem>
<simpara>
<xref linkend="configuration-file-settings"/>
</simpara>
</listitem>
<listitem>
<simpara>
<xref linkend="configuration-file-optional-settings"/>
</simpara>
</listitem>
<listitem>
<simpara>
<xref linkend="configuration-file-log-settings"/>
</simpara>
</listitem>
<listitem>
<simpara>
<xref linkend="configuration-file-service-commands"/>
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
For a full list of annotated configuration items, see the file
<ulink url="https://raw.githubusercontent.com/EnterpriseDB/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink>.
</para>
<para>
For &repmgrd;-specific settings, see <xref linkend="repmgrd-configuration"/>.
</para>
<note>
<para>
The following parameters in the configuration file can be overridden with
command line options:
<itemizedlist>
<listitem>
<simpara>
<literal>-L/--log-level</literal> overrides <literal>log_level</literal> in
<filename>repmgr.conf</filename>
</simpara>
</listitem>
<listitem>
<simpara>
<literal>-b/--pg_bindir</literal> overrides <literal>pg_bindir</literal> in
<filename>repmgr.conf</filename>
</simpara>
</listitem>
</itemizedlist>
</para>
</note>
</sect2>
<sect2 id="configuration-file-location" xreflabel="configuration file location">
<title>Configuration file location</title>
<indexterm>
<primary>repmgr.conf</primary>
<secondary>location</secondary>
</indexterm>
<para>
The configuration file will be searched for in the following locations:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<para>a configuration file specified by the <literal>-f/--config-file</literal> command line option</para>
</listitem>
<listitem>
<para>
a location specified by the package maintainer (if <application>repmgr</application>
as installed from a package and the package maintainer has specified the configuration
file location)
</para>
</listitem>
<listitem>
<para><filename>repmgr.conf</filename> in the local directory</para>
</listitem>
<listitem>
<para><filename>/etc/repmgr.conf</filename></para>
</listitem>
<listitem>
<para>the directory reported by <application>pg_config --sysconfdir</application></para>
</listitem>
</itemizedlist>
</para>
<para>
In examples provided in this documentation, it is assumed the configuration file is located
at <filename>/etc/repmgr.conf</filename>. If &repmgr; is installed from a package, the
configuration file will probably be located at another location specified by the packager;
see appendix <xref linkend="appendix-packages"/> for configuration file locations in
different packaging systems.
</para>
<para>
Note that if a file is explicitly specified with <literal>-f/--config-file</literal>,
an error will be raised if it is not found or not readable, and no attempt will be made to
check default locations; this is to prevent <application>repmgr</application> unexpectedly
reading the wrong configuration file.
</para>
<note>
<para>
If providing the configuration file location with <literal>-f/--config-file</literal>,
avoid using a relative path, particularly when executing <xref linkend="repmgr-primary-register"/>
and <xref linkend="repmgr-standby-register"/>, as &repmgr; stores the configuration file location
in the repmgr metadata for use when &repmgr; is executed remotely (e.g. during
<xref linkend="repmgr-standby-switchover"/>). &repmgr; will attempt to convert the
a relative path into an absolute one, but this may not be the same as the path you
would explicitly provide (e.g. <filename>./repmgr.conf</filename> might be converted
to <filename>/path/to/./repmgr.conf</filename>, whereas you'd normally write
<filename>/path/to/repmgr.conf</filename>).
</para>
</note>
</sect2>
<sect2 id="configuration-file-postgresql-major-upgrades" xreflabel="configuration file and PostgreSQL major version upgrades">
<title>Configuration file and PostgreSQL major version upgrades</title>
<indexterm>
<primary>repmgr.conf</primary>
<secondary>PostgreSQL major version upgrades</secondary>
</indexterm>
<para>
When upgrading the PostgreSQL cluster to a new major version, <filename>repmgr.conf</filename>
will probably needed to be updated.
</para>
<para>
Usually <option>pg_bindir</option> and <option>data_directory</option> will need to be modified,
particularly if the default package locations are used, as these usually change.
</para>
<para>
It's also possible the location of <filename>repmgr.conf</filename> itself will change
(e.g. from <filename>/etc/repmgr/11/repmgr.conf</filename> to <filename>/etc/repmgr/12/repmgr.conf</filename>).
This is stored as part of the &repmgr; metadata and is used by &repmgr; to execute &repmgr; remotely
(e.g. during a <link linkend="performing-switchover">switchover operation</link>).
</para>
<para>
If the content and/or location of <filename>repmgr.conf</filename> has changed, the &repmgr; metadata
needs to be updated to reflect this. The &repmgr; metadata can be updated on each node with:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<link linkend="repmgr-primary-register">
<command>repmgr primary register --force -f /path/to/repmgr.conf</command>
</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="repmgr-standby-register">
<command>repmgr standby register --force -f /path/to/repmgr.conf</command>
</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="repmgr-witness-register">
<command>repmgr witness register --force -f /path/to/repmgr.conf -h primary_host</command>
</link>
</simpara>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>

View File

@@ -0,0 +1,175 @@
<sect1 id="configuration-password-management" xreflabel="password management">
<title>Password Management</title>
<indexterm>
<primary>passwords</primary>
</indexterm>
<sect2 id="configuration-password-management-options" xreflabel="password management options">
<title>Password Management Options</title>
<indexterm>
<primary>passwords</primary>
<secondary>options for managing</secondary>
</indexterm>
<para>
For security purposes it's desirable to protect database access using a password.
</para>
<para>
PostgreSQL has three ways of providing a password:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
including the password in the <option>conninfo</option> string
(e.g. &quot;<literal>host=node1 dbname=repmgr user=repmgr password=foo</literal>&quot;)
</simpara>
</listitem>
<listitem>
<simpara>
exporting the password as an environment variable (<envar>PGPASSWORD</envar>)
</simpara>
</listitem>
<listitem>
<simpara>
storing the password in a dedicated password file
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
We strongly advise against including the password in the <option>conninfo</option> string, as
this will result in the database password being exposed in various places, including in the
<filename>repmgr.conf</filename> file, the <literal>repmgr.nodes</literal> table, any output
generated by &repmgr; which lists the node <option>conninfo</option> strings (e.g.
<link linkend="repmgr-cluster-show">repmgr cluster show</link>) and in the &repmgr; log file,
particularly at <option>log_level=DEBUG</option>.
</para>
<note>
<para>
Currently &repmgr; does not fully support use of the <option>password</option> option in the
<option>conninfo</option> string.
</para>
</note>
<para>
Exporting the password as an environment variable (<envar>PGPASSWORD</envar>) is considered
less insecure, but the PostgreSQL documentation explicitly recommends against doing this:
<blockquote>
<attribution><ulink url="https://www.postgresql.org/docs/current/libpq-envars.html">Environment Variables</ulink></attribution>
<para>
<envar>PGPASSWORD</envar> behaves the same as the <option>password</option>
connection parameter. Use of this environment variable
is not recommended for security reasons, as some operating systems
allow non-root users to see process environment variables via
<application>ps</application>; instead consider using a password file.
</para>
</blockquote>
</para>
<para>
The most secure option for managing passwords is to use a dedicated password file; see the following
section for more details.
</para>
</sect2>
<sect2 id="configuration-password-file" xreflabel="password file">
<title>Using a password file</title>
<indexterm>
<primary>pgpass</primary>
</indexterm>
<indexterm>
<primary>.pgpass</primary>
</indexterm>
<indexterm>
<primary>passwords</primary>
<secondary>using a password file</secondary>
</indexterm>
<para>
The most secure way of storing passwords is in a password file,
which by default is <filename>~/.pgpass</filename>. This file
can only be read by the system user who owns the file, and
PostgreSQL will refuse to use the file unless read/write
permissions are restricted to the file owner. The password(s)
contained in the file will not be directly accessed by
&repmgr; (or any other libpq-based client software such as <application>psql</application>).
</para>
<para>
For full details see the
<ulink url="https://www.postgresql.org/docs/current/libpq-pgpass.html">PostgreSQL password file documentation</ulink>.
</para>
<para>
For use with &repmgr;, the <filename>~/.pgpass</filename> must two entries for each
node in the replication cluster: one for the &repmgr; user who accesses the &repmgr; metadatabase,
and one for replication connections (regardless of whether a dedicated replication user is used).
The file must be present on each node in the replication cluster.
</para>
<para>
A <filename>~/.pgpass</filename> file for a 3-node cluster where the <literal>repmgr</literal> database user
is used for both for accessing the &repmgr; metadatabase and for replication connections would look like this:
<programlisting>
node1:5432:repmgr:repmgr:foo
node1:5432:replication:repmgr:foo
node2:5432:repmgr:repmgr:foo
node2:5432:replication:repmgr:foo
node3:5432:repmgr:repmgr:foo
node3:5432:replication:repmgr:foo</programlisting>
If a dedicated replication user (here: <literal>repluser</literal>) is in use, the file would look like this:
<programlisting>
node1:5432:repmgr:repmgr:foo
node1:5432:replication:repluser:foo
node2:5432:repmgr:repmgr:foo
node2:5432:replication:repluser:foo
node3:5432:repmgr:repmgr:foo
node3:5432:replication:repluser:foo</programlisting>
If you are planning to use the <option>-S</option>/<option>--superuser</option> option,
there must also be an entry enabling the superuser to connect to the &repmgr; database.
Assuming the superuser is <literal>postgres</literal>, the file would look like this:
<programlisting>
node1:5432:repmgr:repmgr:foo
node1:5432:repmgr:postgres:foo
node1:5432:replication:repluser:foo
node2:5432:repmgr:repmgr:foo
node2:5432:repmgr:postgres:foo
node2:5432:replication:repluser:foo
node3:5432:repmgr:repmgr:foo
node3:5432:repmgr:postgres:foo
node3:5432:replication:repluser:foo</programlisting>
</para>
<para>
The <filename>~/.pgpass</filename> file can be simplified with the use of wildcards if
there is no requirement to restrict provision of passwords to particular hosts, ports
or databases. The preceding file could then be formatted like this:
<programlisting>
*:*:*:repmgr:foo
*:*:*:postgres:foo
</programlisting>
</para>
<note>
<para>
It's possible to specify an alternative location for the <filename>~/.pgpass</filename> file, either via
the environment variable <envar>PGPASSFILE</envar>, or (from PostgreSQL 9.6) using the
<varname>passfile</varname> parameter in connection strings.
</para>
<para>
If using the <varname>passfile</varname> parameter, it's essential to ensure the file is in the same
location on all nodes, as when connecting to a remote node, the file referenced is the one on the
local node.
</para>
<para>
Additionally, you <emphasis>must</emphasis> specify the passfile location in <filename>repmgr.conf</filename>
with the <option>passfile</option> option so &repmgr; can write the correct path when creating the
<option>primary_conninfo</option> parameter for replication configuration on standbys.
</para>
</note>
</sect2>
</sect1>

View File

@@ -0,0 +1,192 @@
<sect1 id="configuration-permissions" xreflabel="Database user permissions">
<title>repmgr database user permissions</title>
<indexterm>
<primary>configuration</primary>
<secondary>database user permissions</secondary>
</indexterm>
<para>
If the &repmgr; database user (the PostgreSQL user defined in the
<varname>conninfo</varname> setting is a superuser, no further user permissions need
to be granted.
</para>
<sect2 id="configuration-permissions-no-superuser" xreflabel="Non-super user permissions">
<title>repmgr user as a non-superuser</title>
<para>
In principle the &repmgr; database user does not need to be a superuser.
In this case the &repmgr; will need to be granted execution permissions on certain
functions, and membership of certain roles. However be aware that &repmgr; does
expect to be able to execute certain commands which are restricted to superusers;
in this case either a superuser must be specified with the <option>-S</option>/<option>--superuser</option>
(where available) option, or the corresponding action should be executed manually as a superuser.
</para>
<para>
The following sections describe the actions needed to use &repmgr; with a non-superuser,
and relevant caveats.
</para>
<sect3 id="configuration-permissions-replication" xreflabel="Replication role">
<title>Replication role</title>
<para>
&repmgr; requires a database user with the <literal>REPLICATION</literal> role
to be able to create a replication connection and (if configured) to administer
replication slots.
</para>
<para>
By default this is the database user defined in the <varname>conninfo</varname>
setting. This user can be:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
a superuser
</simpara>
</listitem>
<listitem>
<simpara>
a non-superuser with the <literal>REPLICATION</literal> role
</simpara>
</listitem>
<listitem>
<simpara>
another user defined in the <filename>repmgr.conf</filename> parameter <varname>replication_user</varname> with the <literal>REPLICATION</literal> role
</simpara>
</listitem>
</itemizedlist>
</para>
</sect3>
<sect3 id="configuration-permissions-roles" xreflabel="Database roles for non-superusers">
<title>Database roles</title>
<para>
A non-superuser &repmgr; database user should be a member of the following
<ulink url="https://www.postgresql.org/docs/current/predefined-roles.html">predefined roles</ulink>
(PostgreSQL 10 and later):
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<varname>pg_read_all_stats</varname>
(to read the <varname>status</varname> column of <literal>pg_stat_replication</literal>
and execute <function>pg_database_size()</function> on all databases)
</simpara>
</listitem>
<listitem>
<simpara>
<varname>pg_read_all_settings</varname> (to access the <varname>data_directory</varname> setting)
</simpara>
</listitem>
</itemizedlist>
Alternatively the meta-role <varname>pg_monitor</varname> can be granted, which includes membership
of the above predefined roles.
</para>
<para>
Membership of these roles can be granted with e.g. <command>GRANT pg_read_all_stats TO repmgr</command>.
</para>
<para>
Users of PostgreSQL 9.6 or earlier should upgrade to a supported PostgreSQL version, or provide
the <option>-S</option>/<option>--superuser</option> where available.
</para>
</sect3>
<sect3 id="configuration-permissions-extension" xreflabel="Extension creation">
<title>Extension creation</title>
<para>
&repmgr; requires that the database defined in the <varname>conninfo</varname>
setting contains the <literal>repmgr</literal> extension. The database user defined in the
<varname>conninfo</varname> setting must be able to access this database and
the database objects contained within the extension.
</para>
<para>
The <literal>repmgr</literal> extension can only be installed by a superuser.
If the &repmgr; user is a superuser, &repmgr; will create the extension automatically.
</para>
<para>
Alternatively, the extension can be created manually by a superuser
(with &quot;<command>CREATE EXTENSION repmgr</command>&quot;) before executing
<link linkend="repmgr-primary-register">repmgr primary register</link>.
</para>
</sect3>
<sect3 id="configuration-permissions-functions" xreflabel="Function permissions for non-superusers">
<title>Function permissions</title>
<para>
If the &repmgr; database user is not a superuser, <literal>EXECUTE</literal> permission should be
granted on the following function:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<function>pg_wal_replay_resume()</function> (required by &repmgrd; during failover operations;
if permission is not granted, the failoved process may not function reliably if a node
has WAL replay paused)
</simpara>
</listitem>
<listitem>
<simpara>
<function>pg_promote()</function> (PostgreSQL 12 and later; if permission is not granted,
&repmgr; will fall back to <command>pg_ctl promote</command>)
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
<literal>EXECUTE</literal> permission on functions can be granted with e.g.:
<command>GRANT EXECUTE ON FUNCTION pg_catalog.pg_wal_replay_resume() TO repmgr</command>.
</para>
</sect3>
<sect3 id="configuration-permissions-superuser-required" xreflabel="repmgr actions requiring a superuser">
<title>repmgr actions requiring a superuser</title>
<para>
In some circumstances, &repmgr; may need to perform an operation which cannot be delegated to a
non-superuser.
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
The <command>CHECKPOINT</command> command is executed by
<link linkend="repmgr-standby-switchover">repmgr standby switchover</link>. This can only
be executed by a superuser; if the &repmgr; user is not a superuser,
the <option>-S</option>/<option>--superuser</option> should be used.
</simpara>
<simpara>
If &repmgr; is not able to execute <command>CHECKPOINT</command>,
there is a risk that the demotion candidate may not be able to shut down as smoothly as might otherwise
have been the case.
</simpara>
</listitem>
<listitem>
<simpara>
The <command>ALTER SYSTEM</command> is executed by &repmgrd; if
<varname>standby_disconnect_on_failover</varname> is set to <literal>true</literal> in
<filename>repmgr.conf</filename>. <command>ALTER SYSTEM</command> can only be executed by
a superuser; if the &repmgr; user is not a superuser, this functionality will not be available.
</simpara>
</listitem>
</itemizedlist>
</para>
</sect3>
<sect3 id="configuration-permissions-superuser-option" xreflabel="repmgr commands with --superuser option">
<title>repmgr commands with --superuser option</title>
<para>
The following repmgr commands provide the <option>-S</option>/<option>--superuser</option> option:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara><link linkend="repmgr-standby-clone">repmgr standby clone</link> (to be able to copy configuration files outside of the data directory if <option>--copy-external-config-files</option> provided)</simpara>
</listitem>
<listitem>
<simpara><link linkend="repmgr-standby-switchover">repmgr standby switchover</link> (to execute <command>CHECKPOINT</command>)</simpara>
</listitem>
<listitem>
<simpara><link linkend="repmgr-node-check">repmgr node check</link> (to execute <command>repmgr node check --data-directory-config</command>; note this is also called by <link linkend="repmgr-standby-switchover">repmgr standby switchover</link>)</simpara>
</listitem>
<listitem>
<simpara><link linkend="repmgr-node-service">repmgr node service</link> (to execute <command>CHECKPOINT</command> via the <option>--checkpoint</option>; note this is also called by <link linkend="repmgr-standby-switchover">repmgr standby switchover</link>)</simpara>
</listitem>
</itemizedlist>
</para>
</sect3>
</sect2>
</sect1>

View File

@@ -2,6 +2,8 @@
<title>repmgr configuration</title> <title>repmgr configuration</title>
<sect1 id="configuration-prerequisites" xreflabel="Prerequisites for configuration"> <sect1 id="configuration-prerequisites" xreflabel="Prerequisites for configuration">
<title>Prerequisites for configuration</title>
<indexterm> <indexterm>
<primary>configuration</primary> <primary>configuration</primary>
<secondary>prerequisites</secondary> <secondary>prerequisites</secondary>
@@ -12,7 +14,6 @@
<secondary>ssh</secondary> <secondary>ssh</secondary>
</indexterm> </indexterm>
<title>Prerequisites for configuration</title>
<para> <para>
Following software must be installed on both servers: Following software must be installed on both servers:
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
@@ -62,6 +63,8 @@
</tip> </tip>
<sect2 id="configuration-postgresql" xreflabel="PostgreSQL configuration"> <sect2 id="configuration-postgresql" xreflabel="PostgreSQL configuration">
<title>PostgreSQL configuration for &repmgr;</title>
<indexterm> <indexterm>
<primary>configuration</primary> <primary>configuration</primary>
<secondary>PostgreSQL</secondary> <secondary>PostgreSQL</secondary>
@@ -71,7 +74,6 @@
<primary>PostgreSQL configuration</primary> <primary>PostgreSQL configuration</primary>
</indexterm> </indexterm>
<title>PostgreSQL configuration for &repmgr;</title>
<para> <para>
The following PostgreSQL configuration parameters may need to be changed in order The following PostgreSQL configuration parameters may need to be changed in order
for &repmgr; (and replication itself) to function correctly. for &repmgr; (and replication itself) to function correctly.
@@ -81,13 +83,14 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>hot_standby</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>hot_standby</option></term> <term><option>hot_standby</option></term>
<listitem> <listitem>
<indexterm>
<primary>hot_standby</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
<option>hot_standby</option> must always be set to <literal>on</literal>, as &repmgr; needs <option>hot_standby</option> must always be set to <literal>on</literal>, as &repmgr; needs
to be able to connect to each server it manages. to be able to connect to each server it manages.
@@ -104,13 +107,15 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>wal_level</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>wal_level</option></term> <term><option>wal_level</option></term>
<listitem> <listitem>
<indexterm>
<primary>wal_level</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
<option>wal_level</option> must be one of <option>replica</option> or <option>logical</option> <option>wal_level</option> must be one of <option>replica</option> or <option>logical</option>
(PostgreSQL 9.5 and earlier: one of <option>hot_standby</option> or <option>logical</option>). (PostgreSQL 9.5 and earlier: one of <option>hot_standby</option> or <option>logical</option>).
@@ -123,13 +128,15 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>max_wal_senders</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>max_wal_senders</option></term> <term><option>max_wal_senders</option></term>
<listitem> <listitem>
<indexterm>
<primary>max_wal_senders</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
<option>max_wal_senders</option> must be set to a value of <literal>2</literal> or greater. <option>max_wal_senders</option> must be set to a value of <literal>2</literal> or greater.
In general you will need one WAL sender for each standby which will attach to the PostgreSQL In general you will need one WAL sender for each standby which will attach to the PostgreSQL
@@ -141,21 +148,33 @@
instances in the replication cluster which may potentially become a primary server or instances in the replication cluster which may potentially become a primary server or
(in cascading replication) the upstream server of a standby. (in cascading replication) the upstream server of a standby.
</para> </para>
<para> <para>
PostgreSQL documentation: <ulink url="https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-MAX-WAL-SENDERS">max_wal_senders</ulink>. PostgreSQL documentation: <ulink url="https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-MAX-WAL-SENDERS">max_wal_senders</ulink>.
</para> </para>
<note>
<para>
From <productname>PostgreSQL 12</productname>, <option>max_wal_senders</option>
<emphasis>must</emphasis> be set to the same or a higher value as the primary node
(at the time the node was cloned), otherwise the standby will refuse
to start (unless <option>hot_standby</option> is set to <literal>off</literal>, which
will prevent the node from accepting queries).
</para>
</note>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<indexterm>
<primary>max_replication_slots</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>max_replication_slots</option></term> <term><option>max_replication_slots</option></term>
<listitem> <listitem>
<indexterm>
<primary>max_replication_slots</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
If you are intending to use replication slots, <option>max_replication_slots</option> If you are intending to use replication slots, <option>max_replication_slots</option>
must be set to a non-zero value. must be set to a non-zero value.
@@ -174,19 +193,20 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>wal_log_hints</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>wal_log_hints</option></term> <term><option>wal_log_hints</option></term>
<listitem> <listitem>
<indexterm>
<primary>wal_log_hints</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para>If you are intending to use <application>pg_rewind</application>, <para>If you are intending to use <application>pg_rewind</application>,
and the cluster was not initialised using data checksums, you may want to consider enabling and the cluster was not initialised using data checksums, you may want to consider enabling
<option>wal_log_hints</option>. <option>wal_log_hints</option>.
</para> </para>
<para> <para>
For more details see <xref linkend="repmgr-node-rejoin-pg-rewind">. For more details see <xref linkend="repmgr-node-rejoin-pg-rewind"/>.
</para> </para>
<para> <para>
PostgreSQL documentation: <ulink url="https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LOG-HINTS">wal_log_hints</ulink>. PostgreSQL documentation: <ulink url="https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LOG-HINTS">wal_log_hints</ulink>.
@@ -196,13 +216,15 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>archive_mode</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>archive_mode</option></term> <term><option>archive_mode</option></term>
<listitem> <listitem>
<indexterm>
<primary>archive_mode</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
We suggest setting <option>archive_mode</option> to <literal>on</literal> (and We suggest setting <option>archive_mode</option> to <literal>on</literal> (and
<option>archive_command</option> to <literal>/bin/true</literal>; see below) <option>archive_command</option> to <literal>/bin/true</literal>; see below)
@@ -225,13 +247,15 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>archive_command</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>archive_command</option></term> <term><option>archive_command</option></term>
<listitem> <listitem>
<indexterm>
<primary>archive_command</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
If you have set <option>archive_mode</option> to <literal>on</literal> but are not currently planning If you have set <option>archive_mode</option> to <literal>on</literal> but are not currently planning
to use WAL file archiving, set <option>archive_command</option> to a command which does nothing but returns to use WAL file archiving, set <option>archive_command</option> to a command which does nothing but returns
@@ -246,32 +270,45 @@
<varlistentry> <varlistentry>
<indexterm> <term><option>wal_keep_segments</option> / <option>wal_keep_size</option></term>
<primary>wal_keep_segments</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>wal_keep_segments</option></term>
<listitem> <listitem>
<indexterm>
<primary>wal_keep_segments</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<indexterm>
<primary>wal_keep_size</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
Normally there is no need to set <option>wal_keep_segments</option> (default: <literal>0</literal>), as it Normally there is no need to set <option>wal_keep_segments</option>
is <emphasis>not</emphasis> a reliable way of ensuring that all required WAL segments are available to standbys. (PostgreSQL 13 and later: <varname>wal_keep_size</varname>; default: <literal>0</literal>),
Replication slots and/or an archiving solution such as Barman are recommended to ensure standbys have a reliable as it is <emphasis>not</emphasis> a reliable way of ensuring that all required WAL
segments are available to standbys. Replication slots and/or an archiving solution
such as Barman are recommended to ensure standbys have a reliable
source of WAL segments at all times. source of WAL segments at all times.
</para> </para>
<para> <para>
The only reason ever to set <option>wal_keep_segments</option> is you have The only reason ever to set <option>wal_keep_segments</option> / <option>wal_keep_size</option>
you have configured <option>pg_basebackup_options</option> is you have you have configured <option>pg_basebackup_options</option>
in <filename>repmgr.conf</filename> to include the setting <literal>--wal-method=fetch</literal> in <filename>repmgr.conf</filename> to include the setting <literal>--wal-method=fetch</literal>
(PostgreSQL 9.6 and earlier: <literal>--xlog-method=fetch</literal>) (PostgreSQL 9.6 and earlier: <literal>--xlog-method=fetch</literal>)
<emphasis>and</emphasis> you have <emphasis>not</emphasis> set <option>restore_command</option> <emphasis>and</emphasis> you have <emphasis>not</emphasis> set <option>restore_command</option>
in <filename>repmgr.conf</filename> to fetch WAL files from a reliable source such as Barman, in <filename>repmgr.conf</filename> to fetch WAL files from a reliable source such as Barman,
in which case you'll need to set <option>wal_keep_segments</option> in which case you'll need to set <option>wal_keep_segments</option>
to a sufficiently high number to ensure that all WAL files required by the standby to a sufficiently high number to ensure that all WAL files required by the standby
are retained. However we do not recommend managing replication in this way. are retained. However we do not recommend WAL retention in this way.
</para> </para>
<para> <para>
PostgreSQL documentation: <ulink url="https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-WAL-KEEP-SEGMENTS">wal_keep_segments</ulink>. PostgreSQL documentation: <ulink url="https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-WAL-KEEP-SEGMENTS">wal_keep_segments</ulink>.
<!--
PostgreSQL documentation: <ulink url="https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-WAL-KEEP-SIZE">wal_keep_size</ulink>.
-->
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -289,24 +326,10 @@
&configuration-file; &configuration-file;
&configuration-file-required-settings; &configuration-file-required-settings;
&configuration-file-optional-settings;
&configuration-file-log-settings; &configuration-file-log-settings;
&configuration-file-service-commands; &configuration-file-service-commands;
&configuration-permissions;
&configuration-password-management;
<sect1 id="configuration-permissions" xreflabel="Database user permissions">
<indexterm>
<primary>configuration</primary>
<secondary>database user permissions</secondary>
</indexterm>
<title>repmgr database user permissions</title>
<para>
&repmgr; will create an extension database containing objects
for administering &repmgr; metadata. The user defined in the <varname>conninfo</varname>
setting must be able to access all objects. Additionally, superuser permissions
are required to install the &repmgr; extension. The easiest way to do this
is create the &repmgr; user as a superuser, however if this is not
desirable, the &repmgr; user can be created as a normal user and a
superuser specified with <literal>--superuser</literal> when registering a &repmgr; node.
</para>
</sect1>
</chapter> </chapter>

View File

@@ -1,12 +1,12 @@
<chapter id="event-notifications" xreflabel="event notifications"> <chapter id="event-notifications" xreflabel="event notifications">
<title>Event Notifications</title>
<indexterm> <indexterm>
<primary>event notifications</primary> <primary>event notifications</primary>
</indexterm> </indexterm>
<title>Event Notifications</title>
<para> <para>
Each time &repmgr; or <application>repmgrd</application> perform a significant event, a record Each time &repmgr; or &repmgrd; perform a significant event, a record
of that event is written into the <literal>repmgr.events</literal> table together with of that event is written into the <literal>repmgr.events</literal> table together with
a timestamp, an indication of failure or success, and further details a timestamp, an indication of failure or success, and further details
if appropriate. This is useful for gaining an overview of events if appropriate. This is useful for gaining an overview of events
@@ -27,7 +27,7 @@
(3 rows)</programlisting> (3 rows)</programlisting>
</para> </para>
<para> <para>
Alternatively, use <xref linkend="repmgr-cluster-event"> to output a Alternatively, use <xref linkend="repmgr-cluster-event"/> to output a
formatted list of events. formatted list of events.
</para> </para>
<para> <para>
@@ -91,12 +91,12 @@
may contain spaces, so should be quoted in the provided command may contain spaces, so should be quoted in the provided command
configuration, e.g.: configuration, e.g.:
<programlisting> <programlisting>
event_notification_command='/path/to/some/script %n %e %s "%t" "%d"' event_notification_command='/path/to/some/script %n %e %s "%t" "%d"'</programlisting>
</programlisting>
</para> </para>
<para> <para>
The following parameters are provided for a subset of event notifications: The following parameters are provided for a subset of event notifications; their meaning may
change according to context:
</para> </para>
<variablelist> <variablelist>
@@ -104,10 +104,13 @@
<term><option>%p</option></term> <term><option>%p</option></term>
<listitem> <listitem>
<para> <para>
node ID of the current primary (<xref linkend="repmgr-standby-register"> and <xref linkend="repmgr-standby-follow">) node ID of the current primary (<xref linkend="repmgr-standby-register"/> and <xref linkend="repmgr-standby-follow"/>)
</para> </para>
<para> <para>
node ID of the demoted primary (<xref linkend="repmgr-standby-switchover"> only) node ID of the demoted primary (<xref linkend="repmgr-standby-switchover"/> only)
</para>
<para>
node ID of the former primary (<literal>repmgrd_failover_promote</literal> only)
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -116,11 +119,7 @@
<listitem> <listitem>
<para> <para>
<literal>conninfo</literal> string of the primary node <literal>conninfo</literal> string of the primary node
(<xref linkend="repmgr-standby-register"> and <xref linkend="repmgr-standby-follow">) (<xref linkend="repmgr-standby-register"/> and <xref linkend="repmgr-standby-follow"/>)
</para>
<para>
<literal>conninfo</literal> string of the next available node
(<varname>bdr_failover</varname> and <varname>bdr_recovery</varname>)
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -129,10 +128,7 @@
<term><option>%a</option></term> <term><option>%a</option></term>
<listitem> <listitem>
<para> <para>
name of the current primary node (<xref linkend="repmgr-standby-register"> and <xref linkend="repmgr-standby-follow">) name of the current primary node (<xref linkend="repmgr-standby-register"/> and <xref linkend="repmgr-standby-follow"/>)
</para>
<para>
name of the next available node (<varname>bdr_failover</varname> and <varname>bdr_recovery</varname>)
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -141,13 +137,16 @@
<para> <para>
The values provided for <literal>%c</literal> and <literal>%a</literal> The values provided for <literal>%c</literal> and <literal>%a</literal>
will probably contain spaces, so should always be quoted. may contain spaces, so should always be quoted.
</para> </para>
<para> <para>
By default, all notification types will be passed to the designated script; By default, all notification types will be passed to the designated script;
the notification types can be filtered to explicitly named ones using the the notification types can be filtered to explicitly named ones using the
<varname>event_notifications</varname> parameter. <varname>event_notifications</varname> parameter, e.g.:
<programlisting>
event_notifications='primary_register,standby_register,witness_register'</programlisting>
</para> </para>
<para> <para>
@@ -205,7 +204,7 @@
</para> </para>
<para> <para>
Events generated by <application>repmgrd</application> (streaming replication mode): Events generated by &repmgrd; (streaming replication mode):
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
@@ -255,31 +254,22 @@
<simpara><literal>standby_recovery</literal></simpara> <simpara><literal>standby_recovery</literal></simpara>
</listitem> </listitem>
<listitem>
<simpara><literal><link linkend="repmgrd-primary-child-disconnection-events">child_node_disconnect</link></literal></simpara>
</listitem>
<listitem>
<simpara><literal><link linkend="repmgrd-primary-child-disconnection-events">child_node_reconnect</link></literal></simpara>
</listitem>
<listitem>
<simpara><literal><link linkend="repmgrd-primary-child-disconnection-events">child_node_new_connect</link></literal></simpara>
</listitem>
<listitem>
<simpara><literal><link linkend="repmgrd-primary-child-disconnection-events">child_nodes_disconnect_command</link></literal></simpara>
</listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para>
Events generated by <application>repmgrd</application> (BDR mode):
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara><literal>bdr_failover</literal></simpara>
</listitem>
<listitem>
<simpara><literal>bdr_reconnect</literal></simpara>
</listitem>
<listitem>
<simpara><literal>bdr_recovery</literal></simpara>
</listitem>
<listitem>
<simpara><literal>bdr_register</literal></simpara>
</listitem>
<listitem>
<simpara><literal>bdr_unregister</literal></simpara>
</listitem>
</itemizedlist>
</para>
<para> <para>
Note that under some circumstances (e.g. when no replication cluster primary Note that under some circumstances (e.g. when no replication cluster primary
could be located), it will not be possible to write an entry into the could be located), it will not be possible to write an entry into the

View File

@@ -1,90 +0,0 @@
<!-- doc/filelist.sgml -->
<!ENTITY legal SYSTEM "legal.sgml">
<!ENTITY bookindex SYSTEM "bookindex.sgml">
<!--
Some parts of the documentation are also source for some plain-text
files used during installation. To selectively ignore or include
some parts (e.g., external xref's) when generating these files we use
these parameter entities. See also standalone-install.sgml.
-->
<!ENTITY % standalone-ignore "INCLUDE">
<!ENTITY % standalone-include "IGNORE">
<!-- doc/filelist.sgml -->
<!--
By default, no index is included. Use -i include-index on the command line
to include it.
-->
<!ENTITY % include-index "IGNORE">
<!--
Create empty index element for processing by XSLT stylesheet.
-->
<!ENTITY % include-xslt-index "IGNORE">
<!--
Include external documentation sections
-->
<!ENTITY overview SYSTEM "overview.sgml">
<!ENTITY install SYSTEM "install.sgml">
<!ENTITY install-requirements SYSTEM "install-requirements.sgml">
<!ENTITY install-packages SYSTEM "install-packages.sgml">
<!ENTITY install-source SYSTEM "install-source.sgml">
<!ENTITY quickstart SYSTEM "quickstart.sgml">
<!ENTITY configuration SYSTEM "configuration.sgml">
<!ENTITY configuration-file SYSTEM "configuration-file.sgml">
<!ENTITY configuration-file-required-settings SYSTEM "configuration-file-required-settings.sgml">
<!ENTITY configuration-file-log-settings SYSTEM "configuration-file-log-settings.sgml">
<!ENTITY configuration-file-service-commands SYSTEM "configuration-file-service-commands.sgml">
<!ENTITY cloning-standbys SYSTEM "cloning-standbys.sgml">
<!ENTITY promoting-standby SYSTEM "promoting-standby.sgml">
<!ENTITY follow-new-primary SYSTEM "follow-new-primary.sgml">
<!ENTITY switchover SYSTEM "switchover.sgml">
<!ENTITY event-notifications SYSTEM "event-notifications.sgml">
<!ENTITY upgrading-repmgr SYSTEM "upgrading-repmgr.sgml">
<!ENTITY repmgrd-overview SYSTEM "repmgrd-overview.sgml">
<!ENTITY repmgrd-automatic-failover SYSTEM "repmgrd-automatic-failover.sgml">
<!ENTITY repmgrd-configuration SYSTEM "repmgrd-configuration.sgml">
<!ENTITY repmgrd-operation SYSTEM "repmgrd-operation.sgml">
<!ENTITY repmgrd-bdr SYSTEM "repmgrd-bdr.sgml">
<!ENTITY repmgr-primary-register SYSTEM "repmgr-primary-register.sgml">
<!ENTITY repmgr-primary-unregister SYSTEM "repmgr-primary-unregister.sgml">
<!ENTITY repmgr-standby-clone SYSTEM "repmgr-standby-clone.sgml">
<!ENTITY repmgr-standby-register SYSTEM "repmgr-standby-register.sgml">
<!ENTITY repmgr-standby-unregister SYSTEM "repmgr-standby-unregister.sgml">
<!ENTITY repmgr-standby-promote SYSTEM "repmgr-standby-promote.sgml">
<!ENTITY repmgr-standby-follow SYSTEM "repmgr-standby-follow.sgml">
<!ENTITY repmgr-standby-switchover SYSTEM "repmgr-standby-switchover.sgml">
<!ENTITY repmgr-witness-register SYSTEM "repmgr-witness-register.sgml">
<!ENTITY repmgr-witness-unregister SYSTEM "repmgr-witness-unregister.sgml">
<!ENTITY repmgr-node-status SYSTEM "repmgr-node-status.sgml">
<!ENTITY repmgr-node-check SYSTEM "repmgr-node-check.sgml">
<!ENTITY repmgr-node-rejoin SYSTEM "repmgr-node-rejoin.sgml">
<!ENTITY repmgr-node-service SYSTEM "repmgr-node-service.sgml">
<!ENTITY repmgr-cluster-show SYSTEM "repmgr-cluster-show.sgml">
<!ENTITY repmgr-cluster-matrix SYSTEM "repmgr-cluster-matrix.sgml">
<!ENTITY repmgr-cluster-crosscheck SYSTEM "repmgr-cluster-crosscheck.sgml">
<!ENTITY repmgr-cluster-event SYSTEM "repmgr-cluster-event.sgml">
<!ENTITY repmgr-cluster-cleanup SYSTEM "repmgr-cluster-cleanup.sgml">
<!ENTITY repmgr-daemon-status SYSTEM "repmgr-daemon-status.sgml">
<!ENTITY repmgr-daemon-start SYSTEM "repmgr-daemon-start.sgml">
<!ENTITY repmgr-daemon-stop SYSTEM "repmgr-daemon-stop.sgml">
<!ENTITY repmgr-daemon-pause SYSTEM "repmgr-daemon-pause.sgml">
<!ENTITY repmgr-daemon-unpause SYSTEM "repmgr-daemon-unpause.sgml">
<!ENTITY appendix-release-notes SYSTEM "appendix-release-notes.sgml">
<!ENTITY appendix-faq SYSTEM "appendix-faq.sgml">
<!ENTITY appendix-signatures SYSTEM "appendix-signatures.sgml">
<!ENTITY appendix-packages SYSTEM "appendix-packages.sgml">
<!ENTITY appendix-support SYSTEM "appendix-support.sgml">
<!ENTITY bookindex SYSTEM "bookindex.sgml">

71
doc/filelist.xml Normal file
View File

@@ -0,0 +1,71 @@
<!-- doc/filelist.xml -->
<!ENTITY legal SYSTEM "legal.xml">
<!ENTITY bookindex SYSTEM "bookindex.xml">
<!--
Include external documentation sections
-->
<!ENTITY overview SYSTEM "overview.xml">
<!ENTITY install SYSTEM "install.xml">
<!ENTITY install-requirements SYSTEM "install-requirements.xml">
<!ENTITY install-packages SYSTEM "install-packages.xml">
<!ENTITY install-source SYSTEM "install-source.xml">
<!ENTITY quickstart SYSTEM "quickstart.xml">
<!ENTITY configuration SYSTEM "configuration.xml">
<!ENTITY configuration-file SYSTEM "configuration-file.xml">
<!ENTITY configuration-file-required-settings SYSTEM "configuration-file-required-settings.xml">
<!ENTITY configuration-file-optional-settings SYSTEM "configuration-file-optional-settings.xml">
<!ENTITY configuration-file-log-settings SYSTEM "configuration-file-log-settings.xml">
<!ENTITY configuration-file-service-commands SYSTEM "configuration-file-service-commands.xml">
<!ENTITY configuration-permissions SYSTEM "configuration-permissions.xml">
<!ENTITY configuration-password-management SYSTEM "configuration-password-management.xml">
<!ENTITY cloning-standbys SYSTEM "cloning-standbys.xml">
<!ENTITY promoting-standby SYSTEM "promoting-standby.xml">
<!ENTITY follow-new-primary SYSTEM "follow-new-primary.xml">
<!ENTITY switchover SYSTEM "switchover.xml">
<!ENTITY event-notifications SYSTEM "event-notifications.xml">
<!ENTITY upgrading-repmgr SYSTEM "upgrading-repmgr.xml">
<!ENTITY repmgrd-overview SYSTEM "repmgrd-overview.xml">
<!ENTITY repmgrd-automatic-failover SYSTEM "repmgrd-automatic-failover.xml">
<!ENTITY repmgrd-configuration SYSTEM "repmgrd-configuration.xml">
<!ENTITY repmgrd-operation SYSTEM "repmgrd-operation.xml">
<!ENTITY repmgr-primary-register SYSTEM "repmgr-primary-register.xml">
<!ENTITY repmgr-primary-unregister SYSTEM "repmgr-primary-unregister.xml">
<!ENTITY repmgr-standby-clone SYSTEM "repmgr-standby-clone.xml">
<!ENTITY repmgr-standby-register SYSTEM "repmgr-standby-register.xml">
<!ENTITY repmgr-standby-unregister SYSTEM "repmgr-standby-unregister.xml">
<!ENTITY repmgr-standby-promote SYSTEM "repmgr-standby-promote.xml">
<!ENTITY repmgr-standby-follow SYSTEM "repmgr-standby-follow.xml">
<!ENTITY repmgr-standby-switchover SYSTEM "repmgr-standby-switchover.xml">
<!ENTITY repmgr-witness-register SYSTEM "repmgr-witness-register.xml">
<!ENTITY repmgr-witness-unregister SYSTEM "repmgr-witness-unregister.xml">
<!ENTITY repmgr-node-status SYSTEM "repmgr-node-status.xml">
<!ENTITY repmgr-node-check SYSTEM "repmgr-node-check.xml">
<!ENTITY repmgr-node-rejoin SYSTEM "repmgr-node-rejoin.xml">
<!ENTITY repmgr-node-service SYSTEM "repmgr-node-service.xml">
<!ENTITY repmgr-cluster-show SYSTEM "repmgr-cluster-show.xml">
<!ENTITY repmgr-cluster-matrix SYSTEM "repmgr-cluster-matrix.xml">
<!ENTITY repmgr-cluster-crosscheck SYSTEM "repmgr-cluster-crosscheck.xml">
<!ENTITY repmgr-cluster-event SYSTEM "repmgr-cluster-event.xml">
<!ENTITY repmgr-cluster-cleanup SYSTEM "repmgr-cluster-cleanup.xml">
<!ENTITY repmgr-service-status SYSTEM "repmgr-service-status.xml">
<!ENTITY repmgr-service-pause SYSTEM "repmgr-service-pause.xml">
<!ENTITY repmgr-service-unpause SYSTEM "repmgr-service-unpause.xml">
<!ENTITY repmgr-daemon-start SYSTEM "repmgr-daemon-start.xml">
<!ENTITY repmgr-daemon-stop SYSTEM "repmgr-daemon-stop.xml">
<!ENTITY appendix-release-notes SYSTEM "appendix-release-notes.xml">
<!ENTITY appendix-faq SYSTEM "appendix-faq.xml">
<!ENTITY appendix-signatures SYSTEM "appendix-signatures.xml">
<!ENTITY appendix-packages SYSTEM "appendix-packages.xml">
<!ENTITY appendix-support SYSTEM "appendix-support.xml">
<!ENTITY bookindex SYSTEM "bookindex.xml">

View File

@@ -1,18 +1,19 @@
<chapter id="follow-new-primary"> <chapter id="follow-new-primary">
<title>Following a new primary</title>
<indexterm> <indexterm>
<primary>Following a new primary</primary> <primary>Following a new primary</primary>
<seealso>repmgr standby follow</seealso> <seealso>repmgr standby follow</seealso>
</indexterm> </indexterm>
<title>Following a new primary</title>
<para> <para>
Following the failure or removal of the replication cluster's existing primary Following the failure or removal of the replication cluster's existing primary
server, <xref linkend="repmgr-standby-follow"> can be used to make 'orphaned' standbys server, <xref linkend="repmgr-standby-follow"/> can be used to make &quot;orphaned&quot; standbys
follow the new primary and catch up to its current state. follow the new primary and catch up to its current state.
</para> </para>
<para> <para>
To demonstrate this, assuming a replication cluster in the same state as the To demonstrate this, assuming a replication cluster in the same state as the
end of the preceding section (<xref linkend="promoting-standby">), end of the preceding section (<xref linkend="promoting-standby"/>),
execute this: execute this:
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf standby follow $ repmgr -f /etc/repmgr.conf standby follow

View File

@@ -13,22 +13,30 @@
<sect2 id="installation-packages-redhat" xreflabel="Installing from packages on RHEL, CentOS and Fedora"> <sect2 id="installation-packages-redhat" xreflabel="Installing from packages on RHEL, CentOS and Fedora">
<title>RedHat/CentOS/Fedora</title>
<indexterm> <indexterm>
<primary>installation</primary> <primary>installation</primary>
<secondary>on Red Hat/CentOS/Fedora etc.</secondary> <secondary>on Red Hat/CentOS/Fedora etc.</secondary>
</indexterm> </indexterm>
<title>RedHat/CentOS/Fedora</title>
<para> <para>
&repmgr; RPM packages for RedHat/CentOS variants and Fedora are available from the &repmgr; RPM packages for RedHat/CentOS variants and Fedora are available from the
<ulink url="https://2ndquadrant.com">2ndQuadrant</ulink> <ulink url="https://www.enterprisedb.com">EDB</ulink>
<ulink url="https://dl.2ndquadrant.com/">public repository</ulink>; see following <ulink url="https://dl.enterprisedb.com/">public repository</ulink>; see following
section for details. section for details.
</para> </para>
<note>
<para>
Currently the <ulink url="https://www.enterprisedb.com">EDB</ulink>
<ulink url="https://dl.enterprisedb.com/">public repository</ulink> provides
support for RedHat/CentOS versions 6,7 and 8.
</para>
</note>
<para> <para>
RPM packages for &repmgr; are also available via Yum through RPM packages for &repmgr; are also available via Yum through
the PostgreSQL Global Development Group RPM repository the PostgreSQL Global Development Group (PGDG) RPM repository
(<ulink url="https://yum.postgresql.org/">http://yum.postgresql.org/</ulink>). (<ulink url="https://yum.postgresql.org/">https://yum.postgresql.org/</ulink>).
Follow the instructions for your distribution (RedHat, CentOS, Follow the instructions for your distribution (RedHat, CentOS,
Fedora, etc.) and architecture as detailed there. Note that it can take some days Fedora, etc.) and architecture as detailed there. Note that it can take some days
for new &repmgr; packages to become available via the this repository. for new &repmgr; packages to become available via the this repository.
@@ -36,31 +44,35 @@
<note> <note>
<para> <para>
&repmgr; RPM packages are designed to be compatible with the community-provided PostgreSQL packages &repmgr; RPM packages are designed to be compatible with the community-provided PostgreSQL packages
and 2ndQuadrant's <ulink url="https://www.2ndquadrant.com/en/resources/2ndqpostgres/">2ndQPostgres</ulink>. and EDB's PostgreSQL Extended Server (formerly 2ndQPostgres).
They may not work with vendor-specific packages such as those provided by RedHat for RHEL They may not work with vendor-specific packages such as those provided by RedHat for RHEL
customers, as the PostgreSQL filesystem layout may be different to the community RPMs. customers, as the PostgreSQL filesystem layout may be different to the community RPMs.
Please contact your support vendor for assistance. Please contact your support vendor for assistance.
</para> </para>
<para>
See also <link linkend="appendix-faq">FAQ</link> entry
<xref linkend="faq-third-party-packages"/>.
</para>
</note> </note>
<para> <para>
For more information on the package contents, including details of installation For more information on the package contents, including details of installation
paths and relevant <link linkend="configuration-file-service-commands">service commands</link>, paths and relevant <link linkend="configuration-file-service-commands">service commands</link>,
see the appendix section <xref linkend="packages-centos">. see the appendix section <xref linkend="packages-centos"/>.
</para> </para>
<sect3 id="installation-packages-redhat-2ndq"> <sect3 id="installation-packages-redhat-2ndq">
<title>2ndQuadrant public RPM yum repository</title> <title>EDB public RPM yum repository</title>
<para> <para>
<ulink url="https://2ndquadrant.com/">2ndQuadrant</ulink> provides a dedicated <literal>yum</literal> <ulink url="https://www.enterprisedb.com/">EDB</ulink> provides a dedicated <literal>yum</literal>
<ulink url="https://dl.2ndquadrant.com/">public repository</ulink> for 2ndQuadrant software, <ulink url="https://dl.enterprisedb.com/">public repository</ulink> for EDB software,
including &repmgr;. We recommend using this for all future &repmgr; releases. including &repmgr;. We recommend using this for all future &repmgr; releases.
</para> </para>
<para> <para>
General instructions for using this repository can be found on its General instructions for using this repository can be found on its
<ulink url="https://dl.2ndquadrant.com/">homepage</ulink>. Specific instructions <ulink url="https://dl.enterprisedb.com/">homepage</ulink>. Specific instructions
for installing &repmgr; follow below. for installing &repmgr; follow below.
</para> </para>
<para> <para>
@@ -70,57 +82,46 @@
<listitem> <listitem>
<para> <para>
Locate the repository RPM for your PostgreSQL version from the list at: Locate the repository RPM for your PostgreSQL version from the list at:
<ulink url="https://dl.2ndquadrant.com/">https://dl.2ndquadrant.com/</ulink> <ulink url="https://dl.enterprisedb.com/">https://dl.enterprisedb.com/</ulink>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Install the repository definition for your distribution and PostgreSQL version Install the repository definition for your distribution and PostgreSQL version
(this enables the 2ndQuadrant repository as a source of &repmgr; packages). (this enables the EDB repository as a source of &repmgr; packages).
</para> </para>
<para> <para>
For example, for PostgreSQL 10 on CentOS, execute: For example, for PostgreSQL 14 on Rocky Linux 8, execute:
<programlisting> <programlisting>
curl https://dl.2ndquadrant.com/default/release/get/10/rpm | sudo bash</programlisting> curl https://dl.enterprisedb.com/default/release/get/14/rpm | sudo bash</programlisting>
</para> </para>
<para>
For PostgreSQL 9.6 on CentOS, execute:
<programlisting>
curl https://dl.2ndquadrant.com/default/release/get/9.6/rpm | sudo bash</programlisting>
</para>
<para> <para>
Verify that the repository is installed with: Verify that the repository is installed with:
<programlisting> <programlisting>
sudo yum repolist</programlisting> sudo dnf repolist</programlisting>
The output should contain two entries like this: The output should contain two entries like this:
<programlisting> <programlisting>
2ndquadrant-dl-default-release-pg10/7/x86_64 2ndQuadrant packages (PG10) for 7 - x86_64 4 2ndquadrant-dl-default-release-pg14 2ndQuadrant packages (PG14) for 8 - x86_64
2ndquadrant-dl-default-release-pg10-debug/7/x86_64 2ndQuadrant packages (PG10) for 7 - x86_64 - Debug 3</programlisting> 2ndquadrant-dl-default-release-pg14-debug 2ndQuadrant packages (PG14) for 8 - x86_64 - Debug</programlisting>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Install the &repmgr version appropriate for your PostgreSQL version (e.g. <literal>repmgr10</literal>): Install the &repmgr; version appropriate for your PostgreSQL version (e.g. <literal>repmgr14</literal>):
<programlisting> <programlisting>
sudo yum install repmgr10</programlisting> sudo dnf install repmgr14</programlisting>
</para> </para>
<note>
<para>
For packages for PostgreSQL 9.6 and earlier, the package name does not contain
a period between major and minor version numbers, e.g.
<literal>repmgr96</literal>.
</para>
</note>
<tip> <tip>
<para> <para>
To determine the names of available packages, execute: To determine the names of available packages, execute:
<programlisting> <programlisting>
yum search repmgr</programlisting> dnf search repmgr</programlisting>
</para>
<para>
In CentOS 7 and earlier, use <literal>yum</literal> instead of <literal>dnf</literal>.
</para> </para>
</tip> </tip>
@@ -132,7 +133,7 @@ yum search repmgr</programlisting>
<emphasis>Compatibility with PGDG Repositories</emphasis> <emphasis>Compatibility with PGDG Repositories</emphasis>
</para> </para>
<para> <para>
The 2ndQuadrant &repmgr; yum repository packages use the same definitions and file system layout as the The EDB &repmgr; yum repository packages use the same definitions and file system layout as the
main PGDG repository. main PGDG repository.
</para> </para>
<para> <para>
@@ -141,32 +142,42 @@ yum search repmgr</programlisting>
the packages are installed from. the packages are installed from.
</para> </para>
<para> <para>
To ensure the 2ndQuadrant repository is always prioritised, install <literal>yum-plugin-priorities</literal> To ensure the EDB repository is always prioritised, set the <literal>priority</literal> option
and set the repository priorities accordingly. in the repository configuration file (e.g. <filename>/etc/yum.repos.d/2ndquadrant-dl-default-release-pg14.repo</filename>
accordingly.
</para> </para>
<note>
<para>
With CentOS 7 and earlier, the package <literal>yum-plugin-priorities</literal> must be installed
to be able to set the repository priority.
</para>
</note>
<para> <para>
<emphasis>Installing a specific package version</emphasis> <emphasis>Installing a specific package version</emphasis>
</para> </para>
<para> <para>
To install a specific package version, execute <command>yum --showduplicates list</command> To install a specific package version, execute <command>dnf --showduplicates list</command>
for the package in question: for the package in question:
<programlisting> <programlisting>
[root@localhost ~]# yum --showduplicates list repmgr10 [root@localhost ~]# dnf --showduplicates list repmgr10
Loaded plugins: fastestmirror Last metadata expiration check: 0:09:15 ago on Fri 11 Mar 2022 01:09:19 AM UTC.
Loading mirror speeds from cached hostfile Installed Packages
* base: ftp.iij.ad.jp repmgr10.x86_64 5.3.1-1.el8 @2ndquadrant-dl-default-release-pg10
* extras: ftp.iij.ad.jp Available Packages
* updates: ftp.iij.ad.jp repmgr10.x86_64 5.0.0-1.rhel8 pgdg10
Available Packages repmgr10.x86_64 5.1.0-1.el8 2ndquadrant-dl-default-release-pg10
repmgr10.x86_64 4.0.3-1.rhel7 pgdg10 repmgr10.x86_64 5.1.0-1.rhel8 pgdg10
repmgr10.x86_64 4.0.4-1.rhel7 pgdg10 repmgr10.x86_64 5.1.0-2.el8 2ndquadrant-dl-default-release-pg10
repmgr10.x86_64 4.0.5-1.el7 2ndquadrant-repo-10</programlisting> repmgr10.x86_64 5.2.0-1.el8 2ndquadrant-dl-default-release-pg10
repmgr10.x86_64 5.2.0-1.rhel8 pgdg10
repmgr10.x86_64 5.2.1-1.el8 2ndquadrant-dl-default-release-pg10
repmgr10.x86_64 5.3.0-1.el8 2ndquadrant-dl-default-release-pg10
repmgr10.x86_64 5.3.1-1.el8 2ndquadrant-dl-default-release-pg10</programlisting>
then append the appropriate version number to the package name with a hyphen, e.g.: then append the appropriate version number to the package name with a hyphen, e.g.:
<programlisting> <programlisting>
[root@localhost ~]# yum install repmgr10-4.0.3-1.rhel7</programlisting> [root@localhost ~]# dnf install repmgr10-5.3.0-1.el8</programlisting>
</para> </para>
<para> <para>
<emphasis>Installing old packages</emphasis> <emphasis>Installing old packages</emphasis>
</para> </para>
@@ -174,41 +185,41 @@ yum search repmgr</programlisting>
See appendix <link linkend="packages-old-versions-rhel-centos">Installing old package versions</link> See appendix <link linkend="packages-old-versions-rhel-centos">Installing old package versions</link>
for details on how to retrieve older package versions. for details on how to retrieve older package versions.
</para> </para>
</sect3> </sect3>
</sect2> </sect2>
<sect2 id="installation-packages-debian" xreflabel="Installing from packages on Debian or Ubuntu"> <sect2 id="installation-packages-debian" xreflabel="Installing from packages on Debian or Ubuntu">
<title>Debian/Ubuntu</title>
<indexterm> <indexterm>
<primary>installation</primary> <primary>installation</primary>
<secondary>on Debian/Ubuntu etc.</secondary> <secondary>on Debian/Ubuntu etc.</secondary>
</indexterm> </indexterm>
<title>Debian/Ubuntu</title>
<para>.deb packages for &repmgr; are available from the <para>.deb packages for &repmgr; are available from the
PostgreSQL Community APT repository (<ulink url="http://apt.postgresql.org/">http://apt.postgresql.org/</ulink>). PostgreSQL Community APT repository (<ulink url="https://apt.postgresql.org/">https://apt.postgresql.org/</ulink>).
Instructions can be found in the APT section of the PostgreSQL Wiki Instructions can be found in the APT section of the PostgreSQL Wiki
(<ulink url="https://wiki.postgresql.org/wiki/Apt">https://wiki.postgresql.org/wiki/Apt</ulink>). (<ulink url="https://wiki.postgresql.org/wiki/Apt">https://wiki.postgresql.org/wiki/Apt</ulink>).
</para> </para>
<para> <para>
For more information on the package contents, including details of installation For more information on the package contents, including details of installation
paths and relevant <link linkend="configuration-file-service-commands">service commands</link>, paths and relevant <link linkend="configuration-file-service-commands">service commands</link>,
see the appendix section <xref linkend="packages-debian-ubuntu">. see the appendix section <xref linkend="packages-debian-ubuntu"/>.
</para> </para>
<sect3 id="installation-packages-debian-ubuntu-2ndq"> <sect3 id="installation-packages-debian-ubuntu-2ndq">
<title>2ndQuadrant public apt repository for Debian/Ubuntu</title> <title>EDB public apt repository for Debian/Ubuntu</title>
<para> <para>
<ulink url="https://2ndquadrant.com/">2ndQuadrant</ulink> provides a <ulink url="https://www.enterprisedb.com/">EDB</ulink> provides a
<ulink url="https://dl.2ndquadrant.com/">public apt repository</ulink> for 2ndQuadrant software, <ulink url="https://dl.enterprisedb.com/">public apt repository</ulink> for EDB software,
including &repmgr;. including &repmgr;.
</para> </para>
<para> <para>
General instructions for using this repository can be found on its General instructions for using this repository can be found on its
<ulink url="https://dl.2ndquadrant.com/">homepage</ulink>. Specific instructions <ulink url="https://dl.enterprisedb.com/">homepage</ulink>. Specific instructions
for installing &repmgr; follow below. for installing &repmgr; follow below.
</para> </para>
@@ -218,13 +229,13 @@ yum search repmgr</programlisting>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
Install the repository definition for your distribution and PostgreSQL version Install the repository definition for your distribution and PostgreSQL version
(this enables the 2ndQuadrant repository as a source of &repmgr; packages) by executing: (this enables the EDB repository as a source of &repmgr; packages) by executing:
<programlisting> <programlisting>
curl https://dl.2ndquadrant.com/default/release/get/deb | sudo bash</programlisting> curl https://dl.enterprisedb.com/default/release/get/deb | sudo bash</programlisting>
</para> </para>
<note> <note>
<para> <para>
This will automatically install the following additional packages, if not already present: This will automatically install the following additional packages, if not already present:
@@ -240,20 +251,20 @@ curl https://dl.2ndquadrant.com/default/release/get/deb | sudo bash</programlist
</note> </note>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Install the &repmgr version appropriate for your PostgreSQL version (e.g. <literal>repmgr10</literal>): Install the &repmgr; version appropriate for your PostgreSQL version (e.g. <literal>repmgr11</literal>):
<programlisting> <programlisting>
sudo apt-get install postgresql-10-repmgr</programlisting> sudo apt-get install postgresql-11-repmgr</programlisting>
</para> </para>
<note> <note>
<para> <para>
For packages for PostgreSQL 9.6 and earlier, the package name includes For packages for PostgreSQL 9.6 and earlier, the package name includes
a period between major and minor version numbers, e.g. a period between major and minor version numbers, e.g.
<literal>postgresql-9.6-repmgr</literal>. <literal>postgresql-9.6-repmgr</literal>.
</para> </para>
</note> </note>
</listitem> </listitem>
</itemizedlist> </itemizedlist>

View File

@@ -1,11 +1,12 @@
<sect1 id="install-requirements" xreflabel="installation requirements"> <sect1 id="install-requirements" xreflabel="installation requirements">
<title>Requirements for installing repmgr</title>
<indexterm> <indexterm>
<primary>installation</primary> <primary>installation</primary>
<secondary>requirements</secondary> <secondary>requirements</secondary>
</indexterm> </indexterm>
<title>Requirements for installing repmgr</title>
<para> <para>
repmgr is developed and tested on Linux and OS X, but should work on any repmgr is developed and tested on Linux and OS X, but should work on any
UNIX-like system supported by PostgreSQL itself. There is no support for UNIX-like system supported by PostgreSQL itself. There is no support for
@@ -13,14 +14,14 @@
</para> </para>
<para> <para>
&repmgr; 4.x is compatible with all PostgreSQL versions from 9.3. See &repmgr; &repmgrversion; is compatible with all PostgreSQL versions from 9.4. See
section <link linkend="install-compatibility-matrix">&repmgr; compatibility matrix</link> section <link linkend="install-compatibility-matrix">&repmgr; compatibility matrix</link>
for an overview of version compatibility. for an overview of version compatibility.
</para> </para>
<note> <note>
<simpara> <simpara>
If upgrading from &repmgr; 3.x, please see the section <xref linkend="upgrading-from-repmgr-3">. If upgrading from &repmgr; 3.x, please see the section <xref linkend="upgrading-from-repmgr-3"/>.
</simpara> </simpara>
</note> </note>
@@ -38,21 +39,21 @@
<note> <note>
<simpara> <simpara>
The same &quot;major&quot; &repmgr; version (e.g. <literal>4.2.x</literal>) <emphasis>must</emphasis> The same &quot;major&quot; &repmgr; version (e.g. <literal>&repmgrversion;.x</literal>) <emphasis>must</emphasis>
be installed on all node in the replication cluster. We strongly recommend keeping all be installed on all node in the replication cluster. We strongly recommend keeping all
nodes on the same (preferably latest) &quot;minor&quot; &repmgr; version to minimize the risk nodes on the same (preferably latest) &quot;minor&quot; &repmgr; version to minimize the risk
of incompatibilities. of incompatibilities.
</simpara> </simpara>
<simpara> <simpara>
If different &quot;major&quot; &repmgr; versions (e.g. 3.3.x and 4.1.x) If different &quot;major&quot; &repmgr; versions (e.g. 4.1.x and &repmgrversion;.x)
are installed on different nodes, in the best case &repmgr; (in particular <application>repmgrd</application>) are installed on different nodes, in the best case &repmgr; (in particular &repmgrd;)
will not run. In the worst case, you will end up with a broken cluster. will not run. In the worst case, you will end up with a broken cluster.
</simpara> </simpara>
</note> </note>
<para> <para>
A dedicated system user for &repmgr; is <emphasis>not</emphasis> required; as many &repmgr; and A dedicated system user for &repmgr; is <emphasis>not</emphasis> required; as many &repmgr; and
<application>repmgrd</application> actions require direct access to the PostgreSQL data directory, &repmgrd; actions require direct access to the PostgreSQL data directory,
these commands should be executed by the <literal>postgres</literal> user. these commands should be executed by the <literal>postgres</literal> user.
</para> </para>
@@ -72,6 +73,8 @@
<sect2 id="install-compatibility-matrix"> <sect2 id="install-compatibility-matrix">
<title>&repmgr; compatibility matrix</title>
<indexterm> <indexterm>
<primary>repmgr</primary> <primary>repmgr</primary>
<secondary>compatibility matrix</secondary> <secondary>compatibility matrix</secondary>
@@ -81,7 +84,6 @@
<primary>compatibility matrix</primary> <primary>compatibility matrix</primary>
</indexterm> </indexterm>
<title>&repmgr; compatibility matrix</title>
<para> <para>
The following table provides an overview of which &repmgr; version supports The following table provides an overview of which &repmgr; version supports
which PostgreSQL version. which PostgreSQL version.
@@ -91,56 +93,171 @@
<table id="repmgr-compatibility-matrix"> <table id="repmgr-compatibility-matrix">
<title>&repmgr; compatibility matrix</title> <title>&repmgr; compatibility matrix</title>
<tgroup cols="2"> <tgroup cols="4">
<thead> <thead>
<row> <row>
<entry> <entry>
&repmgr; version &repmgr; version
</entry> </entry>
<entry>
Supported?
</entry>
<entry> <entry>
Latest release Latest release
</entry> </entry>
<entry> <entry>
Supported PostgreSQL versions Supported PostgreSQL versions
</entry> </entry>
<entry>
Notes
</entry>
</row> </row>
</thead> </thead>
<tbody> <tbody>
<row>
<entry>
&repmgr; 5.4
</entry>
<entry>
(dev)
</entry>
<entry>
<link linkend="release-current">&repmgrversion;</link> (&releasedate;)
</entry>
<entry>
9.4, 9.5, 9.6, 10, 11, 12, 13, 15
</entry>
<entry>
&nbsp;
</entry>
</row>
<row>
<entry>
&repmgr; 5.3
</entry>
<entry>
YES
</entry>
<entry>
<link linkend="release-current">&repmgrversion;</link> (&releasedate;)
</entry>
<entry>
9.4, 9.5, 9.6, 10, 11, 12, 13, 14, 15
</entry>
<entry>
PostgreSQL 15 supported from &repmgr; 5.3.3
</entry>
</row>
<row>
<entry>
&repmgr; 5.2
</entry>
<entry>
NO
</entry>
<entry>
<link linkend="release-5.2.1">5.2.1</link> (2020-12-07)
</entry>
<entry>
9.4, 9.5, 9.6, 10, 11, 12, 13
</entry>
<entry>
&nbsp;
</entry>
</row>
<row>
<entry>
&repmgr; 5.1
</entry>
<entry>
NO
</entry>
<entry>
<link linkend="release-5.1.0">5.1.0</link> (2020-04-13)
</entry>
<entry>
9.3, 9.4, 9.5, 9.6, 10, 11, 12
</entry>
<entry>
&nbsp;
</entry>
</row>
<row>
<entry>
&repmgr; 5.0
</entry>
<entry>
NO
</entry>
<entry>
<link linkend="release-5.0">5.0</link> (2019-10-15)
</entry>
<entry>
9.3, 9.4, 9.5, 9.6, 10, 11, 12
</entry>
<entry>
&nbsp;
</entry>
</row>
<row> <row>
<entry> <entry>
&repmgr; 4.x &repmgr; 4.x
</entry> </entry>
<entry> <entry>
<link linkend="release-4.2">4.2</link> (2018-10-24) NO
</entry>
<entry>
<link linkend="release-4.4">4.4</link> (2019-06-27)
</entry> </entry>
<entry> <entry>
9.3, 9.4, 9.5, 9.6, 10, 11 9.3, 9.4, 9.5, 9.6, 10, 11
</entry> </entry>
<entry>
&nbsp;
</entry>
</row> </row>
<row> <row>
<entry> <entry>
&repmgr; 3.x &repmgr; 3.x
</entry> </entry>
<entry>
NO
</entry>
<entry> <entry>
<ulink url="https://repmgr.org/release-notes-3.3.2.html">3.3.2</ulink> (2017-05-30) <ulink url="https://repmgr.org/release-notes-3.3.2.html">3.3.2</ulink> (2017-05-30)
</entry> </entry>
<entry> <entry>
9.3, 9.4, 9.5, 9.6 9.3, 9.4, 9.5, 9.6
</entry> </entry>
<entry>
&nbsp;
</entry>
</row> </row>
<row> <row>
<entry> <entry>
&repmgr; 2.x &repmgr; 2.x
</entry> </entry>
<entry>
NO
</entry>
<entry> <entry>
<ulink url="https://repmgr.org/release-notes-2.0.3.html">2.0.3</ulink> (2015-04-16) <ulink url="https://repmgr.org/release-notes-2.0.3.html">2.0.3</ulink> (2015-04-16)
</entry> </entry>
<entry> <entry>
9.0, 9.1, 9.2, 9.3, 9.4 9.0, 9.1, 9.2, 9.3, 9.4
</entry> </entry>
<entry>
&nbsp;
</entry>
</row> </row>
</tbody> </tbody>
@@ -152,28 +269,61 @@
The &repmgr; 2.x and 3.x series are no longer maintained or supported. The &repmgr; 2.x and 3.x series are no longer maintained or supported.
We strongly recommend upgrading to the latest &repmgr; version. We strongly recommend upgrading to the latest &repmgr; version.
</para> </para>
<para>
Following the release of &repmgr; 5.0, there will be no further releases of
the &repmgr; 4.x series. Note that &repmgr; 5.x is an incremental development
of the 4.x series and &repmgr; 4.x users should upgrade to this as soon as possible.
</para>
</important> </important>
</sect2>
<sect2 id="install-postgresql-93-94">
<title>PostgreSQL 9.4 support</title>
<indexterm>
<primary>PostgreSQL 9.4</primary>
<secondary>repmgr support</secondary>
</indexterm>
<para> <para>
Note that some &repmgr; functionality is not available in PostgreSQL 9.3 and PostgreSQL 9.4. Note that some &repmgr; functionality is not available in PostgreSQL 9.4:
</para> </para>
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
<para> <para>
PostgreSQL 9.3 does not support replication slots, so corresponding &repmgr; functionality In PostgreSQL 9.4, <command>pg_rewind</command> is not part of the core
is not available.
</para>
</listitem>
<listitem>
<para>
In PostgreSQL 9.3 and PostgreSQL 9.4, <command>pg_rewind</command> is not part of the core
distribution. <command>pg_rewind</command> will need to be compiled separately to be able distribution. <command>pg_rewind</command> will need to be compiled separately to be able
to use any &repmgr; functionality which takes advantage of it. to use any &repmgr; functionality which takes advantage of it.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<warning>
<para>
PostgreSQL 9.3 has reached the end of its community support period (final release was
<ulink url="https://www.postgresql.org/docs/9.3/release-9-3-25.html">9.3.25</ulink>
in November 2018) and will no longer be updated with security or bugfixes.
</para>
<para>
Beginning with &repmgr; 5.2, &repmgr; no longer supports PostgreSQL 9.3.
</para>
<para>
PostgreSQL 9.4 has reached the end of its community support period (final release was
<ulink url="https://www.postgresql.org/docs/9.4/release-9-4-26.html">9.4.26</ulink>
in February 2020) and will no longer be updated with security or bugfixes.
</para>
<para>
We recommend that users of these versions migrate to a supported PostgreSQL version
as soon as possible.
</para>
<para>
For further details, see the <ulink url="https://www.postgresql.org/support/versioning/">PostgreSQL Versioning Policy</ulink>.
</para>
</warning>
</sect2> </sect2>
</sect1> </sect1>

View File

@@ -1,11 +1,12 @@
<sect1 id="installation-source" xreflabel="Installing from source code"> <sect1 id="installation-source" xreflabel="Installing from source code">
<indexterm>
<primary>installation</primary>
<secondary>from source</secondary>
</indexterm>
<title>Installing &repmgr; from source</title> <title>Installing &repmgr; from source</title>
<indexterm>
<primary>installation</primary>
<secondary>from source</secondary>
</indexterm>
<sect2 id="installation-source-prereqs"> <sect2 id="installation-source-prereqs">
<title>Prerequisites for installing from source</title> <title>Prerequisites for installing from source</title>
<para> <para>
@@ -23,8 +24,7 @@
<listitem> <listitem>
<para> <para>
<literal>Debian</literal> and <literal>Ubuntu</literal>: First <literal>Debian</literal> and <literal>Ubuntu</literal>: First
add the <ulink add the <ulink url="https://apt.postgresql.org/">apt.postgresql.org</ulink>
url="http://apt.postgresql.org/">apt.postgresql.org</ulink>
repository to your <filename>sources.list</filename> if you repository to your <filename>sources.list</filename> if you
have not already done so, and ensure the source repository is enabled. have not already done so, and ensure the source repository is enabled.
</para> </para>
@@ -35,8 +35,8 @@
line in the repository file, which is usually line in the repository file, which is usually
<filename>/etc/apt/sources.list.d/pgdg.list</filename>, e.g.: <filename>/etc/apt/sources.list.d/pgdg.list</filename>, e.g.:
<programlisting> <programlisting>
deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main deb https://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main
deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisting> deb-src https://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisting>
</para> </para>
</tip> </tip>
<para> <para>
@@ -60,6 +60,9 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara><literal>flex</literal></simpara>
</listitem>
<listitem> <listitem>
<simpara><literal>libedit-dev</literal></simpara> <simpara><literal>libedit-dev</literal></simpara>
</listitem> </listitem>
@@ -114,6 +117,9 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara><literal>flex</literal></simpara>
</listitem>
<listitem> <listitem>
<simpara><literal>libselinux-devel</literal></simpara> <simpara><literal>libselinux-devel</literal></simpara>
</listitem> </listitem>
@@ -172,17 +178,18 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
<para> <para>
The source for &repmgr; is maintained at The source for &repmgr; is maintained at
<ulink url="https://github.com/2ndQuadrant/repmgr">https://github.com/2ndQuadrant/repmgr</ulink>. <ulink url="https://github.com/EnterpriseDB/repmgr">https://github.com/EnterpriseDB/repmgr</ulink>.
</para> </para>
<para> <para>
There are also tags for each &repmgr; release, e.g. <literal>v4.2.0</literal>. There are also tags for each <ulink url="https://github.com/EnterpriseDB/repmgr/releases">&repmgr; release</ulink>, e.g.
<literal><ulink url="https://github.com/EnterpriseDB/repmgr/releases/tag/v4.4.0">v4.4.0</ulink></literal>.
</para> </para>
<para> <para>
Clone the source code using <application>git</application>: Clone the source code using <application>git</application>:
<programlisting> <programlisting>
git clone https://github.com/2ndQuadrant/repmgr</programlisting> git clone https://github.com/EnterpriseDB/repmgr</programlisting>
</para> </para>
<para> <para>
@@ -200,7 +207,7 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
&repmgr; website along with a tarball checksum and a matching GnuPG &repmgr; website along with a tarball checksum and a matching GnuPG
signature. See signature. See
<ulink url="http://repmgr.org/">http://repmgr.org/</ulink> <ulink url="http://repmgr.org/">http://repmgr.org/</ulink>
for the download information. See <xref linkend="appendix-signatures"> for the download information. See <xref linkend="appendix-signatures"/>
for information on verifying digital signatures. for information on verifying digital signatures.
</para> </para>
@@ -208,11 +215,11 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
You will need to download the repmgr source, e.g. <filename>repmgr-4.0.tar.gz</filename>. You will need to download the repmgr source, e.g. <filename>repmgr-4.0.tar.gz</filename>.
You may optionally verify the package checksums from the You may optionally verify the package checksums from the
<literal>.md5</literal> files and/or verify the GnuPG signatures <literal>.md5</literal> files and/or verify the GnuPG signatures
per <xref linkend="appendix-signatures">. per <xref linkend="appendix-signatures"/>.
</para> </para>
<para> <para>
After you unpack the source code archives using <literal>tar xf</literal> After you unpack the source code archives using <command>tar xf</command>
the installation process is the same as if you were installing from a git the installation process is the same as if you were installing from a git
clone. clone.
</para> </para>
@@ -227,7 +234,7 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
To installing &repmgr; from source, simply execute: To installing &repmgr; from source, simply execute:
<programlisting> <programlisting>
./configure && make install</programlisting> ./configure &amp;&amp; make install</programlisting>
Ensure <command>pg_config</command> for the target PostgreSQL version is in Ensure <command>pg_config</command> for the target PostgreSQL version is in
<varname>$PATH</varname>. <varname>$PATH</varname>.
@@ -236,16 +243,30 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
<sect2 id="installation-build-repmgr-docs"> <sect2 id="installation-build-repmgr-docs" xreflabel="Building repmgr documentation">
<title>Building &repmgr; documentation</title> <title>Building &repmgr; documentation</title>
<para> <para>
The &repmgr; documentation is (like the main PostgreSQL project) The &repmgr; documentation is (like the main PostgreSQL project)
written in DocBook format. To build it locally as HTML, you'll need to written in DocBook XML format. To build it locally as HTML, you'll need to
install the required packages as described in the install the required packages as described in the
<ulink url="https://www.postgresql.org/docs/9.6/docguide-toolsets.html"> <ulink url="https://www.postgresql.org/docs/current/docguide-toolsets.html">PostgreSQL documentation</ulink>.
PostgreSQL documentation</ulink> then execute: </para>
<para>
The minimum PostgreSQL version for building the &repmgr; documentation is
PostgreSQL 9.5.
</para>
<note>
<simpara>
In &repmgr; 4.3 and earlier, the documentation can only be built against
PostgreSQL 9.6 or earlier.
</simpara>
</note>
<para>
To build the documentation as HTML, execute:
<programlisting> <programlisting>
./configure && make install-doc</programlisting> ./configure &amp;&amp; make doc</programlisting>
</para> </para>
<para> <para>
The generated HTML files will be placed in the <filename>doc/html</filename> The generated HTML files will be placed in the <filename>doc/html</filename>
@@ -253,19 +274,20 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
</para> </para>
<para> <para>
To build the documentation as a single HTML file, execute: To build the documentation as a single HTML file, after configuring and building
the main &repmgr; source as described above, execute:
<programlisting> <programlisting>
cd doc/ && make repmgr.html</programlisting> ./configure &amp;&amp; make doc-repmgr.html</programlisting>
</para> </para>
<note> <para>
<simpara> To build the documentation as a PDF file, after configuring and building
Due to changes in PostgreSQL's documentation build system from PostgreSQL 10, the main &repmgr; source as described above, execute:
the documentation can currently only be built against PostgreSQL 9.6 or earlier. <programlisting>
This limitation will be fixed when time and resources permit. ./configure &amp;&amp; make doc-repmgr-A4.pdf</programlisting>
</simpara> </para>
</note>
</sect2> </sect2>
</sect1> </sect1>

View File

@@ -1,10 +1,11 @@
<chapter id="installation" xreflabel="Installation"> <chapter id="installation" xreflabel="Installation">
<title>Installation</title>
<indexterm> <indexterm>
<primary>installation</primary> <primary>installation</primary>
</indexterm> </indexterm>
<title>Installation</title>
<para> <para>
&repmgr; can be installed from binary packages provided by your operating &repmgr; can be installed from binary packages provided by your operating
system's packaging system, or from source. system's packaging system, or from source.
@@ -18,7 +19,7 @@
only option if there are no packages for your operating system yet. only option if there are no packages for your operating system yet.
</para> </para>
<para> <para>
Before installing &repmgr; make sure you satisfy the <xref linkend="install-requirements">. Before installing &repmgr; make sure you satisfy the <xref linkend="install-requirements"/>.
</para> </para>
&install-requirements; &install-requirements;

View File

@@ -1,18 +1,18 @@
<!-- doc/legal.sgml --> <!-- doc/legal.xml -->
<date>2017</date> <date>2022</date>
<copyright> <copyright>
<year>2010-2019</year> <year>2010-2022</year>
<holder>2ndQuadrant, Ltd.</holder> <holder>EDB</holder>
</copyright> </copyright>
<legalnotice id="legalnotice"> <legalnotice id="legalnotice">
<title>Legal Notice</title> <title>Legal Notice</title>
<para> <para>
<productname>repmgr</productname> is Copyright &copy; 2010-2019 <productname>repmgr</productname> is Copyright &copy; 2010-2022
by 2ndQuadrant, Ltd. All rights reserved. by EDB All rights reserved.
</para> </para>
<para> <para>

View File

@@ -7,18 +7,18 @@
</para> </para>
<sect1 id="repmgr-concepts" xreflabel="Concepts"> <sect1 id="repmgr-concepts" xreflabel="Concepts">
<title>Concepts</title>
<indexterm> <indexterm>
<primary>concepts</primary> <primary>concepts</primary>
</indexterm> </indexterm>
<title>Concepts</title>
<para> <para>
This guide assumes that you are familiar with PostgreSQL administration and This guide assumes that you are familiar with PostgreSQL administration and
streaming replication concepts. For further details on streaming streaming replication concepts. For further details on streaming
replication, see the PostgreSQL documentation section on <ulink replication, see the PostgreSQL documentation section on <ulink
url="https://www.postgresql.org/docs/current/interactive/warm-standby.html#STREAMING-REPLICATION"> url="https://www.postgresql.org/docs/current/warm-standby.html#STREAMING-REPLICATION">
streaming replication</>. streaming replication</ulink>.
</para> </para>
<para> <para>
The following terms are used throughout the &repmgr; documentation. The following terms are used throughout the &repmgr; documentation.
@@ -58,7 +58,7 @@
<listitem> <listitem>
<simpara> <simpara>
This is the action which occurs if a primary server fails and a suitable standby This is the action which occurs if a primary server fails and a suitable standby
is promoted as the new primary. The <application>repmgrd</application> daemon supports automatic failover is promoted as the new primary. The &repmgrd; daemon supports automatic failover
to minimise downtime. to minimise downtime.
</simpara> </simpara>
</listitem> </listitem>
@@ -107,7 +107,7 @@
promotes a (local) standby. promotes a (local) standby.
</para> </para>
<para> <para>
A witness server only needs to be created if <application>repmgrd</application> A witness server only needs to be created if &repmgrd;
is in use. is in use.
</para> </para>
</listitem> </listitem>
@@ -198,7 +198,7 @@
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>repmgr.monitoring_history</literal>: historical standby monitoring information <simpara><literal>repmgr.monitoring_history</literal>: historical standby monitoring information
written by <application>repmgrd</application></simpara> written by &repmgrd;</simpara>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
@@ -214,7 +214,7 @@
name of the server's upstream node</simpara> name of the server's upstream node</simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara>repmgr.replication_status: when <application>repmgrd</application>'s monitoring is enabled, shows <simpara>repmgr.replication_status: when &repmgrd;'s monitoring is enabled, shows
current monitoring status for each standby.</simpara> current monitoring status for each standby.</simpara>
</listitem> </listitem>
</itemizedlist> </itemizedlist>

View File

@@ -1,13 +1,13 @@
<chapter id="promoting-standby" xreflabel="Promoting a standby"> <chapter id="promoting-standby" xreflabel="Promoting a standby">
<title>Promoting a standby server with repmgr</title>
<indexterm> <indexterm>
<primary>promoting a standby</primary> <primary>promoting a standby</primary>
<seealso>repmgr standby promote</seealso> <seealso>repmgr standby promote</seealso>
</indexterm> </indexterm>
<title>Promoting a standby server with repmgr</title>
<para> <para>
If a primary server fails or needs to be removed from the replication cluster, If a primary server fails or needs to be removed from the replication cluster,
a new primary server must be designated, to ensure the cluster continues a new primary server must be designated, to ensure the cluster continues
to function correctly. This can be done with <xref linkend="repmgr-standby-promote">, to function correctly. This can be done with <xref linkend="repmgr-standby-promote"/>,
which promotes the standby on the current server to primary. which promotes the standby on the current server to primary.
</para> </para>
@@ -31,7 +31,7 @@
At this point the replication cluster will be in a partially disabled state, with At this point the replication cluster will be in a partially disabled state, with
both standbys accepting read-only connections while attempting to connect to the both standbys accepting read-only connections while attempting to connect to the
stopped primary. Note that the &repmgr; metadata table will not yet have been updated; stopped primary. Note that the &repmgr; metadata table will not yet have been updated;
executing <xref linkend="repmgr-cluster-show"> will note the discrepancy: executing <xref linkend="repmgr-cluster-show"/> will note the discrepancy:
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf cluster show $ repmgr -f /etc/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Connection string ID | Name | Role | Status | Upstream | Location | Connection string
@@ -60,7 +60,7 @@
DETAIL: node 2 was successfully promoted to primary</programlisting> DETAIL: node 2 was successfully promoted to primary</programlisting>
</para> </para>
<para> <para>
Executing <xref linkend="repmgr-cluster-show"> will show the current state; as there is now an Executing <xref linkend="repmgr-cluster-show"/> will show the current state; as there is now an
active primary, the previous warning will not be displayed: active primary, the previous warning will not be displayed:
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf cluster show $ repmgr -f /etc/repmgr.conf cluster show
@@ -72,8 +72,8 @@
</para> </para>
<para> <para>
However the sole remaining standby (<literal>node3</literal>) is still trying to replicate from the failed However the sole remaining standby (<literal>node3</literal>) is still trying to replicate from the failed
primary; <xref linkend="repmgr-standby-follow"> must now be executed to rectify this situation primary; <xref linkend="repmgr-standby-follow"/> must now be executed to rectify this situation
(see <xref linkend="follow-new-primary"> for example). (see <xref linkend="follow-new-primary"/> for example).
</para> </para>
</chapter> </chapter>

View File

@@ -17,7 +17,7 @@
<note> <note>
<simpara> <simpara>
To upgrade an existing &repmgr; 3.x installation, see section To upgrade an existing &repmgr; 3.x installation, see section
<xref linkend="upgrading-from-repmgr-3">. <xref linkend="upgrading-from-repmgr-3"/>.
</simpara> </simpara>
</note> </note>
@@ -139,7 +139,7 @@
<para> <para>
Additionally, if you are intending to use <application>pg_rewind</application>, Additionally, if you are intending to use <application>pg_rewind</application>,
and the cluster was not initialised using data checksums, you may want to consider enabling and the cluster was not initialised using data checksums, you may want to consider enabling
<varname>wal_log_hints</varname>; for more details see <xref linkend="repmgr-node-rejoin-pg-rewind">. <varname>wal_log_hints</varname>; for more details see <xref linkend="repmgr-node-rejoin-pg-rewind"/>.
</para> </para>
<para> <para>
See also the <link linkend="configuration-postgresql">PostgreSQL configuration</link> section in the See also the <link linkend="configuration-postgresql">PostgreSQL configuration</link> section in the
@@ -167,7 +167,7 @@
For the sake of simplicity, the <literal>repmgr</literal> user is created For the sake of simplicity, the <literal>repmgr</literal> user is created
as a superuser. If desired, it's possible to create the <literal>repmgr</literal> as a superuser. If desired, it's possible to create the <literal>repmgr</literal>
user as a normal user. However for certain operations superuser permissions user as a normal user. However for certain operations superuser permissions
are requiredl; in this case the command line option <command>--superuser</command> are required; in this case the command line option <command>--superuser</command>
can be provided to specify a superuser. can be provided to specify a superuser.
</para> </para>
<para> <para>
@@ -254,7 +254,7 @@
</para> </para>
<programlisting> <programlisting>
node_id=1 node_id=1
node_name=node1 node_name='node1'
conninfo='host=node1 user=repmgr dbname=repmgr connect_timeout=2' conninfo='host=node1 user=repmgr dbname=repmgr connect_timeout=2'
data_directory='/var/lib/postgresql/data' data_directory='/var/lib/postgresql/data'
</programlisting> </programlisting>
@@ -262,10 +262,9 @@
<para> <para>
<filename>repmgr.conf</filename> should not be stored inside the PostgreSQL data directory, <filename>repmgr.conf</filename> should not be stored inside the PostgreSQL data directory,
as it could be overwritten when setting up or reinitialising the PostgreSQL as it could be overwritten when setting up or reinitialising the PostgreSQL
server. See sections <xref linkend="configuration"> and <xref linkend="configuration-file"> server. See sections <xref linkend="configuration"/> and <xref linkend="configuration-file"/>
for further details about <filename>repmgr.conf</filename>. for further details about <filename>repmgr.conf</filename>.
</para> </para>
<note> <note>
<para> <para>
&repmgr; only uses <option>pg_bindir</option> when it executes &repmgr; only uses <option>pg_bindir</option> when it executes
@@ -285,7 +284,7 @@
<tip> <tip>
<simpara> <simpara>
For Debian-based distributions we recommend explictly setting For Debian-based distributions we recommend explicitly setting
<option>pg_bindir</option> to the directory where <command>pg_ctl</command> and other binaries <option>pg_bindir</option> to the directory where <command>pg_ctl</command> and other binaries
not in the standard path are located. For PostgreSQL 9.6 this would be <filename>/usr/lib/postgresql/9.6/bin/</filename>. not in the standard path are located. For PostgreSQL 9.6 this would be <filename>/usr/lib/postgresql/9.6/bin/</filename>.
</simpara> </simpara>
@@ -303,7 +302,7 @@
<para> <para>
See the file See the file
<ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</> <ulink url="https://raw.githubusercontent.com/EnterpriseDB/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink>
for details of all available configuration parameters. for details of all available configuration parameters.
</para> </para>
@@ -352,7 +351,7 @@
slot_name | slot_name |
config_file | /etc/repmgr.conf</programlisting> config_file | /etc/repmgr.conf</programlisting>
<para> <para>
Each server in the replication cluster will have its own record. If <application>repmgrd</application> Each server in the replication cluster will have its own record. If &repmgrd;
is in use, the fields <literal>upstream_node_id</literal>, <literal>active</literal> and is in use, the fields <literal>upstream_node_id</literal>, <literal>active</literal> and
<literal>type</literal> will be updated when the node's status or role changes. <literal>type</literal> will be updated when the node's status or role changes.
</para> </para>
@@ -368,7 +367,7 @@
</para> </para>
<programlisting> <programlisting>
node_id=2 node_id=2
node_name=node2 node_name='node2'
conninfo='host=node2 user=repmgr dbname=repmgr connect_timeout=2' conninfo='host=node2 user=repmgr dbname=repmgr connect_timeout=2'
data_directory='/var/lib/postgresql/data'</programlisting> data_directory='/var/lib/postgresql/data'</programlisting>
<para> <para>
@@ -406,9 +405,10 @@
</programlisting> </programlisting>
<para> <para>
This has cloned the PostgreSQL data directory files from the primary <literal>node1</literal> This has cloned the PostgreSQL data directory files from the primary <literal>node1</literal>
using PostgreSQL's <command>pg_basebackup</command> utility. A <filename>recovery.conf</filename> using PostgreSQL's <command>pg_basebackup</command> utility. Replication configuration
file containing the correct parameters to start streaming from this primary server will be created containing the correct parameters to start streaming from this primary server will be
automatically. automatically appended to <filename>postgresql.auto.conf</filename>. (In PostgreSQL 11
and earlier the file <filename>recovery.conf</filename> will be created).
</para> </para>
<note> <note>
<simpara> <simpara>
@@ -478,11 +478,14 @@
latest_end_lsn | 0/7000538 latest_end_lsn | 0/7000538
latest_end_time | 2017-08-28 15:20:56.418735+09 latest_end_time | 2017-08-28 15:20:56.418735+09
slot_name | slot_name |
sender_host | node1
sender_port | 5432
conninfo | user=repmgr dbname=replication host=node1 application_name=node2 conninfo | user=repmgr dbname=replication host=node1 application_name=node2
</programlisting> </programlisting>
Note that the <varname>conninfo</varname> value is that generated in <filename>recovery.conf</filename> Note that the <varname>conninfo</varname> value is that generated in <filename>postgresql.auto.conf</filename>
and will differ slightly from the primary's <varname>conninfo</varname> as set in <filename>repmgr.conf</filename> - (PostgreSQL 11 and earlier: <filename>recovery.conf</filename>) and will differ slightly from the primary's
among others it will contain the connecting node's name as <varname>application_name</varname>. <varname>conninfo</varname> as set in <filename>repmgr.conf</filename> - among others it will contain the
connecting node's name as <varname>application_name</varname>.
</para> </para>
</sect1> </sect1>
@@ -497,11 +500,12 @@
<para> <para>
Check the node is registered by executing <command>repmgr cluster show</command> on the standby: Check the node is registered by executing <command>repmgr cluster show</command> on the standby:
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf cluster show $ repmgr -f /etc/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Connection string
----+-------+---------+-----------+----------+----------+-------------------------------------- ID | Name | Role | Status | Upstream | Location | Priority | Timeline | 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</programlisting> 1 | node1 | primary | * running | | default | 100 | 1 | host=node1 dbname=repmgr user=repmgr
2 | node2 | standby | running | node1 | default | 100 | 1 | host=node2 dbname=repmgr user=repmgr</programlisting>
</para> </para>
<para> <para>
Both nodes are now registered with &repmgr; and the records have been copied to the standby server. Both nodes are now registered with &repmgr; and the records have been copied to the standby server.

View File

@@ -38,7 +38,7 @@
<title>Notes</title> <title>Notes</title>
<para> <para>
Monitoring history will only be written if <application>repmgrd</application> is active, and Monitoring history will only be written if &repmgrd; is active, and
<varname>monitoring_history</varname> is set to <literal>true</literal> in <varname>monitoring_history</varname> is set to <literal>true</literal> in
<filename>repmgr.conf</filename>. <filename>repmgr.conf</filename>.
</para> </para>
@@ -69,8 +69,8 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
For more details see the sections <xref linkend="repmgrd-monitoring"> and For more details see the sections <xref linkend="repmgrd-monitoring"/> and
<xref linkend="repmgrd-monitoring-configuration">. <xref linkend="repmgrd-monitoring-configuration"/>.
</para> </para>
</refsect1> </refsect1>

View File

@@ -16,9 +16,9 @@
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para> <para>
<command>repmgr cluster crosscheck</command> is similar to <xref linkend="repmgr-cluster-matrix">, <command>repmgr cluster crosscheck</command> is similar to <xref linkend="repmgr-cluster-matrix"/>,
but cross-checks connections between each combination of nodes. In "Example 3" in but cross-checks connections between each combination of nodes. In "Example 3" in
<xref linkend="repmgr-cluster-matrix"> we have no information about the state of <literal>node3</literal>. <xref linkend="repmgr-cluster-matrix"/> we have no information about the state of <literal>node3</literal>.
However by running <command>repmgr cluster crosscheck</command> it's possible to get a better However by running <command>repmgr cluster crosscheck</command> it's possible to get a better
overview of the cluster situation: overview of the cluster situation:
<programlisting> <programlisting>

View File

@@ -40,12 +40,12 @@
<simpara><literal>--node-name</literal>: restrict entries to node with this name</simpara> <simpara><literal>--node-name</literal>: restrict entries to node with this name</simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>--event</literal>: filter specific event (see <xref linkend="event-notifications"> for a full list)</simpara> <simpara><literal>--event</literal>: filter specific event (see <xref linkend="event-notifications"/> for a full list)</simpara>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para> <para>
The "Details" column can be omitted by providing <literal>--terse</literal>. The &quot;Details&quot; column can be omitted by providing <literal>--compact</literal>.
</para> </para>
</refsect1> </refsect1>
@@ -71,9 +71,9 @@
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf cluster event --event=standby_register $ repmgr -f /etc/repmgr.conf cluster event --event=standby_register
Node ID | Name | Event | OK | Timestamp | Details Node ID | Name | Event | OK | Timestamp | Details
---------+-------+------------------+----+---------------------+-------------------------------- ---------+-------+------------------+----+---------------------+-------------------------------------------------------
3 | node3 | standby_register | t | 2017-08-17 10:28:55 | standby registration succeeded 3 | node3 | standby_register | t | 2019-04-16 10:59:59 | standby registration succeeded; upstream node ID is 1
2 | node2 | standby_register | t | 2017-08-17 10:28:53 | standby registration succeeded</programlisting> 2 | node2 | standby_register | t | 2019-04-16 10:59:57 | standby registration succeeded; upstream node ID is 1</programlisting>
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@@ -93,7 +93,7 @@
connection from <literal>node3</literal>. connection from <literal>node3</literal>.
</para> </para>
<para> <para>
In this case, the <xref linkend="repmgr-cluster-crosscheck"> command will produce a more In this case, the <xref linkend="repmgr-cluster-crosscheck"/> command will produce a more
useful result. useful result.
</para> </para>
</refsect1> </refsect1>

View File

@@ -18,15 +18,17 @@
<para> <para>
Displays information about each registered node in the replication cluster. This Displays information about each registered node in the replication cluster. This
command polls each registered server and shows its role (<literal>primary</literal> / command polls each registered server and shows its role (<literal>primary</literal> /
<literal>standby</literal> / <literal>bdr</literal>) and status. It polls each server <literal>standby</literal>) and status. It polls each server
directly and can be run on any node in the cluster; this is also useful when analyzing directly and can be run on any node in the cluster; this is also useful when analyzing
connectivity from a particular node. connectivity from a particular node.
</para> </para>
<para>
For PostgreSQL 9.6 and later, the output will also contain the node's current timeline ID.
</para>
<para> <para>
Node availability is tested by connecting from the node where Node availability is tested by connecting from the node where
<command>repmgr cluster show</command> is executed, and does not necessarily imply the node <command>repmgr cluster show</command> is executed, and does not necessarily imply the node
is down. See <xref linkend="repmgr-cluster-matrix"> and <xref linkend="repmgr-cluster-crosscheck"> to get is down. See <xref linkend="repmgr-cluster-matrix"/> and <xref linkend="repmgr-cluster-crosscheck"/> to get
better overviews of connections between nodes. better overviews of connections between nodes.
</para> </para>
@@ -51,12 +53,13 @@
<para> <para>
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf cluster show $ repmgr -f /etc/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string
ID | Name | Role | Status | Upstream | Location | Priority | Connection string ----+-------+---------+-----------+----------+----------+----------+----------+-----------------------------------------
----+-------+---------+-----------+----------+----------+----------+----------------------------------------- 1 | node1 | primary | * running | | default | 100 | 1 | host=db_node1 dbname=repmgr user=repmgr
1 | node1 | primary | * running | | default | 100 | host=db_node1 dbname=repmgr user=repmgr 2 | node2 | standby | running | node1 | default | 100 | 1 | host=db_node2 dbname=repmgr user=repmgr
2 | node2 | standby | running | node1 | default | 100 | host=db_node2 dbname=repmgr user=repmgr 3 | node3 | standby | running | node1 | default | 100 | 1 | host=db_node3 dbname=repmgr user=repmgr
3 | node3 | standby | running | node1 | default | 100 | host=db_node3 dbname=repmgr user=repmgr</programlisting> 4 | node4 | standby | running | node1 | default | 100 | 1 | host=db_node4 dbname=repmgr user=repmgr
5 | node5 | witness | * running | node1 | default | 0 | n/a | host=db_node5 dbname=repmgr user=repmgr</programlisting>
</para> </para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@@ -80,18 +83,22 @@
(but <literal>node3</literal> is not attached to it, and its metadata has not yet been updated); (but <literal>node3</literal> is not attached to it, and its metadata has not yet been updated);
<literal>node4</literal> is running but rejecting connections (from <literal>node3</literal> at least). <literal>node4</literal> is running but rejecting connections (from <literal>node3</literal> at least).
<programlisting> <programlisting>
ID | Name | Role | Status | Upstream | Location | Priority | Connection string ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string
----+-------+---------+----------------------+----------+----------+----------+----------------------------------------- ----+-------+---------+----------------------+----------+----------+----------+----------+----------------------------------------------------
1 | node1 | primary | ? unreachable | | default | 100 | host=db_node1 dbname=repmgr user=repmgr 1 | node1 | primary | ? unreachable | | default | 100 | | host=db_node1 dbname=repmgr user=repmgr
2 | node2 | standby | ! running as primary | node1 | default | 100 | host=db_node2 dbname=repmgr user=repmgr 2 | node2 | standby | ! running as primary | ? node1 | default | 100 | 2 | host=db_node2 dbname=repmgr user=repmgr
3 | node3 | standby | running | node1 | default | 100 | host=db_node3 dbname=repmgr user=repmgr 3 | node3 | standby | running | ? node1 | default | 100 | 1 | host=db_node3 dbname=repmgr user=repmgr
4 | node4 | standby | ? running | node1 | default | 100 | host=db_node4 dbname=repmgr user=repmgr 4 | node4 | standby | ? running | ? node1 | default | 100 | | host=db_node4 dbname=repmgr user=repmgr
WARNING: following issues were detected WARNING: following issues were detected
- unable to connect to node "node1" (ID: 1) - unable to connect to node "node1" (ID: 1)
- node "node1" (ID: 1) is registered as an active primary but is unreachable - node "node1" (ID: 1) is registered as an active primary but is unreachable
- node "node2" (ID: 2) is registered as standby but running as primary - node "node2" (ID: 2) is registered as standby but running as primary
- unable to connect to node "node4" (ID: 4) - unable to connect to node "node2" (ID: 2)'s upstream node "node1" (ID: 1)
- unable to determine if node "node2" (ID: 2) is attached to its upstream node "node1" (ID: 1)
- unable to connect to node "node3" (ID: 3)'s upstream node "node1" (ID: 1)
- unable to determine if node "node3" (ID: 3) is attached to its upstream node "node1" (ID: 1)
- unable to connect to node "node4" (ID: 4)
HINT: execute with --verbose option to see connection error messages</programlisting> HINT: execute with --verbose option to see connection error messages</programlisting>
</para> </para>
<para> <para>
@@ -101,7 +108,7 @@
</para> </para>
<tip> <tip>
<para> <para>
Use <xref linkend="repmgr-cluster-matrix"> and <xref linkend="repmgr-cluster-crosscheck"> Use <xref linkend="repmgr-cluster-matrix"/> and <xref linkend="repmgr-cluster-crosscheck"/>
to diagnose connection issues across the whole replication cluster. to diagnose connection issues across the whole replication cluster.
</para> </para>
</tip> </tip>
@@ -231,7 +238,7 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-node-status">, <xref linkend="repmgr-node-check">, <xref linkend="repmgr-daemon-status"> <xref linkend="repmgr-node-status"/>, <xref linkend="repmgr-node-check"/>, <xref linkend="repmgr-service-status"/>
</para> </para>
</refsect1> </refsect1>

View File

@@ -14,18 +14,18 @@
<refnamediv> <refnamediv>
<refname>repmgr daemon start</refname> <refname>repmgr daemon start</refname>
<refpurpose>Start the <application>repmgrd</application> daemon</refpurpose> <refpurpose>Start the &repmgrd; daemon on the local node</refpurpose>
</refnamediv> </refnamediv>
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para> <para>
This command starts the <application>repmgrd</application> daemon on the This command starts the &repmgrd; service on the
local node. local node.
</para> </para>
<para> <para>
By default, &repmgr; will wait for up to 15 seconds to confirm that <application>repmgrd</application> By default, &repmgr; will wait for up to 15 seconds to confirm that &repmgrd;
started. This behaviour can be overridden by specifying a diffent value using the <option>--wait</option> started. This behaviour can be overridden by specifying a different value using the <option>--wait</option>
option, or disabled altogether with the <option>--no-wait</option> option. option, or disabled altogether with the <option>--no-wait</option> option.
</para> </para>
@@ -33,7 +33,7 @@
<para> <para>
The <filename>repmgr.conf</filename> parameter <varname>repmgrd_service_start_command</varname> The <filename>repmgr.conf</filename> parameter <varname>repmgrd_service_start_command</varname>
must be set for <command>repmgr daemon start</command> to work; see section must be set for <command>repmgr daemon start</command> to work; see section
<xref linkend="repmgr-daemon-start-configuration"> for details. <xref linkend="repmgr-daemon-start-configuration"/> for details.
</para> </para>
</important> </important>
</refsect1> </refsect1>
@@ -50,7 +50,7 @@
<term><option>--dry-run</option></term> <term><option>--dry-run</option></term>
<listitem> <listitem>
<para> <para>
Check prerequisites but don't actually attempt to start <application>repmgrd</application>. Check prerequisites but don't actually attempt to start &repmgrd;.
</para> </para>
<para> <para>
This action will output the command which would be executed. This action will output the command which would be executed.
@@ -63,7 +63,7 @@
<term><option>--wait</option></term> <term><option>--wait</option></term>
<listitem> <listitem>
<para> <para>
Wait for the specified number of seconds to confirm that <application>repmgrd</application> Wait for the specified number of seconds to confirm that &repmgrd;
started successfully. started successfully.
</para> </para>
<para> <para>
@@ -77,7 +77,7 @@
<term><option>--no-wait</option></term> <term><option>--no-wait</option></term>
<listitem> <listitem>
<para> <para>
Don't wait to confirm that <application>repmgrd</application> Don't wait to confirm that &repmgrd;
started successfully. started successfully.
</para> </para>
<para> <para>
@@ -99,17 +99,18 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<indexterm>
<primary>repmgrd_service_start_command</primary>
<secondary>with &quot;repmgr daemon start&quot;</secondary>
</indexterm>
<term><option>repmgrd_service_start_command</option></term> <term><option>repmgrd_service_start_command</option></term>
<listitem> <listitem>
<indexterm>
<primary>repmgrd_service_start_command</primary>
<secondary>with &quot;repmgr daemon start&quot;</secondary>
</indexterm>
<para> <para>
<command>repmgr daemon start</command> will execute the command defined by the <command>repmgr daemon start</command> will execute the command defined by the
<varname>repmgrd_service_start_command</varname> parameter in <filename>repmgr.conf</filename>. <varname>repmgrd_service_start_command</varname> parameter in <filename>repmgr.conf</filename>.
This must be set to a shell command which will start <application>repmgrd</application>; This must be set to a shell command which will start &repmgrd;;
if &repmgr; was installed from a package, this will be the service command defined by the if &repmgr; was installed from a package, this will be the service command defined by the
package. For more details see <link linkend="appendix-packages">Appendix: &repmgr; package details</link>. package. For more details see <link linkend="appendix-packages">Appendix: &repmgr; package details</link>.
</para> </para>
@@ -117,7 +118,7 @@
<para> <para>
If &repmgr; was installed from a system package, and you do not configure If &repmgr; was installed from a system package, and you do not configure
<varname>repmgrd_service_start_command</varname> to an appropriate service command, this may <varname>repmgrd_service_start_command</varname> to an appropriate service command, this may
result in the system becoming confused about the state of the <application>repmgrd</application> result in the system becoming confused about the state of the &repmgrd;
service; this is particularly the case with <literal>systemd</literal>. service; this is particularly the case with <literal>systemd</literal>.
</para> </para>
</important> </important>
@@ -139,12 +140,12 @@
<term><option>SUCCESS (0)</option></term> <term><option>SUCCESS (0)</option></term>
<listitem> <listitem>
<para> <para>
The <application>repmgrd</application> start command (defined in The &repmgrd; start command (defined in
<varname>repmgrd_service_start_command</varname>) was successfully executed. <varname>repmgrd_service_start_command</varname>) was successfully executed.
</para> </para>
<para> <para>
If the <option>--wait</option> option was provided, &repmgr; will confirm that If the <option>--wait</option> option was provided, &repmgr; will confirm that
<application>repmgrd</application> has actually started up. &repmgrd; has actually started up.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -167,10 +168,10 @@
&repmgr; was unable to connect to the local PostgreSQL node. &repmgr; was unable to connect to the local PostgreSQL node.
</para> </para>
<para> <para>
PostgreSQL must be running before <application>repmgrd</application> PostgreSQL must be running before &repmgrd;
can be started. Additionally, unless the <option>--no-wait</option> option was can be started. Additionally, unless the <option>--no-wait</option> option was
provided, &repmgr; needs to be able to connect to the local PostgreSQL node provided, &repmgr; needs to be able to connect to the local PostgreSQL node
to determine the state of <application>repmgrd</application>. to determine the state of &repmgrd;.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -180,11 +181,11 @@
<term><option>ERR_REPMGRD_SERVICE (27)</option></term> <term><option>ERR_REPMGRD_SERVICE (27)</option></term>
<listitem> <listitem>
<para> <para>
The <application>repmgrd</application> start command (defined in The &repmgrd; start command (defined in
<varname>repmgrd_service_start_command</varname>) was not successfully executed. <varname>repmgrd_service_start_command</varname>) was not successfully executed.
</para> </para>
<para> <para>
This can also mean that &repmgr; was unable to confirm whether <application>repmgrd</application> This can also mean that &repmgr; was unable to confirm whether &repmgrd;
successfully started (unless the <option>--no-wait</option> option was provided). successfully started (unless the <option>--no-wait</option> option was provided).
</para> </para>
</listitem> </listitem>
@@ -196,7 +197,11 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-daemon-stop">, <xref linkend="repmgr-daemon-status">, <xref linkend="repmgrd-daemon"> <xref linkend="repmgr-daemon-stop"/>,
<xref linkend="repmgrd-daemon"/>,
<xref linkend="repmgr-service-status"/>,
<xref linkend="repmgr-service-pause"/>,
<xref linkend="repmgr-service-unpause"/>
</para> </para>
</refsect1> </refsect1>

View File

@@ -1,186 +0,0 @@
<refentry id="repmgr-daemon-status">
<indexterm>
<primary>repmgr daemon status</primary>
</indexterm>
<indexterm>
<primary>repmgrd</primary>
<secondary>displaying daemon status</secondary>
</indexterm>
<refmeta>
<refentrytitle>repmgr daemon status</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr daemon status</refname>
<refpurpose>display information about the status of <application>repmgrd</application> on each node in the cluster</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
This command provides an overview over all active nodes in the cluster and the state
of each node's <application>repmgrd</application> instance. It can be used to check
the result of <xref linkend="repmgr-daemon-pause"> and <xref linkend="repmgr-daemon-unpause">
operations.
</para>
</refsect1>
<refsect1>
<title>Execution</title>
<para>
<command>repmgr daemon status</command> can be executed on any active node in the
replication cluster. A valid <filename>repmgr.conf</filename> file is required.
</para>
<para>
If PostgreSQL is not running on a node, &repmgr; will not be able to determine the
status of that node's <application>repmgrd</application> instance.
</para>
<note>
<para>
After restarting PostgreSQL on any node, the <application>repmgrd</application> instance
will take a second or two before it is able to update its status. Until then,
<application>repmgrd</application> will be shown as not running.
</para>
</note>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
<application>repmgrd</application> running normally on all nodes:
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
ID | Name | Role | Priority | Status | repmgrd | PID | Paused? | Upstream last seen
----+-------+---------+----------+---------+---------+-------+---------+--------------------
1 | node1 | primary | 100 | running | running | 71987 | no | n/a
2 | node2 | standby | 100 | running | running | 71996 | no | 1 second(s) ago
3 | node3 | standby | 100 | running | running | 72042 | no | 1 second(s) ago
</programlisting>
</para>
<para>
<application>repmgrd</application> paused on all nodes (using <xref linkend="repmgr-daemon-pause">):
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
ID | Name | Role | Priority | Status | repmgrd | PID | Paused? | Upstream last seen
----+-------+---------+----------+---------+---------+-------+---------+--------------------
1 | node1 | primary | 100 | running | running | 71987 | yes | n/a
2 | node2 | standby | 100 | running | running | 71996 | yes | 0 second(s) ago
3 | node3 | standby | 100 | running | running | 72042 | yes | 0 second(s) ago
</programlisting>
</para>
<para>
<application>repmgrd</application> not running on one node:
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
ID | Name | Role | Priority | Status | repmgrd | PID | Paused? | Upstream last seen
----+-------+---------+----------+---------+-------------+-------+---------+--------------------
1 | node1 | primary | 100 | running | running | 71987 | yes | n/a
2 | node2 | standby | 100 | running | not running | n/a | n/a | n/a
3 | node3 | standby | 100 | running | running | 72042 | yes | 0 second(s) ago</programlisting>
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--csv</option></term>
<listitem>
<para>
<command>repmgr daemon status</command> accepts an optional parameter <literal>--csv</literal>, which
outputs the replication cluster's status in a simple CSV format, suitable for
parsing by scripts, e.g.:
<programlisting>
$ repmgr -f /etc/repmgr.conf daemon status --csv
1,node1,primary,1,1,5722,1,100,-1
2,node2,standby,1,0,-1,1,100,1
3,node3,standby,1,1,5779,1,100,1</programlisting>
</para>
<para>
The columns have following meanings:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
node ID
</simpara>
</listitem>
<listitem>
<simpara>
node name
</simpara>
</listitem>
<listitem>
<simpara>
node type (primary or standby)
</simpara>
</listitem>
<listitem>
<simpara>
PostgreSQL server running (1 = running, 0 = not running)
</simpara>
</listitem>
<listitem>
<simpara>
<application>repmgrd</application> running (1 = running, 0 = not running, -1 = unknown)
</simpara>
</listitem>
<listitem>
<simpara>
<application>repmgrd</application> PID (-1 if not running or status unknown)
</simpara>
</listitem>
<listitem>
<simpara>
<application>repmgrd</application> paused (1 = paused, 0 = not paused, -1 = unknown)
</simpara>
</listitem>
<listitem>
<simpara>
<application>repmgrd</application> node priority
</simpara>
</listitem>
<listitem>
<simpara>
interval in seconds since the node's upstream was last seen (this will be -1 if the value could not be retrieved, or the node is primary)
</simpara>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--verbose</option></term>
<listitem>
<para>
Display the full text of any database connection error messages
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-daemon-pause">, <xref linkend="repmgr-daemon-unpause">, <xref linkend="repmgr-cluster-show">
</para>
</refsect1>
</refentry>

View File

@@ -14,25 +14,25 @@
<refnamediv> <refnamediv>
<refname>repmgr daemon stop</refname> <refname>repmgr daemon stop</refname>
<refpurpose>Stop the <application>repmgrd</application> daemon</refpurpose> <refpurpose>Stop the &repmgrd; daemon on the local node</refpurpose>
</refnamediv> </refnamediv>
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para> <para>
This command stops the <application>repmgrd</application> daemon on the This command stops the &repmgrd; daemon on the
local node. local node.
</para> </para>
<para> <para>
By default, &repmgr; will wait for up to 15 seconds to confirm that <application>repmgrd</application> By default, &repmgr; will wait for up to 15 seconds to confirm that &repmgrd;
stopped. This behaviour can be overridden by specifying a diffent value using the <option>--wait</option> stopped. This behaviour can be overridden by specifying a different value using the <option>--wait</option>
option, or disabled altogether with the <option>--no-wait</option> option. option, or disabled altogether with the <option>--no-wait</option> option.
</para> </para>
<note> <note>
<para> <para>
If PostgreSQL is not running on the local node, under some circumstances &repmgr; may not If PostgreSQL is not running on the local node, under some circumstances &repmgr; may not
be able to confirm if <application>repmgrd</application> has actually stopped. be able to confirm if &repmgrd; has actually stopped.
</para> </para>
</note> </note>
@@ -40,7 +40,7 @@
<para> <para>
The <filename>repmgr.conf</filename> parameter <varname>repmgrd_service_stop_command</varname> The <filename>repmgr.conf</filename> parameter <varname>repmgrd_service_stop_command</varname>
must be set for <command>repmgr daemon stop</command> to work; see section must be set for <command>repmgr daemon stop</command> to work; see section
<xref linkend="repmgr-daemon-stop-configuration"> for details. <xref linkend="repmgr-daemon-stop-configuration"/> for details.
</para> </para>
</important> </important>
</refsect1> </refsect1>
@@ -50,7 +50,7 @@
<para> <para>
<command>repmgr daemon stop</command> will execute the command defined by the <command>repmgr daemon stop</command> will execute the command defined by the
<varname>repmgrd_service_stop_command</varname> parameter in <filename>repmgr.conf</filename>. <varname>repmgrd_service_stop_command</varname> parameter in <filename>repmgr.conf</filename>.
This must be set to a shell command which will stop <application>repmgrd</application>; This must be set to a shell command which will stop &repmgrd;;
if &repmgr; was installed from a package, this will be the service command defined by the if &repmgr; was installed from a package, this will be the service command defined by the
package. For more details see <link linkend="appendix-packages">Appendix: &repmgr; package details</link>. package. For more details see <link linkend="appendix-packages">Appendix: &repmgr; package details</link>.
</para> </para>
@@ -59,7 +59,7 @@
<para> <para>
If &repmgr; was installed from a system package, and you do not configure If &repmgr; was installed from a system package, and you do not configure
<varname>repmgrd_service_stop_command</varname> to an appropriate service command, this may <varname>repmgrd_service_stop_command</varname> to an appropriate service command, this may
result in the system becoming confused about the state of the <application>repmgrd</application> result in the system becoming confused about the state of the &repmgrd;
service; this is particularly the case with <literal>systemd</literal>. service; this is particularly the case with <literal>systemd</literal>.
</para> </para>
</important> </important>
@@ -76,7 +76,7 @@
<term><option>--dry-run</option></term> <term><option>--dry-run</option></term>
<listitem> <listitem>
<para> <para>
Check prerequisites but don't actually attempt to stop <application>repmgrd</application>. Check prerequisites but don't actually attempt to stop &repmgrd;.
</para> </para>
<para> <para>
This action will output the command which would be executed. This action will output the command which would be executed.
@@ -89,7 +89,7 @@
<term><option>--wait</option></term> <term><option>--wait</option></term>
<listitem> <listitem>
<para> <para>
Wait for the specified number of seconds to confirm that <application>repmgrd</application> Wait for the specified number of seconds to confirm that &repmgrd;
stopped successfully. stopped successfully.
</para> </para>
<para> <para>
@@ -103,7 +103,7 @@
<term><option>--no-wait</option></term> <term><option>--no-wait</option></term>
<listitem> <listitem>
<para> <para>
Don't wait to confirm that <application>repmgrd</application> Don't wait to confirm that &repmgrd;
stopped successfully. stopped successfully.
</para> </para>
<para> <para>
@@ -124,17 +124,18 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<indexterm>
<primary>repmgrd_service_stop_command</primary>
<secondary>with &quot;repmgr daemon stop&quot;</secondary>
</indexterm>
<term><option>repmgrd_service_stop_command</option></term> <term><option>repmgrd_service_stop_command</option></term>
<listitem> <listitem>
<indexterm>
<primary>repmgrd_service_stop_command</primary>
<secondary>with &quot;repmgr daemon stop&quot;</secondary>
</indexterm>
<para> <para>
<command>repmgr daemon stop</command> will execute the command defined by the <command>repmgr daemon stop</command> will execute the command defined by the
<varname>repmgrd_service_stop_command</varname> parameter in <filename>repmgr.conf</filename>. <varname>repmgrd_service_stop_command</varname> parameter in <filename>repmgr.conf</filename>.
This must be set to a shell command which will stop <application>repmgrd</application>; This must be set to a shell command which will stop &repmgrd;;
if &repmgr; was installed from a package, this will be the service command defined by the if &repmgr; was installed from a package, this will be the service command defined by the
package. For more details see <link linkend="appendix-packages">Appendix: &repmgr; package details</link>. package. For more details see <link linkend="appendix-packages">Appendix: &repmgr; package details</link>.
</para> </para>
@@ -142,7 +143,7 @@
<para> <para>
If &repmgr; was installed from a system package, and you do not configure If &repmgr; was installed from a system package, and you do not configure
<varname>repmgrd_service_stop_command</varname> to an appropriate service command, this may <varname>repmgrd_service_stop_command</varname> to an appropriate service command, this may
result in the system becoming confused about the state of the <application>repmgrd</application> result in the system becoming confused about the state of the &repmgrd;
service; this is particularly the case with <literal>systemd</literal>. service; this is particularly the case with <literal>systemd</literal>.
</para> </para>
</important> </important>
@@ -163,7 +164,7 @@
<term><option>SUCCESS (0)</option></term> <term><option>SUCCESS (0)</option></term>
<listitem> <listitem>
<para> <para>
<application>repmgrd</application> could be stopped. &repmgrd; could be stopped.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -182,7 +183,7 @@
<term><option>ERR_REPMGRD_SERVICE (27)</option></term> <term><option>ERR_REPMGRD_SERVICE (27)</option></term>
<listitem> <listitem>
<para> <para>
<application>repmgrd</application> could not be stopped. &repmgrd; could not be stopped.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -193,7 +194,11 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-daemon-start">, <xref linkend="repmgr-daemon-status">, <xref linkend="repmgrd-daemon"> <xref linkend="repmgr-daemon-start"/>,
<xref linkend="repmgrd-daemon"/>,
<xref linkend="repmgr-service-status"/>,
<xref linkend="repmgr-service-pause"/>,
<xref linkend="repmgr-service-unpause"/>
</para> </para>
</refsect1> </refsect1>

View File

@@ -1,210 +0,0 @@
<refentry id="repmgr-node-check">
<indexterm>
<primary>repmgr node check</primary>
</indexterm>
<refmeta>
<refentrytitle>repmgr node check</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr node check</refname>
<refpurpose>performs some health checks on a node from a replication perspective</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
Performs some health checks on a node from a replication perspective.
This command must be run on the local node.
</para>
<note>
<para>
Currently &repmgr; performs health checks on physical replication
slots only, with the aim of warning about streaming replication standbys which
have become detached and the associated risk of uncontrolled WAL file
growth.
</para>
</note>
</refsect1>
<refsect1>
<title>Example</title>
<para>
<programlisting>
$ repmgr -f /etc/repmgr.conf node check
Node "node1":
Server role: OK (node is primary)
Replication lag: OK (N/A - node is primary)
WAL archiving: OK (0 pending files)
Downstream servers: OK (2 of 2 downstream nodes attached)
Replication slots: OK (node has no physical replication slots)
Missing replication slots: OK (node has no missing physical replication slots)</programlisting>
</para>
</refsect1>
<refsect1>
<title>Individual checks</title>
<para>
Each check can be performed individually by supplying
an additional command line parameter, e.g.:
<programlisting>
$ repmgr node check --role
OK (node is primary)</programlisting>
</para>
<para>
Parameters for individual checks are as follows:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<literal>--role</literal>: checks if the node has the expected role
</simpara>
</listitem>
<listitem>
<simpara>
<literal>--replication-lag</literal>: checks if the node is lagging by more than
<varname>replication_lag_warning</varname> or <varname>replication_lag_critical</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<literal>--archive-ready</literal>: checks for WAL files which have not yet been archived,
and returns <literal>WARNING</literal> or <literal>CRITICAL</literal> if the number
exceeds <varname>archive_ready_warning</varname> or <varname>archive_ready_critical</varname> respectively.
</simpara>
</listitem>
<listitem>
<simpara>
<literal>--downstream</literal>: checks that the expected downstream nodes are attached
</simpara>
</listitem>
<listitem>
<simpara>
<literal>--slots</literal>: checks there are no inactive physical replication slots
</simpara>
</listitem>
<listitem>
<simpara>
<literal>--missing-slots</literal>: checks there are no missing physical replication slots
</simpara>
</listitem>
<listitem>
<simpara>
<literal>--data-directory-config</literal>: checks the data directory configured in
<filename>repmgr.conf</filename> matches the actual data directory.
This check is not directly related to replication, but is useful to verify &repmgr;
is correctly configured.
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title>Output format</title>
<para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<literal>--csv</literal>: generate output in CSV format (not available
for individual checks)
</simpara>
</listitem>
<listitem>
<simpara>
<literal>--nagios</literal>: generate output in a Nagios-compatible format
(for individual checks only)
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title>Exit codes</title>
<para>
When executing <command>repmgr node check</command> with one of the individual
checks listed above, &repmgr; will emit one of the following Nagios-style exit codes
(even if <literal>--nagios</literal> is not supplied):
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<literal>0</literal>: OK
</simpara>
</listitem>
<listitem>
<simpara>
<literal>1</literal>: WARNING
</simpara>
</listitem>
<listitem>
<simpara>
<literal>2</literal>: ERROR
</simpara>
</listitem>
<listitem>
<simpara>
<literal>3</literal>: UNKNOWN
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
One of the following exit codes will be emitted by <command>repmgr status check</command>
if no individual check was specified.
</para>
<variablelist>
<varlistentry>
<term><option>SUCCESS (0)</option></term>
<listitem>
<para>
No issues were detected.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_NODE_STATUS (25)</option></term>
<listitem>
<para>
One or more issues were detected.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-node-status">, <xref linkend="repmgr-cluster-show">
</para>
</refsect1>
</refentry>

308
doc/repmgr-node-check.xml Normal file
View File

@@ -0,0 +1,308 @@
<refentry id="repmgr-node-check">
<indexterm>
<primary>repmgr node check</primary>
</indexterm>
<refmeta>
<refentrytitle>repmgr node check</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr node check</refname>
<refpurpose>performs some health checks on a node from a replication perspective</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
Performs some health checks on a node from a replication perspective.
This command must be run on the local node.
</para>
<note>
<para>
Currently &repmgr; performs health checks on physical replication
slots only, with the aim of warning about streaming replication standbys which
have become detached and the associated risk of uncontrolled WAL file
growth.
</para>
</note>
</refsect1>
<refsect1>
<title>Example</title>
<para>
Execution on the primary server:
<programlisting>
$ repmgr -f /etc/repmgr.conf node check
Node "node1":
Server role: OK (node is primary)
Replication lag: OK (N/A - node is primary)
WAL archiving: OK (0 pending files)
Upstream connection: OK (N/A - is primary)
Downstream servers: OK (2 of 2 downstream nodes attached)
Replication slots: OK (node has no physical replication slots)
Missing replication slots: OK (node has no missing physical replication slots)
Configured data directory: OK (configured "data_directory" is "/var/lib/postgresql/data")</programlisting>
</para>
<para>
Execution on a standby server:
<programlisting>
$ repmgr -f /etc/repmgr.conf node check
Node "node2":
Server role: OK (node is standby)
Replication lag: OK (0 seconds)
WAL archiving: OK (0 pending archive ready files)
Upstream connection: OK (node "node2" (ID: 2) is attached to expected upstream node "node1" (ID: 1))
Downstream servers: OK (this node has no downstream nodes)
Replication slots: OK (node has no physical replication slots)
Missing physical replication slots: OK (node has no missing physical replication slots)
Configured data directory: OK (configured "data_directory" is "/var/lib/postgresql/data")</programlisting>
</para>
</refsect1>
<refsect1>
<title>Individual checks</title>
<para>
Each check can be performed individually by supplying
an additional command line parameter, e.g.:
<programlisting>
$ repmgr node check --role
OK (node is primary)</programlisting>
</para>
<para>
Parameters for individual checks are as follows:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<option>--role</option>: checks if the node has the expected role
</simpara>
</listitem>
<listitem>
<simpara>
<option>--replication-lag</option>: checks if the node is lagging by more than
<varname>replication_lag_warning</varname> or <varname>replication_lag_critical</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<option>--archive-ready</option>: checks for WAL files which have not yet been archived,
and returns <literal>WARNING</literal> or <literal>CRITICAL</literal> if the number
exceeds <varname>archive_ready_warning</varname> or <varname>archive_ready_critical</varname> respectively.
</simpara>
</listitem>
<listitem>
<simpara>
<option>--downstream</option>: checks that the expected downstream nodes are attached
</simpara>
</listitem>
<listitem>
<simpara>
<option>--upstream</option>: checks that the node is attached to its expected upstream
</simpara>
</listitem>
<listitem>
<simpara>
<option>--slots</option>: checks there are no inactive physical replication slots
</simpara>
</listitem>
<listitem>
<simpara>
<option>--missing-slots</option>: checks there are no missing physical replication slots
</simpara>
</listitem>
<listitem>
<simpara>
<option>--data-directory-config</option>: checks the data directory configured in
<filename>repmgr.conf</filename> matches the actual data directory.
This check is not directly related to replication, but is useful to verify &repmgr;
is correctly configured.
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title>repmgrd</title>
<para>
A separate check is available to verify whether &repmgrd; is running,
This is not included in the general output, as this does not
per-se constitute a check of the node's replication status.
</para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<option>--repmgrd</option>: checks whether &repmgrd; is running.
If &repmgrd; is running but paused, status <literal>1</literal>
(<literal>WARNING</literal>) is returned.
</simpara>
</listitem>
</itemizedlist>
</refsect1>
<refsect1>
<title>Additional checks</title>
<para>
Several checks are provided for diagnostic purposes and are not
included in the general output:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<option>--db-connection</option>: checks if &repmgr; can connect to the
database on the local node.
</simpara>
<simpara>
This option is particularly useful in combination with <command>SSH</command>, as
it can be used to troubleshoot connection issues encountered when &repmgr; is
executed remotely (e.g. during a switchover operation).
</simpara>
</listitem>
<listitem>
<simpara>
<option>--replication-config-owner</option>: checks if the file containing replication
configuration (PostgreSQL 12 and later: <filename>postgresql.auto.conf</filename>;
PostgreSQL 11 and earlier: <filename>recovery.conf</filename>) is
owned by the same user who owns the data directory.
</simpara>
<simpara>
Incorrect ownership of these files (e.g. if they are owned by <literal>root</literal>)
will cause operations which need to update the replication configuration
(e.g. <link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>
or <link linkend="repmgr-standby-promote"><command>repmgr standby promote</command></link>)
to fail.
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title>Connection options</title>
<para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<option>-S</option>/<option>--superuser</option>: connect as the
named superuser instead of the &repmgr; user
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title>Output format</title>
<para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<option>--csv</option>: generate output in CSV format (not available
for individual checks)
</simpara>
</listitem>
<listitem>
<simpara>
<option>--nagios</option>: generate output in a Nagios-compatible format
(for individual checks only)
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title>Exit codes</title>
<para>
When executing <command>repmgr node check</command> with one of the individual
checks listed above, &repmgr; will emit one of the following Nagios-style exit codes
(even if <option>--nagios</option> is not supplied):
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<literal>0</literal>: OK
</simpara>
</listitem>
<listitem>
<simpara>
<literal>1</literal>: WARNING
</simpara>
</listitem>
<listitem>
<simpara>
<literal>2</literal>: ERROR
</simpara>
</listitem>
<listitem>
<simpara>
<literal>3</literal>: UNKNOWN
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
One of the following exit codes will be emitted by <command>repmgr status check</command>
if no individual check was specified.
</para>
<variablelist>
<varlistentry>
<term><option>SUCCESS (0)</option></term>
<listitem>
<para>
No issues were detected.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_NODE_STATUS (25)</option></term>
<listitem>
<para>
One or more issues were detected.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-node-status"/>, <xref linkend="repmgr-cluster-show"/>
</para>
</refsect1>
</refentry>

View File

@@ -22,14 +22,18 @@
This can optionally use <application>pg_rewind</application> to re-integrate This can optionally use <application>pg_rewind</application> to re-integrate
a node which has diverged from the rest of the cluster, typically a failed primary. a node which has diverged from the rest of the cluster, typically a failed primary.
</para> </para>
<para>
Note that <command>repmgr node rejoin</command> can only be used to attach
a standby to the current primary, not another standby.
</para>
<tip> <tip>
<para> <para>
If the node is running and needs to be attached to the current primary, use If the node is running and needs to be attached to the current primary, use
<xref linkend="repmgr-standby-follow">. <xref linkend="repmgr-standby-follow"/>.
</para> </para>
<para> <para>
Note <xref linkend="repmgr-standby-follow"> can only be used for standbys which have not diverged Note <xref linkend="repmgr-standby-follow"/> can only be used for standbys which have not diverged
from the rest of the cluster. from the rest of the cluster.
</para> </para>
</tip> </tip>
@@ -43,7 +47,12 @@
<programlisting> <programlisting>
repmgr node rejoin -d '$conninfo'</programlisting> repmgr node rejoin -d '$conninfo'</programlisting>
where <literal>$conninfo</literal> is the conninfo string of any reachable node in the cluster. where <literal>$conninfo</literal> is the PostgreSQL <literal>conninfo</literal> string of the
<emphasis>current</emphasis> primary node (or that of any reachable node in the cluster, but
<emphasis>not</emphasis> the local node). This is so that &repmgr; can fetch up-to-date information
about the current state of the cluster.
</para>
<para>
<filename>repmgr.conf</filename> for the stopped node *must* be supplied explicitly if not <filename>repmgr.conf</filename> for the stopped node *must* be supplied explicitly if not
otherwise available. otherwise available.
</para> </para>
@@ -64,16 +73,16 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>--force-rewind[=/path/to/pg_rewind]</option></term> <term><option>--force-rewind</option></term>
<listitem> <listitem>
<para> <para>
Execute <application>pg_rewind</application>. Execute <application>pg_rewind</application>.
</para> </para>
<para> <para>
It is only necessary to provide the <application>pg_rewind</application> path See <xref linkend="repmgr-node-rejoin-pg-rewind"/> for more details on using
if using PostgreSQL 9.3 or 9.4, and <application>pg_rewind</application> <application>pg_rewind</application>.
is not installed in the PostgreSQL <filename>bin</filename> directory.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -207,9 +216,18 @@
a standby to the current primary, not another standby. a standby to the current primary, not another standby.
</para> </para>
<para> <para>
The node must have been shut down cleanly; if this was not the case, it will The node's PostgreSQL instance must have been shut down cleanly. If this was not the
need to be manually started (remove any existing <filename>recovery.conf</filename> file first) case, it will need to be started up until it has reached a consistent recovery point,
until it has reached a consistent recovery point, then shut down cleanly. then shut down cleanly.
</para>
<para>
In PostgreSQL 13 and later, this will be done automatically
if the <option>--force-rewind</option> is provided (even if an actual rewind
is not necessary).
</para>
<para>
With PostgreSQL 12 and earlier, PostgreSQL will need to
be started and shut down manually; see below for the best way to do this.
</para> </para>
<tip> <tip>
<para> <para>
@@ -221,26 +239,28 @@
rm -f /var/lib/pgsql/data/recovery.conf rm -f /var/lib/pgsql/data/recovery.conf
postgres --single -D /var/lib/pgsql/data/ &lt; /dev/null</programlisting> postgres --single -D /var/lib/pgsql/data/ &lt; /dev/null</programlisting>
</para> </para>
<para>
Note that <filename>standby.signal</filename> (PostgreSQL 11 and earlier:
<filename>recovery.conf</filename>) <emphasis>must</emphasis> be removed
from the data directory for PostgreSQL to be able to start in single
user mode.
</para>
</tip> </tip>
<para>
&repmgr; will attempt to verify whether the node can rejoin as-is, or whether
<command>pg_rewind</command> must be used (see following section).
</para>
</refsect1> </refsect1>
<refsect1 id="repmgr-node-rejoin-pg-rewind" xreflabel="Using pg_rewind"> <refsect1 id="repmgr-node-rejoin-pg-rewind" xreflabel="Using pg_rewind">
<title>Using <command>pg_rewind</command></title>
<indexterm> <indexterm>
<primary>pg_rewind</primary> <primary>pg_rewind</primary>
<secondary>using with "repmgr node rejoin"</secondary> <secondary>using with "repmgr node rejoin"</secondary>
</indexterm> </indexterm>
<title>Using <command>pg_rewind</command></title>
<para> <para>
<command>repmgr node rejoin</command> can optionally use <command>pg_rewind</command> to re-integrate a <command>repmgr node rejoin</command> can optionally use <command>pg_rewind</command> to re-integrate a
node which has diverged from the rest of the cluster, typically a failed primary. node which has diverged from the rest of the cluster, typically a failed primary.
<command>pg_rewind</command> is available in PostgreSQL 9.5 and later as part of the core distribution,
and can be installed from external sources for PostgreSQL 9.3 and 9.4.
</para> </para>
<note> <note>
<para> <para>
@@ -249,6 +269,10 @@
data checksums were enabled when the cluster was initialized. See the data checksums were enabled when the cluster was initialized. See the
<ulink url="https://www.postgresql.org/docs/current/app-pgrewind.html"><command>pg_rewind</command> documentation</ulink> for details. <ulink url="https://www.postgresql.org/docs/current/app-pgrewind.html"><command>pg_rewind</command> documentation</ulink> for details.
</para> </para>
<para>
Additionally, <varname>full_page_writes</varname> must be enabled; this is the default and
normally should never be disabled.
</para>
</note> </note>
<para> <para>
@@ -263,6 +287,7 @@
<programlisting> <programlisting>
$ repmgr node rejoin -f /etc/repmgr.conf -d 'host=node3 dbname=repmgr user=repmgr' \ $ repmgr node rejoin -f /etc/repmgr.conf -d 'host=node3 dbname=repmgr user=repmgr' \
--force-rewind --config-files=postgresql.local.conf,postgresql.conf --verbose --dry-run --force-rewind --config-files=postgresql.local.conf,postgresql.conf --verbose --dry-run
NOTICE: rejoin target is node "node3" (node ID: 3)
INFO: replication connection to the rejoin target node was successful INFO: replication connection to the rejoin target node was successful
INFO: local and rejoin target system identifiers match INFO: local and rejoin target system identifiers match
DETAIL: system identifier is 6652184002263212600 DETAIL: system identifier is 6652184002263212600
@@ -282,7 +307,15 @@
to execute <command>pg_rewind</command> to ensure the node can be rejoined successfully. to execute <command>pg_rewind</command> to ensure the node can be rejoined successfully.
</para> </para>
<important> <refsect2 id="repmgr-node-rejoin-pg-rewind-config-files" xreflabel="pg_rewind and configuration files">
<title><command>pg_rewind</command> and configuration file retention</title>
<indexterm>
<primary>pg_rewind</primary>
<secondary>configuration file retention</secondary>
</indexterm>
<para> <para>
Be aware that if <command>pg_rewind</command> is executed and actually performs a Be aware that if <command>pg_rewind</command> is executed and actually performs a
rewind operation, any configuration files in the PostgreSQL data directory will be rewind operation, any configuration files in the PostgreSQL data directory will be
@@ -290,19 +323,30 @@
</para> </para>
<para> <para>
To prevent this happening, provide a comma-separated list of files to retain To prevent this happening, provide a comma-separated list of files to retain
using the <literal>--config-file</literal> command line option; the specified files using the <option>--config-file</option> command line option; the specified files
will be archived in a temporary directory (whose parent directory can be specified with will be archived in a temporary directory (whose parent directory can be specified with
<literal>--config-archive-dir</literal>) and restored once the rewind operation is <option>--config-archive-dir</option>, default: <filename>/tmp</filename>)
complete. and restored once the rewind operation is complete.
</para> </para>
</important> </refsect2>
<para> <refsect2 id="repmgr-node-rejoin-pg-rewind-example" xreflabel="example using repmgr node rejoin and pg_rewind">
Example, first using <literal>--dry-run</literal>, then actually executing the
<literal>node rejoin command</literal>. <title>Example using <command>repmgr node rejoin</command> and <command>pg_rewind</command></title>
<programlisting>
<indexterm>
<primary>pg_rewind</primary>
<secondary>configuration file retention</secondary>
</indexterm>
<para>
Example, first using <option>--dry-run</option>, then actually executing the
<literal>node rejoin command</literal>.
<programlisting>
$ repmgr node rejoin -f /etc/repmgr.conf -d 'host=node3 dbname=repmgr user=repmgr' \ $ repmgr node rejoin -f /etc/repmgr.conf -d 'host=node3 dbname=repmgr user=repmgr' \
--config-files=postgresql.local.conf,postgresql.conf --verbose --force-rewind --dry-run --config-files=postgresql.local.conf,postgresql.conf --verbose --force-rewind --dry-run
NOTICE: rejoin target is node "node3" (node ID: 3)
INFO: replication connection to the rejoin target node was successful INFO: replication connection to the rejoin target node was successful
INFO: local and rejoin target system identifiers match INFO: local and rejoin target system identifiers match
DETAIL: system identifier is 6652460429293670710 DETAIL: system identifier is 6652460429293670710
@@ -316,17 +360,17 @@
pg_rewind -D '/var/lib/postgresql/data' --source-server='host=node3 dbname=repmgr user=repmgr' pg_rewind -D '/var/lib/postgresql/data' --source-server='host=node3 dbname=repmgr user=repmgr'
INFO: prerequisites for executing NODE REJOIN are met</programlisting> INFO: prerequisites for executing NODE REJOIN are met</programlisting>
<note> <note>
<para> <para>
If <option>--force-rewind</option> is used with the <option>--dry-run</option> option, If <option>--force-rewind</option> is used with the <option>--dry-run</option> option,
this checks the prerequisites for using <application>pg_rewind</application>, but is this checks the prerequisites for using <application>pg_rewind</application>, but is
not an absolute guarantee that actually executing <application>pg_rewind</application> not an absolute guarantee that actually executing <application>pg_rewind</application>
will succeed. See also section <xref linkend="repmgr-node-rejoin-caveats"> below. will succeed. See also section <xref linkend="repmgr-node-rejoin-caveats"/> below.
</para> </para>
</note> </note>
<programlisting> <programlisting>
$ repmgr node rejoin -f /etc/repmgr.conf -d 'host=node3 dbname=repmgr user=repmgr' \ $ repmgr node rejoin -f /etc/repmgr.conf -d 'host=node3 dbname=repmgr user=repmgr' \
--config-files=postgresql.local.conf,postgresql.conf --verbose --force-rewind --config-files=postgresql.local.conf,postgresql.conf --verbose --force-rewind
NOTICE: pg_rewind execution required for this node to attach to rejoin target node 3 NOTICE: pg_rewind execution required for this node to attach to rejoin target node 3
@@ -338,23 +382,47 @@
NOTICE: starting server using "pg_ctl -l /var/log/postgres/startup.log -w -D '/var/lib/pgsql/data' start" NOTICE: starting server using "pg_ctl -l /var/log/postgres/startup.log -w -D '/var/lib/pgsql/data' start"
NOTICE: NODE REJOIN successful NOTICE: NODE REJOIN successful
DETAIL: node 2 is now attached to node 3</programlisting> DETAIL: node 2 is now attached to node 3</programlisting>
</para> </para>
</refsect2>
<refsect2 id="repmgr-node-rejoin-postgresql-94" xreflabel="pg_rewind and PostgreSQL 9.4">
<title><command>pg_rewind</command> and PostgreSQL 9.4</title>
<indexterm>
<primary>pg_rewind</primary>
<secondary>PostgreSQL 9.4</secondary>
</indexterm>
<para>
<application>pg_rewind</application> is available in PostgreSQL 9.5 and later as part of the core distribution.
Users of PostgreSQL 9.4 will need to manually install it; the source code is available here:
<ulink url="https://github.com/vmware/pg_rewind">https://github.com/vmware/pg_rewind</ulink>.
If the <application>pg_rewind</application>
binary is not installed in the PostgreSQL <filename>bin</filename> directory, provide
its full path on the demotion candidate with <option>--force-rewind</option>.
</para>
<para>
Note that building the 9.4 version of <application>pg_rewind</application> requires the PostgreSQL
source code.
</para>
</refsect2>
</refsect1> </refsect1>
<refsect1 id="repmgr-node-rejoin-caveats" xreflabel="Caveats"> <refsect1 id="repmgr-node-rejoin-caveats" xreflabel="Caveats">
<indexterm>
<primary>repmgr node rejoin</primary>
<secondary>caveats</secondary>
</indexterm>
<title>Caveats when using <command>repmgr node rejoin</command></title> <title>Caveats when using <command>repmgr node rejoin</command></title>
<indexterm>
<primary>repmgr node rejoin</primary>
<secondary>caveats</secondary>
</indexterm>
<para> <para>
<command>repmgr node rejoin</command> attempts to determine whether it will succeed by <command>repmgr node rejoin</command> attempts to determine whether it will succeed by
comparing the timelines and relative WAL positions of the local node (rejoin candidate) and primary comparing the timelines and relative WAL positions of the local node (rejoin candidate) and primary
(rejoin target). This is particularly important if planning to use <application>pg_rewind</application>, (rejoin target). This is particularly important if planning to use <application>pg_rewind</application>,
which currently (as of PostgreSQL 11) may appear to succeed (or indicate there is no action which currently (as of PostgreSQL 12) may appear to succeed (or indicate there is no action
needed) but potentially allow an impossible action, such as trying to rejoin a standby to a needed) but potentially allow an impossible action, such as trying to rejoin a standby to a
primary which is behind the standby. &repmgr; will prevent this situation from occurring. primary which is behind the standby. &repmgr; will prevent this situation from occurring.
</para> </para>
@@ -367,6 +435,11 @@
the current standby's PostgreSQL log will contain entries with the text the current standby's PostgreSQL log will contain entries with the text
&quot;<literal>record with incorrect prev-link</literal>&quot;. &quot;<literal>record with incorrect prev-link</literal>&quot;.
</para> </para>
<para>
In PostgreSQL 9.5 and earlier, it is <emphasis>not</emphasis> possible to use
<application>pg_rewind</application> to attach to a target node with a lower
timeline than the local node.
</para>
<para> <para>
We strongly recommend running <command>repmgr node rejoin</command> with the We strongly recommend running <command>repmgr node rejoin</command> with the
<option>--dry-run</option> option first. Additionally it might be a good idea <option>--dry-run</option> option first. Additionally it might be a good idea
@@ -376,12 +449,57 @@
is running in <option>--dry-run</option> mode. is running in <option>--dry-run</option> mode.
</para> </para>
<warning>
<para>
In all PostgreSQL released before February 2021, <application>pg_rewind</application>
contains a corner-case bug which affects standbys in a very specific situation.
</para>
<para>
This situation occurs when a standby was shut down <emphasis>before</emphasis> its
primary node, and an attempt is made to attach this standby to another primary
in the same cluster (following a &quot;split brain&quot; situation where the standby
was connected to the wrong primary). In this case, &repmgr; will correctly determine
that <application>pg_rewind</application> should be executed, however
<application>pg_rewind</application> incorrectly decides that no action is necessary.
</para>
<para>
In this situation, &repmgr; will report something like:
<programlisting>
NOTICE: pg_rewind execution required for this node to attach to rejoin target node 1
DETAIL: rejoin target server's timeline 3 forked off current database system timeline 2 before current recovery point 0/7019C10</programlisting>
but when executed, <application>pg_rewind</application> will report:
<programlisting>
pg_rewind: servers diverged at WAL location 0/7015540 on timeline 2
pg_rewind: no rewind required</programlisting>
and if an attempt is made to attach the standby to the new primary, PostgreSQL logs on the standby
will contain errors like:
<programlisting>
[2020-09-07 15:01:41 UTC] LOG: 00000: replication terminated by primary server
[2020-09-07 15:01:41 UTC] DETAIL: End of WAL reached on timeline 2 at 0/7015540.
[2020-09-07 15:01:41 UTC] LOG: 00000: new timeline 3 forked off current database system timeline 2 before current recovery point 0/7019C10</programlisting>
</para>
<para>
Currently it is not possible to resolve this situation using <application>pg_rewind</application>.
A <ulink url="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=2b4f3130382fe2f8705863e4d38589d4d69cd695">patch</ulink>
was submitted and is included in all PostgreSQL versions released in February 2021 or later.
</para>
<para>
As a workaround, start the primary server the standby was previously attached to,
and ensure the standby can be attached to it. If <application>pg_rewind</application> was actually executed,
it will have copied in the <filename>.history</filename> file from the target primary server; this must
be removed. <command>repmgr node rejoin</command> can then be used to attach the standby to the original
primary. Ensure any changes pending on the primary have propagated to the standby. Then shut down the primary
server <emphasis>first</emphasis>, before shutting down the standby. It should then be possible to
use <command>repmgr node rejoin</command> to attach the standby to the new primary.
</para>
</warning>
</refsect1> </refsect1>
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-standby-follow"> <xref linkend="repmgr-standby-follow"/>, <xref linkend="repmgr-standby-switchover"/>
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@@ -75,8 +75,22 @@
<para> <para>
Issue a <command>CHECKPOINT</command> before stopping or restarting the node. Issue a <command>CHECKPOINT</command> before stopping or restarting the node.
</para> </para>
<para>
Note that a superuser connection is required to be able to execute the
<command>CHECKPOINT</command> command.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>-S</option>/<option>--superuser</option></term>
<listitem>
<para>
Connect as the named superuser instead of the normal &repmgr; user.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
@@ -114,38 +128,38 @@
<para> <para>
See what action would be taken for a restart: See what action would be taken for a restart:
<programlisting> <programlisting>
[postgres@node1 ~]$ repmgr -f /etc/repmgr/11/repmgr.conf node service --action=restart --checkpoint --dry-run [postgres@node1 ~]$ repmgr -f /etc/repmgr/12/repmgr.conf node service --action=restart --checkpoint --dry-run
INFO: a CHECKPOINT would be issued here INFO: a CHECKPOINT would be issued here
INFO: would execute server command "sudo service postgresql-11 restart"</programlisting> INFO: would execute server command "sudo service postgresql-12 restart"</programlisting>
</para> </para>
<para> <para>
Restart the PostgreSQL instance: Restart the PostgreSQL instance:
<programlisting> <programlisting>
[postgres@node1 ~]$ repmgr -f /etc/repmgr/11/repmgr.conf node service --action=restart --checkpoint [postgres@node1 ~]$ repmgr -f /etc/repmgr/12/repmgr.conf node service --action=restart --checkpoint
NOTICE: issuing CHECKPOINT NOTICE: issuing CHECKPOINT
DETAIL: executing server command "sudo service postgresql-11 restart" DETAIL: executing server command "sudo service postgresql-12 restart"
Redirecting to /bin/systemctl restart postgresql-11.service</programlisting> Redirecting to /bin/systemctl restart postgresql-12.service</programlisting>
</para> </para>
<para> <para>
List all commands: List all commands:
<programlisting> <programlisting>
[postgres@node1 ~]$ repmgr -f /etc/repmgr/11/repmgr.conf node service --list-actions [postgres@node1 ~]$ repmgr -f /etc/repmgr/12/repmgr.conf node service --list-actions
Following commands would be executed for each action: Following commands would be executed for each action:
start: "sudo service postgresql-11 start" start: "sudo service postgresql-12 start"
stop: "sudo service postgresql-11 stop" stop: "sudo service postgresql-12 stop"
restart: "sudo service postgresql-11 restart" restart: "sudo service postgresql-12 restart"
reload: "sudo service postgresql-11 reload" reload: "sudo service postgresql-12 reload"
promote: "/usr/pgsql-11/bin/pg_ctl -w -D '/var/lib/pgsql/11/data' promote"</programlisting> promote: "/usr/pgsql-12/bin/pg_ctl -w -D '/var/lib/pgsql/12/data' promote"</programlisting>
</para> </para>
<para> <para>
List a single command: List a single command:
<programlisting> <programlisting>
[postgres@node1 ~]$ repmgr -f /etc/repmgr/11/repmgr.conf node service --list-actions --action=promote [postgres@node1 ~]$ repmgr -f /etc/repmgr/12/repmgr.conf node service --list-actions --action=promote
/usr/pgsql-11/bin/pg_ctl -w -D '/var/lib/pgsql/11/data' promote </programlisting> /usr/pgsql-12/bin/pg_ctl -w -D '/var/lib/pgsql/12/data' promote </programlisting>
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@@ -84,7 +84,7 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
See <xref linkend="repmgr-node-check"> to diagnose issues and <xref linkend="repmgr-cluster-show"> See <xref linkend="repmgr-node-check"/> to diagnose issues and <xref linkend="repmgr-cluster-show"/>
for an overview of all nodes in the cluster. for an overview of all nodes in the cluster.
</para> </para>
</refsect1> </refsect1>

View File

@@ -24,10 +24,15 @@
<note> <note>
<para> <para>
It's possibly to install the &repmgr; extension manually before executing &repmgr; will attempt to install the &repmgr; extension as part of this command,
however this will fail if the <literal>repmgr</literal> user is not a superuser.
</para>
<para>
It's possible to install the &repmgr; extension manually before executing
<command>repmgr primary register</command>; in this case &repmgr; will <command>repmgr primary register</command>; in this case &repmgr; will
detect the presence of the extension and skip that step. detect the presence of the extension and skip that step.
</para> </para>
</note> </note>
</refsect1> </refsect1>
@@ -38,25 +43,42 @@
Execute with the <option>--dry-run</option> option to check what would happen without Execute with the <option>--dry-run</option> option to check what would happen without
actually registering the primary. actually registering the primary.
</para> </para>
<para>
<command>repmgr master register</command> can be used as an alias for
<command>repmgr primary register</command>.
</para>
<note> <note>
<para> <para>
If providing the configuration file location with <option>-f/--config-file</option>, If providing the configuration file location with <option>-f/--config-file</option>,
avoid using a relative path, as &repmgr; stores the configuration file location avoid using a relative path, as &repmgr; stores the configuration file location
in the repmgr metadata for use when &repmgr; is executed remotely (e.g. during in the repmgr metadata for use when &repmgr; is executed remotely (e.g. during
<xref linkend="repmgr-standby-switchover">). &repmgr; will attempt to convert the <xref linkend="repmgr-standby-switchover"/>). &repmgr; will attempt to convert the
a relative path into an absolute one, but this may not be the same as the path you a relative path into an absolute one, but this may not be the same as the path you
would explicitly provide (e.g. <filename>./repmgr.conf</filename> might be converted would explicitly provide (e.g. <filename>./repmgr.conf</filename> might be converted
to <filename>/path/to/./repmgr.conf</filename>, whereas you'd normally write to <filename>/path/to/./repmgr.conf</filename>, whereas you'd normally write
<filename>/path/to/repmgr.conf</filename>). <filename>/path/to/repmgr.conf</filename>).
</para> </para>
</note> </note>
<para>
<command>repmgr master register</command> can be used as an alias for
<command>repmgr primary register</command>.
</para>
</refsect1> </refsect1>
<refsect1>
<title>User permission requirements</title>
<para>
The <literal>repmgr</literal> user must be a superuser in order for &repmgr;
to be able to install the <literal>repmgr</literal> extension.
</para>
<para>
If this is not the case, the <literal>repmgr</literal> extension can be installed
manually before executing <command>repmgr primary register</command>.
</para>
<para>
A future &repmgr; release will enable the provision of a <option>--superuser</option>
name for the installation of the extension.
</para>
</refsect1>
<refsect1> <refsect1>
<title>Options</title> <title>Options</title>

View File

@@ -60,6 +60,17 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--force</option></term>
<listitem>
<para>
Forcibly unregister the node if it is registered as an active primary,
as long as it has no registered standbys; or if it is registered as
a primary but running as a standby.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@@ -1,6 +1,6 @@
<refentry id="repmgr-daemon-pause"> <refentry id="repmgr-service-pause">
<indexterm> <indexterm>
<primary>repmgr daemon pause</primary> <primary>repmgr service pause</primary>
</indexterm> </indexterm>
<indexterm> <indexterm>
@@ -9,43 +9,52 @@
</indexterm> </indexterm>
<refmeta> <refmeta>
<refentrytitle>repmgr daemon pause</refentrytitle> <refentrytitle>repmgr service pause</refentrytitle>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
<refname>repmgr daemon pause</refname> <refname>repmgr service pause</refname>
<refpurpose>Instruct all <application>repmgrd</application> instances in the replication cluster to pause failover operations</refpurpose> <refpurpose>Instruct all &repmgrd; instances in the replication cluster to pause failover operations</refpurpose>
</refnamediv> </refnamediv>
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para> <para>
This command can be run on any active node in the replication cluster to instruct all This command can be run on any active node in the replication cluster to instruct all
running <application>repmgrd</application> instances to &quot;pause&quot; themselves, i.e. take no running &repmgrd; instances to &quot;pause&quot; themselves, i.e. take no
action (such as promoting themselves or following a new primary) if a failover event is detected. action (such as promoting themselves or following a new primary) if a failover event is detected.
</para> </para>
<para> <para>
This functionality is useful for performing maintenance operations, such as switchovers This functionality is useful for performing maintenance operations, such as switchovers
or upgrades, which might otherwise trigger a failover if <application>repmgrd</application> or upgrades, which might otherwise trigger a failover if &repmgrd;
is running normally. is running normally.
</para> </para>
<note> <note>
<para> <para>
It's important to wait a few seconds after restarting PostgreSQL on any node before running It's important to wait a few seconds after restarting PostgreSQL on any node before running
<command>repmgr daemon pause</command>, as the <application>repmgrd</application> instance <command>repmgr service pause</command>, as the &repmgrd; instance
on the restarted node will take a second or two before it has updated its status. on the restarted node will take a second or two before it has updated its status.
</para> </para>
</note> </note>
<para> <para>
<xref linkend="repmgr-daemon-unpause"> will instruct all previously paused <application>repmgrd</application> <xref linkend="repmgr-service-unpause"/> will instruct all previously paused &repmgrd;
instances to resume normal failover operation. instances to resume normal failover operation.
</para> </para>
</refsect1> </refsect1>
<refsect1>
<title>Prerequisites</title>
<para>
PostgreSQL must be accessible on all nodes (using the <varname>conninfo</varname> string shown by
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>)
from the node where <command>repmgr service pause</command> is executed.
</para>
</refsect1>
<refsect1> <refsect1>
<title>Execution</title> <title>Execution</title>
<para> <para>
<command>repmgr daemon pause</command> can be executed on any active node in the <command>repmgr service pause</command> can be executed on any active node in the
replication cluster. A valid <filename>repmgr.conf</filename> file is required. replication cluster. A valid <filename>repmgr.conf</filename> file is required.
It will have no effect on previously paused nodes. It will have no effect on previously paused nodes.
</para> </para>
@@ -55,7 +64,7 @@
<title>Example</title> <title>Example</title>
<para> <para>
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf daemon pause $ repmgr -f /etc/repmgr.conf service pause
NOTICE: node 1 (node1) paused NOTICE: node 1 (node1) paused
NOTICE: node 2 (node2) paused NOTICE: node 2 (node2) paused
NOTICE: node 3 (node3) paused</programlisting> NOTICE: node 3 (node3) paused</programlisting>
@@ -69,7 +78,7 @@ NOTICE: node 3 (node3) paused</programlisting>
<term><option>--dry-run</option></term> <term><option>--dry-run</option></term>
<listitem> <listitem>
<para> <para>
Check if nodes are reachable but don't pause <application>repmgrd</application>. Check if nodes are reachable but don't pause &repmgrd;.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -79,7 +88,7 @@ NOTICE: node 3 (node3) paused</programlisting>
<refsect1> <refsect1>
<title>Exit codes</title> <title>Exit codes</title>
<para> <para>
One of the following exit codes will be emitted by <command>repmgr daemon unpause</command>: One of the following exit codes will be emitted by <command>repmgr service unpause</command>:
</para> </para>
<variablelist> <variablelist>
@@ -87,7 +96,7 @@ NOTICE: node 3 (node3) paused</programlisting>
<term><option>SUCCESS (0)</option></term> <term><option>SUCCESS (0)</option></term>
<listitem> <listitem>
<para> <para>
<application>repmgrd</application> could be paused on all nodes. &repmgrd; could be paused on all nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -96,7 +105,7 @@ NOTICE: node 3 (node3) paused</programlisting>
<term><option>ERR_REPMGRD_PAUSE (26)</option></term> <term><option>ERR_REPMGRD_PAUSE (26)</option></term>
<listitem> <listitem>
<para> <para>
<application>repmgrd</application> could not be paused on one or mode nodes. &repmgrd; could not be paused on one or mode nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -107,7 +116,11 @@ NOTICE: node 3 (node3) paused</programlisting>
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-daemon-unpause">, <xref linkend="repmgr-daemon-status"> <xref linkend="repmgr-service-unpause"/>,
<xref linkend="repmgr-service-status"/>,
<xref linkend="repmgrd-pausing"/>,
<xref linkend="repmgr-daemon-start"/>,
<xref linkend="repmgr-daemon-stop"/>
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@@ -0,0 +1,215 @@
<refentry id="repmgr-service-status">
<indexterm>
<primary>repmgr service status</primary>
</indexterm>
<indexterm>
<primary>repmgrd</primary>
<secondary>displaying service status</secondary>
</indexterm>
<refmeta>
<refentrytitle>repmgr service status</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr service status</refname>
<refpurpose>display information about the status of &repmgrd; on each node in the cluster</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
This command provides an overview over all active nodes in the cluster and the state
of each node's &repmgrd; instance. It can be used to check
the result of <xref linkend="repmgr-service-pause"/> and <xref linkend="repmgr-service-unpause"/>
operations.
</para>
</refsect1>
<refsect1>
<title>Prerequisites</title>
<para>
PostgreSQL should be accessible on all nodes (using the <varname>conninfo</varname> string shown by
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>)
from the node where <command>repmgr service status</command> is executed.
</para>
</refsect1>
<refsect1>
<title>Execution</title>
<para>
<command>repmgr service status</command> can be executed on any active node in the
replication cluster. A valid <filename>repmgr.conf</filename> file is required.
</para>
<para>
If a node is not accessible, or PostgreSQL itself is not running on the node,
&repmgr; will not be able to determine the status of that node's &repmgrd; instance,
and &quot;<literal>n/a</literal>&quot; will be displayed in the node's <literal>repmgrd</literal>
column.
</para>
<note>
<para>
After restarting PostgreSQL on any node, the &repmgrd; instance
will take a second or two before it is able to update its status. Until then,
&repmgrd; will be shown as not running.
</para>
</note>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
&repmgrd; running normally on all nodes:
<programlisting>$ repmgr -f /etc/repmgr.conf service status
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
1 | node1 | primary | * running | | running | 96563 | no | n/a
2 | node2 | standby | running | node1 | running | 96572 | no | 1 second(s) ago
3 | node3 | standby | running | node1 | running | 96584 | no | 0 second(s) ago</programlisting>
</para>
<para>
&repmgrd; paused on all nodes (using <xref linkend="repmgr-service-pause"/>):
<programlisting>$ repmgr -f /etc/repmgr.conf service status
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
1 | node1 | primary | * running | | running | 96563 | yes | n/a
2 | node2 | standby | running | node1 | running | 96572 | yes | 1 second(s) ago
3 | node3 | standby | running | node1 | running | 96584 | yes | 0 second(s) ago</programlisting>
</para>
<para>
&repmgrd; not running on one node:
<programlisting>$ repmgr -f /etc/repmgr.conf service status
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
----+-------+---------+-----------+----------+-------------+-------+---------+--------------------
1 | node1 | primary | * running | | running | 96563 | yes | n/a
2 | node2 | standby | running | node1 | not running | n/a | n/a | n/a
3 | node3 | standby | running | node1 | running | 96584 | yes | 0 second(s) ago</programlisting>
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--csv</option></term>
<listitem>
<para>
<command>repmgr service status</command> accepts an optional parameter <literal>--csv</literal>, which
outputs the replication cluster's status in a simple CSV format, suitable for
parsing by scripts, e.g.:
<programlisting>
$ repmgr -f /etc/repmgr.conf service status --csv
1,node1,primary,1,1,5722,1,100,-1,default
2,node2,standby,1,0,-1,1,100,1,default
3,node3,standby,1,1,5779,1,100,1,default</programlisting>
</para>
<para>
The columns have following meanings:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
node ID
</simpara>
</listitem>
<listitem>
<simpara>
node name
</simpara>
</listitem>
<listitem>
<simpara>
node type (primary or standby)
</simpara>
</listitem>
<listitem>
<simpara>
PostgreSQL server running (1 = running, 0 = not running)
</simpara>
</listitem>
<listitem>
<simpara>
&repmgrd; running (1 = running, 0 = not running, -1 = unknown)
</simpara>
</listitem>
<listitem>
<simpara>
&repmgrd; PID (-1 if not running or status unknown)
</simpara>
</listitem>
<listitem>
<simpara>
&repmgrd; paused (1 = paused, 0 = not paused, -1 = unknown)
</simpara>
</listitem>
<listitem>
<simpara>
&repmgrd; node priority
</simpara>
</listitem>
<listitem>
<simpara>
interval in seconds since the node's upstream was last seen (this will be -1 if the value could not be retrieved, or the node is primary)
</simpara>
</listitem>
<listitem>
<simpara>
node location
</simpara>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--detail</option></term>
<listitem>
<para>
Display additional information (<literal>location</literal>, <literal>priority</literal>)
about the &repmgr; configuration.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--verbose</option></term>
<listitem>
<para>
Display the full text of any database connection error messages.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-service-pause"/>,
<xref linkend="repmgr-service-unpause"/>,
<xref linkend="repmgr-cluster-show"/>,
<xref linkend="repmgrd-pausing"/>,
<xref linkend="repmgr-daemon-start"/>,
<xref linkend="repmgr-daemon-stop"/>
</para>
</refsect1>
</refentry>

View File

@@ -1,6 +1,6 @@
<refentry id="repmgr-daemon-unpause"> <refentry id="repmgr-service-unpause">
<indexterm> <indexterm>
<primary>repmgr daemon unpause</primary> <primary>repmgr service unpause</primary>
</indexterm> </indexterm>
<indexterm> <indexterm>
@@ -8,39 +8,47 @@
<secondary>unpausing</secondary> <secondary>unpausing</secondary>
</indexterm> </indexterm>
<refmeta> <refmeta>
<refentrytitle>repmgr daemon unpause</refentrytitle> <refentrytitle>repmgr service unpause</refentrytitle>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
<refname>repmgr daemon unpause</refname> <refname>repmgr service unpause</refname>
<refpurpose>Instruct all <application>repmgrd</application> instances in the replication cluster to resume failover operations</refpurpose> <refpurpose>Instruct all &repmgrd; instances in the replication cluster to resume failover operations</refpurpose>
</refnamediv> </refnamediv>
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para> <para>
This command can be run on any active node in the replication cluster to instruct all This command can be run on any active node in the replication cluster to instruct all
running <application>repmgrd</application> instances to &quot;unpause&quot; running &repmgrd; instances to &quot;unpause&quot;
(following a previous execution of <xref linkend="repmgr-daemon-pause">) (following a previous execution of <xref linkend="repmgr-service-pause"/>)
and resume normal failover/monitoring operation. and resume normal failover/monitoring operation.
</para> </para>
<note> <note>
<para> <para>
It's important to wait a few seconds after restarting PostgreSQL on any node before running It's important to wait a few seconds after restarting PostgreSQL on any node before running
<command>repmgr daemon pause</command>, as the <application>repmgrd</application> instance <command>repmgr service pause</command>, as the &repmgrd; instance
on the restarted node will take a second or two before it has updated its status. on the restarted node will take a second or two before it has updated its status.
</para> </para>
</note> </note>
</refsect1> </refsect1>
<refsect1>
<title>Prerequisites</title>
<para>
PostgreSQL must be accessible on all nodes (using the <varname>conninfo</varname> string shown by
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>)
from the node where <command>repmgr service pause</command> is executed.
</para>
</refsect1>
<refsect1> <refsect1>
<title>Execution</title> <title>Execution</title>
<para> <para>
<command>repmgr daemon unpause</command> can be executed on any active node in the <command>repmgr service unpause</command> can be executed on any active node in the
replication cluster. A valid <filename>repmgr.conf</filename> file is required. replication cluster. A valid <filename>repmgr.conf</filename> file is required.
It will have no effect on nodes which are not already paused. It will have no effect on nodes which are not already paused.
</para> </para>
@@ -50,7 +58,7 @@
<title>Example</title> <title>Example</title>
<para> <para>
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf daemon unpause $ repmgr -f /etc/repmgr.conf service unpause
NOTICE: node 1 (node1) unpaused NOTICE: node 1 (node1) unpaused
NOTICE: node 2 (node2) unpaused NOTICE: node 2 (node2) unpaused
NOTICE: node 3 (node3) unpaused</programlisting> NOTICE: node 3 (node3) unpaused</programlisting>
@@ -64,7 +72,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<term><option>--dry-run</option></term> <term><option>--dry-run</option></term>
<listitem> <listitem>
<para> <para>
Check if nodes are reachable but don't unpause <application>repmgrd</application>. Check if nodes are reachable but don't unpause &repmgrd;.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -74,7 +82,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<refsect1> <refsect1>
<title>Exit codes</title> <title>Exit codes</title>
<para> <para>
One of the following exit codes will be emitted by <command>repmgr daemon unpause</command>: One of the following exit codes will be emitted by <command>repmgr service unpause</command>:
</para> </para>
<variablelist> <variablelist>
@@ -82,7 +90,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<term><option>SUCCESS (0)</option></term> <term><option>SUCCESS (0)</option></term>
<listitem> <listitem>
<para> <para>
<application>repmgrd</application> could be unpaused on all nodes. &repmgrd; could be unpaused on all nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -91,7 +99,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<term><option>ERR_REPMGRD_PAUSE (26)</option></term> <term><option>ERR_REPMGRD_PAUSE (26)</option></term>
<listitem> <listitem>
<para> <para>
<application>repmgrd</application> could not be unpaused on one or mode nodes. &repmgrd; could not be unpaused on one or mode nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -102,7 +110,11 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-daemon-pause">, <xref linkend="repmgr-daemon-status"> <xref linkend="repmgr-service-pause"/>,
<xref linkend="repmgr-service-status"/>,
<xref linkend="repmgrd-pausing"/>,
<xref linkend="repmgr-daemon-start"/>,
<xref linkend="repmgr-daemon-stop"/>
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@@ -18,7 +18,7 @@
<para> <para>
<command>repmgr standby clone</command> clones a PostgreSQL node from another <command>repmgr standby clone</command> clones a PostgreSQL node from another
PostgreSQL node, typically the primary, but optionally from any other node in PostgreSQL node, typically the primary, but optionally from any other node in
the cluster or from Barman. It creates the <filename>recovery.conf</filename> file required the cluster or from Barman. It creates the replication configuration required
to attach the cloned node to the primary node (or another standby, if cascading replication to attach the cloned node to the primary node (or another standby, if cascading replication
is in use). is in use).
</para> </para>
@@ -85,27 +85,25 @@
</refsect1> </refsect1>
<refsect1 id="repmgr-standby-clone-recovery-conf"> <refsect1 id="repmgr-standby-clone-recovery-conf">
<indexterm> <title>Customising replication configuration</title>
<indexterm>
<primary>recovery.conf</primary> <primary>recovery.conf</primary>
<secondary>customising with &quot;repmgr standby clone&quot;</secondary> <secondary>customising with &quot;repmgr standby clone&quot;</secondary>
</indexterm> </indexterm>
<indexterm>
<primary>replication configuration</primary>
<secondary>customising with &quot;repmgr standby clone&quot;</secondary>
</indexterm>
<title>Customising recovery.conf</title>
<para> <para>
By default, &repmgr; will create a minimal <filename>recovery.conf</filename> By default, &repmgr; will create a minimal replication configuration
containing following parameters: containing following parameters:
</para> </para>
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara><varname>standby_mode</varname> (always <literal>'on'</literal>)</simpara>
</listitem>
<listitem>
<simpara><varname>recovery_target_timeline</varname> (always <literal>'latest'</literal>)</simpara>
</listitem>
<listitem> <listitem>
<simpara><varname>primary_conninfo</varname></simpara> <simpara><varname>primary_conninfo</varname></simpara>
</listitem> </listitem>
@@ -116,9 +114,24 @@
</itemizedlist> </itemizedlist>
<para>
For PostgreSQL 11 and earlier, these parameters will also be set:
</para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara><varname>standby_mode</varname> (always <literal>'on'</literal>)</simpara>
</listitem>
<listitem>
<simpara><varname>recovery_target_timeline</varname> (always <literal>'latest'</literal>)</simpara>
</listitem>
</itemizedlist>
<para> <para>
The following additional parameters can be specified in <filename>repmgr.conf</filename> The following additional parameters can be specified in <filename>repmgr.conf</filename>
for inclusion in <filename>recovery.conf</filename>: for inclusion in the replication configuration:
</para> </para>
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
@@ -142,7 +155,7 @@
We recommend using <ulink url="https://www.pgbarman.org/">Barman</ulink> to manage We recommend using <ulink url="https://www.pgbarman.org/">Barman</ulink> to manage
WAL file archiving. For more details on combining &repmgr; and <application>Barman</application>, WAL file archiving. For more details on combining &repmgr; and <application>Barman</application>,
in particular using <varname>restore_command</varname> to configure Barman as a backup source of in particular using <varname>restore_command</varname> to configure Barman as a backup source of
WAL files, see <xref linkend="cloning-from-barman">. WAL files, see <xref linkend="cloning-from-barman"/>.
</para> </para>
</note> </note>
@@ -154,7 +167,7 @@
When initially cloning a standby, you will need to ensure When initially cloning a standby, you will need to ensure
that all required WAL files remain available while the cloning is taking that all required WAL files remain available while the cloning is taking
place. To ensure this happens when using the default <command>pg_basebackup</command> method, place. To ensure this happens when using the default <command>pg_basebackup</command> method,
&repmgr; will set <command>pg_basebackup</command>'s <literal>--xlog-method</literal> &repmgr; will set <command>pg_basebackup</command>'s <literal>--wal-method</literal>
parameter to <literal>stream</literal>, parameter to <literal>stream</literal>,
which will ensure all WAL files generated during the cloning process are which will ensure all WAL files generated during the cloning process are
streamed in parallel with the main backup. Note that this requires two streamed in parallel with the main backup. Note that this requires two
@@ -164,64 +177,112 @@
</para> </para>
<para> <para>
To override this behaviour, in <filename>repmgr.conf</filename> set To override this behaviour, in <filename>repmgr.conf</filename> set
<command>pg_basebackup</command>'s <literal>--xlog-method</literal> <command>pg_basebackup</command>'s <literal>--wal-method</literal>
parameter to <literal>fetch</literal>: parameter to <literal>fetch</literal>:
<programlisting> <programlisting>
pg_basebackup_options='--xlog-method=fetch'</programlisting> pg_basebackup_options='--wal-method=fetch'</programlisting>
and ensure that <literal>wal_keep_segments</literal> is set to an appropriately high value. and ensure that <literal>wal_keep_segments</literal> (PostgreSQL 13 and later:
<literal>wal_keep_size</literal>) is set to an appropriately high value. Note
however that this is not a particularly reliable way of ensuring sufficient
WAL is retained and is not recommended.
See the <ulink url="https://www.postgresql.org/docs/current/app-pgbasebackup.html"> See the <ulink url="https://www.postgresql.org/docs/current/app-pgbasebackup.html">
pg_basebackup</ulink> documentation for details. pg_basebackup</ulink> documentation for details.
</para> </para>
<note> <note>
<simpara> <simpara>
From PostgreSQL 10, <command>pg_basebackup</command>'s If using PostgreSQL 9.6 or earlier, replace <literal>--wal-method</literal>
<literal>--xlog-method</literal> parameter has been renamed to with <literal>--xlog-method</literal>.
<literal>--wal-method</literal>.
</simpara> </simpara>
</note> </note>
</refsect1> </refsect1>
<refsect1 id="repmgr-standby-clone-wal-directory">
<title>Placing WAL files into a different directory</title>
<para>
To ensure that WAL files are placed in a directory outside of the main data
directory (e.g. to keep them on a separate disk for performance reasons),
specify the location with <option>--waldir</option>
(PostgreSQL 9.6 and earlier: <option>--xlogdir</option>) in
the <filename>repmgr.conf</filename> parameter <option>pg_basebackup_options</option>,
e.g.:
<programlisting>
pg_basebackup_options='--waldir=/path/to/wal-directory'</programlisting>
This setting will also be honored by &repmgr; when cloning from Barman
(&repmgr; 5.2 and later).
</para>
</refsect1>
<!-- don't rename this id as it may be used in external links -->
<refsect1 id="repmgr-standby-create-recovery-conf"> <refsect1 id="repmgr-standby-create-recovery-conf">
<title>Using a standby cloned by another method</title>
<indexterm>
<primary>replication configuration</primary>
<secondary>generating for a standby cloned by another method</secondary>
</indexterm>
<indexterm> <indexterm>
<primary>recovery.conf</primary> <primary>recovery.conf</primary>
<secondary>generating for a standby cloned by another method</secondary> <secondary>generating for a standby cloned by another method</secondary>
</indexterm> </indexterm>
<title>Using a standby cloned by another method</title>
<para> <para>
&repmgr; supports standbys cloned by another method (e.g. using <application>barman</application>'s &repmgr; supports standbys cloned by another method (e.g. using <application>barman</application>'s
<command><ulink url="http://docs.pgbarman.org/release/2.5/#recover">barman recover</ulink></command> command). <command><ulink url="https://docs.pgbarman.org/#recover">barman recover</ulink></command> command).
</para> </para>
<para> <para>
To integrate the standby as a &repmgr; node, once the standby has been cloned, To integrate the standby as a &repmgr; node, once the standby has been cloned,
ensure the <filename>repmgr.conf</filename> ensure the <filename>repmgr.conf</filename>
file is created for the node, and that it has been registered using file is created for the node, and that it has been registered using
<command><link linkend="repmgr-standby-register">repmgr standby register</link></command>. <command><link linkend="repmgr-standby-register">repmgr standby register</link></command>.
Then execute the command <command>repmgr standby clone --recovery-conf-only</command>. </para>
<tip>
<para>
To register a standby which is not running, execute
<link linkend="repmgr-standby-register">repmgr standby register --force</link>
and provide the connection details for the primary.
</para>
<para>
See <xref linkend="repmgr-standby-register-inactive-node"/> for more details.
</para>
</tip>
<para>
Then execute the command <command>repmgr standby clone --replication-conf-only</command>.
This will create the <filename>recovery.conf</filename> file needed to attach This will create the <filename>recovery.conf</filename> file needed to attach
the node to its upstream, and will also create a replication slot on the the node to its upstream (in PostgreSQL 12 and later: append replication configuration
to <filename>postgresql.auto.conf</filename>), and will also create a replication slot on the
upstream node if required. upstream node if required.
</para> </para>
<para> <para>
Note that the upstream node must be running. An existing The upstream node must be running so the correct replication configuration can be obtained.
<filename>recovery.conf</filename> will not be overwritten unless the
<option>-F/--force</option> option is provided.
</para> </para>
<para> <para>
Execute <command>repmgr standby clone --recovery-conf-only --dry-run</command> If the standby is running, the replication configuration will not be written unless the
to check the prerequisites for creating the <filename>recovery.conf</filename> file, <option>-F/--force</option> option is provided.
and display the contents of the file without actually creating it. </para>
<tip>
<para>
Execute <command>repmgr standby clone --replication-conf-only --dry-run</command>
to check the prerequisites for creating the recovery configuration,
and display the configuration changes which would be made without actually
making any changes.
</para>
</tip>
<para>
In PostgreSQL 13 and later, the PostgreSQL configuration must be reloaded for replication
configuration changes to take effect.
</para>
<para>
In PostgreSQL 12 and earlier, the PostgreSQL instance must be restarted for replication
configuration changes to take effect.
</para> </para>
<note>
<para>
<option>--recovery-conf-only</option> was introduced in &repmgr; <link linkend="release-4.0.4">4.0.4</link>.
</para>
</note>
</refsect1> </refsect1>
@@ -247,9 +308,9 @@
Check prerequisites but don't actually clone the standby. Check prerequisites but don't actually clone the standby.
</para> </para>
<para> <para>
If <option>--recovery-conf-only</option> specified, the contents of If <option>--replication-conf-only</option> specified, the contents of
the generated <filename>recovery.conf</filename> file will be displayed the generated recovery configuration will be displayed
but the file itself not written. but not written.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -271,6 +332,12 @@
node to the same path on the standby (default) or to the node to the same path on the standby (default) or to the
PostgreSQL data directory. PostgreSQL data directory.
</para> </para>
<para>
Note that to be able to use this option, the &repmgr; user must be a superuser or
member of the <literal>pg_read_all_settings</literal> predefined role.
If this is not the case, provide a valid superuser with the
<option>-S</option>/<option>--superuser</option> option.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -283,6 +350,25 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--recovery-min-apply-delay</option></term>
<listitem>
<para>
Set PostgreSQL configuration <option>recovery_min_apply_delay</option> parameter
to the provided value.
</para>
<para>
This overrides any <option>recovery_min_apply_delay</option> provided via
<filename>repmgr.conf</filename>.
</para>
<para>
For more details on this parameter, see:
<ulink url="https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-RECOVERY-MIN-APPLY-DELAY">recovery_min_apply_delay</ulink>.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>-R, --remote-user=USERNAME</option></term> <term><option>-R, --remote-user=USERNAME</option></term>
<listitem> <listitem>
@@ -293,11 +379,19 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option> --recovery-conf-only</option></term> <term><option>--replication-conf-only</option></term>
<listitem> <listitem>
<para> <para>
Create <filename>recovery.conf</filename> file for a previously cloned instance. &repmgr 4.0.4 and later. Create recovery configuration for a previously cloned instance.
</para> </para>
<para>
In PostgreSQL 12 and later, the replication configuration will be
written to <filename>postgresql.auto.conf</filename>.
</para>
<para>
In PostgreSQL 11 and earlier, the replication configuration will be
written to <filename>recovery.conf</filename>.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -311,11 +405,15 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>--superuser</option></term> <term><option>-S</option>/<option>--superuser</option></term>
<listitem> <listitem>
<para> <para>
If the &repmgr; user is not a superuser, the name of a valid superuser must The name of a valid PostgreSQL superuser can be provided with this option.
be provided with this option. </para>
<para>
This is only required if the <option>--copy-external-config-files</option> was provided
and the &repmgr; user is not a superuser or member of the <literal>pg_read_all_settings</literal>
predefined role.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -325,9 +423,13 @@
<term><option>--upstream-conninfo</option></term> <term><option>--upstream-conninfo</option></term>
<listitem> <listitem>
<para> <para>
<literal>primary_conninfo</literal> value to write in recovery.conf <literal>primary_conninfo</literal> value to include in the recovery configuration
when the intended upstream server does not yet exist. when the intended upstream server does not yet exist.
</para> </para>
<para>
Note that &repmgr; may modify the provided value, in particular to set the
correct <literal>application_name</literal>.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -339,6 +441,23 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--verify-backup</option></term>
<listitem>
<para>
<!-- update link after Pg13 release -->
Verify a cloned node using the
<ulink url="https://www.postgresql.org/docs/13/app-pgverifybackup.html">pg_verifybackup</ulink>
utility (PostgreSQL 13 and later).
</para>
<para>
This option can currently only be used when cloning directly from an upstream
node.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--without-barman </option></term> <term><option>--without-barman </option></term>
<listitem> <listitem>
@@ -361,7 +480,7 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
See <xref linkend="cloning-standbys"> for details about various aspects of cloning. See <xref linkend="cloning-standbys"/> for details about various aspects of cloning.
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@@ -20,49 +20,62 @@
(&quot;follow target&quot;). Typically this will be the primary, but this (&quot;follow target&quot;). Typically this will be the primary, but this
command can also be used to attach the standby to another standby. command can also be used to attach the standby to another standby.
</para> </para>
<para> <para>
This command requires a valid This command requires a valid <filename>repmgr.conf</filename> file for the standby,
<filename>repmgr.conf</filename> file for the standby, either specified either specified explicitly with <literal>-f/--config-file</literal> or located in a
explicitly with <literal>-f/--config-file</literal> or located in a
default location; no additional arguments are required. default location; no additional arguments are required.
</para> </para>
<para> <para>The standby node (&quot;follow candidate&quot;) <emphasis>must</emphasis>
By default &repmgr; will attempt to attach the standby to the current primary. be running. If the new upstream (&quot;follow target&quot;) is not the primary,
If <option>--upstream-node-id</option> is provided, &repmgr; will attempt the cluster primary <emphasis>must</emphasis> be running and accessible from the
to attach the standby to the specified node, which can be another standby. standby node.
</para>
<para>
This command will force a restart of the standby server, which must be
running.
</para> </para>
<tip> <tip>
<para> <para>
To re-add an inactive node to the replication cluster, use To re-add an inactive node to the replication cluster, use
<xref linkend="repmgr-node-rejoin">. <xref linkend="repmgr-node-rejoin"/>.
</para> </para>
</tip> </tip>
<para> <para>
<command>repmgr standby follow</command> will wait up to By default &repmgr; will attempt to attach the standby to the current primary.
<varname>standby_follow_timeout</varname> seconds (default: <literal>30</literal>) If <option>--upstream-node-id</option> is provided, &repmgr; will attempt
to verify the standby has actually connected to the new upstream node. to attach the standby to the specified node, which can be another standby.
</para> </para>
<note> <para>
<para> In PostgreSQL 12 and earlier, this command will force a restart of PostgreSQL on the standby node.
If <option>recovery_min_apply_delay</option> is set for the standby, it </para>
will not attach to the new upstream node until it has replayed available
WAL. <para>
</para> In PostgreSQL 13 and later, by default this command will signal PostgreSQL to reload its
<para> configuration, which will cause PostgreSQL to follow the new upstream without
Conversely, if the standby is attached to an upstream standby a restart. If this behaviour is not desired for whatever reason, the configuration
which has <option>recovery_min_apply_delay</option> set, the upstream file parameter <varname>standby_follow_restart</varname> can be set <literal>true</literal>
standby's replay state may actually be behind that of its new downstream node. to always force a restart.
</para> </para>
</note>
<para>
<command>repmgr standby follow</command> will wait up to
<varname>standby_follow_timeout</varname> seconds (default: <literal>30</literal>)
to verify the standby has actually connected to the new upstream node.
</para>
<note>
<para>
If <option>recovery_min_apply_delay</option> is set for the standby, it
will not attach to the new upstream node until it has replayed available
WAL.
</para>
<para>
Conversely, if the standby is attached to an upstream standby
which has <option>recovery_min_apply_delay</option> set, the upstream
standby's replay state may actually be behind that of its new downstream node.
</para>
</note>
</refsect1> </refsect1>
@@ -122,9 +135,9 @@
If not provided, &repmgr; will attempt to follow the current primary node. If not provided, &repmgr; will attempt to follow the current primary node.
</para> </para>
<para> <para>
Note that when using <application>repmgrd</application>, <option>--upstream-node-id</option> Note that when using &repmgrd;, <option>--upstream-node-id</option>
should always be configured; should always be configured;
see <link linkend="repmgrd-automatic-failover-configuration">Automatic failover configuration</link> see <link linkend="repmgrd-automatic-failover-configuration">Automatic failover configuration</link>
for details. for details.
</para> </para>
</listitem> </listitem>
@@ -166,7 +179,7 @@
be possible to follow the new upstream node, and &repmgr; will emit an error be possible to follow the new upstream node, and &repmgr; will emit an error
message like this: message like this:
<programlisting> <programlisting>
ERROR: this node cannot attach to follow target node 3 ERROR: this node cannot attach to follow target node &quot;node3&quot; (ID 3)
DETAIL: follow target server's timeline 2 forked off current database system timeline 1 before current recovery point 0/6108880</programlisting> DETAIL: follow target server's timeline 2 forked off current database system timeline 1 before current recovery point 0/6108880</programlisting>
</para> </para>
<para> <para>
@@ -252,7 +265,7 @@ DETAIL: follow target server's timeline 2 forked off current database system tim
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-node-rejoin"> <xref linkend="repmgr-node-rejoin"/>
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@@ -1,199 +0,0 @@
<refentry id="repmgr-standby-promote">
<indexterm>
<primary>repmgr standby promote</primary>
</indexterm>
<refmeta>
<refentrytitle>repmgr standby promote</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr standby promote</refname>
<refpurpose>promote a standby to a primary</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
Promotes a standby to a primary if the current primary has failed. This
command requires a valid <filename>repmgr.conf</filename> file for the standby, either
specified explicitly with <literal>-f/--config-file</literal> or located in a
default location; no additional arguments are required.
</para>
<para>
If the standby promotion succeeds, the server will not need to be
restarted. However any other standbys will need to follow the new server,
by using <xref linkend="repmgr-standby-follow">; if <application>repmgrd</application>
is active, it will handle this automatically.
</para>
<para>
Note that &repmgr; will wait for up to <varname>promote_check_timeout</varname> seconds
(default: 60 seconds) to verify that the standby has been promoted, and will
check the promotion every <varname>promote_check_interval</varname> seconds (default: 1 second).
Both values can be defined in <filename>repmgr.conf</filename>.
</para>
<note>
<para>
If WAL replay is paused on the standby, and not all WAL files on the standby have been
replayed, &repmgr; will not attempt to promote it.
</para>
<para>
This is because if WAL replay is paused, PostgreSQL itself will not react to a promote command
until WAL replay is resumed and all pending WAL has been replayed. This means
attempting to promote PostgreSQL in this state will leave PostgreSQL in a condition where the
promotion may occur at a unpredictable point in the future.
</para>
<para>
Note that if the standby is in archive recovery, &repmgr; will not be able to determine
if more WAL is pending replay, and will abort the promotion attempt if WAL replay is paused.
</para>
</note>
</refsect1>
<refsect1>
<title>Example</title>
<para>
<programlisting>
$ repmgr -f /etc/repmgr.conf standby promote
NOTICE: promoting standby to primary
DETAIL: promoting server "node2" (ID: 2) using "pg_ctl -l /var/log/postgres/startup.log -w -D '/var/lib/postgres/data' promote"
server promoting
DEBUG: setting node 2 as primary and marking existing primary as failed
NOTICE: STANDBY PROMOTE successful
DETAIL: server "node2" (ID: 2) was successfully promoted to primary</programlisting>
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--dry-run</option></term>
<listitem>
<para>
Check if this node can be promoted, but don't carry out the promotion
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Configuration file settings</title>
<para>
The following parameters in <filename>repmgr.conf</filename> are relevant to the
promote operation:
</para>
<para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<indexterm>
<primary>promote_check_interval</primary>
<secondary>with &quot;repmgr standby promote &quot;</secondary>
</indexterm>
<simpara>
<literal>promote_check_interval</literal>:
interval (in seconds, default: 1 second) to wait between each check
to determine whether the standby has been promoted.
</simpara>
</listitem>
<listitem>
<indexterm>
<primary>promote_check_timeout</primary>
<secondary>with &quot;repmgr standby promote &quot;</secondary>
</indexterm>
<simpara>
<literal>promote_check_timeout</literal>:
time (in seconds, default: 60 seconds) to wait to verify that the standby has been promoted
before exiting with <literal>ERR_PROMOTION_FAIL</literal>.
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title>Exit codes</title>
<para>
Following exit codes can be emitted by <command>repmgr standby promote</command>:
</para>
<variablelist>
<varlistentry>
<term><option>SUCCESS (0)</option></term>
<listitem>
<para>
The standby was successfully promoted to primary.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_DB_CONN (6)</option></term>
<listitem>
<para>
&repmgr; was unable to connect to the local PostgreSQL node.
</para>
<para>
PostgreSQL must be running before the node can be promoted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_PROMOTION_FAIL (8)</option></term>
<listitem>
<para>
The node could not be promoted to primary for one of the following
reasons:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
there is an existing primary node in the replication cluster
</simpara>
</listitem>
<listitem>
<simpara>
the node is not a standby
</simpara>
</listitem>
<listitem>
<simpara>
WAL replay is paused on the node
</simpara>
</listitem>
<listitem>
<simpara>
execution of the PostgreSQL promote command failed
</simpara>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="repmgr-standby-promote-events">
<title>Event notifications</title>
<para>
A <literal>standby_promote</literal> <link linkend="event-notifications">event notification</link> will be generated.
</para>
</refsect1>
</refentry>

View File

@@ -0,0 +1,345 @@
<refentry id="repmgr-standby-promote">
<indexterm>
<primary>repmgr standby promote</primary>
</indexterm>
<refmeta>
<refentrytitle>repmgr standby promote</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr standby promote</refname>
<refpurpose>promote a standby to a primary</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
Promotes a standby to a primary if the current primary has failed. This
command requires a valid <filename>repmgr.conf</filename> file for the standby, either
specified explicitly with <literal>-f/--config-file</literal> or located in a
default location; no additional arguments are required.
</para>
<important>
<para>
If &repmgrd; is active, you must execute
<command><link linkend="repmgr-service-pause">repmgr service pause</link></command>
(&repmgr; 4.2 - 4.4: <command><link linkend="repmgr-service-pause">repmgr service pause</link></command>)
to temporarily disable &repmgrd; while making any changes
to the replication cluster.
</para>
</important>
<para>
If the standby promotion succeeds, the server will not need to be
restarted. However any other standbys will need to follow the new primary,
and will need to be restarted to do this.
</para>
<para>
Beginning with <link linkend="release-4.4">repmgr 4.4</link>,
the option <option>--siblings-follow</option> can be used to have
all other standbys (and a witness server, if in use)
follow the new primary.
</para>
<note>
<para>
If using &repmgrd;, when invoking
<command>repmgr standby promote</command> (either directly via
the <option>promote_command</option>, or in a script called
via <option>promote_command</option>), <option>--siblings-follow</option>
<emphasis>must not</emphasis> be included as a
command line option for <command>repmgr standby promote</command>.
</para>
</note>
<para>
In <link linkend="release-4.3">repmgr 4.3</link> and earlier,
<command><link linkend="repmgr-standby-follow">repmgr standby follow</link></command>
must be executed on each standby individually.
</para>
<para>
&repmgr; will wait for up to <varname>promote_check_timeout</varname> seconds
(default: <literal>60</literal>) to verify that the standby has been promoted, and will
check the promotion every <varname>promote_check_interval</varname> seconds (default: 1 second).
Both values can be defined in <filename>repmgr.conf</filename>.
</para>
<warning>
<para>
In PostgreSQL 12 and earlier, if WAL replay is paused on the standby, and not all
WAL files on the standby have been replayed, &repmgr; will not attempt to promote it.
</para>
<para>
This is because if WAL replay is paused, PostgreSQL itself will not react to a promote command
until WAL replay is resumed and all pending WAL has been replayed. This means
attempting to promote PostgreSQL in this state will leave PostgreSQL in a condition where the
promotion may occur at a unpredictable point in the future.
</para>
<para>
Note that if the standby is in archive recovery, &repmgr; will not be able to determine
if more WAL is pending replay, and will abort the promotion attempt if WAL replay is paused.
</para>
<para>
This restriction does <emphasis>not</emphasis> apply to PostgreSQL 13 and later.
</para>
</warning>
</refsect1>
<refsect1>
<title>Example</title>
<para>
<programlisting>
$ repmgr -f /etc/repmgr.conf standby promote
NOTICE: promoting standby to primary
DETAIL: promoting server "node2" (ID: 2) using "pg_ctl -l /var/log/postgres/startup.log -w -D '/var/lib/postgres/data' promote"
server promoting
NOTICE: STANDBY PROMOTE successful
DETAIL: server "node2" (ID: 2) was successfully promoted to primary</programlisting>
</para>
</refsect1>
<refsect1>
<title>User permission requirements</title>
<para><emphasis>pg_promote() (PostgreSQL 12 and later)</emphasis></para>
<para>
From PostgreSQL 12, &repmgr; will attempt to use the built-in <function>pg_promote()</function>
function to promote a standby to primary.
</para>
<para>
By default, execution of <function>pg_promote()</function> is restricted to superusers.
If the <literal>repmgr</literal> user does not have permission to execute
<function>pg_promote()</function>, &repmgr; will fall back to using &quot;<command>pg_ctl promote</command>&quot;.
</para>
<tip>
<para>
Execute <command>repmgr standby promote</command> with the <option>--dry-run</option>
to check whether the &repmgr; user has permission to execute <function>pg_promote()</function>.
</para>
<para>
If the <literal>repmgr</literal> user is not a superuser, execution permission for this
function can be granted with e.g.:
<programlisting>
GRANT EXECUTE ON FUNCTION pg_catalog.pg_promote TO repmgr</programlisting>
</para>
<para>
Note that permissions are only effective for the database they are granted in, so
this <emphasis>must</emphasis> be executed in the &repmgr; database to be effective.
</para>
</tip>
<para>
For more details on <function>pg_promote()</function>, see the
<ulink url="https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-RECOVERY-CONTROL-TABLE">PostgreSQL documentation</ulink>.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--dry-run</option></term>
<listitem>
<para>
Check if this node can be promoted, but don't carry out the promotion.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--siblings-follow</option></term>
<listitem>
<para>
Have all sibling nodes (nodes formerly attached to the same upstream
node as the promotion candidate) follow this node after it has been promoted.
</para>
<para>
Note that a witness server, if in use, is also
counted as a &quot;sibling node&quot; as it needs to be instructed to
synchronise its metadata with the new primary.
</para>
<important>
<para>
Do <emphasis>not</emphasis> provide this option when configuring
&repmgrd;'s <option>promote_command</option>.
</para>
</important>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-F</option></term>
<term><option>--force</option></term>
<listitem>
<para>
Ignore warnings and continue anyway.
</para>
<para>
This option is relevant in the following situations if <option>--siblings-follow</option> was specified:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
If one or more sibling nodes was not reachable via SSH, the standby will be promoted anyway.
</simpara>
</listitem>
<listitem>
<simpara>
If the promotion candidate has insufficient free walsenders to accommodate the standbys which will
be attached to it, the standby will be promoted anyway.
</simpara>
</listitem>
<listitem>
<simpara>
If replication slots are in use but the promotion candidate has insufficient free replication slots
to accommodate the standbys which will be attached to it, the standby will be promoted anyway.
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
Note that if the <option>-F</option>/<option>--force</option> option is used when any of the above
situations is encountered, the onus is on the user to manually resolve any resulting issues.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Configuration file settings</title>
<para>
The following parameters in <filename>repmgr.conf</filename> are relevant to the
promote operation:
</para>
<para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<indexterm>
<primary>promote_check_interval</primary>
<secondary>with &quot;repmgr standby promote &quot;</secondary>
</indexterm>
<simpara>
<literal>promote_check_interval</literal>:
interval (in seconds, default: 1 second) to wait between each check
to determine whether the standby has been promoted.
</simpara>
</listitem>
<listitem>
<indexterm>
<primary>promote_check_timeout</primary>
<secondary>with &quot;repmgr standby promote &quot;</secondary>
</indexterm>
<simpara>
<literal>promote_check_timeout</literal>:
time (in seconds, default: 60 seconds) to wait to verify that the standby has been promoted
before exiting with <literal>ERR_PROMOTION_FAIL</literal>.
</simpara>
</listitem>
<listitem>
<indexterm>
<primary>service_promote_command</primary>
<secondary>with &quot;repmgr standby promote &quot;</secondary>
</indexterm>
<simpara>
<literal>service_promote_command</literal>:
a command which will be executed instead of <command>pg_ctl promote</command>
or (in PostgreSQL 12 and later) <function>pg_promote()</function>.
</simpara>
<simpara>
This is intended for systems which provide a package-level promote command,
such as Debian's <application>pg_ctlcluster</application>, to promote the
PostgreSQL from standby to primary.
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title>Exit codes</title>
<para>
Following exit codes can be emitted by <command>repmgr standby promote</command>:
</para>
<variablelist>
<varlistentry>
<term><option>SUCCESS (0)</option></term>
<listitem>
<para>
The standby was successfully promoted to primary.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_DB_CONN (6)</option></term>
<listitem>
<para>
&repmgr; was unable to connect to the local PostgreSQL node.
</para>
<para>
PostgreSQL must be running before the node can be promoted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_PROMOTION_FAIL (8)</option></term>
<listitem>
<para>
The node could not be promoted to primary for one of the following
reasons:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
there is an existing primary node in the replication cluster
</simpara>
</listitem>
<listitem>
<simpara>
the node is not a standby
</simpara>
</listitem>
<listitem>
<simpara>
WAL replay is paused on the node
</simpara>
</listitem>
<listitem>
<simpara>
execution of the PostgreSQL promote command failed
</simpara>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="repmgr-standby-promote-events">
<title>Event notifications</title>
<para>
A <literal>standby_promote</literal> <link linkend="event-notifications">event notification</link> will be generated.
</para>
</refsect1>
</refentry>

View File

@@ -17,7 +17,7 @@
<para> <para>
<command>repmgr standby register</command> adds a standby's information to <command>repmgr standby register</command> adds a standby's information to
the &repmgr; metadata. This command needs to be executed to enable the &repmgr; metadata. This command needs to be executed to enable
promote/follow operations and to allow <application>repmgrd</application> to work with the node. promote/follow operations and to allow &repmgrd; to work with the node.
An existing standby can be registered using this command. Execute with the An existing standby can be registered using this command. Execute with the
<literal>--dry-run</literal> option to check what would happen without actually registering the <literal>--dry-run</literal> option to check what would happen without actually registering the
standby. standby.
@@ -28,7 +28,7 @@
If providing the configuration file location with <literal>-f/--config-file</literal>, If providing the configuration file location with <literal>-f/--config-file</literal>,
avoid using a relative path, as &repmgr; stores the configuration file location avoid using a relative path, as &repmgr; stores the configuration file location
in the repmgr metadata for use when &repmgr; is executed remotely (e.g. during in the repmgr metadata for use when &repmgr; is executed remotely (e.g. during
<xref linkend="repmgr-standby-switchover">). &repmgr; will attempt to convert the <xref linkend="repmgr-standby-switchover"/>). &repmgr; will attempt to convert the
a relative path into an absolute one, but this may not be the same as the path you a relative path into an absolute one, but this may not be the same as the path you
would explicitly provide (e.g. <filename>./repmgr.conf</filename> might be converted would explicitly provide (e.g. <filename>./repmgr.conf</filename> might be converted
to <filename>/path/to/./repmgr.conf</filename>, whereas you'd normally write to <filename>/path/to/./repmgr.conf</filename>, whereas you'd normally write
@@ -59,7 +59,7 @@
<para> <para>
Depending on your environment and workload, it may take some time for the standby's node record Depending on your environment and workload, it may take some time for the standby's node record
to propagate from the primary to the standby. Some actions (such as starting to propagate from the primary to the standby. Some actions (such as starting
<application>repmgrd</application>) require that the standby's node record &repmgrd;) require that the standby's node record
is present and up-to-date to function correctly. is present and up-to-date to function correctly.
</para> </para>
<para> <para>
@@ -75,10 +75,22 @@
<para> <para>
Under some circumstances you may wish to register a standby which is not Under some circumstances you may wish to register a standby which is not
yet running; this can be the case when using provisioning tools to create yet running; this can be the case when using provisioning tools to create
a complex replication cluster. In this case, by using the <option>-F/--force</option> a complex replication cluster, or if the node was not cloned by &repmgr;.
option and providing the connection parameters to the primary server,
the standby can be registered.
</para> </para>
<para>
In this case, by using the <option>-F/--force</option>
option and providing the connection parameters to the primary server,
the standby can be registered even if it has not yet been started.
</para>
<tip>
<para>
Connection parameters can either be provided either as a <literal>conninfo</literal> string
(e.g. <option>-d 'host=node1 user=repmgr'</option> or as individual connection parameters
(<option>-h/--host</option>, <option>-d/--dbname</option>,
<option>-U/--user</option>, <option>-p/--port</option> etc.).
</para>
</tip>
<para> <para>
Similarly, with cascading replication it may be necessary to register Similarly, with cascading replication it may be necessary to register
a standby whose upstream node has not yet been registered - in this case, a standby whose upstream node has not yet been registered - in this case,
@@ -96,9 +108,11 @@
<title>Registering a node not cloned by repmgr</title> <title>Registering a node not cloned by repmgr</title>
<para> <para>
If you've cloned a standby using another method (e.g. <application>barman</application>'s If you've cloned a standby using another method (e.g. <application>barman</application>'s
<command>barman recover</command> command), first execute <command><ulink url="https://docs.pgbarman.org/#recover">barman recover</ulink></command>
<link linkend="repmgr-standby-create-recovery-conf">repmgr standby clone --recovery-conf-only</link> command), register the node as detailed in section
to add the <filename>recovery.conf</filename> file, then register the standby as usual. <xref linkend="repmgr-standby-register-inactive-node"/> then execute
<link linkend="repmgr-standby-create-recovery-conf">repmgr standby clone --replication-conf-only</link>
to generate the appropriate replication configuration.
</para> </para>
</refsect1> </refsect1>
@@ -119,7 +133,7 @@
<varlistentry> <varlistentry>
<term><option>-F</option><option>--force</option></term> <term><option>-F</option>/<option>--force</option></term>
<listitem> <listitem>
<para> <para>
Overwrite an existing node record Overwrite an existing node record

View File

@@ -26,7 +26,9 @@
these to follow the new primary if the option <literal>--siblings-follow</literal> these to follow the new primary if the option <literal>--siblings-follow</literal>
is specified. This requires a passwordless SSH connection between the promotion is specified. This requires a passwordless SSH connection between the promotion
candidate (new primary) and the nodes attached to the demotion candidate candidate (new primary) and the nodes attached to the demotion candidate
(existing primary). (existing primary). Note that a witness server, if in use, is also
counted as a &quot;sibling node&quot; as it needs to be instructed to
synchronise its metadata with the new primary.
</para> </para>
<note> <note>
<para> <para>
@@ -42,18 +44,18 @@
</note> </note>
<para> <para>
For more details on performing a switchover, including preparation and configuration, For more details on performing a switchover, including preparation and configuration,
see section <xref linkend="performing-switchover">. see section <xref linkend="performing-switchover"/>.
</para> </para>
<note> <note>
<para> <para>
From <link linkend="release-4.2">repmgr 4.2</link>, &repmgr; will instruct any running From <link linkend="release-4.2">repmgr 4.2</link>, &repmgr; will instruct any running
<application>repmgrd</application> instances to pause operations while the switchover &repmgrd; instances to pause operations while the switchover
is being carried out, to prevent <application>repmgrd</application> from is being carried out, to prevent &repmgrd; from
unintentionally promoting a node. For more details, see <xref linkend="repmgrd-pausing">. unintentionally promoting a node. For more details, see <xref linkend="repmgrd-pausing"/>.
</para> </para>
<para> <para>
Users of &repmgr; versions prior to 4.2 should ensure that <application>repmgrd</application> Users of &repmgr; versions prior to 4.2 should ensure that &repmgrd;
is not running on any nodes while a switchover is being executed. is not running on any nodes while a switchover is being executed.
</para> </para>
</note> </note>
@@ -61,6 +63,45 @@
</refsect1> </refsect1>
<refsect1> <refsect1>
<title>User permission requirements</title>
<para><emphasis>data_directory</emphasis></para>
<para>
&repmgr; needs to be able to determine the location of the data directory on the
demotion candidate. If the &repmgr; is not a superuser or member of the <varname>pg_read_all_settings</varname>
<ulink url="https://www.postgresql.org/docs/current/predefined-roles.html">predefined roles</ulink>,
the name of a superuser should be provided with the <option>-S</option>/<option>--superuser</option> option.
</para>
<para><emphasis>CHECKPOINT</emphasis></para>
<para>
&repmgr; executes <command>CHECKPOINT</command> on the demotion candidate as part of the shutdown
process to ensure it shuts down as smoothly as possible.
</para>
<para>
Note that <command>CHECKPOINT</command> requires database superuser permissions to execute.
If the <literal>repmgr</literal> user is not a superuser, the name of a superuser should be
provided with the <option>-S</option>/<option>--superuser</option> option.
</para>
<para>
If &repmgr; is unable to execute the <command>CHECKPOINT</command> command, the switchover
can still be carried out, albeit at a greater risk that the demotion candidate may not
be able to shut down as smoothly as might otherwise have been the case.
</para>
<para><emphasis>pg_promote() (PostgreSQL 12 and later)</emphasis></para>
<para>
From PostgreSQL 12, &repmgr; defaults to using the built-in <command>pg_promote()</command> function to
promote a standby to primary.
</para>
<para>
Note that execution of <function>pg_promote()</function> is restricted to superusers or to
any user who has been granted execution permission for this function. If the &repmgr; user
is not permitted to execute <function>pg_promote()</function>, &repmgr; will fall back to using
&quot;<command>pg_ctl promote</command>&quot;. For more details see
<link linkend="repmgr-standby-promote">repmgr standby promote</link>.
</para>
</refsect1>
<refsect1>
<title>Options</title> <title>Options</title>
<variablelist> <variablelist>
@@ -113,9 +154,12 @@
<para> <para>
Use <application>pg_rewind</application> to reintegrate the old primary if necessary Use <application>pg_rewind</application> to reintegrate the old primary if necessary
(and the prerequisites for using <application>pg_rewind</application> are met). (and the prerequisites for using <application>pg_rewind</application> are met).
If using PostgreSQL 9.3 or 9.4, and the <application>pg_rewind</application> </para>
<para>
If using PostgreSQL 9.4, and the <application>pg_rewind</application>
binary is not installed in the PostgreSQL <filename>bin</filename> directory, binary is not installed in the PostgreSQL <filename>bin</filename> directory,
provide its full path. For more details see also <xref linkend="switchover-pg-rewind">. provide its full path. For more details see also <xref linkend="switchover-pg-rewind"/>
and <xref linkend="repmgr-node-rejoin-pg-rewind"/>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -134,12 +178,30 @@
<term><option>--repmgrd-no-pause</option></term> <term><option>--repmgrd-no-pause</option></term>
<listitem> <listitem>
<para> <para>
Don't pause <application>repmgrd</application> while executing a switchover. Don't pause &repmgrd; while executing a switchover.
</para> </para>
<para> <para>
This option should not be used unless you take steps by other means This option should not be used unless you take steps by other means
to ensure <application>repmgrd</application> is paused or not to ensure &repmgrd; is paused or not
running on all nodes. running on all nodes.
</para>
<para>
This option cannot be used together with <option>--repmgrd-force-unpause</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--repmgrd-force-unpause</option></term>
<listitem>
<para>
Always unpause all &repmgrd; instances after executing a switchover. This will ensure that
any &repmgrd; instances which were paused before the switchover will be
unpaused.
</para>
<para>
This option cannot be used together with <option>--repmgrd-no-pause</option>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -164,6 +226,17 @@
</note> </note>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>-S</option>/<option>--superuser</option></term>
<listitem>
<para>
Use the named superuser instead of the normal &repmgr; user to perform
actions requiring superuser permissions.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
@@ -179,13 +252,14 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<indexterm>
<primary>replication_lag_critical</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<term><option>replication_lag_critical</option></term> <term><option>replication_lag_critical</option></term>
<listitem> <listitem>
<indexterm>
<primary>replication_lag_critical</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para> <para>
If replication lag (in seconds) on the standby exceeds this value, the If replication lag (in seconds) on the standby exceeds this value, the
switchover will be aborted (unless the <literal>-F/--force</literal> option switchover will be aborted (unless the <literal>-F/--force</literal> option
@@ -195,13 +269,14 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<indexterm>
<primary>shutdown_check_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<term><option>shutdown_check_timeout</option></term> <term><option>shutdown_check_timeout</option></term>
<listitem> <listitem>
<indexterm>
<primary>shutdown_check_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para> <para>
The maximum number of seconds to wait for the The maximum number of seconds to wait for the
demotion candidate (current primary) to shut down, before aborting the switchover. demotion candidate (current primary) to shut down, before aborting the switchover.
@@ -223,13 +298,13 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>wal_receive_check_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<term><option>wal_receive_check_timeout</option></term> <term><option>wal_receive_check_timeout</option></term>
<listitem> <listitem>
<indexterm>
<primary>wal_receive_check_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para> <para>
After the primary has shut down, the maximum number of seconds to wait for the After the primary has shut down, the maximum number of seconds to wait for the
walreceiver on the standby to flush WAL to disk before comparing WAL receive location walreceiver on the standby to flush WAL to disk before comparing WAL receive location
@@ -240,13 +315,14 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>standby_reconnect_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<term><option>standby_reconnect_timeout</option></term> <term><option>standby_reconnect_timeout</option></term>
<listitem> <listitem>
<indexterm>
<primary>standby_reconnect_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para> <para>
The maximum number of seconds to attempt to wait for the demotion candidate (former primary) The maximum number of seconds to attempt to wait for the demotion candidate (former primary)
to reconnect to the promoted primary (default: 60 seconds) to reconnect to the promoted primary (default: 60 seconds)
@@ -259,14 +335,16 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<indexterm>
<primary>node_rejoin_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<term><option>node_rejoin_timeout</option></term> <term><option>node_rejoin_timeout</option></term>
<listitem> <listitem>
<indexterm>
<primary>node_rejoin_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para> <para>
maximum number of seconds to attempt to wait for the demotion candidate (former primary) maximum number of seconds to attempt to wait for the demotion candidate (former primary)
to reconnect to the promoted primary (default: 60 seconds) to reconnect to the promoted primary (default: 60 seconds)
@@ -360,10 +438,10 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-standby-follow">, <xref linkend="repmgr-node-rejoin"> <xref linkend="repmgr-standby-follow"/>, <xref linkend="repmgr-node-rejoin"/>
</para> </para>
<para> <para>
For more details on performing a switchover operation, see the section <xref linkend="performing-switchover">. For more details on performing a switchover operation, see the section <xref linkend="performing-switchover"/>.
</para> </para>
</refsect1> </refsect1>

View File

@@ -20,7 +20,7 @@
record to the &repmgr; metadata, and if necessary initialises the witness record to the &repmgr; metadata, and if necessary initialises the witness
node by installing the &repmgr; extension and copying the &repmgr; metadata node by installing the &repmgr; extension and copying the &repmgr; metadata
to the witness server. This command needs to be executed to enable to the witness server. This command needs to be executed to enable
use of the witness server with <application>repmgrd</application>. use of the witness server with &repmgrd;.
</para> </para>
<para> <para>
When executing <command>repmgr witness register</command>, database connection When executing <command>repmgr witness register</command>, database connection
@@ -63,6 +63,34 @@
</refsect1> </refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--dry-run</option></term>
<listitem>
<para>
Check prerequisites but don't actually register the witness
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-F</option>/<option>--force</option></term>
<listitem>
<para>
Overwrite an existing node record
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="repmgr-witness-register-events"> <refsect1 id="repmgr-witness-register-events">
<title>Event notifications</title> <title>Event notifications</title>
<para> <para>

View File

@@ -1,11 +1,12 @@
<!-- doc/src/sgml/postgres.sgml --> <!-- doc/repmgr.xml -->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [ <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
<!ENTITY % version SYSTEM "version.sgml"> [
<!ENTITY % version SYSTEM "version.xml">
%version; %version;
<!ENTITY % filelist SYSTEM "filelist.sgml"> <!ENTITY % filelist SYSTEM "filelist.xml">
%filelist; %filelist;
<!ENTITY repmgr "<productname>repmgr</productname>"> <!ENTITY repmgr "<productname>repmgr</productname>">
@@ -17,7 +18,7 @@
<title>repmgr &repmgrversion; Documentation</title> <title>repmgr &repmgrversion; Documentation</title>
<bookinfo> <bookinfo>
<corpauthor>2ndQuadrant Ltd</corpauthor> <corpauthor>EDB</corpauthor>
<productname>repmgr</productname> <productname>repmgr</productname>
<productnumber>&repmgrversion;</productnumber> <productnumber>&repmgrversion;</productnumber>
&legal; &legal;
@@ -25,7 +26,7 @@
<abstract> <abstract>
<para> <para>
This is the official documentation of &repmgr; &repmgrversion; for This is the official documentation of &repmgr; &repmgrversion; for
use with PostgreSQL 9.3 - PostgreSQL 11. use with PostgreSQL 9.4 - PostgreSQL 15.
</para> </para>
<para> <para>
&repmgr; is being continually developed and we strongly recommend using the &repmgr; is being continually developed and we strongly recommend using the
@@ -37,20 +38,19 @@
<para> <para>
&repmgr; is developed by &repmgr; is developed by
<ulink url="https://2ndquadrant.com">2ndQuadrant</ulink> <ulink url="https://www.enterprisedb.com/">EDB</ulink>
along with contributions from other individuals and companies. along with contributions from other individuals and organisations.
Contributions from the community are appreciated and welcome - get Contributions from the community are appreciated and welcome - get
in touch via <ulink url="https://github.com/2ndQuadrant/repmgr">github</ulink> in touch via <ulink url="https://github.com/EnterpriseDB/repmgr">github</ulink>
or <ulink url="https://groups.google.com/group/repmgr">the mailing list/forum</ulink>. or <ulink url="https://groups.google.com/group/repmgr">the mailing list/forum</ulink>.
Multiple 2ndQuadrant customers contribute funding Multiple EDB customers contribute funding to make &repmgr; development possible.
to make repmgr development possible.
</para> </para>
<para> <para>
&repmgr; is fully supported by 2ndQuadrant's &repmgr; is fully supported by EDB's
<ulink url="https://www.2ndquadrant.com/en/support/support-postgresql/">24/7 Production Support</ulink>. <ulink url="https://www.enterprisedb.com/support/postgresql-support-overview-get-the-most-out-of-postgresql">24/7 Production Support</ulink>.
2ndQuadrant, a Major Sponsor of the PostgreSQL project, continues to develop and maintain &repmgr;. EDB, a Major Sponsor of the PostgreSQL project, continues to maintain &repmgr;.
Other companies as well as individual developers are welcome to participate in the efforts. We welcome participation from other organisations and individual developers.
</para> </para>
</abstract> </abstract>
@@ -90,7 +90,6 @@
&repmgrd-automatic-failover; &repmgrd-automatic-failover;
&repmgrd-configuration; &repmgrd-configuration;
&repmgrd-operation; &repmgrd-operation;
&repmgrd-bdr;
</part> </part>
<part id="repmgr-command-reference"> <part id="repmgr-command-reference">
@@ -115,11 +114,11 @@
&repmgr-cluster-crosscheck; &repmgr-cluster-crosscheck;
&repmgr-cluster-event; &repmgr-cluster-event;
&repmgr-cluster-cleanup; &repmgr-cluster-cleanup;
&repmgr-daemon-status; &repmgr-service-status;
&repmgr-service-pause;
&repmgr-service-unpause;
&repmgr-daemon-start; &repmgr-daemon-start;
&repmgr-daemon-stop; &repmgr-daemon-stop;
&repmgr-daemon-pause;
&repmgr-daemon-unpause;
</part> </part>
&appendix-release-notes; &appendix-release-notes;
@@ -128,7 +127,6 @@
&appendix-packages; &appendix-packages;
&appendix-support; &appendix-support;
<![%include-index;[&bookindex;]]> <index id="bookindex"></index>
<![%include-xslt-index;[<index id="bookindex"></index>]]>
</book> </book>

View File

@@ -1,297 +0,0 @@
<chapter id="repmgrd-automatic-failover" xreflabel="Automatic failover with repmgrd">
<indexterm>
<primary>repmgrd</primary>
<secondary>automatic failover</secondary>
</indexterm>
<title>Automatic failover with repmgrd</title>
<para>
<application>repmgrd</application> is a management and monitoring daemon which runs
on each node in a replication cluster. It can automate actions such as
failover and updating standbys to follow the new primary, as well as
providing monitoring information about the state of each standby.
</para>
<sect1 id="repmgrd-witness-server" xreflabel="Using a witness server with repmgrd">
<indexterm>
<primary>repmgrd</primary>
<secondary>witness server</secondary>
</indexterm>
<indexterm>
<primary>witness server</primary>
<secondary>repmgrd</secondary>
</indexterm>
<title>Using a witness server</title>
<para>
A <xref linkend="witness-server"> is a normal PostgreSQL instance which
is not part of the streaming replication cluster; its purpose is, if a
failover situation occurs, to provide proof that it is the primary server
itself which is unavailable, rather than e.g. a network split between
different physical locations.
</para>
<para>
A typical use case for a witness server is a two-node streaming replication
setup, where the primary and standby are in different locations (data centres).
By creating a witness server in the same location (data centre) as the primary,
if the primary becomes unavailable it's possible for the standby to decide whether
it can promote itself without risking a "split brain" scenario: if it can't see either the
witness or the primary server, it's likely there's a network-level interruption
and it should not promote itself. If it can see the witness but not the primary,
this proves there is no network interruption and the primary itself is unavailable,
and it can therefore promote itself (and ideally take action to fence the
former primary).
</para>
<note>
<para>
<emphasis>Never</emphasis> install a witness server on the same physical host
as another node in the replication cluster managed by &repmgr; - it's essential
the witness is not affected in any way by failure of another node.
</para>
</note>
<para>
For more complex replication scenarios,e.g. with multiple datacentres, it may
be preferable to use location-based failover, which ensures that only nodes
in the same location as the primary will ever be promotion candidates;
see <xref linkend="repmgrd-network-split"> for more details.
</para>
<note>
<simpara>
A witness server will only be useful if <application>repmgrd</application>
is in use.
</simpara>
</note>
<sect2 id="creating-witness-server">
<title>Creating a witness server</title>
<para>
To create a witness server, set up a normal PostgreSQL instance on a server
in the same physical location as the cluster's primary server.
</para>
<para>
This instance should <emphasis>not</emphasis> be on the same physical host as the primary server,
as otherwise if the primary server fails due to hardware issues, the witness
server will be lost too.
</para>
<note>
<simpara>
&repmgr; 3.3 and earlier provided a <command>repmgr create witness</command>
command, which would automatically create a PostgreSQL instance. However
this often resulted in an unsatisfactory, hard-to-customise instance.
</simpara>
</note>
<para>
The witness server should be configured in the same way as a normal
&repmgr; node; see section <xref linkend="configuration">.
</para>
<para>
Register the witness server with <xref linkend="repmgr-witness-register">.
This will create the &repmgr; extension on the witness server, and make
a copy of the &repmgr; metadata.
</para>
<note>
<simpara>
As the witness server is not part of the replication cluster, further
changes to the &repmgr; metadata will be synchronised by
<application>repmgrd</application>.
</simpara>
</note>
<para>
Once the witness server has been configured, <application>repmgrd</application>
should be started.
</para>
<para>
To unregister a witness server, use <xref linkend="repmgr-witness-unregister">.
</para>
</sect2>
</sect1>
<sect1 id="repmgrd-network-split" xreflabel="Handling network splits with repmgrd">
<indexterm>
<primary>repmgrd</primary>
<secondary>network splits</secondary>
</indexterm>
<indexterm>
<primary>network splits</primary>
</indexterm>
<title>Handling network splits with repmgrd</title>
<para>
A common pattern for replication cluster setups is to spread servers over
more than one datacentre. This can provide benefits such as geographically-
distributed read replicas and DR (disaster recovery capability). However
this also means there is a risk of disconnection at network level between
datacentre locations, which would result in a split-brain scenario if
servers in a secondary data centre were no longer able to see the primary
in the main data centre and promoted a standby among themselves.
</para>
<para>
&repmgr; enables provision of &quot;<xref linkend="witness-server">&quot; to
artificially create a quorum of servers in a particular location, ensuring
that nodes in another location will not elect a new primary if they
are unable to see the majority of nodes. However this approach does not
scale well, particularly with more complex replication setups, e.g.
where the majority of nodes are located outside of the primary datacentre.
It also means the <literal>witness</literal> node needs to be managed as an
extra PostgreSQL instance outside of the main replication cluster, which
adds administrative and programming complexity.
</para>
<para>
<literal>repmgr4</literal> introduces the concept of <literal>location</literal>:
each node is associated with an arbitrary location string (default is
<literal>default</literal>); this is set in <filename>repmgr.conf</filename>, e.g.:
<programlisting>
node_id=1
node_name=node1
conninfo='host=node1 user=repmgr dbname=repmgr connect_timeout=2'
data_directory='/var/lib/postgresql/data'
location='dc1'</programlisting>
</para>
<para>
In a failover situation, <application>repmgrd</application> will check if any servers in the
same location as the current primary node are visible. If not, <application>repmgrd</application>
will assume a network interruption and not promote any node in any
other location (it will however enter <link linkend="repmgrd-degraded-monitoring">degraded monitoring</link>
mode until a primary becomes visible).
</para>
</sect1>
<sect1 id="repmgrd-standby-disconnection-on-failover" xreflabel="Standby disconnection on failover">
<indexterm>
<primary>repmgrd</primary>
<secondary>standby disconnection on failover</secondary>
</indexterm>
<indexterm>
<primary>standby disconnection on failover</primary>
</indexterm>
<title>Standby disconnection on failover</title>
<para>
If <option>standby_disconnect_on_failover</option> is set to <literal>true</literal> in
<filename>repmgr.conf</filename>, in a failover situation <application>repmgrd</application> will forcibly disconnect
the local node's WAL receiver before making a failover decision.
</para>
<note>
<para>
<option>standby_disconnect_on_failover</option> is available from PostgreSQL 9.5 and later.
Additionally this requires that the <literal>repmgr</literal> database user is a superuser.
</para>
</note>
<para>
By doing this, it's possible to ensure that, at the point the failover decision is made, no nodes
are receiving data from the primary and their LSN location will be static.
</para>
<important>
<para>
<option>standby_disconnect_on_failover</option> <emphasis>must</emphasis> be set to the same value on
all nodes.
</para>
</important>
<para>
Note that when using <option>standby_disconnect_on_failover</option> there will be a delay of 5 seconds
plus however many seconds it takes to confirm the WAL receiver is disconnected before
<application>repmgrd</application> proceeds with the failover decision.
</para>
<para>
Following the failover operation, no matter what the outcome, each node will reconnect its WAL receiver.
</para>
</sect1>
<sect1 id="repmgrd-failover-validation" xreflabel="Failover validation">
<indexterm>
<primary>repmgrd</primary>
<secondary>failover validation</secondary>
</indexterm>
<indexterm>
<primary>failover validation</primary>
</indexterm>
<title>Failover validation</title>
<para>
From <link linkend="release-4.3">repmgr 4.3</link>, &repmgr; makes it possible to provide a script
to <application>repmgrd</application> which, in a failover situation,
will be executed by the promotion candidate (the node which has been selected
to be the new primary) to confirm whether the node should actually be promoted.
</para>
<para>
To use this, <option>failover_validation_command</option> in <filename>repmgr.conf</filename>
to a script executable by the <literal>postgres</literal> system user, e.g.:
<programlisting>
failover_validation_command=/path/to/script.sh %n %a</programlisting>
</para>
<para>
The <literal>%n</literal> parameter will be replaced with the node ID, and the
<literal>%a</literal> parameter will be replaced by the node name when the script is executed.
</para>
<para>
This script must return an exit code of <literal>0</literal> to indicate the node should promote itself.
Any other value will result in the promotion being aborted and the election rerun.
There is a pause of <option>election_rerun_interval</option> seconds before the election is rerun.
</para>
<para>
Sample <application>repmgrd</application> log file output during which the failover validation
script rejects the proposed promotion candidate:
<programlisting>
[2019-03-13 21:01:30] [INFO] visible nodes: 2; total nodes: 2; no nodes have seen the primary within the last 4 seconds
[2019-03-13 21:01:30] [NOTICE] promotion candidate is "node2" (ID: 2)
[2019-03-13 21:01:30] [NOTICE] executing "failover_validation_command"
[2019-03-13 21:01:30] [DETAIL] /usr/local/bin/failover-validation.sh 2
[2019-03-13 21:01:30] [INFO] output returned by failover validation command:
Node ID: 2
[2019-03-13 21:01:30] [NOTICE] failover validation command returned a non-zero value: "1"
[2019-03-13 21:01:30] [NOTICE] promotion candidate election will be rerun
[2019-03-13 21:01:30] [INFO] 1 followers to notify
[2019-03-13 21:01:30] [NOTICE] notifying node "node3" (node ID: 3) to rerun promotion candidate selection
INFO: node 3 received notification to rerun promotion candidate election
[2019-03-13 21:01:30] [NOTICE] rerunning election after 15 seconds ("election_rerun_interval")</programlisting>
</para>
</sect1>
<sect1 id="cascading-replication" xreflabel="Cascading replication">
<indexterm>
<primary>repmgrd</primary>
<secondary>cascading replication</secondary>
</indexterm>
<indexterm>
<primary>cascading replication</primary>
<secondary>repmgrd</secondary>
</indexterm>
<title>repmgrd and cascading replication</title>
<para>
Cascading replication - where a standby can connect to an upstream node and not
the primary server itself - was introduced in PostgreSQL 9.2. &repmgr; and
<application>repmgrd</application> support cascading replication by keeping track of the relationship
between standby servers - each node record is stored with the node id of its
upstream ("parent") server (except of course the primary server).
</para>
<para>
In a failover situation where the primary node fails and a top-level standby
is promoted, a standby connected to another standby will not be affected
and continue working as normal (even if the upstream standby it's connected
to becomes the primary node). If however the node's direct upstream fails,
the &quot;cascaded standby&quot; will attempt to reconnect to that node's parent
(unless <varname>failover</varname> is set to <literal>manual</literal> in
<filename>repmgr.conf</filename>).
</para>
</sect1>
</chapter>

View File

@@ -0,0 +1,939 @@
<chapter id="repmgrd-automatic-failover" xreflabel="Automatic failover with repmgrd">
<title>Automatic failover with repmgrd</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>automatic failover</secondary>
</indexterm>
<para>
&repmgrd; is a management and monitoring daemon which runs
on each node in a replication cluster. It can automate actions such as
failover and updating standbys to follow the new primary, as well as
providing monitoring information about the state of each standby.
</para>
<sect1 id="repmgrd-witness-server" xreflabel="Using a witness server with repmgrd">
<title>Using a witness server</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>witness server</secondary>
</indexterm>
<indexterm>
<primary>witness server</primary>
<secondary>repmgrd</secondary>
</indexterm>
<para>
A <xref linkend="witness-server"/> is a normal PostgreSQL instance which
is not part of the streaming replication cluster; its purpose is, if a
failover situation occurs, to provide proof that it is the primary server
itself which is unavailable, rather than e.g. a network split between
different physical locations.
</para>
<para>
A typical use case for a witness server is a two-node streaming replication
setup, where the primary and standby are in different locations (data centres).
By creating a witness server in the same location (data centre) as the primary,
if the primary becomes unavailable it's possible for the standby to decide whether
it can promote itself without risking a "split brain" scenario: if it can't see either the
witness or the primary server, it's likely there's a network-level interruption
and it should not promote itself. If it can see the witness but not the primary,
this proves there is no network interruption and the primary itself is unavailable,
and it can therefore promote itself (and ideally take action to fence the
former primary).
</para>
<note>
<para>
<emphasis>Never</emphasis> install a witness server on the same physical host
as another node in the replication cluster managed by &repmgr; - it's essential
the witness is not affected in any way by failure of another node.
</para>
</note>
<para>
For more complex replication scenarios, e.g. with multiple datacentres, it may
be preferable to use location-based failover, which ensures that only nodes
in the same location as the primary will ever be promotion candidates;
see <xref linkend="repmgrd-network-split"/> for more details.
</para>
<note>
<simpara>
A witness server will only be useful if &repmgrd;
is in use.
</simpara>
</note>
<sect2 id="creating-witness-server">
<title>Creating a witness server</title>
<para>
To create a witness server, set up a normal PostgreSQL instance on a server
in the same physical location as the cluster's primary server.
</para>
<para>
This instance should <emphasis>not</emphasis> be on the same physical host as the primary server,
as otherwise if the primary server fails due to hardware issues, the witness
server will be lost too.
</para>
<note>
<simpara>
A PostgreSQL instance can only accommodate a single witness server.
</simpara>
<simpara>
If you are planning to use a single server to support more than one
witness server, a separate PostgreSQL instance is required for each
witness server in use.
</simpara>
</note>
<para>
The witness server should be configured in the same way as a normal
&repmgr; node; see section <xref linkend="configuration"/>.
</para>
<para>
Register the witness server with <xref linkend="repmgr-witness-register"/>.
This will create the &repmgr; extension on the witness server, and make
a copy of the &repmgr; metadata.
</para>
<note>
<simpara>
As the witness server is not part of the replication cluster, further
changes to the &repmgr; metadata will be synchronised by
&repmgrd;.
</simpara>
</note>
<para>
Once the witness server has been configured, &repmgrd;
should be started.
</para>
<para>
To unregister a witness server, use <xref linkend="repmgr-witness-unregister"/>.
</para>
</sect2>
</sect1>
<sect1 id="repmgrd-network-split" xreflabel="Handling network splits with repmgrd">
<title>Handling network splits with repmgrd</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>network splits</secondary>
</indexterm>
<indexterm>
<primary>network splits</primary>
</indexterm>
<para>
A common pattern for replication cluster setups is to spread servers over
more than one datacentre. This can provide benefits such as geographically-
distributed read replicas and DR (disaster recovery capability). However
this also means there is a risk of disconnection at network level between
datacentre locations, which would result in a split-brain scenario if
servers in a secondary data centre were no longer able to see the primary
in the main data centre and promoted a standby among themselves.
</para>
<para>
&repmgr; enables provision of &quot;<xref linkend="witness-server"/>&quot; to
artificially create a quorum of servers in a particular location, ensuring
that nodes in another location will not elect a new primary if they
are unable to see the majority of nodes. However this approach does not
scale well, particularly with more complex replication setups, e.g.
where the majority of nodes are located outside of the primary datacentre.
It also means the <literal>witness</literal> node needs to be managed as an
extra PostgreSQL instance outside of the main replication cluster, which
adds administrative and programming complexity.
</para>
<para>
<literal>repmgr4</literal> introduces the concept of <literal>location</literal>:
each node is associated with an arbitrary location string (default is
<literal>default</literal>); this is set in <filename>repmgr.conf</filename>, e.g.:
<programlisting>
node_id=1
node_name=node1
conninfo='host=node1 user=repmgr dbname=repmgr connect_timeout=2'
data_directory='/var/lib/postgresql/data'
location='dc1'</programlisting>
</para>
<para>
In a failover situation, &repmgrd; will check if any servers in the
same location as the current primary node are visible. If not, &repmgrd;
will assume a network interruption and not promote any node in any
other location (it will however enter <link linkend="repmgrd-degraded-monitoring">degraded monitoring</link>
mode until a primary becomes visible).
</para>
</sect1>
<sect1 id="repmgrd-primary-visibility-consensus" xreflabel="Primary visibility consensus">
<title>Primary visibility consensus</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>primary visibility consensus</secondary>
</indexterm>
<indexterm>
<primary>primary_visibility_consensus</primary>
</indexterm>
<para>
In more complex replication setups, particularly where replication occurs between
multiple datacentres, it's possible that some but not all standbys get cut off from the
primary (but not from the other standbys).
</para>
<para>
In this situation, normally it's not desirable for any of the standbys which have been
cut off to initiate a failover, as the primary is still functioning and standbys are
connected. Beginning with <link linkend="release-4.4">&repmgr; 4.4</link>
it is now possible for the affected standbys to build a consensus about whether
the primary is still available to some standbys (&quot;primary visibility consensus&quot;).
This is done by polling each standby (and the witness, if present) for the time it last saw the
primary; if any have seen the primary very recently, it's reasonable
to infer that the primary is still available and a failover should not be started.
</para>
<para>
The time the primary was last seen by each node can be checked by executing
<link linkend="repmgr-service-status"><command>repmgr service status</command></link>
(&repmgr; 4.2 - 4.4: <link linkend="repmgr-service-status"><command>repmgr daemon status</command></link>)
which includes this in its output, e.g.:
<programlisting>$ repmgr -f /etc/repmgr.conf service status
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
1 | node1 | primary | * running | | running | 27259 | no | n/a
2 | node2 | standby | running | node1 | running | 27272 | no | 1 second(s) ago
3 | node3 | standby | running | node1 | running | 27282 | no | 0 second(s) ago
4 | node4 | witness | * running | node1 | running | 27298 | no | 1 second(s) ago</programlisting>
</para>
<para>
To enable this functionality, in <filename>repmgr.conf</filename> set:
<programlisting>
primary_visibility_consensus=true</programlisting>
</para>
<note>
<para>
<option>primary_visibility_consensus</option> <emphasis>must</emphasis> be set to
<literal>true</literal> on all nodes for it to be effective.
</para>
</note>
<para>
The following sample &repmgrd; log output demonstrates the behaviour in a situation
where one of three standbys is no longer able to connect to the primary, but <emphasis>can</emphasis>
connect to the two other standbys (&quot;sibling nodes&quot;):
<programlisting>
[2019-05-17 05:36:12] [WARNING] unable to reconnect to node 1 after 3 attempts
[2019-05-17 05:36:12] [INFO] 2 active sibling nodes registered
[2019-05-17 05:36:12] [INFO] local node's last receive lsn: 0/7006E58
[2019-05-17 05:36:12] [INFO] checking state of sibling node "node3" (ID: 3)
[2019-05-17 05:36:12] [INFO] node "node3" (ID: 3) reports its upstream is node 1, last seen 1 second(s) ago
[2019-05-17 05:36:12] [NOTICE] node 3 last saw primary node 1 second(s) ago, considering primary still visible
[2019-05-17 05:36:12] [INFO] last receive LSN for sibling node "node3" (ID: 3) is: 0/7006E58
[2019-05-17 05:36:12] [INFO] node "node3" (ID: 3) has same LSN as current candidate "node2" (ID: 2)
[2019-05-17 05:36:12] [INFO] checking state of sibling node "node4" (ID: 4)
[2019-05-17 05:36:12] [INFO] node "node4" (ID: 4) reports its upstream is node 1, last seen 0 second(s) ago
[2019-05-17 05:36:12] [NOTICE] node 4 last saw primary node 0 second(s) ago, considering primary still visible
[2019-05-17 05:36:12] [INFO] last receive LSN for sibling node "node4" (ID: 4) is: 0/7006E58
[2019-05-17 05:36:12] [INFO] node "node4" (ID: 4) has same LSN as current candidate "node2" (ID: 2)
[2019-05-17 05:36:12] [INFO] 2 nodes can see the primary
[2019-05-17 05:36:12] [DETAIL] following nodes can see the primary:
- node "node3" (ID: 3): 1 second(s) ago
- node "node4" (ID: 4): 0 second(s) ago
[2019-05-17 05:36:12] [NOTICE] cancelling failover as some nodes can still see the primary
[2019-05-17 05:36:12] [NOTICE] election cancelled
[2019-05-17 05:36:14] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (ID: 1) in degraded state</programlisting>
In this situation it will cancel the failover and enter degraded monitoring node,
waiting for the primary to reappear.
</para>
</sect1>
<sect1 id="repmgrd-standby-disconnection-on-failover" xreflabel="Standby disconnection on failover">
<title>Standby disconnection on failover</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>standby disconnection on failover</secondary>
</indexterm>
<indexterm>
<primary>standby disconnection on failover</primary>
</indexterm>
<para>
If <option>standby_disconnect_on_failover</option> is set to <literal>true</literal> in
<filename>repmgr.conf</filename>, in a failover situation &repmgrd; will forcibly disconnect
the local node's WAL receiver, and wait for the WAL receiver on all sibling nodes to be
disconnected, before making a failover decision.
</para>
<note>
<para>
<option>standby_disconnect_on_failover</option> is available with PostgreSQL 9.5 and later.
Additionally this requires that the <literal>repmgr</literal> database user is a superuser.
</para>
</note>
<para>
By doing this, it's possible to ensure that, at the point the failover decision is made, no nodes
are receiving data from the primary and their LSN location will be static.
</para>
<important>
<para>
<option>standby_disconnect_on_failover</option> <emphasis>must</emphasis> be set to the same value on
all nodes.
</para>
</important>
<para>
Note that when using <option>standby_disconnect_on_failover</option> there will be a delay of 5 seconds
plus however many seconds it takes to confirm the WAL receiver is disconnected before
&repmgrd; proceeds with the failover decision.
</para>
<para>
&repmgrd; will wait up to <option>sibling_nodes_disconnect_timeout</option> seconds (default:
<literal>30</literal>) to confirm that the WAL receiver on all sibling nodes hase been
disconnected before proceding with the failover operation. If the timeout is reached, the
failover operation will go ahead anyway.
</para>
<para>
Following the failover operation, no matter what the outcome, each node will reconnect its WAL receiver.
</para>
<para>
If using <option>standby_disconnect_on_failover</option>, we recommend that the
<option>primary_visibility_consensus</option> option is also used.
</para>
</sect1>
<sect1 id="repmgrd-failover-validation" xreflabel="Failover validation">
<title>Failover validation</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>failover validation</secondary>
</indexterm>
<indexterm>
<primary>failover validation</primary>
</indexterm>
<para>
From <link linkend="release-4.3">repmgr 4.3</link>, &repmgr; makes it possible to provide a script
to &repmgrd; which, in a failover situation,
will be executed by the promotion candidate (the node which has been selected
to be the new primary) to confirm whether the node should actually be promoted.
</para>
<para>
To use this, <option>failover_validation_command</option> in <filename>repmgr.conf</filename>
to a script executable by the <literal>postgres</literal> system user, e.g.:
<programlisting>
failover_validation_command=/path/to/script.sh %n</programlisting>
</para>
<para>
The <literal>%n</literal> parameter will be replaced with the node ID when the script is
executed. A number of other parameters are also available, see section
&quot;<xref linkend="repmgrd-automatic-failover-configuration-optional"/>&quot; for details.
</para>
<para>
This script must return an exit code of <literal>0</literal> to indicate the node should promote itself.
Any other value will result in the promotion being aborted and the election rerun.
There is a pause of <option>election_rerun_interval</option> seconds before the election is rerun.
</para>
<para>
Sample &repmgrd; log file output during which the failover validation
script rejects the proposed promotion candidate:
<programlisting>
[2019-03-13 21:01:30] [INFO] visible nodes: 2; total nodes: 2; no nodes have seen the primary within the last 4 seconds
[2019-03-13 21:01:30] [NOTICE] promotion candidate is "node2" (ID: 2)
[2019-03-13 21:01:30] [NOTICE] executing "failover_validation_command"
[2019-03-13 21:01:30] [DETAIL] /usr/local/bin/failover-validation.sh 2
[2019-03-13 21:01:30] [INFO] output returned by failover validation command:
Node ID: 2
[2019-03-13 21:01:30] [NOTICE] failover validation command returned a non-zero value: "1"
[2019-03-13 21:01:30] [NOTICE] promotion candidate election will be rerun
[2019-03-13 21:01:30] [INFO] 1 followers to notify
[2019-03-13 21:01:30] [NOTICE] notifying node "node3" (ID: 3) to rerun promotion candidate selection
INFO: node 3 received notification to rerun promotion candidate election
[2019-03-13 21:01:30] [NOTICE] rerunning election after 15 seconds ("election_rerun_interval")</programlisting>
</para>
</sect1>
<sect1 id="cascading-replication" xreflabel="Cascading replication">
<title>repmgrd and cascading replication</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>cascading replication</secondary>
</indexterm>
<indexterm>
<primary>cascading replication</primary>
<secondary>repmgrd</secondary>
</indexterm>
<para>
Cascading replication - where a standby can connect to an upstream node and not
the primary server itself - was introduced in PostgreSQL 9.2. &repmgr; and
&repmgrd; support cascading replication by keeping track of the relationship
between standby servers - each node record is stored with the node id of its
upstream ("parent") server (except of course the primary server).
</para>
<para>
In a failover situation where the primary node fails and a top-level standby
is promoted, a standby connected to another standby will not be affected
and continue working as normal (even if the upstream standby it's connected
to becomes the primary node). If however the node's direct upstream fails,
the &quot;cascaded standby&quot; will attempt to reconnect to that node's parent
(unless <varname>failover</varname> is set to <literal>manual</literal> in
<filename>repmgr.conf</filename>).
</para>
</sect1>
<sect1 id="repmgrd-primary-child-disconnection" xreflabel="Monitoring standby disconnections on the primary">
<title>Monitoring standby disconnections on the primary node</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>standby disconnection</secondary>
</indexterm>
<indexterm>
<primary>repmgrd</primary>
<secondary>child node disconnection</secondary>
</indexterm>
<note>
<para>
This functionality is available in <link linkend="release-4.4">&repmgr; 4.4</link> and later.
</para>
</note>
<para>
When running on the primary node, &repmgrd; can
monitor connections and in particular disconnections by its attached
child nodes (standbys, and if in use, the witness server), and optionally
execute a custom command if certain criteria are met (such as the number of
attached nodes falling to zero following a failover to a new primary); this
command can be used for example to &quot;fence&quot; the node and ensure it
is isolated from any applications attempting to access the replication cluster.
</para>
<note>
<para>
Currently &repmgrd; can only detect disconnections
of streaming replication standbys and cannot determine whether a standby
has disconnected and fallen back to archive recovery.
</para>
<para>
See section <link linkend="repmgrd-primary-child-disconnection-caveats">caveats</link> below.
</para>
</note>
<sect2 id="repmgrd-primary-child-disconnection-monitoring-process">
<title>Standby disconnections monitoring process and criteria</title>
<para>
&repmgrd; monitors attached child nodes and decides
whether to invoke the user-defined command based on the following process
and criteria:
<itemizedlist>
<listitem>
<para>
Every few seconds (defined by the configuration parameter <varname>child_nodes_check_interval</varname>;
default: <literal>5</literal> seconds, a value of <literal>0</literal> disables this altogether), &repmgrd; queries
the <literal>pg_stat_replication</literal> system view and compares
the nodes present there against the list of nodes registered with &repmgr; which
should be attached to the primary.
</para>
<para>
If a witness server is in use, &repmgrd; connects to it and checks which upstream node
it is following.
</para>
</listitem>
<listitem>
<para>
If a child node (standby) is no longer present in <literal>pg_stat_replication</literal>,
&repmgrd; notes the time it detected the node's absence, and additionally generates a
<literal>child_node_disconnect</literal> event.
</para>
<para>
If a witness server is in use, and it is no longer following the primary, or not
reachable at all, &repmgrd; notes the time it detected the node's absence, and additionally generates a
<literal>child_node_disconnect</literal> event.
</para>
</listitem>
<listitem>
<para>
If a child node (standby) which was absent from <literal>pg_stat_replication</literal> reappears,
&repmgrd; clears the time it detected the node's absence, and additionally generates a
<literal>child_node_reconnect</literal> event.
</para>
<para>
If a witness server is in use, which was previously not reachable or not following the
primary node, has become reachable and is following the primary node, &repmgrd; clears the
time it detected the node's absence, and additionally generates a
<literal>child_node_reconnect</literal> event.
</para>
</listitem>
<listitem>
<para>
If an entirely new child node (standby or witness) is detected, &repmgrd; adds it to its internal list
and additionally generates a <literal>child_node_new_connect</literal> event.
</para>
</listitem>
<listitem>
<para>
If the <varname>child_nodes_disconnect_command</varname> parameter is set in
<filename>repmgr.conf</filename>, &repmgrd; will then loop through all child nodes.
If it determines that insufficient child nodes are connected, and a
minimum of <varname>child_nodes_disconnect_timeout</varname> seconds (default: <literal>30</literal>)
has elapsed since the last node became disconnected, &repmgrd; will then execute the
<varname>child_nodes_disconnect_command</varname> script.
</para>
<para>
By default, the <varname>child_nodes_disconnect_command</varname> will only be executed
if all child nodes are disconnected. If <varname>child_nodes_connected_min_count</varname>
is set, the <varname>child_nodes_disconnect_command</varname> script will be triggered
if the number of connected child nodes falls below the specified value (e.g.
if set to <literal>2</literal>, the script will be triggered if only one child node
is connected). Alternatively, if <varname>child_nodes_disconnect_min_count</varname>
and more than that number of child nodes disconnects, the script will be triggered.
</para>
<note>
<para>
By default, a witness node, if in use, will <emphasis>not</emphasis> be counted as a
child node for the purposes of determining whether to execute
<varname>child_nodes_disconnect_command</varname>.
</para>
<para>
To enable the witness node to be counted as a child node, set
<varname>child_nodes_connected_include_witness</varname> in <filename>repmgr.conf</filename>
to <literal>true</literal>
(and <link linkend="repmgrd-reloading-configuration">reload the configuration</link> if &repmgrd;
is running).
</para>
</note>
</listitem>
<listitem>
<para>
Note that child nodes which are not attached when &repmgrd;
starts will <emphasis>not</emphasis> be considered as missing, as &repmgrd;
cannot know why they are not attached.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2 id="repmgrd-primary-child-disconnection-example">
<title>Standby disconnections monitoring process example</title>
<para>
This example shows typical &repmgrd; log output from a three-node cluster
(primary and two child nodes), with <varname>child_nodes_connected_min_count</varname>
set to <literal>2</literal>.
</para>
<para>
&repmgrd; on the primary has started up, while two child
nodes are being provisioned:
<programlisting>
[2019-04-24 15:25:33] [INFO] monitoring primary node "node1" (ID: 1) in normal state
[2019-04-24 15:25:35] [NOTICE] new node "node2" (ID: 2) has connected
[2019-04-24 15:25:35] [NOTICE] 1 (of 1) child nodes are connected, but at least 2 child nodes required
[2019-04-24 15:25:35] [INFO] no child nodes have detached since repmgrd startup
(...)
[2019-04-24 15:25:44] [NOTICE] new node "node3" (ID: 3) has connected
[2019-04-24 15:25:46] [INFO] monitoring primary node "node1" (ID: 1) in normal state
(...)</programlisting>
</para>
<para>
One of the child nodes has disconnected; &repmgrd;
is now waiting <varname>child_nodes_disconnect_timeout</varname> seconds
before executing <varname>child_nodes_disconnect_command</varname>:
<programlisting>
[2019-04-24 15:28:11] [INFO] monitoring primary node "node1" (ID: 1) in normal state
[2019-04-24 15:28:17] [INFO] monitoring primary node "node1" (ID: 1) in normal state
[2019-04-24 15:28:19] [NOTICE] node "node3" (ID: 3) has disconnected
[2019-04-24 15:28:19] [NOTICE] 1 (of 2) child nodes are connected, but at least 2 child nodes required
[2019-04-24 15:28:19] [INFO] most recently detached child node was 3 (ca. 0 seconds ago), not triggering "child_nodes_disconnect_command"
[2019-04-24 15:28:19] [DETAIL] "child_nodes_disconnect_timeout" set To 30 seconds
(...)</programlisting>
</para>
<para>
<varname>child_nodes_disconnect_command</varname> is executed once:
<programlisting>
[2019-04-24 15:28:49] [INFO] most recently detached child node was 3 (ca. 30 seconds ago), triggering "child_nodes_disconnect_command"
[2019-04-24 15:28:49] [INFO] "child_nodes_disconnect_command" is:
"/usr/bin/fence-all-the-things.sh"
[2019-04-24 15:28:51] [NOTICE] 1 (of 2) child nodes are connected, but at least 2 child nodes required
[2019-04-24 15:28:51] [INFO] "child_nodes_disconnect_command" was previously executed, taking no action</programlisting>
</para>
</sect2>
<sect2 id="repmgrd-primary-child-disconnection-caveats">
<title>Standby disconnections monitoring caveats</title>
<para>
The following caveats should be considered if you are intending to use this functionality.
</para>
<para>
<itemizedlist mark="bullet">
<listitem>
<para>
If a child node is configured to use archive recovery, it's possible that
the child node will disconnect from the primary node and fall back to
archive recovery. In this case &repmgrd;
will nevertheless register a node disconnection.
</para>
</listitem>
<listitem>
<para>
&repmgr; relies on <varname>application_name</varname> in the child node's
<varname>primary_conninfo</varname> string to be the same as the node name
defined in the node's <filename>repmgr.conf</filename> file. Furthermore,
this <varname>application_name</varname> must be unique across the replication
cluster.
</para>
<para>
If a custom <varname>application_name</varname> is used, or the
<varname>application_name</varname> is not unique across the replication
cluster, &repmgr; will not be able to reliably monitor child node connections.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2 id="repmgrd-primary-child-disconnection-configuration">
<title>Standby disconnections monitoring process configuration</title>
<para>
The following parameters, set in <filename>repmgr.conf</filename>,
control how child node disconnection monitoring operates.
</para>
<variablelist>
<varlistentry>
<term><varname>child_nodes_check_interval</varname></term>
<listitem>
<indexterm>
<primary>child_nodes_check_interval</primary>
<secondary>child node disconnection monitoring</secondary>
</indexterm>
<para>
Interval (in seconds) after which &repmgrd; queries the
<literal>pg_stat_replication</literal> system view and compares the nodes present
there against the list of nodes registered with repmgr which should be attached to the primary.
</para>
<para>
Default is <literal>5</literal> seconds, a value of <literal>0</literal> disables this check
altogether.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>child_nodes_disconnect_command</varname></term>
<listitem>
<indexterm>
<primary>child_nodes_disconnect_command</primary>
<secondary>child node disconnection monitoring</secondary>
</indexterm>
<para>
User-definable script to be executed when &repmgrd;
determines that an insufficient number of child nodes are connected. By default
the script is executed when no child nodes are executed, but the execution
threshold can be modified by setting one of <varname>child_nodes_connected_min_count</varname>
or<varname>child_nodes_disconnect_min_count</varname> (see below).
</para>
<para>
The <varname>child_nodes_disconnect_command</varname> script can be
any user-defined script or program. It <emphasis>must</emphasis> be able
to be executed by the system user under which the PostgreSQL server itself
runs (usually <literal>postgres</literal>).
</para>
<note>
<para>
If <varname>child_nodes_disconnect_command</varname> is not set, no action
will be taken.
</para>
</note>
<para>
If specified, the following format placeholder will be substituted when
executing <varname>child_nodes_disconnect_command</varname>:
</para>
<variablelist>
<varlistentry>
<term><option>%p</option></term>
<listitem>
<para>
ID of the node executing the <varname>child_nodes_disconnect_command</varname> script.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
The <varname>child_nodes_disconnect_command</varname> script will only be executed once
while the criteria for its execution are met. If the criteria for its execution are no longer
met (i.e. some child nodes have reconnected), it will be executed again if
the criteria for its execution are met again.
</para>
<para>
The <varname>child_nodes_disconnect_command</varname> script will not be executed if
&repmgrd; is <link linkend="repmgrd-pausing">paused</link>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>child_nodes_disconnect_timeout</varname></term>
<listitem>
<indexterm>
<primary>child_nodes_disconnect_timeout</primary>
<secondary>child node disconnection monitoring</secondary>
</indexterm>
<para>
If &repmgrd; determines that an insufficient number of
child nodes are connected, it will wait for the specified number of seconds
to execute the <varname>child_nodes_disconnect_command</varname>.
</para>
<para>
Default: <literal>30</literal> seconds.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>child_nodes_connected_min_count</varname></term>
<listitem>
<indexterm>
<primary>child_nodes_connected_min_count</primary>
<secondary>child node disconnection monitoring</secondary>
</indexterm>
<para>
If the number of child nodes connected falls below the number specified in
this parameter, the <varname>child_nodes_disconnect_command</varname> script
will be executed.
</para>
<para>
For example, if <varname>child_nodes_connected_min_count</varname> is set
to <literal>2</literal>, the <varname>child_nodes_disconnect_command</varname>
script will be executed if one or no child nodes are connected.
</para>
<para>
Note that <varname>child_nodes_connected_min_count</varname> overrides any value
set in <varname>child_nodes_disconnect_min_count</varname>.
</para>
<para>
If neither of <varname>child_nodes_connected_min_count</varname> or
<varname>child_nodes_disconnect_min_count</varname> are set,
the <varname>child_nodes_disconnect_command</varname> script
will be executed when no child nodes are connected.
</para>
<para>
A witness node, if in use, will not be counted as a child node unless
<varname>child_nodes_connected_include_witness</varname> is set to <literal>true</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>child_nodes_disconnect_min_count</varname></term>
<listitem>
<indexterm>
<primary>child_nodes_disconnect_min_count</primary>
<secondary>child node disconnection monitoring</secondary>
</indexterm>
<para>
If the number of disconnected child nodes exceeds the number specified in
this parameter, the <varname>child_nodes_disconnect_command</varname> script
will be executed.
</para>
<para>
For example, if <varname>child_nodes_disconnect_min_count</varname> is set
to <literal>2</literal>, the <varname>child_nodes_disconnect_command</varname>
script will be executed if more than two child nodes are disconnected.
</para>
<para>
Note that any value set in <varname>child_nodes_disconnect_min_count</varname>
will be overriden by <varname>child_nodes_connected_min_count</varname>.
</para>
<para>
If neither of <varname>child_nodes_connected_min_count</varname> or
<varname>child_nodes_disconnect_min_count</varname> are set,
the <varname>child_nodes_disconnect_command</varname> script
will be executed when no child nodes are connected.
</para>
<para>
A witness node, if in use, will not be counted as a child node unless
<varname>child_nodes_connected_include_witness</varname> is set to <literal>true</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>child_nodes_connected_include_witness</varname></term>
<listitem>
<indexterm>
<primary>child_nodes_connected_include_witness</primary>
<secondary>child node disconnection monitoring</secondary>
</indexterm>
<para>
Whether to count the witness node (if in use) as a child node when
determining whether to execute <varname>child_nodes_disconnect_command</varname>.
</para>
<para>
Default to <literal>false</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
<sect2 id="repmgrd-primary-child-disconnection-events">
<title>Standby disconnections monitoring process event notifications</title>
<para>
The following <link linkend="event-notifications">event notifications</link> may be generated:
</para>
<variablelist>
<varlistentry>
<term><varname>child_node_disconnect</varname></term>
<listitem>
<indexterm>
<primary>child_node_disconnect</primary>
<secondary>event notification</secondary>
</indexterm>
<para>
This event is generated after &repmgrd;
detects that a child node is no longer streaming from the primary node.
</para>
<para>
Example:
<programlisting>
$ repmgr cluster event --event=child_node_disconnect
Node ID | Name | Event | OK | Timestamp | Details
---------+-------+-----------------------+----+---------------------+--------------------------------------------
1 | node1 | child_node_disconnect | t | 2019-04-24 12:41:36 | node "node3" (ID: 3) has disconnected</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>child_node_reconnect</varname></term>
<listitem>
<indexterm>
<primary>child_node_reconnect</primary>
<secondary>event notification</secondary>
</indexterm>
<para>
This event is generated after &repmgrd;
detects that a child node has resumed streaming from the primary node.
</para>
<para>
Example:
<programlisting>
$ repmgr cluster event --event=child_node_reconnect
Node ID | Name | Event | OK | Timestamp | Details
---------+-------+----------------------+----+---------------------+------------------------------------------------------------
1 | node1 | child_node_reconnect | t | 2019-04-24 12:42:19 | node "node3" (ID: 3) has reconnected after 42 seconds</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>child_node_new_connect</varname></term>
<listitem>
<indexterm>
<primary>child_node_new_connect</primary>
<secondary>event notification</secondary>
</indexterm>
<para>
This event is generated after &repmgrd;
detects that a new child node has been registered with &repmgr; and has
connected to the primary.
</para>
<para>
Example:
<programlisting>
$ repmgr cluster event --event=child_node_new_connect
Node ID | Name | Event | OK | Timestamp | Details
---------+-------+------------------------+----+---------------------+---------------------------------------------
1 | node1 | child_node_new_connect | t | 2019-04-24 12:41:30 | new node "node3" (ID: 3) has connected</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>child_nodes_disconnect_command</varname></term>
<listitem>
<indexterm>
<primary>child_nodes_disconnect_command</primary>
<secondary>event notification</secondary>
</indexterm>
<para>
This event is generated after &repmgrd; detects
that sufficient child nodes have been disconnected for a sufficient amount
of time to trigger execution of the <varname>child_nodes_disconnect_command</varname>.
</para>
<para>
Example:
<programlisting>
$ repmgr cluster event --event=child_nodes_disconnect_command
Node ID | Name | Event | OK | Timestamp | Details
---------+-------+--------------------------------+----+---------------------+--------------------------------------------------------
1 | node1 | child_nodes_disconnect_command | t | 2019-04-24 13:08:17 | "child_nodes_disconnect_command" successfully executed</programlisting>
</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
</sect1>
</chapter>

View File

@@ -1,428 +0,0 @@
<chapter id="repmgrd-bdr">
<indexterm>
<primary>repmgrd</primary>
<secondary>BDR</secondary>
</indexterm>
<indexterm>
<primary>BDR</primary>
</indexterm>
<title>BDR failover with repmgrd</title>
<para>
&repmgr; 4.x provides support for monitoring a pair of BDR 2.x nodes and taking action in
case one of the nodes fails.
</para>
<note>
<simpara>
Due to the nature of BDR 1.x/2.x, it's only safe to use this solution for
a two-node scenario. Introducing additional nodes will create an inherent
risk of node desynchronisation if a node goes down without being cleanly
removed from the cluster.
</simpara>
</note>
<para>
In contrast to streaming replication, there's no concept of "promoting" a new
primary node with BDR. Instead, "failover" involves monitoring both nodes
with <application>repmgrd</application> and redirecting queries from the failed node to the remaining
active node. This can be done by using an
<link linkend="event-notifications">event notification</link> script
which is called by <application>repmgrd</application> to dynamically
reconfigure a proxy server/connection pooler such as <application>PgBouncer</application>.
</para>
<note>
<simpara>
This &repmgr; functionality is for BDR 2.x only running on PostgreSQL 9.4/9.6.
It is <emphasis>not</emphasis> required for later BDR versions.
</simpara>
</note>
<sect1 id="bdr-prerequisites" xreflabel="BDR prequisites">
<title>Prerequisites</title>
<important>
<para>
This &repmgr; functionality is for BDR 2.x only running on PostgreSQL 9.4/9.6.
It is <emphasis>not</emphasis> required for later BDR versions.
</para>
</important>
<para>
&repmgr; 4 requires PostgreSQL 9.4 or 9.6 with the BDR 2 extension
enabled and configured for a two-node BDR network. &repmgr; 4 packages
must be installed on each node before attempting to configure
<application>repmgr</application>.
</para>
<note>
<simpara>
&repmgr; 4 will refuse to install if it detects more than two BDR nodes.
</simpara>
</note>
<para>
Application database connections *must* be passed through a proxy server/
connection pooler such as <application>PgBouncer</application>, and it must be possible to dynamically
reconfigure that from <application>repmgrd</application>. The example demonstrated in this document
will use <application>PgBouncer</application>
</para>
<para>
The proxy server / connection poolers must <emphasis>not</emphasis>
be installed on the database servers.
</para>
<para>
For this example, it's assumed password-less SSH connections are available
from the PostgreSQL servers to the servers where <application>PgBouncer</application>
runs, and that the user on those servers has permission to alter the
<application>PgBouncer</application> configuration files.
</para>
<para>
PostgreSQL connections must be possible between each node, and each node
must be able to connect to each PgBouncer instance.
</para>
</sect1>
<sect1 id="bdr-configuration" xreflabel="BDR configuration">
<title>Configuration</title>
<para>
A sample configuration for <filename>repmgr.conf</filename> on each
BDR node would look like this:
<programlisting>
# Node information
node_id=1
node_name='node1'
conninfo='host=node1 dbname=bdrtest user=repmgr connect_timeout=2'
data_directory='/var/lib/postgresql/data'
replication_type='bdr'
# Event notification configuration
event_notifications=bdr_failover
event_notification_command='/path/to/bdr-pgbouncer.sh %n %e %s "%c" "%a" >> /tmp/bdr-failover.log 2>&1'
# repmgrd options
monitor_interval_secs=5
reconnect_attempts=6
reconnect_interval=5</programlisting>
</para>
<para>
Adjust settings as appropriate; copy and adjust for the second node (particularly
the values <varname>node_id</varname>, <varname>node_name</varname>
and <varname>conninfo</varname>).
</para>
<para>
Note that the values provided for the <varname>conninfo</varname> string
must be valid for connections from <emphasis>both</emphasis> nodes in the
replication cluster. The database must be the BDR-enabled database.
</para>
<para>
If defined, the <varname>event_notifications</varname> parameter will restrict
execution of the script defined in <varname>event_notification_command</varname>
to the specified event(s).
</para>
<note>
<simpara>
<varname>event_notification_command</varname> is the script which does the actual "heavy lifting"
of reconfiguring the proxy server/ connection pooler. It is fully
user-definable; see section <xref linkend="bdr-event-notification-command"> for a reference
implementation.
</simpara>
</note>
</sect1>
<sect1 id="bdr-repmgr-setup" xreflabel="repmgr setup with BDR">
<title>repmgr setup</title>
<para>
Register both nodes; example on <literal>node1</literal>:
<programlisting>
$ repmgr -f /etc/repmgr.conf bdr register
NOTICE: attempting to install extension "repmgr"
NOTICE: "repmgr" extension successfully installed
NOTICE: node record created for node 'node1' (ID: 1)
NOTICE: BDR node 1 registered (conninfo: host=node1 dbname=bdrtest user=repmgr)</programlisting>
</para>
<para>
and on <literal>node1</literal>:
<programlisting>
$ repmgr -f /etc/repmgr.conf bdr register
NOTICE: node record created for node 'node2' (ID: 2)
NOTICE: BDR node 2 registered (conninfo: host=node2 dbname=bdrtest user=repmgr)</programlisting>
</para>
<para>
The <literal>repmgr</literal> extension will be automatically created
when the first node is registered, and will be propagated to the second
node.
</para>
<important>
<simpara>
Ensure the &repmgr; package is available on both nodes before
attempting to register the first node.
</simpara>
</important>
<para>
At this point the meta data for both nodes has been created; executing
<xref linkend="repmgr-cluster-show"> (on either node) should produce output like this:
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Connection string
----+-------+------+-----------+----------+--------------------------------------------------------
1 | node1 | bdr | * running | | default | host=node1 dbname=bdrtest user=repmgr connect_timeout=2
2 | node2 | bdr | * running | | default | host=node2 dbname=bdrtest user=repmgr connect_timeout=2</programlisting>
</para>
<para>
Additionally it's possible to display log of significant events; executing
<xref linkend="repmgr-cluster-event"> (on either node) should produce output like this:
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster event
Node ID | Event | OK | Timestamp | Details
---------+--------------+----+---------------------+----------------------------------------------
2 | bdr_register | t | 2017-07-27 17:51:48 | node record created for node 'node2' (ID: 2)
1 | bdr_register | t | 2017-07-27 17:51:00 | node record created for node 'node1' (ID: 1)
</programlisting>
</para>
<para>
At this point there will only be records for the two node registrations (displayed here
in reverse chronological order).
</para>
</sect1>
<sect1 id="bdr-event-notification-command" xreflabel="Defining the BDR failover &quot;event_notification command&quot;">
<title>Defining the BDR failover "event_notification_command"</title>
<para>
Key to "failover" execution is the <literal>event_notification_command</literal>,
which is a user-definable script specified in <filename>repmpgr.conf</filename>
and which can use a &repmgr; <link linkend="event-notifications">event notification</link>
to reconfigure the proxy server / connection pooler so it points to the other, still-active node.
Details of the event will be passed as parameters to the script.
</para>
<para>
Following parameter placeholders are available for the script definition in <filename>repmpgr.conf</filename>;
these will be replaced with the appropriate value when the script is executed:
</para>
<variablelist>
<varlistentry>
<term><option>%n</option></term>
<listitem>
<para>
node ID
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%e</option></term>
<listitem>
<para>
event type
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%t</option></term>
<listitem>
<para>
success (1 or 0)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%t</option></term>
<listitem>
<para>
timestamp
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%d</option></term>
<listitem>
<para>
details
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%c</option></term>
<listitem>
<para>
conninfo string of the next available node (<varname>bdr_failover</varname> and <varname>bdr_recovery</varname>)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%a</option></term>
<listitem>
<para>
name of the next available node (<varname>bdr_failover</varname> and <varname>bdr_recovery</varname>)
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
Note that <literal>%c</literal> and <literal>%a</literal> are only provided with
particular failover events, in this case <varname>bdr_failover</varname>.
</para>
<para>
The provided sample script
(<literal><ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/scripts/bdr-pgbouncer.sh">scripts/bdr-pgbouncer.sh</ulink></literal>)
is configured as follows:
<programlisting>
event_notification_command='/path/to/bdr-pgbouncer.sh %n %e %s "%c" "%a"'</programlisting>
</para>
<para>
and parses the placeholder parameters like this:
<programlisting>
NODE_ID=$1
EVENT_TYPE=$2
SUCCESS=$3
NEXT_CONNINFO=$4
NEXT_NODE_NAME=$5</programlisting>
</para>
<note>
<para>
The sample script also contains some hard-coded values for the <application>PgBouncer</application>
configuration for both nodes; these will need to be adjusted for your local environment
(ideally the scripts would be maintained as templates and generated by some
kind of provisioning system).
</para>
</note>
<para>
The script performs following steps:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>pauses <application>PgBouncer</application> on all nodes</simpara>
</listitem>
<listitem>
<simpara>recreates the <application>PgBouncer</application> configuration file on each
node using the information provided by <application>repmgrd</application>
(primarily the <varname>conninfo</varname> string) to configure
<application>PgBouncer</application></simpara>
</listitem>
<listitem>
<simpara>reloads the <application>PgBouncer</application> configuration</simpara>
</listitem>
<listitem>
<simpara>executes the <command>RESUME</command> command (in <application>PgBouncer</application>)</simpara>
</listitem>
</itemizedlist>
</para>
<para>
Following successful script execution, any connections to PgBouncer on the failed BDR node
will be redirected to the active node.
</para>
</sect1>
<sect1 id="bdr-monitoring-failover" xreflabel="Node monitoring and failover">
<title>Node monitoring and failover</title>
<para>
At the intervals specified by <varname>monitor_interval_secs</varname>
in <filename>repmgr.conf</filename>, <application>repmgrd</application>
will ping each node to check if it's available. If a node isn't available,
<application>repmgrd</application> will enter failover mode and check <varname>reconnect_attempts</varname>
times at intervals of <varname>reconnect_interval</varname> to confirm the node is definitely unreachable.
This buffer period is necessary to avoid false positives caused by transient
network outages.
</para>
<para>
If the node is still unavailable, <application>repmgrd</application> will enter failover mode and execute
the script defined in <varname>event_notification_command</varname>; an entry will be logged
in the <literal>repmgr.events</literal> table and <application>repmgrd</application> will
(unless otherwise configured) resume monitoring of the node in "degraded" mode until it reappears.
</para>
<para>
<application>repmgrd</application> logfile output during a failover event will look something like this
on one node (usually the node which has failed, here <literal>node2</literal>):
<programlisting>
...
[2017-07-27 21:08:39] [INFO] starting continuous BDR node monitoring
[2017-07-27 21:08:39] [INFO] monitoring BDR replication status on node "node2" (ID: 2)
[2017-07-27 21:08:55] [INFO] monitoring BDR replication status on node "node2" (ID: 2)
[2017-07-27 21:09:11] [INFO] monitoring BDR replication status on node "node2" (ID: 2)
[2017-07-27 21:09:23] [WARNING] unable to connect to node node2 (ID 2)
[2017-07-27 21:09:23] [INFO] checking state of node 2, 0 of 5 attempts
[2017-07-27 21:09:23] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-07-27 21:09:24] [INFO] checking state of node 2, 1 of 5 attempts
[2017-07-27 21:09:24] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-07-27 21:09:25] [INFO] checking state of node 2, 2 of 5 attempts
[2017-07-27 21:09:25] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-07-27 21:09:26] [INFO] checking state of node 2, 3 of 5 attempts
[2017-07-27 21:09:26] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-07-27 21:09:27] [INFO] checking state of node 2, 4 of 5 attempts
[2017-07-27 21:09:27] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-07-27 21:09:28] [WARNING] unable to reconnect to node 2 after 5 attempts
[2017-07-27 21:09:28] [NOTICE] setting node record for node 2 to inactive
[2017-07-27 21:09:28] [INFO] executing notification command for event "bdr_failover"
[2017-07-27 21:09:28] [DETAIL] command is:
/path/to/bdr-pgbouncer.sh 2 bdr_failover 1 "host=host=node1 dbname=bdrtest user=repmgr connect_timeout=2" "node1"
[2017-07-27 21:09:28] [INFO] node 'node2' (ID: 2) detected as failed; next available node is 'node1' (ID: 1)
[2017-07-27 21:09:28] [INFO] monitoring BDR replication status on node "node2" (ID: 2)
[2017-07-27 21:09:28] [DETAIL] monitoring node "node2" (ID: 2) in degraded mode
...</programlisting>
</para>
<para>
Output on the other node (<literal>node1</literal>) during the same event will look like this:
<programlisting>
...
[2017-07-27 21:08:35] [INFO] starting continuous BDR node monitoring
[2017-07-27 21:08:35] [INFO] monitoring BDR replication status on node "node1" (ID: 1)
[2017-07-27 21:08:51] [INFO] monitoring BDR replication status on node "node1" (ID: 1)
[2017-07-27 21:09:07] [INFO] monitoring BDR replication status on node "node1" (ID: 1)
[2017-07-27 21:09:23] [WARNING] unable to connect to node node2 (ID 2)
[2017-07-27 21:09:23] [INFO] checking state of node 2, 0 of 5 attempts
[2017-07-27 21:09:23] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-07-27 21:09:24] [INFO] checking state of node 2, 1 of 5 attempts
[2017-07-27 21:09:24] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-07-27 21:09:25] [INFO] checking state of node 2, 2 of 5 attempts
[2017-07-27 21:09:25] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-07-27 21:09:26] [INFO] checking state of node 2, 3 of 5 attempts
[2017-07-27 21:09:26] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-07-27 21:09:27] [INFO] checking state of node 2, 4 of 5 attempts
[2017-07-27 21:09:27] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-07-27 21:09:28] [WARNING] unable to reconnect to node 2 after 5 attempts
[2017-07-27 21:09:28] [NOTICE] other node's repmgrd is handling failover
[2017-07-27 21:09:28] [INFO] monitoring BDR replication status on node "node1" (ID: 1)
[2017-07-27 21:09:28] [DETAIL] monitoring node "node2" (ID: 2) in degraded mode
...</programlisting>
</para>
<para>
This assumes only the PostgreSQL instance on <literal>node2</literal> has failed. In this case the
<application>repmgrd</application> instance running on <literal>node2</literal> has performed the failover. However if
the entire server becomes unavailable, <application>repmgrd</application> on <literal>node1</literal> will perform
the failover.
</para>
</sect1>
<sect1 id="bdr-node-recovery" xreflabel="Node recovery">
<title>Node recovery</title>
<para>
Following failure of a BDR node, if the node subsequently becomes available again,
a <varname>bdr_recovery</varname> event will be generated. This could potentially be used to
reconfigure PgBouncer automatically to bring the node back into the available pool,
however it would be prudent to manually verify the node's status before
exposing it to the application.
</para>
<para>
If the failed node comes back up and connects correctly, output similar to this
will be visible in the <application>repmgrd</application> log:
<programlisting>
[2017-07-27 21:25:30] [DETAIL] monitoring node "node2" (ID: 2) in degraded mode
[2017-07-27 21:25:46] [INFO] monitoring BDR replication status on node "node2" (ID: 2)
[2017-07-27 21:25:46] [DETAIL] monitoring node "node2" (ID: 2) in degraded mode
[2017-07-27 21:25:55] [INFO] active replication slot for node "node1" found after 1 seconds
[2017-07-27 21:25:55] [NOTICE] node "node2" (ID: 2) has recovered after 986 seconds</programlisting>
</para>
</sect1>
<sect1 id="bdr-complete-shutdown" xreflabel="Shutdown of both nodes">
<title>Shutdown of both nodes</title>
<para>
If both PostgreSQL instances are shut down, <application>repmgrd</application> will try and handle the
situation as gracefully as possible, though with no failover candidates available
there's not much it can do. Should this case ever occur, we recommend shutting
down <application>repmgrd</application> on both nodes and restarting it once the PostgreSQL instances
are running properly.
</para>
</sect1>
</chapter>

View File

@@ -1,29 +1,33 @@
<chapter id="repmgrd-configuration"> <chapter id="repmgrd-configuration">
<title>repmgrd setup and configuration</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>configuration</secondary> <secondary>configuration</secondary>
</indexterm> </indexterm>
<title>repmgrd setup and configuration</title>
<para> <para>
<application>repmgrd</application> is a daemon which runs on each PostgreSQL node, &repmgrd; is a daemon process which runs on each PostgreSQL node,
monitoring the local node, and (unless it's the primary node) the upstream server monitoring the local node, and (unless it's the primary node) the upstream server
(the primary server or with cascading replication, another standby) which it's (the primary server or with cascading replication, another standby) which it's
connected to. connected to.
</para> </para>
<para> <para>
<application>repmgrd</application> can be configured to provide failover &repmgrd; can be configured to provide failover
capability in case the primary upstream node becomes unreachable, and/or capability in case the primary or upstream node becomes unreachable, and/or
provide monitoring data to the &repmgr; metadatabase. provide monitoring data to the &repmgr; metadatabase.
</para> </para>
<para>
From &repmgr; 4.4, when running on the primary node, &repmgrd; can also monitor
standby disconnections/reconnections (see <xref linkend="repmgrd-primary-child-disconnection"/>).
</para>
<sect1 id="repmgrd-basic-configuration"> <sect1 id="repmgrd-basic-configuration">
<title>repmgrd configuration</title> <title>repmgrd configuration</title>
<para> <para>
To use <application>repmgrd</application>, its associated function library <emphasis>must</emphasis> be To use &repmgrd;, its associated function library <emphasis>must</emphasis> be
included via <filename>postgresql.conf</filename> with: included via <filename>postgresql.conf</filename> with:
<programlisting> <programlisting>
@@ -35,124 +39,131 @@
</para> </para>
<para> <para>
The following configuraton options apply to <application>repmgrd</application> in all circumstances: The following configuraton options apply to &repmgrd; in all circumstances:
</para> </para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><option>monitor_interval_secs</option></term>
<indexterm> <listitem>
<indexterm>
<primary>monitor_interval_secs</primary> <primary>monitor_interval_secs</primary>
</indexterm> </indexterm>
<term><option>monitor_interval_secs</option></term>
<listitem>
<para>
The interval (in seconds, default: <literal>2</literal>) to check the availability of the upstream node.
</para>
</listitem>
</varlistentry> <para>
The interval (in seconds, default: <literal>2</literal>) to check the availability of the upstream node.
</para>
</listitem>
<varlistentry id="connection-check-type"> </varlistentry>
<varlistentry id="connection-check-type">
<term><option>connection_check_type</option></term>
<listitem>
<indexterm> <indexterm>
<primary>connection_check_type</primary> <primary>connection_check_type</primary>
</indexterm> </indexterm>
<term><option>connection_check_type</option></term>
<listitem> <para>
<para> The option <option>connection_check_type</option> is used to select the method
The option <option>connection_check_type</option> is used to select the method &repmgrd; uses to determine whether the upstream node is available.
<application>repmgrd</application> uses to determine whether the upstream node is available. </para>
</para> <para>
<para> Possible values are:
Possible values are: <itemizedlist spacing="compact" mark="bullet">
<itemizedlist spacing="compact" mark="bullet"> <listitem>
<listitem>
<simpara> <simpara>
<literal>ping</literal> (default) - uses <command>PQping()</command> to <literal>ping</literal> (default) - uses <command>PQping()</command> to
determine server availability determine server availability
</simpara> </simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara> <simpara>
<literal>connection</literal> - determines server availability <literal>connection</literal> - determines server availability
by attempt ingto make a new connection to the upstream node by attempting to make a new connection to the upstream node
</simpara> </simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara> <simpara>
<literal>query</literal> - determines server availability <literal>query</literal> - determines server availability
by executing an SQL statement on the node via the existing connection by executing an SQL statement on the node via the existing connection
</simpara> </simpara>
</listitem> <simpara>
The query is a minimal throwaway query - <command>SELECT 1</command> -
which is used to determine that the server can accept queries.
</simpara>
</listitem>
</itemizedlist> </itemizedlist>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<indexterm> <term><option>reconnect_attempts</option></term>
<listitem>
<indexterm>
<primary>reconnect_attempts</primary> <primary>reconnect_attempts</primary>
</indexterm> </indexterm>
<term><option>reconnect_attempts</option></term> <para>
<listitem> The number of attempts (default: <literal>6</literal>) will be made to reconnect to an unreachable
<para> upstream node before initiating a failover.
The number of attempts (default: <literal>6</literal>) will be made to reconnect to an unreachable </para>
upstream node before initiating a failover. <para>
</para> There will be an interval of <option>reconnect_interval</option> seconds between each reconnection
<para> attempt.
There will be an interval of <option>reconnect_interval</option> seconds between each reconnection </para>
attempt. </listitem>
</para> </varlistentry>
</listitem>
</varlistentry> <varlistentry>
<varlistentry> <term><option>reconnect_interval</option></term>
<indexterm>
<listitem>
<indexterm>
<primary>reconnect_interval</primary> <primary>reconnect_interval</primary>
</indexterm> </indexterm>
<term><option>reconnect_interval</option></term>
<listitem> <para>
<para> Interval (in seconds, default: <literal>10</literal>) between attempts to reconnect to an unreachable
Interval (in seconds, default: <literal>10</literal>) between attempts to reconnect to an unreachable upstream node.
upstream node. </para>
</para> <para>
<para>
The number of reconnection attempts is defined by the parameter <option>reconnect_attempts</option>. The number of reconnection attempts is defined by the parameter <option>reconnect_attempts</option>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>degraded_monitoring_timeout</option></term>
<varlistentry> <listitem>
<indexterm> <indexterm>
<primary>degraded_monitoring_timeout</primary> <primary>degraded_monitoring_timeout</primary>
</indexterm> </indexterm>
<term><option>degraded_monitoring_timeout</option></term>
<listitem> <para>
<para> Interval (in seconds) after which &repmgrd; will terminate if
Interval (in seconds) after which <application>repmgrd</application> will terminate if either of the servers (local node and or upstream node) being monitored is no longer available
either of the servers (local node and or upstream node) being monitored is no longer available (<link linkend="repmgrd-degraded-monitoring">degraded monitoring mode</link>).
(<link linkend="repmgrd-degraded-monitoring">degraded monitoring mode</link>). </para>
</para> <para>
<para> <literal>-1</literal> (default) disables this timeout completely.
<literal>-1</literal> (default) disables this timeout completely. </para>
</para> </listitem>
</listitem> </varlistentry>
</varlistentry>
</variablelist> </variablelist>
<para> <para>
See also <filename><ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink></filename> for an annotated sample configuration file. See also <filename><ulink url="https://raw.githubusercontent.com/EnterpriseDB/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink></filename> for an annotated sample configuration file.
</para> </para>
<sect2 id="repmgrd-automatic-failover-configuration"> <sect2 id="repmgrd-automatic-failover-configuration">
<title>Required configuration for automatic failover</title> <title>Required configuration for automatic failover</title>
<para> <para>
The following <application>repmgrd</application> options <emphasis>must</emphasis> be set in The following &repmgrd; options <emphasis>must</emphasis> be set in
<filename>repmgr.conf</filename>: <filename>repmgr.conf</filename>:
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
@@ -182,17 +193,18 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<indexterm>
<primary>failover</primary>
</indexterm>
<term><option>failover</option></term> <term><option>failover</option></term>
<listitem> <listitem>
<indexterm>
<primary>failover</primary>
</indexterm>
<para> <para>
<option>failover</option> can be one of <literal>automatic</literal> or <literal>manual</literal>. <option>failover</option> can be one of <literal>automatic</literal> or <literal>manual</literal>.
</para> </para>
<note> <note>
<para> <para>
If <option>failover</option> is set to <literal>manual</literal>, <application>repmgrd</application> If <option>failover</option> is set to <literal>manual</literal>, &repmgrd;
will not take any action if a failover situation is detected, and the node may need to will not take any action if a failover situation is detected, and the node may need to
be modified manually (e.g. by executing <command><link linkend="repmgr-standby-follow">repmgr standby follow</link></command>). be modified manually (e.g. by executing <command><link linkend="repmgr-standby-follow">repmgr standby follow</link></command>).
</para> </para>
@@ -202,20 +214,33 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<indexterm>
<primary>promote_command</primary>
</indexterm>
<term><option>promote_command</option></term> <term><option>promote_command</option></term>
<listitem> <listitem>
<indexterm>
<primary>promote_command</primary>
</indexterm>
<para> <para>
The program or script defined in <option>promote_command</option> will be executed The program or script defined in <option>promote_command</option> will be executed
in a failover situation when <application>repmgrd</application> determines that in a failover situation when &repmgrd; determines that
the current node is to become the new primary node. the current node is to become the new primary node.
</para> </para>
<para> <para>
Normally <option>promote_command</option> is set as &repmgr;'s Normally <option>promote_command</option> is set as &repmgr;'s
<command><link linkend="repmgr-standby-promote">repmgr standby promote</link></command> command. <command><link linkend="repmgr-standby-promote">repmgr standby promote</link></command> command.
</para> </para>
<note>
<para>
When invoking <command>repmgr standby promote</command> (either directly via
the <option>promote_command</option>, or in a script called
via <option>promote_command</option>), <option>--siblings-follow</option>
<emphasis>must not</emphasis> be included as a
command line option for <command>repmgr standby promote</command>.
</para>
</note>
<para> <para>
It is also possible to provide a shell script to e.g. perform user-defined tasks It is also possible to provide a shell script to e.g. perform user-defined tasks
before promoting the current node. In this case the script <emphasis>must</emphasis> before promoting the current node. In this case the script <emphasis>must</emphasis>
@@ -231,8 +256,8 @@
<para> <para>
Note that the <literal>--log-to-file</literal> option will cause Note that the <literal>--log-to-file</literal> option will cause
output generated by the &repmgr; command, when executed by <application>repmgrd</application>, output generated by the &repmgr; command, when executed by &repmgrd;,
to be logged to the same destination configured to receive log output for <application>repmgrd</application>. to be logged to the same destination configured to receive log output for &repmgrd;.
</para> </para>
<note> <note>
<para> <para>
@@ -245,14 +270,15 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<indexterm>
<primary>follow_command</primary>
</indexterm>
<term><option>follow_command</option></term> <term><option>follow_command</option></term>
<listitem> <listitem>
<indexterm>
<primary>follow_command</primary>
</indexterm>
<para> <para>
The program or script defined in <option>follow_command</option> will be executed The program or script defined in <option>follow_command</option> will be executed
in a failover situation when <application>repmgrd</application> determines that in a failover situation when &repmgrd; determines that
the current node is to follow the new primary node. the current node is to follow the new primary node.
</para> </para>
<para> <para>
@@ -263,7 +289,7 @@
The <option>follow_command</option> parameter The <option>follow_command</option> parameter
should provide the <literal>--upstream-node-id=%n</literal> should provide the <literal>--upstream-node-id=%n</literal>
option to <command>repmgr standby follow</command>; the <literal>%n</literal> will be replaced by option to <command>repmgr standby follow</command>; the <literal>%n</literal> will be replaced by
<application>repmgrd</application> with the ID of the new primary node. If this is not provided, &repmgrd; with the ID of the new primary node. If this is not provided,
<command>repmgr standby follow</command> will attempt to determine the new primary by itself, but if the <command>repmgr standby follow</command> will attempt to determine the new primary by itself, but if the
original primary comes back online after the new primary is promoted, there is a risk that original primary comes back online after the new primary is promoted, there is a risk that
<command>repmgr standby follow</command> will result in the node continuing to follow <command>repmgr standby follow</command> will result in the node continuing to follow
@@ -284,8 +310,8 @@
<para> <para>
Note that the <literal>--log-to-file</literal> option will cause Note that the <literal>--log-to-file</literal> option will cause
output generated by the &repmgr; command, when executed by <application>repmgrd</application>, output generated by the &repmgr; command, when executed by &repmgrd;,
to be logged to the same destination configured to receive log output for <application>repmgrd</application>. to be logged to the same destination configured to receive log output for &repmgrd;.
</para> </para>
<note> <note>
<para> <para>
@@ -303,41 +329,47 @@
</sect2> </sect2>
<sect2 id="repmgrd-automatic-failover-configuration-optional"> <sect2 id="repmgrd-automatic-failover-configuration-optional" xreflabel="Optional configuration for automatic failover">
<title>Optional configuration for automatic failover</title> <title>Optional configuration for automatic failover</title>
<para> <para>
The following configuraton options can be use to fine-tune automatic failover: The following configuraton options can be used to fine-tune automatic failover:
</para> </para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<indexterm>
<primary>priority</primary>
</indexterm>
<term><option>priority</option></term> <term><option>priority</option></term>
<listitem> <listitem>
<indexterm>
<primary>priority</primary>
</indexterm>
<para> <para>
Indicates a preferred priority (default: <literal>100</literal>) for promoting nodes; Indicates a preferred priority (default: <literal>100</literal>) for promoting nodes.
a value of zero prevents the node being promoted to primary.
</para> </para>
<para> <para>
Note that the priority setting is only applied if two or more nodes are Note that the priority setting is only applied if two or more nodes are
determined as promotion candidates; in that case the node with the determined as promotion candidates; in that case the node with the
higher priority is selected. higher priority is selected.
</para> </para>
<para>
A value of zero will always prevent the node being promoted to primary, even if there
is no other promotion candidate.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<indexterm>
<primary>failover_validation_command</primary>
</indexterm>
<term><option>failover_validation_command</option></term> <term><option>failover_validation_command</option></term>
<listitem> <listitem>
<indexterm>
<primary>failover_validation_command</primary>
</indexterm>
<para> <para>
User-defined script to execute for an external mechanism to validate the failover User-defined script to execute for an external mechanism to validate the failover
decision made by <application>repmgrd</application>. decision made by &repmgrd;.
</para> </para>
<note> <note>
<para> <para>
@@ -346,8 +378,8 @@
</para> </para>
</note> </note>
<para> <para>
One or both of the following parameter placeholders One or more of the following parameter placeholders
should be provided, which will be replaced by repmgrd with the appropriate may be provided, which will be replaced by repmgrd with the appropriate
value: value:
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
@@ -356,6 +388,15 @@
<listitem> <listitem>
<simpara><literal>%a</literal>: node name</simpara> <simpara><literal>%a</literal>: node name</simpara>
</listitem> </listitem>
<listitem>
<simpara><literal>%v</literal>: number of visible nodes</simpara>
</listitem>
<listitem>
<simpara><literal>%u</literal>: number of shared upstream nodes</simpara>
</listitem>
<listitem>
<simpara><literal>%t</literal>: total number of nodes</simpara>
</listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para> <para>
@@ -364,13 +405,63 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>primary_visibility_consensus</option></term>
<listitem>
<indexterm>
<primary>primary_visibility_consensus</primary>
</indexterm>
<para>
If <literal>true</literal>, only continue with failover if no standbys
(or the witness server, if present) have seen the primary node recently.
</para>
<note>
<para>
This option <emphasis>must</emphasis> be identically configured
on all nodes.
</para>
</note>
</listitem>
</varlistentry>
<varlistentry>
<term><option>always_promote</option></term>
<listitem>
<indexterm>
<primary>always_promote</primary>
</indexterm>
<para>
Default: <literal>false</literal>.
</para>
<para>
If <literal>true</literal>, promote the local node even if its
&repmgr; metadata is not up-to-date.
</para>
<para>
Normally &repmgr; expects its metadata (stored in the <varname>repmgr.nodes</varname>
table) to be up-to-date so &repmgrd; can take the correct action during a failover.
However it's possible that updates made on the primary may not
have propagated to the standby (promotion candidate). In this case &repmgrd; will
default to not promoting the standby. This behaviour can be overridden by setting
<option>always_promote</option> to <literal>true</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<indexterm>
<primary>standby_disconnect_on_failover</primary>
</indexterm>
<term><option>standby_disconnect_on_failover</option></term> <term><option>standby_disconnect_on_failover</option></term>
<listitem> <listitem>
<indexterm>
<primary>standby_disconnect_on_failover</primary>
</indexterm>
<para> <para>
In a failover situation, disconnect the local node's WAL receiver. In a failover situation, disconnect the local node's WAL receiver.
</para> </para>
@@ -387,7 +478,7 @@
for this option. for this option.
</para> </para>
<para> <para>
<application>repmgrd</application> will refuse to start if this option is set &repmgrd; will refuse to start if this option is set
but either of these prerequisites is not met. but either of these prerequisites is not met.
</para> </para>
</note> </note>
@@ -398,6 +489,32 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>repmgrd_exit_on_inactive_node</option></term>
<listitem>
<indexterm>
<primary>repmgrd_exit_on_inactive_node</primary>
</indexterm>
<para>
This parameter is available in &repmgr; 5.3 and later.
</para>
<para>
If a node was marked as inactive but is running, and this option is set to
<literal>true</literal>, &repmgrd; will abort on startup.
</para>
<para>
By default, <option>repmgrd_exit_on_inactive_node</option> is set
to <literal>false</literal>, in which case &repmgrd; will set the
node record to active on startup.
</para>
<para>
Setting this parameter to <literal>true</literal> causes &repmgrd;
to behave in the same way it did in &repmgr; 5.2 and earlier.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
<para> <para>
@@ -408,11 +525,12 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<indexterm>
<primary>election_rerun_interval</primary>
</indexterm>
<term><option>election_rerun_interval</option></term> <term><option>election_rerun_interval</option></term>
<listitem> <listitem>
<indexterm>
<primary>election_rerun_interval</primary>
</indexterm>
<para> <para>
If <option>failover_validation_command</option> is set, and the command returns If <option>failover_validation_command</option> is set, and the command returns
an error, pause the specified amount of seconds (default: 15) before rerunning the election. an error, pause the specified amount of seconds (default: 15) before rerunning the election.
@@ -422,11 +540,12 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>sibling_nodes_disconnect_timeout</primary>
</indexterm>
<term><option>sibling_nodes_disconnect_timeout</option></term> <term><option>sibling_nodes_disconnect_timeout</option></term>
<listitem> <listitem>
<indexterm>
<primary>sibling_nodes_disconnect_timeout</primary>
</indexterm>
<para> <para>
If <option>standby_disconnect_on_failover</option> is <literal>true</literal>, the If <option>standby_disconnect_on_failover</option> is <literal>true</literal>, the
maximum length of time (in seconds, default: <literal>30</literal>) maximum length of time (in seconds, default: <literal>30</literal>)
@@ -441,38 +560,58 @@
</sect2> </sect2>
<sect2 id="repmgrd-automatic-failover-configuration-pgbouncer-fencing">
<title>Configuring &repmgrd; and pgbouncer to fence a failed primary node</title>
<indexterm>
<primary>fencing</primary>
<secondary>using repmgrd and pgbouncer to fence a failed primary node</secondary>
</indexterm>
<indexterm>
<primary>PgBouncer</primary>
<secondary>using repmgrd and pgbouncer to fence a failed primary node</secondary>
</indexterm>
<para>
For further details and a reference implementation, see the separate document
<ulink url="https://github.com/EnterpriseDB/repmgr/blob/master/doc/repmgrd-node-fencing.md">Fencing a failed master node with repmgrd and PgBouncer</ulink>.
</para>
</sect2>
<sect2 id="postgresql-service-configuration"> <sect2 id="postgresql-service-configuration">
<title>PostgreSQL service configuration</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>PostgreSQL service configuration</secondary> <secondary>PostgreSQL service configuration</secondary>
</indexterm> </indexterm>
<title>PostgreSQL service configuration</title>
<para> <para>
If using automatic failover, currently <application>repmgrd</application> will need to execute If using automatic failover, currently &repmgrd; will need to execute
<link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link> <link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>
to restart PostgreSQL on standbys to have them follow a new primary. to restart PostgreSQL on standbys to have them follow a new primary.
</para> </para>
<para> <para>
To ensure this happens smoothly, it's essential to provide the appropriate system/service restart To ensure this happens smoothly, it's essential to provide the appropriate system/service restart
command appropriate to your operating system via <varname>service_restart_command</varname> command appropriate to your operating system via <varname>service_restart_command</varname>
in <filename>repmgr.conf</filename>. If you don't do this, <application>repmgrd</application> in <filename>repmgr.conf</filename>. If you don't do this, &repmgrd;
will default to using <command>pg_ctl</command>, which can result in unexpected problems, will default to using <command>pg_ctl</command>, which can result in unexpected problems,
particularly on <application>systemd</application>-based systems. particularly on <application>systemd</application>-based systems.
</para> </para>
<para> <para>
For more details, see <xref linkend="configuration-file-service-commands">. For more details, see <xref linkend="configuration-file-service-commands"/>.
</para> </para>
</sect2> </sect2>
<sect2 id="repmgrd-service-configuration"> <sect2 id="repmgrd-service-configuration">
<title>repmgrd service configuration</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>repmgrd service configuration</secondary> <secondary>repmgrd service configuration</secondary>
</indexterm> </indexterm>
<title>repmgrd service configuration</title>
<para> <para>
If you are intending to use the <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> If you are intending to use the <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link>
and <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> commands, the following and <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link>
commands, the following
parameters <emphasis>must</emphasis> be set in <filename>repmgr.conf</filename>: parameters <emphasis>must</emphasis> be set in <filename>repmgr.conf</filename>:
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
@@ -488,10 +627,10 @@
</para> </para>
<para> <para>
Example (for &repmgr; with PostgreSQL 11 on CentOS 7): Example (for &repmgr; with PostgreSQL 12 on CentOS 7):
<programlisting> <programlisting>
repmgrd_service_start_command='sudo systemctl repmgr11 start' repmgrd_service_start_command='sudo systemctl repmgr12 start'
repmgrd_service_stop_command='sudo systemctl repmgr11 stop' repmgrd_service_stop_command='sudo systemctl repmgr12 stop'
</programlisting> </programlisting>
</para> </para>
<para> <para>
@@ -501,11 +640,12 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
<sect2 id="repmgrd-monitoring-configuration" xreflabel="repmgrd monitoring configuration"> <sect2 id="repmgrd-monitoring-configuration" xreflabel="repmgrd monitoring configuration">
<title>Monitoring configuration</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>monitoring configuration</secondary> <secondary>monitoring configuration</secondary>
</indexterm> </indexterm>
<title>Monitoring configuration</title>
<para> <para>
To enable monitoring, set: To enable monitoring, set:
<programlisting> <programlisting>
@@ -517,32 +657,34 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
the option <option>monitor_interval_secs</option> (see above). the option <option>monitor_interval_secs</option> (see above).
</para> </para>
<para> <para>
For more details on monitoring, see <xref linkend="repmgrd-monitoring">. For more details on monitoring, see <xref linkend="repmgrd-monitoring"/>. For information on
monitoring standby disconnections, see <xref linkend="repmgrd-primary-child-disconnection"/>.
</para> </para>
</sect2> </sect2>
<sect2 id="repmgrd-reloading-configuration"xreflabel="reloading repmgrd configuration"> <sect2 id="repmgrd-reloading-configuration" xreflabel="reloading repmgrd configuration">
<title>Applying configuration changes to repmgrd</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>applying configuration changes</secondary> <secondary>applying configuration changes</secondary>
</indexterm> </indexterm>
<title>Applying configuration changes to repmgrd</title>
<para> <para>
To apply configuration file changes to a running <application>repmgrd</application> To apply configuration file changes to a running &repmgrd;
daemon, execute the operating system's <application>repmgrd</application> service reload command daemon, execute the operating system's &repmgrd; service reload command
(see <xref linkend="appendix-packages"> for examples), (see <xref linkend="appendix-packages"/> for examples),
or for instances which were manually started, execute <command>kill -HUP</command>, e.g. or for instances which were manually started, execute <command>kill -HUP</command>, e.g.
<command>kill -HUP `cat /tmp/repmgrd.pid`</command>. <command>kill -HUP `cat /tmp/repmgrd.pid`</command>.
</para> </para>
<tip> <tip>
<para> <para>
Check the <application>repmgrd</application> log to see what changes were Check the &repmgrd; log to see what changes were
applied, or if any issues were encountered when reloading the configuration. applied, or if any issues were encountered when reloading the configuration.
</para> </para>
</tip> </tip>
<para> <para>
Note that only the following subset of configuration file parameters can be changed on a Note that only the following subset of configuration file parameters can be changed on a
running <application>repmgrd</application> daemon: running &repmgrd; daemon:
</para> </para>
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
@@ -552,18 +694,41 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
</simpara> </simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara> <simpara>
<varname>bdr_local_monitoring_only</varname> <varname>child_nodes_check_interval</varname>
</simpara> </simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara> <simpara>
<varname>bdr_recovery_timeout</varname> <varname>child_nodes_connected_include_witness</varname>
</simpara> </simpara>
</listitem> </listitem>
<listitem>
<simpara>
<varname>child_nodes_connected_min_count</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>child_nodes_disconnect_command</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>child_nodes_disconnect_min_count</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>child_nodes_disconnect_timeout</varname>
</simpara>
</listitem>
<listitem> <listitem>
<simpara> <simpara>
@@ -655,6 +820,18 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
</simpara> </simpara>
</listitem> </listitem>
<listitem>
<simpara>
<varname>primary_visibility_consensus</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>always_promote</varname>
</simpara>
</listitem>
<listitem> <listitem>
<simpara> <simpara>
<varname>promote_command</varname> <varname>promote_command</varname>
@@ -743,7 +920,7 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
<note> <note>
<para> <para>
After executing <command><link linkend="repmgr-standby-register">repmgr standby register --force</link></command>, After executing <command><link linkend="repmgr-standby-register">repmgr standby register --force</link></command>,
<application>repmgrd</application> <emphasis>must</emphasis> be restarted for the changes to take effect. &repmgrd; <emphasis>must</emphasis> be restarted for the changes to take effect.
</para> </para>
</note> </note>
@@ -752,24 +929,25 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
</sect1> </sect1>
<sect1 id="repmgrd-daemon" xreflabel="repmgrd daemon"> <sect1 id="repmgrd-daemon" xreflabel="repmgrd daemon">
<title>repmgrd daemon</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>starting and stopping</secondary> <secondary>starting and stopping</secondary>
</indexterm> </indexterm>
<title>repmgrd daemon</title>
<para> <para>
If installed from a package, the <application>repmgrd</application> can be started If installed from a package, the &repmgrd; can be started
via the operating system's service command, e.g. in <application>systemd</application> via the operating system's service command, e.g. in <application>systemd</application>
using <command>systemctl</command>. using <command>systemctl</command>.
</para> </para>
<para> <para>
See appendix <xref linkend="appendix-packages"> for details of service commands See appendix <xref linkend="appendix-packages"/> for details of service commands
for different distributions. for different distributions.
</para> </para>
<para> <para>
The commands <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> and The commands <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> and
<link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> can be used <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> can be used
as convenience wrappers to start and stop <application>repmgrd</application>. as convenience wrappers to start and stop &repmgrd; on the local node.
</para> </para>
<important> <important>
<para> <para>
@@ -781,13 +959,15 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
</para> </para>
</important> </important>
<para> <para>
<application>repmgrd</application> can be started manually like this: &repmgrd; can be started manually like this:
<programlisting> <programlisting>
repmgrd -f /etc/repmgr.conf --pid-file /tmp/repmgrd.pid</programlisting> repmgrd -f /etc/repmgr.conf --pid-file /tmp/repmgrd.pid</programlisting>
and stopped with <command>kill `cat /tmp/repmgrd.pid`</command>. Adjust paths as appropriate. and stopped with <command>kill `cat /tmp/repmgrd.pid`</command>. Adjust paths as appropriate.
</para> </para>
<sect2 id="repmgrd-pid-file" xreflabel="repmgrd's PID file"> <sect2 id="repmgrd-pid-file" xreflabel="repmgrd's PID file">
<title>repmgrd's PID file</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>PID file</secondary> <secondary>PID file</secondary>
@@ -796,9 +976,8 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
<primary>PID file</primary> <primary>PID file</primary>
<secondary>repmgrd</secondary> <secondary>repmgrd</secondary>
</indexterm> </indexterm>
<title>repmgrd's PID file</title>
<para> <para>
<application>repmgrd</application> will generate a PID file by default. &repmgrd; will generate a PID file by default.
</para> </para>
<note> <note>
<simpara> <simpara>
@@ -818,13 +997,13 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
<option>--pid-file</option> may be deprecated in future releases. <option>--pid-file</option> may be deprecated in future releases.
</para> </para>
<para> <para>
If a PID file location was specified by the package maintainer, <application>repmgrd</application> If a PID file location was specified by the package maintainer, &repmgrd;
will use that. This only applies if &repmgr; was installed from a package and the package will use that. This only applies if &repmgr; was installed from a package and the package
maintainer has specified the PID file location. maintainer has specified the PID file location.
</para> </para>
<para> <para>
If none of the above apply, <application>repmgrd</application> will create a PID file If none of the above apply, &repmgrd; will create a PID file
in the operating system's temporary directory (as setermined by the environment variable in the operating system's temporary directory (as determined by the environment variable
<varname>TMPDIR</varname>, or if that is not set, will use <filename>/tmp</filename>). <varname>TMPDIR</varname>, or if that is not set, will use <filename>/tmp</filename>).
</para> </para>
<para> <para>
@@ -832,15 +1011,17 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
<option>--no-pid-file</option>. <option>--no-pid-file</option>.
</para> </para>
<para> <para>
To see which PID file <application>repmgrd</application> would use, execute <application>repmgrd</application> To see which PID file &repmgrd; would use, execute &repmgrd;
with the option <option>--show-pid-file</option>. <application>repmgrd</application> with the option <option>--show-pid-file</option>. &repmgrd;
will not start if this option is provided. Note that the value shown is the will not start if this option is provided. Note that the value shown is the
file <application>repmgrd</application> would use next time it starts, and is file &repmgrd; would use next time it starts, and is
not necessarily the PID file currently in use. not necessarily the PID file currently in use.
</para> </para>
</sect2> </sect2>
<sect2 id="repmgrd-configuration-debian-ubuntu"> <sect2 id="repmgrd-configuration-debian-ubuntu">
<title>repmgrd daemon configuration on Debian/Ubuntu</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>Debian/Ubuntu and daemon configuration</secondary> <secondary>Debian/Ubuntu and daemon configuration</secondary>
@@ -850,11 +1031,9 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
<secondary>repmgrd daemon configuration</secondary> <secondary>repmgrd daemon configuration</secondary>
</indexterm> </indexterm>
<title>repmgrd daemon configuration on Debian/Ubuntu</title>
<para> <para>
If &repmgr; was installed from Debian/Ubuntu packages, additional configuration If &repmgr; was installed from Debian/Ubuntu packages, additional configuration
is required before <application>repmgrd</application> is started as a daemon. is required before &repmgrd; is started as a daemon.
</para> </para>
<para> <para>
This is done via the file <filename>/etc/default/repmgrd</filename>, which by default This is done via the file <filename>/etc/default/repmgrd</filename>, which by default
@@ -888,22 +1067,45 @@ REPMGRD_OPTS="--daemonize=false"
</para> </para>
<tip> <tip>
<para> <para>
See <xref linkend="packages-debian-ubuntu"> for details of the Debian/Ubuntu packages and See <xref linkend="packages-debian-ubuntu"/> for details of the Debian/Ubuntu packages and
typical file locations (including <filename>repmgr.conf</filename>). typical file locations (including <filename>repmgr.conf</filename>).
</para> </para>
</tip> </tip>
<para> <para>
From <application>repmgrd</application> 4.1, ensure <varname>REPMGRD_OPTS</varname> includes From &repmgrd; 4.1, ensure <varname>REPMGRD_OPTS</varname> includes
<option>--daemonize=false</option>, as daemonization is handled by the service command. <option>--daemonize=false</option>, as daemonization is handled by the service command.
</para> </para>
<para> <para>
If using <application>systemd</application>, you may need to execute <command>systemctl daemon-reload</command>. If using <application>systemd</application>, you may need to execute <command>systemctl daemon-reload</command>.
Also, if you attempted to start <application>repmgrd</application> using <command>systemctl start repmgrd</command>, Also, if you attempted to start &repmgrd; using <command>systemctl start repmgrd</command>,
you'll need to execute <command>systemctl stop repmgrd</command>. Because that's how <application>systemd</application> you'll need to execute <command>systemctl stop repmgrd</command>. Because that's how <application>systemd</application>
rolls. rolls.
</para> </para>
</sect2> </sect2>
<sect2 id="repmgrd-daemon-monitoring">
<title>repmgrd daemon monitoring</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>monitoring</secondary>
</indexterm>
<indexterm>
<primary>monitoring</primary>
<secondary>repmgrd</secondary>
</indexterm>
<para>
The command <command><link linkend="repmgr-service-status">repmgr service status</link></command>
provides an overview of the &repmgrd; daemon status (including pause status)
on all nodes in the cluster.
</para>
<para>
From &repmgr; 5.3, <command><link linkend="repmgr-node-check">repmgr node check --repmgrd</link></command>
can be used to check the status of &repmgrd; (including pause status)
on the local node.
</para>
</sect2>
</sect1> </sect1>
<sect1 id="repmgrd-connection-settings"> <sect1 id="repmgrd-connection-settings">
@@ -932,7 +1134,9 @@ REPMGRD_OPTS="--daemonize=false"
<sect1 id="repmgrd-log-rotation"> <sect1 id="repmgrd-log-rotation">
<title>repmgrd log rotation</title>
<indexterm> <indexterm>
<primary>log rotation</primary> <primary>log rotation</primary>
<secondary>repmgrd</secondary> <secondary>repmgrd</secondary>
@@ -943,9 +1147,8 @@ REPMGRD_OPTS="--daemonize=false"
<secondary>log rotation</secondary> <secondary>log rotation</secondary>
</indexterm> </indexterm>
<title>repmgrd log rotation</title>
<para> <para>
To ensure the current <application>repmgrd</application> logfile To ensure the current &repmgrd; logfile
(specified in <filename>repmgr.conf</filename> with the parameter (specified in <filename>repmgr.conf</filename> with the parameter
<option>log_file</option>) does not grow indefinitely, configure your <option>log_file</option>) does not grow indefinitely, configure your
system's <command>logrotate</command> to regularly rotate it. system's <command>logrotate</command> to regularly rotate it.

View File

@@ -108,7 +108,7 @@ The actual script is as follows; adjust the configurable items as appropriate:
# 1. Promote this node from standby to primary # 1. Promote this node from standby to primary
repmgr standby promote -f /etc/repmgr.conf repmgr standby promote -f /etc/repmgr.conf --log-to-file
# 2. Reconfigure pgbouncer instances # 2. Reconfigure pgbouncer instances
@@ -146,7 +146,7 @@ Script and template file should be installed on each node where `repmgrd` is run
Finally, set `promote_command` in `repmgr.conf` on each node to Finally, set `promote_command` in `repmgr.conf` on each node to
point to the custom promote script: point to the custom promote script:
promote_command=/var/lib/postgres/repmgr/promote.sh promote_command='/var/lib/postgres/repmgr/promote.sh'
and reload/restart any running `repmgrd` instances for the changes to take and reload/restart any running `repmgrd` instances for the changes to take
effect. effect.

View File

@@ -1,13 +1,14 @@
<chapter id="repmgrd-operation" xreflabel="repmgrd operation"> <chapter id="repmgrd-operation" xreflabel="repmgrd operation">
<title>repmgrd operation</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>operation</secondary> <secondary>operation</secondary>
</indexterm> </indexterm>
<title>repmgrd operation</title> <sect1 id="repmgrd-pausing" xreflabel="pausing the repmgrd service">
<title>Pausing the repmgrd service</title>
<sect1 id="repmgrd-pausing">
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
@@ -18,45 +19,44 @@
<primary>pausing repmgrd</primary> <primary>pausing repmgrd</primary>
</indexterm> </indexterm>
<title>Pausing repmgrd</title>
<para> <para>
In normal operation, <application>repmgrd</application> monitors the state of the In normal operation, &repmgrd; monitors the state of the
PostgreSQL node it is running on, and will take appropriate action if problems PostgreSQL node it is running on, and will take appropriate action if problems
are detected, e.g. (if so configured) promote the node to primary, if the existing are detected, e.g. (if so configured) promote the node to primary, if the existing
primary has been determined as failed. primary has been determined as failed.
</para> </para>
<para> <para>
However, <application>repmgrd</application> is unable to distinguish between However, &repmgrd; is unable to distinguish between
planned outages (such as performing a <link linkend="performing-switchover">switchover</link> planned outages (such as performing a <link linkend="performing-switchover">switchover</link>
or installing PostgreSQL maintenance released), and an actual server outage. In versions prior to or installing PostgreSQL maintenance released), and an actual server outage. In versions prior to
&repmgr; 4.2 it was necessary to stop <application>repmgrd</application> on all nodes (or at least &repmgr; 4.2 it was necessary to stop &repmgrd; on all nodes (or at least
on all nodes where <application>repmgrd</application> is on all nodes where &repmgrd; is
<link linkend="repmgrd-automatic-failover">configured for automatic failover</link>) <link linkend="repmgrd-automatic-failover">configured for automatic failover</link>)
to prevent <application>repmgrd</application> from making unintentional changes to the to prevent &repmgrd; from making unintentional changes to the
replication cluster. replication cluster.
</para> </para>
<para> <para>
From <link linkend="release-4.2">&repmgr; 4.2</link>, <application>repmgrd</application> From <link linkend="release-4.2">&repmgr; 4.2</link>, &repmgrd;
can now be &quot;paused&quot;, i.e. instructed not to take any action such as performing a failover. can now be &quot;paused&quot;, i.e. instructed not to take any action such as performing a failover.
This can be done from any node in the cluster, removing the need to stop/restart This can be done from any node in the cluster, removing the need to stop/restart
each <application>repmgrd</application> individually. each &repmgrd; individually.
</para> </para>
<note> <note>
<para> <para>
For major PostgreSQL upgrades, e.g. from PostgreSQL 10 to PostgreSQL 11, For major PostgreSQL upgrades, e.g. from PostgreSQL 11 to PostgreSQL 12,
<application>repmgrd</application> should be shut down completely and only started up &repmgrd; should be shut down completely and only started up
once the &repmgr; packages for the new PostgreSQL major version have been installed. once the &repmgr; packages for the new PostgreSQL major version have been installed.
</para> </para>
</note> </note>
<sect2 id="repmgrd-pausing-prerequisites"> <sect2 id="repmgrd-pausing-prerequisites">
<title>Prerequisites for pausing <application>repmgrd</application></title> <title>Prerequisites for pausing &repmgrd;</title>
<para> <para>
In order to be able to pause/unpause <application>repmgrd</application>, following In order to be able to pause/unpause &repmgrd;, following
prerequisites must be met: prerequisites must be met:
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
@@ -86,19 +86,23 @@
</sect2> </sect2>
<sect2 id="repmgrd-pausing-execution"> <sect2 id="repmgrd-pausing-execution">
<title>Pausing/unpausing <application>repmgrd</application></title> <title>Pausing/unpausing &repmgrd;</title>
<para> <para>
To pause <application>repmgrd</application>, execute <link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link>, e.g.: To pause &repmgrd;, execute <link linkend="repmgr-service-pause"><command>repmgr service pause</command></link>
(&repmgr; 4.2 - 4.4: <link linkend="repmgr-service-pause"><command>repmgr daemon pause</command></link>),
e.g.:
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf daemon pause $ repmgr -f /etc/repmgr.conf service pause
NOTICE: node 1 (node1) paused NOTICE: node 1 (node1) paused
NOTICE: node 2 (node2) paused NOTICE: node 2 (node2) paused
NOTICE: node 3 (node3) paused</programlisting> NOTICE: node 3 (node3) paused</programlisting>
</para> </para>
<para> <para>
The state of <application>repmgrd</application> on each node can be checked with The state of &repmgrd; on each node can be checked with
<link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>, e.g.: <link linkend="repmgr-service-status"><command>repmgr service status</command></link>
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status (&repmgr; 4.2 - 4.4: <link linkend="repmgr-service-status"><command>repmgr daemon status</command></link>),
e.g.:
<programlisting>$ repmgr -f /etc/repmgr.conf service status
ID | Name | Role | Status | repmgrd | PID | Paused? ID | Name | Role | Status | repmgrd | PID | Paused?
----+-------+---------+---------+---------+------+--------- ----+-------+---------+---------+---------+------+---------
1 | node1 | primary | running | running | 7851 | yes 1 | node1 | primary | running | running | 7851 | yes
@@ -108,38 +112,41 @@ NOTICE: node 3 (node3) paused</programlisting>
<note> <note>
<para> <para>
If executing a switchover with <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>, If executing a switchover with <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>,
&repmgr; will automatically pause/unpause <application>repmgrd</application> as part of the switchover process. &repmgr; will automatically pause/unpause the &repmgrd; service as part of the switchover process.
</para> </para>
</note> </note>
<para> <para>
If the primary (in this example, <literal>node1</literal>) is stopped, <application>repmgrd</application> If the primary (in this example, <literal>node1</literal>) is stopped, &repmgrd;
running on one of the standbys (here: <literal>node2</literal>) will react like this: running on one of the standbys (here: <literal>node2</literal>) will react like this:
<programlisting> <programlisting>
[2018-09-20 12:22:21] [WARNING] unable to connect to upstream node "node1" (node ID: 1) [2019-08-28 12:22:21] [WARNING] unable to connect to upstream node "node1" (node ID: 1)
[2018-09-20 12:22:21] [INFO] checking state of node 1, 1 of 5 attempts [2019-08-28 12:22:21] [INFO] checking state of node 1, 1 of 5 attempts
[2018-09-20 12:22:21] [INFO] sleeping 1 seconds until next reconnection attempt [2019-08-28 12:22:21] [INFO] sleeping 1 seconds until next reconnection attempt
... ...
[2018-09-20 12:22:24] [INFO] sleeping 1 seconds until next reconnection attempt [2019-08-28 12:22:24] [INFO] sleeping 1 seconds until next reconnection attempt
[2018-09-20 12:22:25] [INFO] checking state of node 1, 5 of 5 attempts [2019-08-28 12:22:25] [INFO] checking state of node 1, 5 of 5 attempts
[2018-09-20 12:22:25] [WARNING] unable to reconnect to node 1 after 5 attempts [2019-08-28 12:22:25] [WARNING] unable to reconnect to node 1 after 5 attempts
[2018-09-20 12:22:25] [NOTICE] node is paused [2019-08-28 12:22:25] [NOTICE] node is paused
[2018-09-20 12:22:33] [INFO] node "node2" (node ID: 2) monitoring upstream node "node1" (node ID: 1) in degraded state [2019-08-28 12:22:33] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (node ID: 1) in degraded state
[2018-09-20 12:22:33] [DETAIL] repmgrd paused by administrator [2019-08-28 12:22:33] [DETAIL] repmgrd paused by administrator
[2018-09-20 12:22:33] [HINT] execute "repmgr daemon unpause" to resume normal failover mode</programlisting> [2019-08-28 12:22:33] [HINT] execute "repmgr service unpause" to resume normal failover mode</programlisting>
</para> </para>
<para> <para>
If the primary becomes available again (e.g. following a software upgrade), <application>repmgrd</application> If the primary becomes available again (e.g. following a software upgrade), &repmgrd;
will automatically reconnect, e.g.: will automatically reconnect, e.g.:
<programlisting> <programlisting>
[2018-09-20 13:12:41] [NOTICE] reconnected to upstream node 1 after 8 seconds, resuming monitoring</programlisting> [2019-08-28 12:25:41] [NOTICE] reconnected to upstream node "node1" (ID: 1) after 8 seconds, resuming monitoring</programlisting>
</para> </para>
<para> <para>
To unpause <application>repmgrd</application>, execute <link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>, e.g.: To unpause the &repmgrd; service, execute
<link linkend="repmgr-service-unpause"><command>repmgr service unpause</command></link>
((&repmgr; 4.2 - 4.4: <link linkend="repmgr-service-unpause"><command>repmgr daemon unpause</command></link>),
e.g.:
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf daemon unpause $ repmgr -f /etc/repmgr.conf service unpause
NOTICE: node 1 (node1) unpaused NOTICE: node 1 (node1) unpaused
NOTICE: node 2 (node2) unpaused NOTICE: node 2 (node2) unpaused
NOTICE: node 3 (node3) unpaused</programlisting> NOTICE: node 3 (node3) unpaused</programlisting>
@@ -147,54 +154,61 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<note> <note>
<para> <para>
If the previous primary is no longer accessible when <application>repmgrd</application> If the previous primary is no longer accessible when &repmgrd;
is unpaused, no failover action will be taken. Instead, a new primary must be manually promoted using is unpaused, no failover action will be taken. Instead, a new primary must be manually promoted using
<link linkend="repmgr-standby-promote"><command>repmgr standby promote</command></link>, <link linkend="repmgr-standby-promote"><command>repmgr standby promote</command></link>,
and any standbys attached to the new primary with and any standbys attached to the new primary with
<link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>. <link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>.
</para> </para>
<para> <para>
This is to prevent <link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link> This is to prevent execution of <link linkend="repmgr-service-unpause"><command>repmgr service unpause</command></link>
resulting in the automatic promotion of a new primary, which may be a problem particularly resulting in the automatic promotion of a new primary, which may be a problem particularly
in larger clusters, where <application>repmgrd</application> could select a different promotion in larger clusters, where &repmgrd; could select a different promotion
candidate to the one intended by the administrator. candidate to the one intended by the administrator.
</para> </para>
</note> </note>
</sect2> </sect2>
<sect2 id="repmgrd-pausing-details"> <sect2 id="repmgrd-pausing-details">
<title>Details on the <application>repmgrd</application> pausing mechanism</title> <title>Details on the &repmgrd; pausing mechanism</title>
<para> <para>
The pause state of each node will be stored over a PostgreSQL restart. The pause state of each node will be stored over a PostgreSQL restart.
</para> </para>
<para> <para>
<link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link> and <link linkend="repmgr-service-pause"><command>repmgr service pause</command></link> and
<link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link> can be <link linkend="repmgr-service-unpause"><command>repmgr service unpause</command></link> can be
executed even if <application>repmgrd</application> is not running; in this case, executed even if &repmgrd; is not running; in this case,
<application>repmgrd</application> will start up in whichever pause state has been set. &repmgrd; will start up in whichever pause state has been set.
</para> </para>
<note> <note>
<para> <para>
<link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link> and <link linkend="repmgr-service-pause"><command>repmgr service pause</command></link> and
<link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link> <link linkend="repmgr-service-unpause"><command>repmgr service unpause</command></link>
<emphasis>do not</emphasis> stop/start <application>repmgrd</application>. <emphasis>do not</emphasis> start/stop &repmgrd;.
</para>
<para>
The commands <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link>
and <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link>
(<link linkend="repmgrd-service-configuration">if correctly configured</link>) can be used to start/stop
&repmgrd; on individual nodes.
</para> </para>
</note> </note>
</sect2> </sect2>
</sect1> </sect1>
<sect1 id="repmgrd-wal-replay-pause"> <sect1 id="repmgrd-wal-replay-pause">
<title>repmgrd and paused WAL replay</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>paused WAL replay</secondary> <secondary>paused WAL replay</secondary>
</indexterm> </indexterm>
<title>repmgrd and paused WAL replay</title>
<para> <para>
If WAL replay has been paused (using <command>pg_wal_replay_pause()</command>, If WAL replay has been paused (using <command>pg_wal_replay_pause()</command>,
on PostgreSQL 9.6 and earlier <command>pg_xlog_replay_pause()</command>), on PostgreSQL 9.6 and earlier <command>pg_xlog_replay_pause()</command>),
in a failover situation <application>repmgrd</application> will in a failover situation &repmgrd; will
automatically resume WAL replay. automatically resume WAL replay.
</para> </para>
<para> <para>
@@ -214,6 +228,8 @@ NOTICE: node 3 (node3) unpaused</programlisting>
</sect1> </sect1>
<sect1 id="repmgrd-degraded-monitoring" xreflabel="repmgrd degraded monitoring"> <sect1 id="repmgrd-degraded-monitoring" xreflabel="repmgrd degraded monitoring">
<title>"degraded monitoring" mode</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>degraded monitoring</secondary> <secondary>degraded monitoring</secondary>
@@ -223,11 +239,10 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<primary>degraded monitoring</primary> <primary>degraded monitoring</primary>
</indexterm> </indexterm>
<title>"degraded monitoring" mode</title>
<para> <para>
In certain circumstances, <application>repmgrd</application> is not able to fulfill its primary mission In certain circumstances, &repmgrd; is not able to fulfill its primary mission
of monitoring the node's upstream server. In these cases it enters &quot;degraded monitoring&quot; of monitoring the node's upstream server. In these cases it enters &quot;degraded monitoring&quot;
mode, where <application>repmgrd</application> remains active but is waiting for the situation mode, where &repmgrd; remains active but is waiting for the situation
to be resolved. to be resolved.
</para> </para>
<para> <para>
@@ -268,8 +283,8 @@ NOTICE: node 3 (node3) unpaused</programlisting>
Example output in a situation where there is only one standby with <literal>failover=manual</literal>, Example output in a situation where there is only one standby with <literal>failover=manual</literal>,
and the primary node is unavailable (but is later restarted): and the primary node is unavailable (but is later restarted):
<programlisting> <programlisting>
[2017-08-29 10:59:19] [INFO] node "node2" (node ID: 2) monitoring upstream node "node1" (node ID: 1) in normal state (automatic failover disabled) [2017-08-29 10:59:19] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (ID: 1) in normal state (automatic failover disabled)
[2017-08-29 10:59:33] [WARNING] unable to connect to upstream node "node1" (node ID: 1) [2017-08-29 10:59:33] [WARNING] unable to connect to upstream node "node1" (ID: 1)
[2017-08-29 10:59:33] [INFO] checking state of node 1, 1 of 5 attempts [2017-08-29 10:59:33] [INFO] checking state of node 1, 1 of 5 attempts
[2017-08-29 10:59:33] [INFO] sleeping 1 seconds until next reconnection attempt [2017-08-29 10:59:33] [INFO] sleeping 1 seconds until next reconnection attempt
(...) (...)
@@ -278,21 +293,21 @@ NOTICE: node 3 (node3) unpaused</programlisting>
[2017-08-29 10:59:37] [NOTICE] this node is not configured for automatic failover so will not be considered as promotion candidate [2017-08-29 10:59:37] [NOTICE] this node is not configured for automatic failover so will not be considered as promotion candidate
[2017-08-29 10:59:37] [NOTICE] no other nodes are available as promotion candidate [2017-08-29 10:59:37] [NOTICE] no other nodes are available as promotion candidate
[2017-08-29 10:59:37] [HINT] use "repmgr standby promote" to manually promote this node [2017-08-29 10:59:37] [HINT] use "repmgr standby promote" to manually promote this node
[2017-08-29 10:59:37] [INFO] node "node2" (node ID: 2) monitoring upstream node "node1" (node ID: 1) in degraded state (automatic failover disabled) [2017-08-29 10:59:37] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (ID: 1) in degraded state (automatic failover disabled)
[2017-08-29 10:59:53] [INFO] node "node2" (node ID: 2) monitoring upstream node "node1" (node ID: 1) in degraded state (automatic failover disabled) [2017-08-29 10:59:53] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (ID: 1) in degraded state (automatic failover disabled)
[2017-08-29 11:00:45] [NOTICE] reconnected to upstream node 1 after 68 seconds, resuming monitoring [2017-08-29 11:00:45] [NOTICE] reconnected to upstream node "node1" (ID: 1) after 68 seconds, resuming monitoring
[2017-08-29 11:00:57] [INFO] node "node2" (node ID: 2) monitoring upstream node "node1" (node ID: 1) in normal state (automatic failover disabled)</programlisting> [2017-08-29 11:00:57] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (ID: 1) in normal state (automatic failover disabled)</programlisting>
</para> </para>
<para> <para>
By default, <literal>repmgrd</literal> will continue in degraded monitoring mode indefinitely. By default, <literal>repmgrd</literal> will continue in degraded monitoring mode indefinitely.
However a timeout (in seconds) can be set with <varname>degraded_monitoring_timeout</varname>, However a timeout (in seconds) can be set with <varname>degraded_monitoring_timeout</varname>,
after which <application>repmgrd</application> will terminate. after which &repmgrd; will terminate.
</para> </para>
<note> <note>
<para> <para>
If <application>repmgrd</application> is monitoring a primary mode which has been stopped If &repmgrd; is monitoring a primary mode which has been stopped
and manually restarted as a standby attached to a new primary, it will automatically detect and manually restarted as a standby attached to a new primary, it will automatically detect
the status change and update the node record to reflect the node's new status the status change and update the node record to reflect the node's new status
as an active standby. It will then resume monitoring the node as a standby. as an active standby. It will then resume monitoring the node as a standby.
@@ -302,6 +317,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<sect1 id="repmgrd-monitoring" xreflabel="Storing monitoring data"> <sect1 id="repmgrd-monitoring" xreflabel="Storing monitoring data">
<title>Storing monitoring data</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>monitoring</secondary> <secondary>monitoring</secondary>
@@ -311,9 +327,8 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<secondary>with repmgrd</secondary> <secondary>with repmgrd</secondary>
</indexterm> </indexterm>
<title>Storing monitoring data</title>
<para> <para>
When <application>repmgrd</application> is running with the option <literal>monitoring_history=true</literal>, When &repmgrd; is running with the option <literal>monitoring_history=true</literal>,
it will constantly write standby node status information to the it will constantly write standby node status information to the
<varname>monitoring_history</varname> table, providing a near-real time <varname>monitoring_history</varname> table, providing a near-real time
overview of replication status on all nodes overview of replication status on all nodes
@@ -346,12 +361,12 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<para> <para>
As this can generate a large amount of monitoring data in the table As this can generate a large amount of monitoring data in the table
<literal>repmgr.monitoring_history</literal>. it's advisable to regularly <literal>repmgr.monitoring_history</literal>. it's advisable to regularly
purge historical data using the <xref linkend="repmgr-cluster-cleanup"> purge historical data using the <xref linkend="repmgr-cluster-cleanup"/>
command; use the <literal>-k/--keep-history</literal> option to command; use the <literal>-k/--keep-history</literal> option to
specify how many day's worth of data should be retained. specify how many day's worth of data should be retained.
</para> </para>
<para> <para>
It's possible to use <application>repmgrd</application> to run in monitoring It's possible to use &repmgrd; to run in monitoring
mode only (without automatic failover capability) for some or all mode only (without automatic failover capability) for some or all
nodes by setting <literal>failover=manual</literal> in the node's nodes by setting <literal>failover=manual</literal> in the node's
<filename>repmgr.conf</filename> file. In the event of the node's upstream failing, <filename>repmgr.conf</filename> file. In the event of the node's upstream failing,

View File

@@ -1,24 +1,24 @@
<chapter id="repmgrd-overview" xreflabel="repmgrd overview"> <chapter id="repmgrd-overview" xreflabel="repmgrd overview">
<title>repmgrd overview</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>overview</secondary> <secondary>overview</secondary>
</indexterm> </indexterm>
<title>repmgrd overview</title>
<para> <para>
<application>repmgrd</application> (&quot;<literal>replication manager daemon</literal>&quot;) &repmgrd; (&quot;<literal>replication manager daemon</literal>&quot;)
is a management and monitoring daemon which runs is a management and monitoring daemon which runs
on each node in a replication cluster. It can automate actions such as on each node in a replication cluster. It can automate actions such as
failover and updating standbys to follow the new primary, as well as failover and updating standbys to follow the new primary, as well as
providing monitoring information about the state of each standby. providing monitoring information about the state of each standby.
</para> </para>
<para> <para>
<application>repmgrd</application> is designed to be straightforward to set up &repmgrd; is designed to be straightforward to set up
and does not require additional external infrastructure. and does not require additional external infrastructure.
</para> </para>
<para> <para>
Functionality provided by <application>repmgrd</application> includes: Functionality provided by &repmgrd; includes:
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
@@ -29,7 +29,7 @@
<listitem> <listitem>
<simpara> <simpara>
option to execute custom scripts (&quot;<link linkend="event-notifications">event notifications</link> option to execute custom scripts (&quot;<link linkend="event-notifications">event notifications</link>&quot;)
at different points in the failover sequence at different points in the failover sequence
</simpara> </simpara>
</listitem> </listitem>
@@ -38,7 +38,7 @@
<simpara> <simpara>
ability to <link linkend="repmgrd-pausing">pause repmgrd</link> ability to <link linkend="repmgrd-pausing">pause repmgrd</link>
operation on all nodes with a operation on all nodes with a
<link linkend="repmgr-daemon-pause"><command>single command</command></link> <link linkend="repmgr-service-pause"><command>single command</command></link>
</simpara> </simpara>
</listitem> </listitem>
@@ -93,28 +93,28 @@
<tip> <tip>
<para> <para>
See section <link linkend="repmgrd-automatic-failover-configuration">Required configuration for automatic failover</link> See section <link linkend="repmgrd-automatic-failover-configuration">Required configuration for automatic failover</link>
for an example of minimal <filename>repmgr.conf</filename> file settings suitable for use with <application>repmgrd</application>. for an example of minimal <filename>repmgr.conf</filename> file settings suitable for use with &repmgrd;.
</para> </para>
</tip> </tip>
<para> <para>
Start <application>repmgrd</application> on each standby and verify that it's running by examining the Start &repmgrd; on each standby and verify that it's running by examining the
log output, which at log level <literal>INFO</literal> will look like this: log output, which at log level <literal>INFO</literal> will look like this:
<programlisting> <programlisting>
[2019-03-15 06:32:05] [NOTICE] repmgrd (repmgrd 4.3) starting up [2019-08-15 07:14:42] [NOTICE] repmgrd (repmgrd 5.0) starting up
[2019-03-15 06:32:05] [INFO] connecting to database "host=node2 dbname=repmgr user=repmgr connect_timeout=2" [2019-08-15 07:14:42] [INFO] connecting to database "host=node2 dbname=repmgr user=repmgr connect_timeout=2"
INFO: set_repmgrd_pid(): provided pidfile is /var/run/repmgr/repmgrd-11.pid INFO: set_repmgrd_pid(): provided pidfile is /var/run/repmgr/repmgrd-12.pid
[2019-03-15 06:32:05] [NOTICE] starting monitoring of node "node2" (ID: 2) [2019-08-15 07:14:42] [NOTICE] starting monitoring of node "node2" (ID: 2)
[2019-03-15 06:32:05] [INFO] monitoring connection to upstream node "node1" (node ID: 1)</programlisting> [2019-08-15 07:14:42] [INFO] monitoring connection to upstream node "node1" (ID: 1)</programlisting>
</para> </para>
<para> <para>
Each <application>repmgrd</application> should also have recorded its successful startup as an event: Each &repmgrd; should also have recorded its successful startup as an event:
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf cluster event --event=repmgrd_start $ repmgr -f /etc/repmgr.conf cluster event --event=repmgrd_start
Node ID | Name | Event | OK | Timestamp | Details Node ID | Name | Event | OK | Timestamp | Details
---------+-------+---------------+----+---------------------+------------------------------------------------------------- ---------+-------+---------------+----+---------------------+--------------------------------------------------------
3 | node3 | repmgrd_start | t | 2019-03-14 04:17:30 | monitoring connection to upstream node "node1" (node ID: 1) 3 | node3 | repmgrd_start | t | 2019-08-15 07:14:42 | monitoring connection to upstream node "node1" (ID: 1)
2 | node2 | repmgrd_start | t | 2019-03-14 04:11:47 | monitoring connection to upstream node "node1" (node ID: 1) 2 | node2 | repmgrd_start | t | 2019-08-15 07:14:41 | monitoring connection to upstream node "node1" (ID: 1)
1 | node1 | repmgrd_start | t | 2019-03-14 04:04:31 | monitoring cluster primary "node1" (node ID: 1)</programlisting> 1 | node1 | repmgrd_start | t | 2019-08-15 07:14:39 | monitoring cluster primary "node1" (ID: 1)</programlisting>
</para> </para>
<para> <para>
Now stop the current primary server with e.g.: Now stop the current primary server with e.g.:
@@ -123,38 +123,38 @@
</para> </para>
<para> <para>
This will force the primary to shut down straight away, aborting all processes This will force the primary to shut down straight away, aborting all processes
and transactions. This will cause a flurry of activity in the <application>repmgrd</application> log and transactions. This will cause a flurry of activity in the &repmgrd; log
files as each <application>repmgrd</application> detects the failure of the primary and a failover files as each &repmgrd; detects the failure of the primary and a failover
decision is made. This is an extract from the log of a standby server (<literal>node2</literal>) decision is made. This is an extract from the log of a standby server (<literal>node2</literal>)
which has promoted to new primary after failure of the original primary (<literal>node1</literal>). which has promoted to new primary after failure of the original primary (<literal>node1</literal>).
<programlisting> <programlisting>
[2019-03-15 06:37:50] [WARNING] unable to connect to upstream node "node1" (node ID: 1) [2019-08-15 07:27:50] [WARNING] unable to connect to upstream node "node1" (ID: 1)
[2019-03-15 06:37:50] [INFO] checking state of node 1, 1 of 3 attempts [2019-08-15 07:27:50] [INFO] checking state of node 1, 1 of 3 attempts
[2019-03-15 06:37:50] [INFO] sleeping 5 seconds until next reconnection attempt [2019-08-15 07:27:50] [INFO] sleeping 5 seconds until next reconnection attempt
[2019-03-15 06:37:55] [INFO] checking state of node 1, 2 of 3 attempts [2019-08-15 07:27:55] [INFO] checking state of node 1, 2 of 3 attempts
[2019-03-15 06:37:55] [INFO] sleeping 5 seconds until next reconnection attempt [2019-08-15 07:27:55] [INFO] sleeping 5 seconds until next reconnection attempt
[2019-03-15 06:38:00] [INFO] checking state of node 1, 3 of 3 attempts [2019-08-15 07:28:00] [INFO] checking state of node 1, 3 of 3 attempts
[2019-03-15 06:38:00] [WARNING] unable to reconnect to node 1 after 3 attempts [2019-08-15 07:28:00] [WARNING] unable to reconnect to node 1 after 3 attempts
[2019-03-15 06:38:00] [INFO] primary and this node have the same location ("default") [2019-08-15 07:28:00] [INFO] primary and this node have the same location ("default")
[2019-03-15 06:38:00] [INFO] local node's last receive lsn: 0/900CBF8 [2019-08-15 07:28:00] [INFO] local node's last receive lsn: 0/900CBF8
[2019-03-15 06:38:00] [INFO] node 3 last saw primary node 12 second(s) ago [2019-08-15 07:28:00] [INFO] node 3 last saw primary node 12 second(s) ago
[2019-03-15 06:38:00] [INFO] last receive LSN for sibling node "node3" (ID: 3) is: 0/900CBF8 [2019-08-15 07:28:00] [INFO] last receive LSN for sibling node "node3" (ID: 3) is: 0/900CBF8
[2019-03-15 06:38:00] [INFO] node "node3" (ID: 3) has same LSN as current candidate "node2" (ID: 2) [2019-08-15 07:28:00] [INFO] node "node3" (ID: 3) has same LSN as current candidate "node2" (ID: 2)
[2019-03-15 06:38:00] [INFO] visible nodes: 2; total nodes: 2; no nodes have seen the primary within the last 4 seconds [2019-08-15 07:28:00] [INFO] visible nodes: 2; total nodes: 2; no nodes have seen the primary within the last 4 seconds
[2019-03-15 06:38:00] [NOTICE] promotion candidate is "node2" (ID: 2) [2019-08-15 07:28:00] [NOTICE] promotion candidate is "node2" (ID: 2)
[2019-03-15 06:38:00] [NOTICE] this node is the winner, will now promote itself and inform other nodes [2019-08-15 07:28:00] [NOTICE] this node is the winner, will now promote itself and inform other nodes
[2019-03-15 06:38:00] [INFO] promote_command is: [2019-08-15 07:28:00] [INFO] promote_command is:
"/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf standby promote" "/usr/pgsql-12/bin/repmgr -f /etc/repmgr/12/repmgr.conf standby promote"
NOTICE: promoting standby to primary NOTICE: promoting standby to primary
DETAIL: promoting server "node2" (ID: 2) using "/usr/pgsql-11/bin/pg_ctl -w -D '/var/lib/pgsql/11/data' promote" DETAIL: promoting server "node2" (ID: 2) using "/usr/pgsql-12/bin/pg_ctl -w -D '/var/lib/pgsql/12/data' promote"
NOTICE: waiting up to 60 seconds (parameter "promote_check_timeout") for promotion to complete NOTICE: waiting up to 60 seconds (parameter "promote_check_timeout") for promotion to complete
NOTICE: STANDBY PROMOTE successful NOTICE: STANDBY PROMOTE successful
DETAIL: server "node2" (ID: 2) was successfully promoted to primary DETAIL: server "node2" (ID: 2) was successfully promoted to primary
[2019-03-15 06:38:01] [INFO] 3 followers to notify [2019-08-15 07:28:01] [INFO] 3 followers to notify
[2019-03-15 06:38:01] [NOTICE] notifying node "node3" (node ID: 3) to follow node 2 [2019-08-15 07:28:01] [NOTICE] notifying node "node3" (ID: 3) to follow node 2
INFO: node 3 received notification to follow node 2 INFO: node 3 received notification to follow node 2
[2019-03-15 06:38:01] [INFO] switching to primary monitoring mode [2019-08-15 07:28:01] [INFO] switching to primary monitoring mode
[2019-03-15 06:38:01] [NOTICE] monitoring cluster primary "node2" (node ID: 2)</programlisting> [2019-08-15 07:28:01] [NOTICE] monitoring cluster primary "node2" (ID: 2)</programlisting>
</para> </para>
<para> <para>
The cluster status will now look like this, with the original primary (<literal>node1</literal>) The cluster status will now look like this, with the original primary (<literal>node1</literal>)
@@ -176,11 +176,11 @@
$ repmgr -f /etc/repmgr.conf cluster event $ repmgr -f /etc/repmgr.conf cluster event
Node ID | Name | Event | OK | Timestamp | Details Node ID | Name | Event | OK | Timestamp | Details
---------+-------+----------------------------+----+---------------------+------------------------------------------------------------- ---------+-------+----------------------------+----+---------------------+-------------------------------------------------------------
3 | node3 | repmgrd_failover_follow | t | 2019-03-15 06:38:03 | node 3 now following new upstream node 2 3 | node3 | repmgrd_failover_follow | t | 2019-08-15 07:38:03 | node 3 now following new upstream node 2
3 | node3 | standby_follow | t | 2019-03-15 06:38:02 | standby attached to upstream node "node2" (node ID: 2) 3 | node3 | standby_follow | t | 2019-08-15 07:38:02 | standby attached to upstream node "node2" (ID: 2)
2 | node2 | repmgrd_reload | t | 2019-03-15 06:38:01 | monitoring cluster primary "node2" (node ID: 2) 2 | node2 | repmgrd_reload | t | 2019-08-15 07:38:01 | monitoring cluster primary "node2" (ID: 2)
2 | node2 | repmgrd_failover_promote | t | 2019-03-15 06:38:01 | node 2 promoted to primary; old primary 1 marked as failed 2 | node2 | repmgrd_failover_promote | t | 2019-08-15 07:38:01 | node 2 promoted to primary; old primary 1 marked as failed
2 | node2 | standby_promote | t | 2019-03-15 06:38:01 | server "node2" (ID: 2) was successfully promoted to primary</programlisting> 2 | node2 | standby_promote | t | 2019-08-15 07:38:01 | server "node2" (ID: 2) was successfully promoted to primary</programlisting>
</para> </para>
</sect1> </sect1>

89
doc/stylesheet-common.xsl Normal file
View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<!--
This file contains XSLT stylesheet customizations that are common to
all output formats (HTML, HTML Help, XSL-FO, etc.).
-->
<xsl:include href="stylesheet-speedup-common.xsl" />
<!-- Parameters -->
<!--
<xsl:param name="draft.mode">
<xsl:choose>
<xsl:when test="contains($repmgr.version, 'devel')">yes</xsl:when>
<xsl:otherwise>no</xsl:otherwise>
</xsl:choose>
</xsl:param>
-->
<xsl:param name="show.comments">
<xsl:choose>
<xsl:when test="contains($repmgr.version, 'devel')">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:param name="callout.graphics" select="'0'"></xsl:param>
<xsl:param name="toc.section.depth">2</xsl:param>
<xsl:param name="linenumbering.extension" select="'0'"></xsl:param>
<xsl:param name="section.autolabel" select="1"></xsl:param>
<xsl:param name="section.label.includes.component.label" select="1"></xsl:param>
<xsl:param name="refentry.generate.name" select="0"></xsl:param>
<xsl:param name="refentry.generate.title" select="1"></xsl:param>
<xsl:param name="refentry.xref.manvolnum" select="0"/>
<xsl:param name="formal.procedures" select="0"></xsl:param>
<xsl:param name="generate.consistent.ids" select="1"/>
<xsl:param name="punct.honorific" select="''"></xsl:param>
<xsl:param name="variablelist.term.break.after">1</xsl:param>
<xsl:param name="variablelist.term.separator"></xsl:param>
<xsl:param name="xref.with.number.and.title" select="0"></xsl:param>
<!-- Change display of some elements -->
<xsl:template match="productname">
<xsl:call-template name="inline.charseq"/>
</xsl:template>
<xsl:template match="structfield">
<xsl:call-template name="inline.monoseq"/>
</xsl:template>
<xsl:template match="structname">
<xsl:call-template name="inline.monoseq"/>
</xsl:template>
<xsl:template match="symbol">
<xsl:call-template name="inline.monoseq"/>
</xsl:template>
<xsl:template match="systemitem">
<xsl:call-template name="inline.charseq"/>
</xsl:template>
<xsl:template match="token">
<xsl:call-template name="inline.monoseq"/>
</xsl:template>
<xsl:template match="type">
<xsl:call-template name="inline.monoseq"/>
</xsl:template>
<xsl:template match="programlisting/emphasis">
<xsl:call-template name="inline.boldseq"/>
</xsl:template>
<!-- Special support for Tcl synopses -->
<xsl:template match="optional[@role='tcl']">
<xsl:text>?</xsl:text>
<xsl:call-template name="inline.charseq"/>
<xsl:text>?</xsl:text>
</xsl:template>
</xsl:stylesheet>

97
doc/stylesheet-fo.xsl Normal file
View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
<xsl:include href="stylesheet-common.xsl" />
<xsl:param name="fop1.extensions" select="1"></xsl:param>
<xsl:param name="tablecolumns.extension" select="0"></xsl:param>
<xsl:param name="toc.max.depth">3</xsl:param>
<xsl:param name="ulink.footnotes" select="1"></xsl:param>
<xsl:param name="use.extensions" select="1"></xsl:param>
<xsl:param name="variablelist.as.blocks" select="1"></xsl:param>
<xsl:attribute-set name="monospace.verbatim.properties"
use-attribute-sets="verbatim.properties monospace.properties">
<xsl:attribute name="wrap-option">wrap</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="nongraphical.admonition.properties">
<xsl:attribute name="border-style">solid</xsl:attribute>
<xsl:attribute name="border-width">1pt</xsl:attribute>
<xsl:attribute name="border-color">black</xsl:attribute>
<xsl:attribute name="padding-start">12pt</xsl:attribute>
<xsl:attribute name="padding-end">12pt</xsl:attribute>
<xsl:attribute name="padding-top">6pt</xsl:attribute>
<xsl:attribute name="padding-bottom">6pt</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="admonition.title.properties">
<xsl:attribute name="text-align">center</xsl:attribute>
</xsl:attribute-set>
<!-- fix missing space after vertical simplelist
https://github.com/docbook/xslt10-stylesheets/issues/31 -->
<xsl:attribute-set name="normal.para.spacing">
<xsl:attribute name="space-after.optimum">1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.8em</xsl:attribute>
<xsl:attribute name="space-after.maximum">1.2em</xsl:attribute>
</xsl:attribute-set>
<!-- Change display of some elements -->
<xsl:template match="command">
<xsl:call-template name="inline.monoseq"/>
</xsl:template>
<xsl:template match="confgroup" mode="bibliography.mode">
<fo:inline>
<xsl:apply-templates select="conftitle/text()" mode="bibliography.mode"/>
<xsl:text>, </xsl:text>
<xsl:apply-templates select="confdates/text()" mode="bibliography.mode"/>
<xsl:value-of select="$biblioentry.item.separator"/>
</fo:inline>
</xsl:template>
<xsl:template match="isbn" mode="bibliography.mode">
<fo:inline>
<xsl:text>ISBN </xsl:text>
<xsl:apply-templates mode="bibliography.mode"/>
<xsl:value-of select="$biblioentry.item.separator"/>
</fo:inline>
</xsl:template>
<!-- bug fix from <https://sourceforge.net/p/docbook/bugs/1360/#831b> -->
<xsl:template match="varlistentry/term" mode="xref-to">
<xsl:param name="verbose" select="1"/>
<xsl:apply-templates mode="no.anchor.mode"/>
</xsl:template>
<!-- include refsects in PDF bookmarks
(https://github.com/docbook/xslt10-stylesheets/issues/46) -->
<xsl:template match="refsect1|refsect2|refsect3"
mode="bookmark">
<xsl:variable name="id">
<xsl:call-template name="object.id"/>
</xsl:variable>
<xsl:variable name="bookmark-label">
<xsl:apply-templates select="." mode="object.title.markup"/>
</xsl:variable>
<fo:bookmark internal-destination="{$id}">
<xsl:attribute name="starting-state">
<xsl:value-of select="$bookmarks.state"/>
</xsl:attribute>
<fo:bookmark-title>
<xsl:value-of select="normalize-space($bookmark-label)"/>
</fo:bookmark-title>
<xsl:apply-templates select="*" mode="bookmark"/>
</fo:bookmark>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,292 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY % common.entities SYSTEM "http://docbook.sourceforge.net/release/xsl/current/common/entities.ent">
%common.entities;
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<!--
This file contains XSLT stylesheet customizations that are common to
all HTML output variants (chunked and single-page).
-->
<!-- Parameters -->
<xsl:param name="make.valid.html" select="1"></xsl:param>
<xsl:param name="generate.id.attributes" select="1"></xsl:param>
<xsl:param name="make.graphic.viewport" select="0"/>
<xsl:param name="link.mailto.url">pgsql-docs@lists.postgresql.org</xsl:param>
<xsl:param name="toc.max.depth">2</xsl:param>
<!-- Change display of some elements -->
<xsl:template match="command">
<xsl:call-template name="inline.monoseq"/>
</xsl:template>
<xsl:template match="confgroup" mode="bibliography.mode">
<span>
<xsl:call-template name="common.html.attributes"/>
<xsl:call-template name="id.attribute"/>
<xsl:apply-templates select="conftitle/text()" mode="bibliography.mode"/>
<xsl:text>, </xsl:text>
<xsl:apply-templates select="confdates/text()" mode="bibliography.mode"/>
<xsl:copy-of select="$biblioentry.item.separator"/>
</span>
</xsl:template>
<xsl:template match="isbn" mode="bibliography.mode">
<span>
<xsl:call-template name="common.html.attributes"/>
<xsl:call-template name="id.attribute"/>
<xsl:text>ISBN </xsl:text>
<xsl:apply-templates mode="bibliography.mode"/>
<xsl:copy-of select="$biblioentry.item.separator"/>
</span>
</xsl:template>
<!-- table of contents configuration -->
<xsl:param name="generate.toc">
appendix toc,title
article/appendix nop
article toc,title
book toc,title
chapter toc,title
part toc,title
preface toc,title
qandadiv toc
qandaset toc
reference toc,title
sect1 toc
sect2 toc
sect3 toc
sect4 toc
sect5 toc
section toc
set toc,title
</xsl:param>
<xsl:param name="generate.section.toc.level" select="1"></xsl:param>
<!-- include refentry under sect1 in tocs -->
<xsl:template match="sect1" mode="toc">
<xsl:param name="toc-context" select="."/>
<xsl:call-template name="subtoc">
<xsl:with-param name="toc-context" select="$toc-context"/>
<xsl:with-param name="nodes" select="sect2|refentry
|bridgehead[$bridgehead.in.toc != 0]"/>
</xsl:call-template>
</xsl:template>
<!-- Put index "quicklinks" (A | B | C | ...) at the top of the bookindex page. -->
<!-- from html/autoidx.xsl -->
<xsl:template name="generate-basic-index">
<xsl:param name="scope" select="NOTANODE"/>
<xsl:variable name="role">
<xsl:if test="$index.on.role != 0">
<xsl:value-of select="@role"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="type">
<xsl:if test="$index.on.type != 0">
<xsl:value-of select="@type"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="terms"
select="//indexterm
[count(.|key('letter',
translate(substring(&primary;, 1, 1),
&lowercase;,
&uppercase;))
[&scope;][1]) = 1
and not(@class = 'endofrange')]"/>
<xsl:variable name="alphabetical"
select="$terms[contains(concat(&lowercase;, &uppercase;),
substring(&primary;, 1, 1))]"/>
<xsl:variable name="others" select="$terms[not(contains(concat(&lowercase;,
&uppercase;),
substring(&primary;, 1, 1)))]"/>
<div class="index">
<!-- pgsql-docs: begin added stuff -->
<p class="indexdiv-quicklinks">
<a href="#indexdiv-Symbols">
<xsl:call-template name="gentext">
<xsl:with-param name="key" select="'index symbols'"/>
</xsl:call-template>
</a>
<xsl:apply-templates select="$alphabetical[count(.|key('letter',
translate(substring(&primary;, 1, 1),
&lowercase;,&uppercase;))[&scope;][1]) = 1]"
mode="index-div-quicklinks">
<xsl:with-param name="position" select="position()"/>
<xsl:with-param name="scope" select="$scope"/>
<xsl:with-param name="role" select="$role"/>
<xsl:with-param name="type" select="$type"/>
<xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
</xsl:apply-templates>
</p>
<!-- pgsql-docs: end added stuff -->
<xsl:if test="$others">
<xsl:choose>
<xsl:when test="normalize-space($type) != '' and
$others[@type = $type][count(.|key('primary', &primary;)[&scope;][1]) = 1]">
<!-- pgsql-docs: added id attribute here for linking to it -->
<div class="indexdiv" id="indexdiv-Symbols">
<h3>
<xsl:call-template name="gentext">
<xsl:with-param name="key" select="'index symbols'"/>
</xsl:call-template>
</h3>
<dl>
<xsl:apply-templates select="$others[count(.|key('primary', &primary;)[&scope;][1]) = 1]"
mode="index-symbol-div">
<xsl:with-param name="position" select="position()"/>
<xsl:with-param name="scope" select="$scope"/>
<xsl:with-param name="role" select="$role"/>
<xsl:with-param name="type" select="$type"/>
<xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
</xsl:apply-templates>
</dl>
</div>
</xsl:when>
<xsl:when test="normalize-space($type) != ''">
<!-- Output nothing, as there isn't a match for $other using this $type -->
</xsl:when>
<xsl:otherwise>
<!-- pgsql-docs: added id attribute here for linking to it -->
<div class="indexdiv" id="indexdiv-Symbols">
<h3>
<xsl:call-template name="gentext">
<xsl:with-param name="key" select="'index symbols'"/>
</xsl:call-template>
</h3>
<dl>
<xsl:apply-templates select="$others[count(.|key('primary',
&primary;)[&scope;][1]) = 1]"
mode="index-symbol-div">
<xsl:with-param name="position" select="position()"/>
<xsl:with-param name="scope" select="$scope"/>
<xsl:with-param name="role" select="$role"/>
<xsl:with-param name="type" select="$type"/>
<xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
</xsl:apply-templates>
</dl>
</div>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:apply-templates select="$alphabetical[count(.|key('letter',
translate(substring(&primary;, 1, 1),
&lowercase;,&uppercase;))[&scope;][1]) = 1]"
mode="index-div-basic">
<xsl:with-param name="position" select="position()"/>
<xsl:with-param name="scope" select="$scope"/>
<xsl:with-param name="role" select="$role"/>
<xsl:with-param name="type" select="$type"/>
<xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
</xsl:apply-templates>
</div>
</xsl:template>
<xsl:template match="indexterm" mode="index-div-basic">
<xsl:param name="scope" select="."/>
<xsl:param name="role" select="''"/>
<xsl:param name="type" select="''"/>
<xsl:variable name="key"
select="translate(substring(&primary;, 1, 1),
&lowercase;,&uppercase;)"/>
<xsl:if test="key('letter', $key)[&scope;]
[count(.|key('primary', &primary;)[&scope;][1]) = 1]">
<div class="indexdiv">
<!-- pgsql-docs: added id attribute here for linking to it -->
<xsl:attribute name="id">
<xsl:value-of select="concat('indexdiv-', $key)"/>
</xsl:attribute>
<xsl:if test="contains(concat(&lowercase;, &uppercase;), $key)">
<h3>
<xsl:value-of select="translate($key, &lowercase;, &uppercase;)"/>
</h3>
</xsl:if>
<dl>
<xsl:apply-templates select="key('letter', $key)[&scope;]
[count(.|key('primary', &primary;)
[&scope;][1])=1]"
mode="index-primary">
<xsl:with-param name="position" select="position()"/>
<xsl:with-param name="scope" select="$scope"/>
<xsl:with-param name="role" select="$role"/>
<xsl:with-param name="type" select="$type"/>
<xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
</xsl:apply-templates>
</dl>
</div>
</xsl:if>
</xsl:template>
<!-- pgsql-docs -->
<xsl:template match="indexterm" mode="index-div-quicklinks">
<xsl:param name="scope" select="."/>
<xsl:param name="role" select="''"/>
<xsl:param name="type" select="''"/>
<xsl:variable name="key"
select="translate(substring(&primary;, 1, 1),
&lowercase;,&uppercase;)"/>
<xsl:if test="key('letter', $key)[&scope;]
[count(.|key('primary', &primary;)[&scope;][1]) = 1]">
<xsl:if test="contains(concat(&lowercase;, &uppercase;), $key)">
|
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat('#indexdiv-', $key)"/>
</xsl:attribute>
<xsl:value-of select="translate($key, &lowercase;, &uppercase;)"/>
</a>
</xsl:if>
</xsl:if>
</xsl:template>
<!-- upper case HTML anchors for backward compatibility -->
<xsl:template name="object.id">
<xsl:param name="object" select="."/>
<xsl:choose>
<xsl:when test="$object/@id">
<xsl:value-of select="translate($object/@id, &lowercase;, &uppercase;)"/>
</xsl:when>
<xsl:when test="$object/@xml:id">
<xsl:value-of select="$object/@xml:id"/>
</xsl:when>
<xsl:when test="$generate.consistent.ids != 0">
<!-- Make $object the current node -->
<xsl:for-each select="$object">
<xsl:text>id-</xsl:text>
<xsl:number level="multiple" count="*"/>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="generate-id($object)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,23 @@
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'
xmlns="http://www.w3.org/TR/xhtml1/transitional"
exclude-result-prefixes="#default">
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"/>
<xsl:include href="stylesheet-common.xsl" />
<xsl:include href="stylesheet-html-common.xsl" />
<xsl:include href="stylesheet-speedup-xhtml.xsl" />
<!-- embed SVG images into output file -->
<xsl:template match="imagedata[@format='SVG']">
<xsl:variable name="filename">
<xsl:call-template name="mediaobject.filename">
<xsl:with-param name="object" select=".."/>
</xsl:call-template>
</xsl:variable>
<xsl:copy-of select="document($filename)"/>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'>
<!-- Performance-optimized versions of some upstream templates from common/
directory -->
<!-- from common/labels.xsl -->
<xsl:template match="chapter" mode="label.markup">
<xsl:choose>
<xsl:when test="@label">
<xsl:value-of select="@label"/>
</xsl:when>
<xsl:when test="string($chapter.autolabel) != 0">
<xsl:if test="$component.label.includes.part.label != 0 and
ancestor::part">
<xsl:variable name="part.label">
<xsl:apply-templates select="ancestor::part"
mode="label.markup"/>
</xsl:variable>
<xsl:if test="$part.label != ''">
<xsl:value-of select="$part.label"/>
<xsl:apply-templates select="ancestor::part"
mode="intralabel.punctuation">
<xsl:with-param name="object" select="."/>
</xsl:apply-templates>
</xsl:if>
</xsl:if>
<xsl:variable name="format">
<xsl:call-template name="autolabel.format">
<xsl:with-param name="format" select="$chapter.autolabel"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$label.from.part != 0 and ancestor::part">
<xsl:number from="part" count="chapter" format="{$format}" level="any"/>
</xsl:when>
<xsl:otherwise>
<!-- Optimization for pgsql-docs: When counting to get label for
this chapter, preceding chapters can only be our siblings or
children of a preceding part, so only count those instead of
scanning the entire node tree. -->
<!-- <xsl:number from="book" count="chapter" format="{$format}" level="any"/> -->
<xsl:number value="count(../preceding-sibling::part/chapter) + count(preceding-sibling::chapter) + 1" format="{$format}"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="appendix" mode="label.markup">
<xsl:choose>
<xsl:when test="@label">
<xsl:value-of select="@label"/>
</xsl:when>
<xsl:when test="string($appendix.autolabel) != 0">
<xsl:if test="$component.label.includes.part.label != 0 and
ancestor::part">
<xsl:variable name="part.label">
<xsl:apply-templates select="ancestor::part"
mode="label.markup"/>
</xsl:variable>
<xsl:if test="$part.label != ''">
<xsl:value-of select="$part.label"/>
<xsl:apply-templates select="ancestor::part"
mode="intralabel.punctuation">
<xsl:with-param name="object" select="."/>
</xsl:apply-templates>
</xsl:if>
</xsl:if>
<xsl:variable name="format">
<xsl:call-template name="autolabel.format">
<xsl:with-param name="format" select="$appendix.autolabel"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$label.from.part != 0 and ancestor::part">
<xsl:number from="part" count="appendix" format="{$format}" level="any"/>
</xsl:when>
<xsl:otherwise>
<!-- Optimization for pgsql-docs: When counting to get label for
this appendix, preceding appendixes can only be our siblings or
children of a preceding part, so only count those instead of
scanning the entire node tree. -->
<!-- <xsl:number from="book|article" count="appendix" format="{$format}" level="any"/> -->
<xsl:number value="count(../preceding-sibling::part/appendix) + count(preceding-sibling::appendix) + 1" format="{$format}"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:template>
<!-- from common/l10n.xsl -->
<!-- Just hardcode the language for the whole document, to make it faster. -->
<xsl:template name="l10n.language">en</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,345 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
version='1.0'>
<!-- Performance-optimized versions of some upstream templates from xhtml/
directory -->
<!-- from xhtml/autoidx.xsl -->
<xsl:template match="indexterm" mode="reference">
<xsl:param name="scope" select="."/>
<xsl:param name="role" select="''"/>
<xsl:param name="type" select="''"/>
<xsl:param name="position"/>
<xsl:param name="separator" select="''"/>
<xsl:variable name="term.separator">
<xsl:call-template name="index.separator">
<xsl:with-param name="key" select="'index.term.separator'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="number.separator">
<xsl:call-template name="index.separator">
<xsl:with-param name="key" select="'index.number.separator'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="range.separator">
<xsl:call-template name="index.separator">
<xsl:with-param name="key" select="'index.range.separator'"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$separator != ''">
<xsl:value-of select="$separator"/>
</xsl:when>
<xsl:when test="$position = 1">
<xsl:value-of select="$term.separator"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$number.separator"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="@zone and string(@zone)">
<xsl:call-template name="reference">
<xsl:with-param name="zones" select="normalize-space(@zone)"/>
<xsl:with-param name="position" select="position()"/>
<xsl:with-param name="scope" select="$scope"/>
<xsl:with-param name="role" select="$role"/>
<xsl:with-param name="type" select="$type"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<a>
<xsl:apply-templates select="." mode="class.attribute"/>
<xsl:variable name="title">
<xsl:choose>
<xsl:when test="$index.prefer.titleabbrev != 0">
<xsl:apply-templates select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]" mode="titleabbrev.markup"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]" mode="title.markup"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:attribute name="href">
<xsl:choose>
<xsl:when test="$index.links.to.section = 1">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]"/>
<!-- Optimization for pgsql-docs: We only have an index as a
child of book, so look that up directly instead of
scanning the entire node tree. Also, don't look for
setindex. -->
<!-- <xsl:with-param name="context" select="(//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))] | //setindex[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/> -->
<xsl:with-param name="context" select="(/book/index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="."/>
<xsl:with-param name="context" select="(//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))] | //setindex[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:value-of select="$title"/> <!-- text only -->
</a>
<xsl:variable name="id" select="(@id|@xml:id)[1]"/>
<xsl:if test="key('endofrange', $id)[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))]">
<xsl:apply-templates select="key('endofrange', $id)[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][last()]" mode="reference">
<xsl:with-param name="position" select="position()"/>
<xsl:with-param name="scope" select="$scope"/>
<xsl:with-param name="role" select="$role"/>
<xsl:with-param name="type" select="$type"/>
<xsl:with-param name="separator" select="$range.separator"/>
</xsl:apply-templates>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="reference">
<xsl:param name="scope" select="."/>
<xsl:param name="role" select="''"/>
<xsl:param name="type" select="''"/>
<xsl:param name="zones"/>
<xsl:choose>
<xsl:when test="contains($zones, ' ')">
<xsl:variable name="zone" select="substring-before($zones, ' ')"/>
<xsl:variable name="target" select="key('sections', $zone)"/>
<a>
<xsl:apply-templates select="." mode="class.attribute"/>
<!-- Optimization for pgsql-docs: this call adds nothing but fails with docbook-xsl 1.76 -->
<!-- <xsl:call-template name="id.attribute"/> -->
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$target[1]"/>
<xsl:with-param name="context" select="//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/>
</xsl:call-template>
</xsl:attribute>
<xsl:apply-templates select="$target[1]" mode="index-title-content"/>
</a>
<xsl:text>, </xsl:text>
<xsl:call-template name="reference">
<xsl:with-param name="zones" select="substring-after($zones, ' ')"/>
<xsl:with-param name="position" select="position()"/>
<xsl:with-param name="scope" select="$scope"/>
<xsl:with-param name="role" select="$role"/>
<xsl:with-param name="type" select="$type"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="zone" select="$zones"/>
<xsl:variable name="target" select="key('sections', $zone)"/>
<a>
<xsl:apply-templates select="." mode="class.attribute"/>
<!-- Optimization for pgsql-docs: this call adds nothing but fails with docbook-xsl 1.76 -->
<!-- <xsl:call-template name="id.attribute"/> -->
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$target[1]"/>
<!-- Optimization for pgsql-docs: Only look for index under book
instead of searching the whole node tree. -->
<!-- <xsl:with-param name="context" select="//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/> -->
<xsl:with-param name="context" select="/book/index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/>
</xsl:call-template>
</xsl:attribute>
<xsl:apply-templates select="$target[1]" mode="index-title-content"/>
</a>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- from xhtml/chunk-common.xsl -->
<xsl:template name="chunk-all-sections">
<xsl:param name="content">
<xsl:apply-imports/>
</xsl:param>
<!-- Optimization for pgsql-docs: Since we set a fixed $chunk.section.depth,
we can do away with a bunch of complicated XPath searches for the
previous and next sections at various levels. -->
<xsl:if test="$chunk.section.depth != 1">
<xsl:message terminate="yes">
<xsl:text>Error: If you change $chunk.section.depth, then you must update the performance-optimized chunk-all-sections-template.</xsl:text>
</xsl:message>
</xsl:if>
<xsl:variable name="prev"
select="(preceding::book[1]
|preceding::preface[1]
|preceding::chapter[1]
|preceding::appendix[1]
|preceding::part[1]
|preceding::reference[1]
|preceding::refentry[1]
|preceding::colophon[1]
|preceding::article[1]
|preceding::topic[1]
|preceding::bibliography[parent::article or parent::book or parent::part][1]
|preceding::glossary[parent::article or parent::book or parent::part][1]
|preceding::index[$generate.index != 0]
[parent::article or parent::book or parent::part][1]
|preceding::setindex[$generate.index != 0][1]
|ancestor::set
|ancestor::book[1]
|ancestor::preface[1]
|ancestor::chapter[1]
|ancestor::appendix[1]
|ancestor::part[1]
|ancestor::reference[1]
|ancestor::article[1]
|ancestor::topic[1]
|preceding::sect1[1]
|ancestor::sect1[1])[last()]"/>
<xsl:variable name="next"
select="(following::book[1]
|following::preface[1]
|following::chapter[1]
|following::appendix[1]
|following::part[1]
|following::reference[1]
|following::refentry[1]
|following::colophon[1]
|following::bibliography[parent::article or parent::book or parent::part][1]
|following::glossary[parent::article or parent::book or parent::part][1]
|following::index[$generate.index != 0]
[parent::article or parent::book][1]
|following::article[1]
|following::topic[1]
|following::setindex[$generate.index != 0][1]
|descendant::book[1]
|descendant::preface[1]
|descendant::chapter[1]
|descendant::appendix[1]
|descendant::article[1]
|descendant::topic[1]
|descendant::bibliography[parent::article or parent::book][1]
|descendant::glossary[parent::article or parent::book or parent::part][1]
|descendant::index[$generate.index != 0]
[parent::article or parent::book][1]
|descendant::colophon[1]
|descendant::setindex[$generate.index != 0][1]
|descendant::part[1]
|descendant::reference[1]
|descendant::refentry[1]
|following::sect1[1]
|descendant::sect1[1])[1]"/>
<xsl:call-template name="process-chunk">
<xsl:with-param name="prev" select="$prev"/>
<xsl:with-param name="next" select="$next"/>
<xsl:with-param name="content" select="$content"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="href.target">
<xsl:param name="context" select="."/>
<xsl:param name="object" select="."/>
<xsl:param name="toc-context" select="."/>
<!-- Optimization for pgsql-docs: Remove support for dbhtml processing
instruction here -->
<xsl:variable name="href.to.uri">
<xsl:call-template name="href.target.uri">
<xsl:with-param name="object" select="$object"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="href.from.uri">
<xsl:choose>
<xsl:when test="not($toc-context = .)">
<xsl:call-template name="href.target.uri">
<xsl:with-param name="object" select="$toc-context"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="href.target.uri">
<xsl:with-param name="object" select="$context"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="href.to">
<xsl:value-of select="$href.to.uri"/>
</xsl:variable>
<xsl:variable name="href.from">
<xsl:call-template name="trim.common.uri.paths">
<xsl:with-param name="uriA" select="$href.to.uri"/>
<xsl:with-param name="uriB" select="$href.from.uri"/>
<xsl:with-param name="return" select="'B'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="depth">
<xsl:call-template name="count.uri.path.depth">
<xsl:with-param name="filename" select="$href.from"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="href">
<xsl:call-template name="copy-string">
<xsl:with-param name="string" select="'../'"/>
<xsl:with-param name="count" select="$depth"/>
</xsl:call-template>
<xsl:value-of select="$href.to"/>
</xsl:variable>
<xsl:value-of select="$href"/>
</xsl:template>
<xsl:template name="html.head">
<xsl:param name="prev" select="/foo"/>
<xsl:param name="next" select="/foo"/>
<!-- Optimization for pgsql-docs: Cut out a bunch of things we don't need
here, including an expensive //legalnotice search. -->
<head>
<xsl:call-template name="system.head.content"/>
<xsl:call-template name="head.content"/>
<xsl:if test="$prev">
<link rel="prev">
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$prev"/>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="title">
<xsl:apply-templates select="$prev" mode="object.title.markup.textonly"/>
</xsl:attribute>
</link>
</xsl:if>
<xsl:if test="$next">
<link rel="next">
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$next"/>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="title">
<xsl:apply-templates select="$next" mode="object.title.markup.textonly"/>
</xsl:attribute>
</link>
</xsl:if>
<xsl:call-template name="user.head.content"/>
</head>
</xsl:template>
</xsl:stylesheet>

View File

@@ -1,96 +1,471 @@
/* doc/src/sgml/stylesheet.css */ /* PostgreSQL.org Documentation Style */
/* color scheme similar to www.postgresql.org */ @import 'website-docs.css';
BODY { /* requires global.css, table.css and text.css to be loaded before this file! */
color: #000000; body {
background: #FFFFFF; font-family: verdana, sans-serif;
font-family: verdana, sans-serif; font-size: 76%;
background: url("/resources/background.png") repeat-x scroll left top transparent;
padding: 15px 4%;
margin: 0;
} }
A:link { color:#0066A2; } /* monospace font size fix */
A:visited { color:#004E66; } pre, code, kbd, samp, tt {
A:active { color:#0066A2; } font-family: monospace,monospace;
A:hover { color:#000000; } font-size: 1em;
H1 {
font-size: 1.4em;
font-weight: bold;
margin-top: 0em;
margin-bottom: 0em;
color: #EC5800;
} }
H2 { div.NAVHEADER table {
font-size: 1.2em; margin-left: 0;
margin: 1.2em 0em 1.2em 0em;
font-weight: bold;
color: #666;
} }
H3 { /* Container Definitions */
font-size: 1.1em;
margin: 1.2em 0em 1.2em 0em; #docContainerWrap {
font-weight: bold; text-align: center; /* Win IE5 */
color: #666;
} }
H4 { #docContainer {
font-size: 0.95em; margin: 0 auto;
margin: 1.2em 0em 1.2em 0em; width: 90%;
font-weight: normal; padding-bottom: 2em;
color: #666; display: block;
text-align: left; /* Win IE5 */
} }
H5 { #docHeader {
font-size: 0.9em; background-image: url("/media/img/docs/bg_hdr.png");
margin: 1.2em 0em 1.2em 0em; height: 83px;
font-weight: normal; margin: 0px;
padding: 0px;
display: block;
} }
H6 { #docHeaderLogo {
font-size: 0.85em; position: relative;
margin: 1.2em 0em 1.2em 0em; width: 206px;
font-weight: normal; height: 83px;
border: 0px;
padding: 0px;
margin: 0 0 0 20px;
} }
/* center some titles */ #docHeaderLogo img {
border: 0px;
.BOOK .TITLE, .BOOK .CORPAUTHOR, .BOOK .COPYRIGHT {
text-align: center;
} }
/* decoration for formal examples */ #docNavSearchContainer {
padding-bottom: 2px;
DIV.EXAMPLE {
padding-left: 15px;
border-style: solid;
border-width: 0px;
border-left-width: 2px;
border-color: black;
margin: 0.5ex;
} }
/* less dense spacing of TOC */ #docNav, #docVersions {
position: relative;
.BOOK .TOC DL DT { text-align: left;
padding-top: 1.5ex; margin-left: 10px;
padding-bottom: 1.5ex; margin-top: 5px;
color: #666;
font-size: 0.95em;
} }
.BOOK .TOC DL DL DT { #docSearch {
padding-top: 0ex; position: relative;
padding-bottom: 0ex; text-align: right;
padding: 0;
margin: 0;
color: #666;
} }
/* miscellaneous */ #docTextSize {
text-align: right;
PRE.LITERALLAYOUT, .SCREEN, .SYNOPSIS, .PROGRAMLISTING { white-space: nowrap;
margin-left: 4ex; margin-top: 7px;
font-size: 0.95em;
} }
.COMMENT { color: red; } #docSearch form {
position: relative;
top: 5px;
right: 0;
margin: 0; /* need for IE 5.5 OSX */
text-align: right; /* need for IE 5.5 OSX */
white-space: nowrap; /* for Opera */
}
VAR { font-family: monospace; font-style: italic; } #docSearch form label {
/* Konqueror's standard style for ACRONYM is italic. */ color: #666;
ACRONYM { font-style: inherit; } font-size: 0.95em;
}
#docSearch form input {
font-size: 0.95em;
}
#docSearch form #submit {
font-size: 0.95em;
background: #7A7A7A;
color: #fff;
border: 1px solid #7A7A7A;
padding: 1px 4px;
}
#docSearch form #q {
width: 170px;
font-size: 0.95em;
border: 1px solid #7A7A7A;
background: #E1E1E1;
color: #000000;
padding: 2px;
}
.frmDocSearch {
padding: 0;
margin: 0;
display: inline;
}
.inpDocSearch {
padding: 0;
margin: 0;
color: #000;
}
#docContent {
position: relative;
margin-left: 10px;
margin-right: 10px;
margin-top: 40px;
}
#docFooter {
position: relative;
font-size: 0.9em;
color: #666;
line-height: 1.3em;
margin-left: 10px;
margin-right: 10px;
}
#docComments {
margin-top: 10px;
}
#docClear {
clear: both;
margin: 0;
padding: 0;
}
/* Heading Definitions */
h1, h2, h3 {
font-weight: bold;
margin-top: 2ex;
color: #444;
}
h1 {
font-size: 1.4em;
}
h2 {
font-size: 1.2em !important;
}
h3 {
font-size: 1.1em;
}
h1 a:hover,
h2 a:hover,
h3 a:hover,
h4 a:hover {
color: #444;
text-decoration: none;
}
/* Text Styles */
div.SECT2 {
margin-top: 4ex;
}
div.SECT3 {
margin-top: 3ex;
margin-left: 3ex;
}
.txtCurrentLocation {
font-weight: bold;
}
p, ol, ul, li {
line-height: 1.5em;
}
.txtCommentsWrap {
border: 2px solid #F5F5F5;
width: 100%;
}
.txtCommentsContent {
background: #F5F5F5;
padding: 3px;
}
.txtCommentsPoster {
float: left;
}
.txtCommentsDate {
float: right;
}
.txtCommentsComment {
padding: 3px;
}
#docContainer pre code,
#docContainer pre tt,
#docContainer pre pre,
#docContainer tt tt,
#docContainer tt code,
#docContainer tt pre {
font-size: 1em;
}
pre.LITERALLAYOUT,
.SCREEN,
.SYNOPSIS,
.PROGRAMLISTING,
.REFSYNOPSISDIV p,
table.CAUTION,
table.WARNING,
blockquote.NOTE,
blockquote.TIP,
table.CALSTABLE {
-moz-box-shadow: 3px 3px 5px #DFDFDF;
-webkit-box-shadow: 3px 3px 5px #DFDFDF;
-khtml-box-shadow: 3px 3px 5px #DFDFDF;
-o-box-shadow: 3px 3px 5px #DFDFDF;
box-shadow: 3px 3px 5px #DFDFDF;
}
pre.LITERALLAYOUT,
.SCREEN,
.SYNOPSIS,
.PROGRAMLISTING,
.REFSYNOPSISDIV p,
table.CAUTION,
table.WARNING,
blockquote.NOTE,
blockquote.TIP {
color: black;
border-width: 1px;
border-style: solid;
padding: 2ex;
margin: 2ex 0 2ex 2ex;
overflow: auto;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
-khtml-border-radius: 8px;
border-radius: 8px;
}
pre.LITERALLAYOUT,
pre.SYNOPSIS,
pre.PROGRAMLISTING,
.REFSYNOPSISDIV p,
.SCREEN {
border-color: #CFCFCF;
background-color: #F7F7F7;
}
blockquote.NOTE,
blockquote.TIP {
border-color: #DBDBCC;
background-color: #EEEEDD;
padding: 14px;
width: 572px;
}
blockquote.NOTE,
blockquote.TIP,
table.CAUTION,
table.WARNING {
margin: 4ex auto;
}
blockquote.NOTE p,
blockquote.TIP p {
margin: 0;
}
blockquote.NOTE pre,
blockquote.NOTE code,
blockquote.TIP pre,
blockquote.TIP code {
margin-left: 0;
margin-right: 0;
-moz-box-shadow: none;
-webkit-box-shadow: none;
-khtml-box-shadow: none;
-o-box-shadow: none;
box-shadow: none;
}
.emphasis,
.c2 {
font-weight: bold;
}
.REPLACEABLE {
font-style: italic;
}
/* Table Styles */
table {
margin-left: 2ex;
}
table.CALSTABLE td,
table.CALSTABLE th,
table.CAUTION td,
table.CAUTION th,
table.WARNING td,
table.WARNING th {
border-style: solid;
}
table.CALSTABLE,
table.CAUTION,
table.WARNING {
border-spacing: 0;
border-collapse: collapse;
}
table.CALSTABLE
{
margin: 2ex 0 2ex 2ex;
background-color: #E0ECEF;
border: 2px solid #A7C6DF;
}
table.CALSTABLE tr:hover td
{
background-color: #EFEFEF;
}
table.CALSTABLE td {
background-color: #FFF;
}
table.CALSTABLE td,
table.CALSTABLE th {
border: 1px solid #A7C6DF;
padding: 0.5ex 0.5ex;
}
table.CAUTION,
table.WARNING {
border-collapse: separate;
display: block;
padding: 0;
max-width: 600px;
}
table.CAUTION {
background-color: #F5F5DC;
border-color: #DEDFA7;
}
table.WARNING {
background-color: #FFD7D7;
border-color: #DF421E;
}
table.CAUTION td,
table.CAUTION th,
table.WARNING td,
table.WARNING th {
border-width: 0;
padding-left: 2ex;
padding-right: 2ex;
}
table.CAUTION td,
table.CAUTION th {
border-color: #F3E4D5
}
table.WARNING td,
table.WARNING th {
border-color: #FFD7D7;
}
td.c1,
td.c2,
td.c3,
td.c4,
td.c5,
td.c6 {
font-size: 1.1em;
font-weight: bold;
border-bottom: 0px solid #FFEFEF;
padding: 1ex 2ex 0;
}
/* Link Styles */
#docNav a {
font-weight: bold;
}
a:link,
a:visited,
a:active,
a:hover {
text-decoration: underline;
}
a:link,
a:active {
color:#0066A2;
}
a:visited {
color:#004E66;
}
a:hover {
color:#000000;
}
#docFooter a:link,
#docFooter a:visited,
#docFooter a:active {
color:#666;
}
#docContainer code.FUNCTION tt {
font-size: 1em;
}
div.header {
color: #444;
margin-top: 5px;
}
div.footer {
text-align: center;
background-image: url("/resources/footerl.png"), url("/resources/footerr.png"), url("/resources/footerc.png");
background-position: left top, right top, center top;
background-repeat: no-repeat, no-repeat, repeat-x;
padding-top: 45px;
}
img {
border-style: none;
}

Some files were not shown because too many files have changed in this diff Show More