Compare commits

..

65 Commits

Author SHA1 Message Date
Ian Barwick
aa442e0dd5 doc: emphasise that BDR2 support is for BDR2 only 2019-04-05 11:16:14 +09:00
Ian Barwick
1a35f7a2a4 doc: add a link to the current documentation from the contents page 2019-04-03 10:45:26 +09:00
Ian Barwick
5b87156870 doc: clarify "cluster show" error codes 2019-03-18 10:51:04 +09:00
Ian Barwick
d29df0067f doc: update HISTORY 2019-03-15 15:08:19 +09:00
Ian Barwick
7926011fa4 doc: add explanation of the configuration file format 2019-03-15 14:02:59 +09:00
Ian Barwick
488afa9f7f doc: clarify replication slot usage with Barman
Barman will usually use one replication slot, but that's generally
preferable to multiple slots.
2019-02-22 13:50:03 +09:00
John Naylor
0f873df13a Bring list of supported versions on the doc front page in line with the supported version matrix 2019-02-22 09:48:08 +09:00
Ian Barwick
b71ce07210 doc: update source install instructions
Note packages required to compile if the package "build dep"
option is not viable.
2019-02-04 17:09:54 +09:00
Ian Barwick
4b4f98e897 doc: update Debian/Ubuntu repmgrd configuration
Remove reference to setting "repmgrd_pid_file", as this should not
be set in this context.

Per GitHub #517.
2019-02-04 16:11:45 +09:00
Ian Barwick
b1c048a74b doc: improve package install instructions
Including:
- additional clarification for Pg 9.x RPM package names
- consistent usage of sudo
2019-01-23 12:56:07 +09:00
Ian Barwick
24d7f7227e doc: clarify use-cases for pausing repmgrd 2019-01-23 12:33:05 +09:00
Ian Barwick
8add8231f8 doc: better document relevant PostgreSQL settings
There is a brief section in the Quickstart Guide, but it is hard to find
unless you know it is there.
2019-01-23 12:25:11 +09:00
Ian Barwick
160ace6436 doc: use "/current/" in URL path
From the next major release, the current documentation will be located in the
"/docs/current/" subdirectory. This makes it easier to provide canonical
links to the latest version of the documentation (similar to how  the
main PostgreSQL documentation is organised).

Once the following major release is available, the documentation will be moved
to a subdirectory with the version number, e.g. "/docs/4.3/".
2019-01-23 10:33:17 +09:00
Ian Barwick
3ea97d407f doc: update internal documentation links 2019-01-23 10:19:28 +09:00
Ian Barwick
0feaf8db1b doc: clarify data directory requirement in quickstart guide 2019-01-21 15:12:57 +09:00
Ian Barwick
63fabfd848 Standardize on --host option 2019-01-17 10:50:41 +09:00
Ian Barwick
a965bc005f Improve "witness register" documentation, help and logging
Make it clearer that a) the primary server's hostname is required,
and b) how to provide it.

Based on feedback provided in GitHub #529.
2019-01-17 10:45:17 +09:00
Fabio Pardi
8e0088d51e doc: command to unpause should be 'unpause'
GitHub #530.
2019-01-17 10:13:28 +09:00
Ian Barwick
a66ef24293 doc: note "pg_read_all_settings" in FAQ
Relevant for PostgreSQL 10 and later where the repmgr user is not a superuser.
2019-01-16 11:29:05 +09:00
Ian Barwick
630e25b83a doc: add FAQ entry clarifying why "data_directory" is required in repmgr.conf 2019-01-16 09:51:38 +09:00
Fabio Pardi
4a084e5e7d doc: add missing space after varname
GitHub #526
2019-01-16 09:40:24 +09:00
Ian Barwick
4a9bd87c53 doc: fix typos and update version example 2019-01-15 12:55:44 +09:00
Ian Barwick
0512826ed5 doc: clarify Debian source install instructions 2019-01-15 12:53:01 +09:00
Ian Barwick
677487d893 Fix "repmgr --help" output
Add missing references to "witness" and "daemon" actions.
2019-01-08 10:12:22 +09:00
Ian Barwick
e78c762d2c Fix "repmgr cluster cleanup" help output
Table name mentioned was incorrect.
2019-01-08 09:52:30 +09:00
Ian Barwick
7195512b99 Note primary/standby aliases for "node check" and "node status" actions
Add comment noting the intent behind those code sections, otherwise it
looks like a copy'n'paste error.

This currently isn't documented.
2019-01-08 09:31:27 +09:00
Ian Barwick
4a327c8be2 Update comment listing valid actions 2019-01-08 09:17:23 +09:00
Ian Barwick
1091cd0c68 doc: update FAQ
Make it clear 3.x is no longer maintained.
2019-01-07 12:34:26 +09:00
Ian Barwick
6fbc09741a doc: update FAQ
Add link to repmgr compatibility matrix.
2019-01-07 12:24:58 +09:00
Ian Barwick
1a82eecdb6 doc: note importance of installing same repmgr versions 2019-01-07 12:24:54 +09:00
Ian Barwick
5886772cdb Teach witness repmgrd to deal with the absence of a primary
Previously it would refuse to start if the primary was not reachable,
the thinking being that it's pointless trying to monitor an incomplete
cluster.

However following an aborted failover situation, repmgrd will restart
monitoring and on the witness server, this will lead to it aborting
itself due to to continuing absence of primary.

To resolve this, witness repmgrd will now start monitoring in degraded
mode if no primary is found in the hope a primary will reappear at
some point.
2018-11-29 12:17:26 +09:00
Ian Barwick
8bbcaffac7 doc: update HISTORY 2018-11-29 12:17:20 +09:00
Ian Barwick
71dda21b85 "witness register": don't try and read nodes table if it doesn't exist
Previously, "repmgr witness register --dry-run" would attempt to check
for records in the nodes table, but that might not exist yet. Skip
that check if the repmgr extension is not yet installed.

Implements GitHub #513.
2018-11-28 15:07:31 +09:00
Ian Barwick
ae729adb32 "standby switchover": use empheral witness server connection
Intended to prevent issue reported in GitHub #514.
2018-11-28 14:35:21 +09:00
Ian Barwick
687e707a7b Remove redundant function declaration 2018-11-28 13:51:28 +09:00
Ian Barwick
ae3f302dc2 doc: document "repmgr node service"
This was originally intended for internal use, but it's mentioned
several times in the documentation and is useful for diagnostic
purposes.
2018-11-28 12:58:24 +09:00
Ian Barwick
d4216d053e doc: fix missing quotation marks
Patch from Cédric Villemain
2018-11-12 10:19:34 +09:00
Ian Barwick
075d193a87 doc: remove redundant warning
No longer relevant for 4.2 and later.
2018-11-12 09:38:50 +09:00
Ian Barwick
7652a19e62 doc: update FAQ
Emphasize that repmgr does not actually perform replication.
2018-11-05 09:59:57 +09:00
Ian Barwick
7ae771e573 doc: add version compatibility matrix 2018-11-05 09:56:36 +09:00
Ian Barwick
44de7751f9 doc: clarify replication slot FAQ entry 2018-10-31 16:21:15 +09:00
Ian Barwick
d098c6a114 doc: update FAQ
Emphasize that repmgr does not actually perform replication.
2018-10-31 11:44:07 +09:00
Ian Barwick
3c5ef69f38 Add sanity check for extension version
This should cover the cases where the "repmgr" extension was installed
manually but not updated, or an upgrade was not fully completed.
2018-10-31 11:28:19 +09:00
Ian Barwick
b74129f363 doc: consolidate descriptions of SSH connectivity requirements 2018-10-31 10:11:13 +09:00
Ian Barwick
fdcc3850c8 doc: clarify network and software prerequisites 2018-10-31 10:01:58 +09:00
Ian Barwick
46f46612f8 Formatting standardization 2018-10-26 10:42:34 +09:00
Ian Barwick
a554914854 Avoid defining variable-length arrays
As of PostgreSQL commit d9dd406f, variable length arrays are no longer
permitted. As they're not actually required anyway, just define appropriate
constants.

Also noted in GitHub #510.
2018-10-26 10:15:01 +09:00
Ian Barwick
4f0b10cac6 doc: update README 2018-10-24 15:23:24 +09:00
Ian Barwick
9fe1e9cb3e doc: update 4.2 release notes 2018-10-24 15:03:57 +09:00
Ian Barwick
0cafeb3828 repmgrd: fix upstream role check
Only take action if it's confirmed as a standby.
2018-10-23 12:50:04 +09:00
Ian Barwick
79e79bd5f2 "standby switchover": close all connections used to check repmgrd status
The connections used to check repmgrd status on all nodes were not being
closed if repmgrd was not running. Normally this wouldn't be a huge
problem as they will go away when repmgr terminates or the PostgreSQL
server restarted. However, if shutdown mode is "smart", the open
connection on the demotion candidate will cause the shutdown operation
to fail until repmgr times out.
2018-10-23 10:59:24 +09:00
Ian Barwick
a4e21fd8fe Update doc version 2018-10-23 09:28:46 +09:00
Ian Barwick
e826f72312 Bump version number
4.2
2018-10-23 09:24:17 +09:00
Ian Barwick
1e8b3313ee doc: fix typos 2018-10-23 09:22:04 +09:00
Ian Barwick
b5772d88dd doc: fix typo
Per user report on mailing list.
2018-10-23 09:00:09 +09:00
Ian Barwick
22614573b9 Fix Makefile for VPATH builds under PostgreSQL 11 2018-10-22 20:05:09 +09:00
Ian Barwick
77c9092794 repmgrd: improve node role change detection 2018-10-19 11:33:08 +09:00
Ian Barwick
15bbe04a6f Speed up witness "failover" during a switchover 2018-10-18 18:35:23 +09:00
Ian Barwick
0842560a88 repmgrd: handle case where upstream is no longer primary
If the upstream comes back on line (e.g. after a switchover), and its
status is no longer primary, restart monitoring to ensure the correct
primary (potentially the current node) is being monitored.
2018-10-18 17:04:14 +09:00
Ian Barwick
8bec4946bc Ensure witness repmgrd detects change in upstream's role
This ensures that e.g. after a switchover, repmgrd running on a witness
node will automatically detect the new primary and monitor that.
2018-10-18 16:15:52 +09:00
Ian Barwick
3ab22f9442 repmgrd: ensure witness node doesn't try and follow another witness
Theoretically there should never be more than one witness node
visible here, but it's not impossible to rule it out, so add a
check just in case.
2018-10-18 12:20:04 +09:00
Ian Barwick
3a9c36a36c doc: improve upgrade instructions
Note requirement to execute "systemctl daemon-reload" for systemd
systems...
2018-10-17 17:08:54 +09:00
Ian Barwick
2ded8987ac doc: improve upgrade instructions 2018-10-17 14:35:36 +09:00
Ian Barwick
6311f3f30a Handle NULL strings when parsing boolean arguments 2018-10-17 11:46:29 +09:00
Ian Barwick
12ec6c7abc Doc: update HISTORY and 4.2 release notes 2018-10-17 09:50:36 +09:00
145 changed files with 5526 additions and 17314 deletions

5
.gitignore vendored
View File

@@ -42,12 +42,11 @@ lib*.pc
/regression.diffs /regression.diffs
/regression.out /regression.out
/doc/Makefile
# other # other
/.lineno /.lineno
*.dSYM *.dSYM
*.orig
*.rej
# generated binaries # generated binaries
repmgr repmgr
repmgrd repmgrd

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-2018, 2ndQuadrant Limited. 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.
@@ -24,7 +24,7 @@ Code style
Code in repmgr should be formatted to the same standards as the main PostgreSQL Code in repmgr should be formatted to the same standards as the main PostgreSQL
project. For more details see: project. For more details see:
https://www.postgresql.org/docs/current/source-format.html https://www.postgresql.org/docs/current/static/source-format.html
Contributors should reformat their code similarly before submitting code to Contributors should reformat their code similarly before submitting code to
the project, in order to minimize merge conflicts with other work. the project, in order to minimize merge conflicts with other work.

View File

@@ -1,4 +1,4 @@
Copyright (c) 2010-2019, 2ndQuadrant Limited Copyright (c) 2010-2018, 2ndQuadrant Limited
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

62
HISTORY
View File

@@ -1,65 +1,3 @@
4.4 2019-??-??
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)
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
repmgr: add "daemon (start|stop)" command; GitHub #528 (Ian)
repmgr: add --version-number command line option (Ian)
repmgr: add --compact option to "cluster show"; GitHub #521 (Ian)
repmgr: cluster show - differentiate between unreachable nodes
and nodes which are running but rejecting connections (Ian)
repmgr: add --dry-run option to "standby promote"; GitHub #522 (Ian)
repmgr: add "node check --data-directory-config"; GitHub #523 (Ian)
repmgr: prevent potential race condition in "standby switchover"
when checking received WAL location; GitHub #518 (Ian)
repmgr: ensure "standby switchover" verifies repmgr can read the
data directory on the demotion candidate; GitHub #523 (Ian)
repmgr: ensure "standby switchover" verifies replication connection
exists; GitHub #519 (Ian)
repmgr: add sanity check for correct extension version (Ian)
repmgr: ensure "witness register --dry-run" does not attempt to read node
tables if repmgr extension not installed; GitHub #513 (Ian)
repmgr: ensure "standby register" fails when --upstream-node-id is the
same as the local node ID (Ian)
repmgrd: check binary and extension major versions match; GitHub #515 (Ian)
repmgrd: on a cascaded standby, don't fail over if "failover=manual";
GitHub #531 (Ian)
repmgrd: don't consider nodes where repmgrd is not running as promotion
candidates (Ian)
repmgrd: add option "connection_check_type" (Ian)
repmgrd: improve witness monitoring when primary node not available (Ian)
repmgrd: handle situation where a primary has unexpectedly appeared
during failover; GitHub #420 (Ian)
general: fix Makefile (John)
4.2 2018-10-24 4.2 2018-10-24
repmgr: add parameter "shutdown_check_timeout" for use by "standby switchover"; repmgr: add parameter "shutdown_check_timeout" for use by "standby switchover";
GitHub #504 (Ian) GitHub #504 (Ian)

View File

@@ -15,11 +15,7 @@ DATA = \
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.3.sql \
repmgr--4.3--4.4.sql \
repmgr--4.4.sql
REGRESS = repmgr_extension REGRESS = repmgr_extension
@@ -52,8 +48,8 @@ $(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-bdr.o repmgr-action-cluster.o repmgr-action-node.o repmgr-action-daemon.o \
configfile.o log.o strutil.o controldata.o dirutil.o compat.o dbutils.o sysutils.o configfile.o log.o strutil.o controldata.o dirutil.o compat.o dbutils.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 REPMGRD_OBJS = repmgrd.o repmgrd-physical.o repmgrd-bdr.o configfile.o log.o dbutils.o strutil.o controldata.o compat.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
@@ -77,19 +73,10 @@ 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: repmgr_version.h doc:
$(MAKE) -C doc html $(MAKE) -C doc all
doc-repmgr.html: repmgr_version.h install-doc:
$(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
@@ -97,16 +84,29 @@ clean: additional-clean
maintainer-clean: additional-maintainer-clean maintainer-clean: additional-maintainer-clean
additional-clean: additional-clean:
rm -f *.o rm -f repmgr-client.o
$(MAKE) -C doc clean rm -f repmgr-action-primary.o
rm -f repmgr-action-standby.o
rm -f repmgr-action-witness.o
rm -f repmgr-action-bdr.o
rm -f repmgr-action-node.o
rm -f repmgr-action-cluster.o
rm -f repmgr-action-daemon.o
rm -f repmgrd.o
rm -f repmgrd-physical.o
rm -f repmgrd-bdr.o
rm -f compat.o
rm -f configfile.o
rm -f controldata.o
rm -f dbutils.o
rm -f dirutil.o
rm -f log.o
rm -f strutil.o
additional-maintainer-clean: clean maintainer-additional-clean: clean
$(MAKE) -C doc maintainer-clean rm -f configure
rm -f config.status config.log rm -f config.status config.log
rm -f config.h
rm -f repmgr_version.h
rm -f Makefile rm -f Makefile
rm -f Makefile.global
@rm -rf autom4te.cache/ @rm -rf autom4te.cache/
ifeq ($(MAJORVERSION),$(filter $(MAJORVERSION),9.3 9.4)) ifeq ($(MAJORVERSION),$(filter $(MAJORVERSION),9.3 9.4))
@@ -121,4 +121,3 @@ 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

@@ -27,7 +27,7 @@ Documentation
The main `repmgr` documentation is available here: The main `repmgr` documentation is available here:
> [repmgr documentation](https://repmgr.org/docs/current/index.html) > [repmgr 4 documentation](https://repmgr.org/docs/4.2/index.html)
The `README` file for `repmgr` 3.x is available here: The `README` file for `repmgr` 3.x is available here:
@@ -72,7 +72,7 @@ Please report bugs and other issues to:
* https://github.com/2ndQuadrant/repmgr * https://github.com/2ndQuadrant/repmgr
Further information is available at https://repmgr.org/ Further information is available at https://www.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 us an email at info@2ndQuadrant.com, or
@@ -97,7 +97,6 @@ Thanks from the repmgr core team.
Further reading Further reading
--------------- ---------------
* [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/ * https://blog.2ndquadrant.com/repmgr-3-2-is-here-barman-support-brand-new-high-availability-features/
* https://blog.2ndquadrant.com/improvements-in-repmgr-3-1-4/ * https://blog.2ndquadrant.com/improvements-in-repmgr-3-1-4/
* https://blog.2ndquadrant.com/managing-useful-clusters-repmgr/ * https://blog.2ndquadrant.com/managing-useful-clusters-repmgr/

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) 2ndQuadrant, 2010-2018
* *
* 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
@@ -98,42 +98,9 @@ appendShellString(PQExpBuffer buf, const char *str)
if (*p == '\'') if (*p == '\'')
appendPQExpBufferStr(buf, "'\"'\"'"); appendPQExpBufferStr(buf, "'\"'\"'");
else if (*p == '&')
appendPQExpBufferStr(buf, "\\&");
else else
appendPQExpBufferChar(buf, *p); appendPQExpBufferChar(buf, *p);
} }
appendPQExpBufferChar(buf, '\''); appendPQExpBufferChar(buf, '\'');
} }
/*
* Adapted from: src/fe_utils/string_utils.c
*/
void
appendRemoteShellString(PQExpBuffer buf, const char *str)
{
const char *p;
appendPQExpBufferStr(buf, "\\'");
for (p = str; *p; p++)
{
if (*p == '\n' || *p == '\r')
{
fprintf(stderr,
_("shell command argument contains a newline or carriage return: \"%s\"\n"),
str);
exit(ERR_BAD_CONFIG);
}
if (*p == '\'')
appendPQExpBufferStr(buf, "'\"'\"'");
else if (*p == '&')
appendPQExpBufferStr(buf, "\\&");
else
appendPQExpBufferChar(buf, *p);
}
appendPQExpBufferStr(buf, "\\'");
}

View File

@@ -1,6 +1,6 @@
/* /*
* compat.h * compat.h
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) 2ndQuadrant, 2010-2018
* *
* 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
@@ -27,6 +27,4 @@ extern void appendConnStrVal(PQExpBuffer buf, const char *str);
extern void appendShellString(PQExpBuffer buf, const char *str); extern void appendShellString(PQExpBuffer buf, const char *str);
extern void appendRemoteShellString(PQExpBuffer buf, const char *str);
#endif #endif

View File

@@ -1,7 +1,7 @@
/* /*
* config.c - parse repmgr.conf and other configuration-related functionality * config.c - parse repmgr.conf and other configuration-related functionality
* *
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) 2ndQuadrant, 2010-2018
* *
* 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
@@ -123,9 +123,9 @@ load_config(const char *config_file, bool verbose, bool terse, t_configuration_o
if (stat(config_file_path, &stat_config) != 0) if (stat(config_file_path, &stat_config) != 0)
{ {
log_error(_("provided configuration file \"%s\" not found"), log_error(_("provided configuration file \"%s\" not found: %s"),
config_file); config_file,
log_detail("%s", strerror(errno)); strerror(errno));
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }
@@ -335,7 +335,6 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
*/ */
options->shutdown_check_timeout = DEFAULT_SHUTDOWN_CHECK_TIMEOUT; options->shutdown_check_timeout = DEFAULT_SHUTDOWN_CHECK_TIMEOUT;
options->standby_reconnect_timeout = DEFAULT_STANDBY_RECONNECT_TIMEOUT; options->standby_reconnect_timeout = DEFAULT_STANDBY_RECONNECT_TIMEOUT;
options->wal_receive_check_timeout = DEFAULT_WAL_RECEIVE_CHECK_TIMEOUT;
/*----------------- /*-----------------
* repmgrd settings * repmgrd settings
@@ -344,7 +343,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
options->failover = FAILOVER_MANUAL; options->failover = FAILOVER_MANUAL;
options->priority = DEFAULT_PRIORITY; options->priority = DEFAULT_PRIORITY;
memset(options->location, 0, sizeof(options->location)); memset(options->location, 0, sizeof(options->location));
strncpy(options->location, DEFAULT_LOCATION, sizeof(options->location)); strncpy(options->location, DEFAULT_LOCATION, MAXLEN);
memset(options->promote_command, 0, sizeof(options->promote_command)); memset(options->promote_command, 0, sizeof(options->promote_command));
memset(options->follow_command, 0, sizeof(options->follow_command)); memset(options->follow_command, 0, sizeof(options->follow_command));
options->monitor_interval_secs = DEFAULT_MONITORING_INTERVAL; options->monitor_interval_secs = DEFAULT_MONITORING_INTERVAL;
@@ -358,19 +357,6 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
options->primary_notification_timeout = DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT; options->primary_notification_timeout = DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT;
options->repmgrd_standby_startup_timeout = -1; /* defaults to "standby_reconnect_timeout" if not set */ options->repmgrd_standby_startup_timeout = -1; /* defaults to "standby_reconnect_timeout" if not set */
memset(options->repmgrd_pid_file, 0, sizeof(options->repmgrd_pid_file)); memset(options->repmgrd_pid_file, 0, sizeof(options->repmgrd_pid_file));
options->standby_disconnect_on_failover = false;
options->sibling_nodes_disconnect_timeout = DEFAULT_SIBLING_NODES_DISCONNECT_TIMEOUT;
options->connection_check_type = CHECK_PING;
options->primary_visibility_consensus = false;
memset(options->failover_validation_command, 0, sizeof(options->failover_validation_command));
options->election_rerun_interval = DEFAULT_ELECTION_RERUN_INTERVAL;
options->child_nodes_check_interval = DEFAULT_CHILD_NODES_CHECK_INTERVAL;
options->child_nodes_disconnect_min_count = DEFAULT_CHILD_NODES_DISCONNECT_MIN_COUNT;
options->child_nodes_connected_min_count = DEFAULT_CHILD_NODES_CONNECTED_MIN_COUNT;
options->child_nodes_connected_include_witness = DEFAULT_CHILD_NODES_CONNECTED_INCLUDE_WITNESS;
options->child_nodes_disconnect_timeout = DEFAULT_CHILD_NODES_DISCONNECT_TIMEOUT;
memset(options->child_nodes_disconnect_command, 0, sizeof(options->child_nodes_disconnect_command));
/*------------- /*-------------
* witness settings * witness settings
@@ -385,24 +371,17 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
options->bdr_local_monitoring_only = false; options->bdr_local_monitoring_only = false;
options->bdr_recovery_timeout = DEFAULT_BDR_RECOVERY_TIMEOUT; options->bdr_recovery_timeout = DEFAULT_BDR_RECOVERY_TIMEOUT;
/*------------------------- /*-----------------
* service command settings * service settings
*------------------------- *-----------------
*/ */
memset(options->pg_ctl_options, 0, sizeof(options->pg_ctl_options)); memset(options->pg_ctl_options, 0, sizeof(options->pg_ctl_options));
memset(options->service_start_command, 0, sizeof(options->service_start_command));
memset(options->service_stop_command, 0, sizeof(options->service_stop_command)); memset(options->service_stop_command, 0, sizeof(options->service_stop_command));
memset(options->service_start_command, 0, sizeof(options->service_start_command));
memset(options->service_restart_command, 0, sizeof(options->service_restart_command)); memset(options->service_restart_command, 0, sizeof(options->service_restart_command));
memset(options->service_reload_command, 0, sizeof(options->service_reload_command)); memset(options->service_reload_command, 0, sizeof(options->service_reload_command));
memset(options->service_promote_command, 0, sizeof(options->service_promote_command)); memset(options->service_promote_command, 0, sizeof(options->service_promote_command));
/*---------------------------------
* repmgrd service command settings
*---------------------------------
*/
memset(options->repmgrd_service_start_command, 0, sizeof(options->repmgrd_service_start_command));
memset(options->repmgrd_service_stop_command, 0, sizeof(options->repmgrd_service_stop_command));
/*---------------------------- /*----------------------------
* event notification settings * event notification settings
*---------------------------- *----------------------------
@@ -487,38 +466,25 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
/* Copy into correct entry in parameters struct */ /* Copy into correct entry in parameters struct */
if (strcmp(name, "node_id") == 0) if (strcmp(name, "node_id") == 0)
{ {
options->node_id = repmgr_atoi(value, name, error_list, MIN_NODE_ID); options->node_id = repmgr_atoi(value, name, error_list, 1);
node_id_found = true; node_id_found = true;
} }
else if (strcmp(name, "node_name") == 0) else if (strcmp(name, "node_name") == 0)
{ strncpy(options->node_name, value, MAXLEN);
if (strlen(value) < sizeof(options->node_name))
strncpy(options->node_name, value, sizeof(options->node_name));
else
item_list_append_format(error_list,
_("value for \"node_name\" must contain fewer than %lu characters"),
sizeof(options->node_name));
}
else if (strcmp(name, "conninfo") == 0) else if (strcmp(name, "conninfo") == 0)
strncpy(options->conninfo, value, MAXLEN); strncpy(options->conninfo, value, MAXLEN);
else if (strcmp(name, "data_directory") == 0) else if (strcmp(name, "data_directory") == 0)
{
strncpy(options->data_directory, value, MAXPGPATH); strncpy(options->data_directory, value, MAXPGPATH);
canonicalize_path(options->data_directory);
}
else if (strcmp(name, "config_directory") == 0) else if (strcmp(name, "config_directory") == 0)
{
strncpy(options->config_directory, value, MAXPGPATH); strncpy(options->config_directory, value, MAXPGPATH);
canonicalize_path(options->config_directory);
}
else if (strcmp(name, "replication_user") == 0) else if (strcmp(name, "replication_user") == 0)
{ {
if (strlen(value) < sizeof(options->replication_user)) if (strlen(value) < NAMEDATALEN)
strncpy(options->replication_user, value, sizeof(options->replication_user)); strncpy(options->replication_user, value, NAMEDATALEN);
else else
item_list_append_format(error_list, item_list_append(error_list,
_("value for \"replication_user\" must contain fewer than %lu characters"), _("value for \"replication_user\" must contain fewer than " STR(NAMEDATALEN) " characters"));
sizeof(options->replication_user));
} }
else if (strcmp(name, "pg_bindir") == 0) else if (strcmp(name, "pg_bindir") == 0)
strncpy(options->pg_bindir, value, MAXPGPATH); strncpy(options->pg_bindir, value, MAXPGPATH);
@@ -584,8 +550,6 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
options->shutdown_check_timeout = repmgr_atoi(value, name, error_list, 0); options->shutdown_check_timeout = repmgr_atoi(value, name, error_list, 0);
else if (strcmp(name, "standby_reconnect_timeout") == 0) else if (strcmp(name, "standby_reconnect_timeout") == 0)
options->standby_reconnect_timeout = repmgr_atoi(value, name, error_list, 0); options->standby_reconnect_timeout = repmgr_atoi(value, name, error_list, 0);
else if (strcmp(name, "wal_receive_check_timeout") == 0)
options->wal_receive_check_timeout = repmgr_atoi(value, name, error_list, 0);
/* node rejoin settings */ /* node rejoin settings */
else if (strcmp(name, "node_rejoin_timeout") == 0) else if (strcmp(name, "node_rejoin_timeout") == 0)
@@ -621,11 +585,11 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
else if (strcmp(name, "priority") == 0) else if (strcmp(name, "priority") == 0)
options->priority = repmgr_atoi(value, name, error_list, 0); options->priority = repmgr_atoi(value, name, error_list, 0);
else if (strcmp(name, "location") == 0) else if (strcmp(name, "location") == 0)
strncpy(options->location, value, sizeof(options->location)); strncpy(options->location, value, MAXLEN);
else if (strcmp(name, "promote_command") == 0) else if (strcmp(name, "promote_command") == 0)
strncpy(options->promote_command, value, sizeof(options->promote_command)); strncpy(options->promote_command, value, MAXLEN);
else if (strcmp(name, "follow_command") == 0) else if (strcmp(name, "follow_command") == 0)
strncpy(options->follow_command, value, sizeof(options->follow_command)); strncpy(options->follow_command, value, MAXLEN);
else if (strcmp(name, "reconnect_attempts") == 0) else if (strcmp(name, "reconnect_attempts") == 0)
options->reconnect_attempts = repmgr_atoi(value, name, error_list, 0); options->reconnect_attempts = repmgr_atoi(value, name, error_list, 0);
else if (strcmp(name, "reconnect_interval") == 0) else if (strcmp(name, "reconnect_interval") == 0)
@@ -644,48 +608,6 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
options->repmgrd_standby_startup_timeout = repmgr_atoi(value, name, error_list, 0); options->repmgrd_standby_startup_timeout = repmgr_atoi(value, name, error_list, 0);
else if (strcmp(name, "repmgrd_pid_file") == 0) else if (strcmp(name, "repmgrd_pid_file") == 0)
strncpy(options->repmgrd_pid_file, value, MAXPGPATH); strncpy(options->repmgrd_pid_file, value, MAXPGPATH);
else if (strcmp(name, "standby_disconnect_on_failover") == 0)
options->standby_disconnect_on_failover = parse_bool(value, name, error_list);
else if (strcmp(name, "sibling_nodes_disconnect_timeout") == 0)
options->sibling_nodes_disconnect_timeout = repmgr_atoi(value, name, error_list, 0);
else if (strcmp(name, "connection_check_type") == 0)
{
if (strcasecmp(value, "ping") == 0)
{
options->connection_check_type = CHECK_PING;
}
else if (strcasecmp(value, "connection") == 0)
{
options->connection_check_type = CHECK_CONNECTION;
}
else if (strcasecmp(value, "query") == 0)
{
options->connection_check_type = CHECK_QUERY;
}
else
{
item_list_append(error_list,
_("value for \"connection_check_type\" must be \"ping\", \"connection\" or \"query\"\n"));
}
}
else if (strcmp(name, "primary_visibility_consensus") == 0)
options->primary_visibility_consensus = parse_bool(value, name, error_list);
else if (strcmp(name, "failover_validation_command") == 0)
strncpy(options->failover_validation_command, value, sizeof(options->failover_validation_command));
else if (strcmp(name, "election_rerun_interval") == 0)
options->election_rerun_interval = repmgr_atoi(value, name, error_list, 0);
else if (strcmp(name, "child_nodes_check_interval") == 0)
options->child_nodes_check_interval = repmgr_atoi(value, name, error_list, 1);
else if (strcmp(name, "child_nodes_disconnect_command") == 0)
snprintf(options->child_nodes_disconnect_command, sizeof(options->child_nodes_disconnect_command), "%s", value);
else if (strcmp(name, "child_nodes_disconnect_min_count") == 0)
options->child_nodes_disconnect_min_count = repmgr_atoi(value, name, error_list, -1);
else if (strcmp(name, "child_nodes_connected_min_count") == 0)
options->child_nodes_connected_min_count = repmgr_atoi(value, name, error_list, -1);
else if (strcmp(name, "child_nodes_connected_include_witness") == 0)
options->child_nodes_connected_include_witness = parse_bool(value, name, error_list);
else if (strcmp(name, "child_nodes_disconnect_timeout") == 0)
options->child_nodes_disconnect_timeout = repmgr_atoi(value, name, error_list, 0);
/* witness settings */ /* witness settings */
else if (strcmp(name, "witness_sync_interval") == 0) else if (strcmp(name, "witness_sync_interval") == 0)
@@ -699,48 +621,41 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
/* service settings */ /* service settings */
else if (strcmp(name, "pg_ctl_options") == 0) else if (strcmp(name, "pg_ctl_options") == 0)
strncpy(options->pg_ctl_options, value, sizeof(options->pg_ctl_options)); strncpy(options->pg_ctl_options, value, MAXLEN);
else if (strcmp(name, "service_start_command") == 0)
strncpy(options->service_start_command, value, sizeof(options->service_start_command));
else if (strcmp(name, "service_stop_command") == 0) else if (strcmp(name, "service_stop_command") == 0)
strncpy(options->service_stop_command, value, sizeof(options->service_stop_command)); strncpy(options->service_stop_command, value, MAXLEN);
else if (strcmp(name, "service_start_command") == 0)
strncpy(options->service_start_command, value, MAXLEN);
else if (strcmp(name, "service_restart_command") == 0) else if (strcmp(name, "service_restart_command") == 0)
strncpy(options->service_restart_command, value, sizeof(options->service_restart_command)); strncpy(options->service_restart_command, value, MAXLEN);
else if (strcmp(name, "service_reload_command") == 0) else if (strcmp(name, "service_reload_command") == 0)
strncpy(options->service_reload_command, value, sizeof(options->service_reload_command)); strncpy(options->service_reload_command, value, MAXLEN);
else if (strcmp(name, "service_promote_command") == 0) else if (strcmp(name, "service_promote_command") == 0)
strncpy(options->service_promote_command, value, sizeof(options->service_promote_command)); strncpy(options->service_promote_command, value, MAXLEN);
/* repmgrd service settings */
else if (strcmp(name, "repmgrd_service_start_command") == 0)
strncpy(options->repmgrd_service_start_command, value, sizeof(options->repmgrd_service_start_command));
else if (strcmp(name, "repmgrd_service_stop_command") == 0)
strncpy(options->repmgrd_service_stop_command, value, sizeof(options->repmgrd_service_stop_command));
/* event notification settings */ /* event notification settings */
else if (strcmp(name, "event_notification_command") == 0) else if (strcmp(name, "event_notification_command") == 0)
strncpy(options->event_notification_command, value, sizeof(options->event_notification_command)); strncpy(options->event_notification_command, value, MAXLEN);
else if (strcmp(name, "event_notifications") == 0) else if (strcmp(name, "event_notifications") == 0)
{ {
/* store unparsed value for comparison when reloading config */ /* store unparsed value for comparison when reloading config */
strncpy(options->event_notifications_orig, value, sizeof(options->event_notifications_orig)); strncpy(options->event_notifications_orig, value, MAXLEN);
parse_event_notifications_list(options, value); parse_event_notifications_list(options, value);
} }
/* barman settings */ /* barman settings */
else if (strcmp(name, "barman_host") == 0) else if (strcmp(name, "barman_host") == 0)
strncpy(options->barman_host, value, sizeof(options->barman_host)); strncpy(options->barman_host, value, MAXLEN);
else if (strcmp(name, "barman_server") == 0) else if (strcmp(name, "barman_server") == 0)
strncpy(options->barman_server, value, sizeof(options->barman_server)); strncpy(options->barman_server, value, MAXLEN);
else if (strcmp(name, "barman_config") == 0) else if (strcmp(name, "barman_config") == 0)
strncpy(options->barman_config, value, sizeof(options->barman_config)); strncpy(options->barman_config, value, MAXLEN);
/* rsync/ssh settings */ /* rsync/ssh settings */
else if (strcmp(name, "rsync_options") == 0) else if (strcmp(name, "rsync_options") == 0)
strncpy(options->rsync_options, value, sizeof(options->rsync_options)); strncpy(options->rsync_options, value, MAXLEN);
else if (strcmp(name, "ssh_options") == 0) else if (strcmp(name, "ssh_options") == 0)
strncpy(options->ssh_options, value, sizeof(options->ssh_options)); strncpy(options->ssh_options, value, MAXLEN);
/* undocumented settings for testing */ /* undocumented settings for testing */
else if (strcmp(name, "promote_delay") == 0) else if (strcmp(name, "promote_delay") == 0)
@@ -860,16 +775,15 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
conninfo_options = PQconninfoParse(options->conninfo, &conninfo_errmsg); conninfo_options = PQconninfoParse(options->conninfo, &conninfo_errmsg);
if (conninfo_options == NULL) if (conninfo_options == NULL)
{ {
PQExpBufferData error_message_buf; char error_message_buf[MAXLEN] = "";
initPQExpBuffer(&error_message_buf);
appendPQExpBuffer(&error_message_buf, snprintf(error_message_buf,
_("\"conninfo\": %s (provided: \"%s\")"), MAXLEN,
conninfo_errmsg, _("\"conninfo\": %s (provided: \"%s\")"),
options->conninfo); conninfo_errmsg,
options->conninfo);
item_list_append(error_list, error_message_buf.data); item_list_append(error_list, error_message_buf);
termPQExpBuffer(&error_message_buf);
} }
PQconninfoFree(conninfo_options); PQconninfoFree(conninfo_options);
@@ -1118,25 +1032,15 @@ parse_time_unit_parameter(const char *name, const char *value, char *dest, ItemL
* loop is started up; it therefore only needs to reload options required * loop is started up; it therefore only needs to reload options required
* by repmgrd, which are as follows: * by repmgrd, which are as follows:
* *
* changeable options (keep the list in "doc/repmgrd-configuration.xml" in sync * changeable options:
* with these):
*
* - async_query_timeout * - async_query_timeout
* - bdr_local_monitoring_only * - bdr_local_monitoring_only
* - bdr_recovery_timeout * - bdr_recovery_timeout
* - child_nodes_check_interval
* - child_nodes_connected_min_count
* - child_nodes_connected_include_witness
* - child_nodes_disconnect_command
* - child_nodes_disconnect_min_count
* - child_nodes_disconnect_timeout
* - connection_check_type
* - conninfo * - conninfo
* - degraded_monitoring_timeout * - degraded_monitoring_timeout
* - event_notification_command * - event_notification_command
* - event_notifications * - event_notifications
* - failover * - failover
* - failover_validation_command
* - follow_command * - follow_command
* - log_facility * - log_facility
* - log_file * - log_file
@@ -1144,19 +1048,12 @@ parse_time_unit_parameter(const char *name, const char *value, char *dest, ItemL
* - log_status_interval * - log_status_interval
* - monitor_interval_secs * - monitor_interval_secs
* - monitoring_history * - monitoring_history
* - primary_notification_timeout
* - primary_visibility_consensus
* - promote_command * - promote_command
* - promote_delay
* - reconnect_attempts * - reconnect_attempts
* - reconnect_interval * - reconnect_interval
* - repmgrd_standby_startup_timeout * - repmgrd_standby_startup_timeout
* - retry_promote_interval_secs * - retry_promote_interval_secs
* - sibling_nodes_disconnect_timeout
* - standby_disconnect_on_failover
*
*
* Not publicly documented:
* - promote_delay
* *
* non-changeable options (repmgrd references these from the "repmgr.nodes" * non-changeable options (repmgrd references these from the "repmgr.nodes"
* table, not the configuration file) * table, not the configuration file)
@@ -1235,12 +1132,13 @@ reload_config(t_configuration_options *orig_options, t_server_type server_type)
return false; return false;
} }
if (strncmp(new_options.node_name, orig_options->node_name, sizeof(orig_options->node_name)) != 0) if (strncmp(new_options.node_name, orig_options->node_name, MAXLEN) != 0)
{ {
log_warning(_("\"node_name\" cannot be changed, keeping current configuration")); log_warning(_("\"node_name\" cannot be changed, keeping current configuration"));
return false; return false;
} }
/* /*
* No configuration problems detected - copy any changed values * No configuration problems detected - copy any changed values
* *
@@ -1277,95 +1175,8 @@ reload_config(t_configuration_options *orig_options, t_server_type server_type)
config_changed = true; config_changed = true;
} }
/* child_nodes_check_interval */
if (orig_options->child_nodes_check_interval != new_options.child_nodes_check_interval)
{
if (new_options.child_nodes_check_interval < 0)
{
log_error(_("\"child_nodes_check_interval\" must be \"0\" or greater; provided: \"%i\""),
new_options.child_nodes_check_interval);
}
else
{
orig_options->child_nodes_check_interval = new_options.child_nodes_check_interval;
log_info(_("\"child_nodes_check_interval\" is now \"%i\""), new_options.child_nodes_check_interval);
config_changed = true;
}
}
/* child_nodes_disconnect_command */
if (strncmp(orig_options->child_nodes_disconnect_command, new_options.child_nodes_disconnect_command, sizeof(orig_options->child_nodes_disconnect_command)) != 0)
{
snprintf(orig_options->child_nodes_disconnect_command, sizeof(orig_options->child_nodes_disconnect_command),
"%s", new_options.child_nodes_disconnect_command);
log_info(_("\"child_nodes_disconnect_command\" is now \"%s\""), new_options.child_nodes_disconnect_command);
config_changed = true;
}
/* child_nodes_disconnect_min_count */
if (orig_options->child_nodes_disconnect_min_count != new_options.child_nodes_disconnect_min_count)
{
if (new_options.child_nodes_disconnect_min_count < 0)
{
log_error(_("\"child_nodes_disconnect_min_count\" must be \"0\" or greater; provided: \"%i\""),
new_options.child_nodes_disconnect_min_count);
}
else
{
orig_options->child_nodes_disconnect_min_count = new_options.child_nodes_disconnect_min_count;
log_info(_("\"child_nodes_disconnect_min_count\" is now \"%i\""), new_options.child_nodes_disconnect_min_count);
config_changed = true;
}
}
/* child_nodes_connected_min_count */
if (orig_options->child_nodes_connected_min_count != new_options.child_nodes_connected_min_count)
{
if (new_options.child_nodes_connected_min_count < 0)
{
log_error(_("\"child_nodes_connected_min_count\" must be \"0\" or greater; provided: \"%i\""),
new_options.child_nodes_connected_min_count);
}
else
{
orig_options->child_nodes_connected_min_count = new_options.child_nodes_connected_min_count;
log_info(_("\"child_nodes_connected_min_count\" is now \"%i\""), new_options.child_nodes_connected_min_count);
config_changed = true;
}
}
/* child_nodes_connected_include_witness */
if (orig_options->child_nodes_connected_include_witness != new_options.child_nodes_connected_include_witness)
{
orig_options->child_nodes_connected_include_witness = new_options.child_nodes_connected_include_witness;
log_info(_("\"child_nodes_connected_include_witness\" is now \"%i\""), new_options.child_nodes_connected_include_witness);
config_changed = true;
}
/* child_nodes_disconnect_timeout */
if (orig_options->child_nodes_disconnect_timeout != new_options.child_nodes_disconnect_timeout)
{
if (new_options.child_nodes_disconnect_timeout < 0)
{
log_error(_("\"child_nodes_disconnect_timeout\" must be \"0\" or greater; provided: \"%i\""),
new_options.child_nodes_disconnect_timeout);
}
else
{
orig_options->child_nodes_disconnect_timeout = new_options.child_nodes_disconnect_timeout;
log_info(_("\"child_nodes_disconnect_timeout\" is now \"%i\""), new_options.child_nodes_disconnect_timeout);
config_changed = true;
}
}
/* conninfo */ /* conninfo */
if (strncmp(orig_options->conninfo, new_options.conninfo, sizeof(orig_options->conninfo)) != 0) if (strncmp(orig_options->conninfo, new_options.conninfo, MAXLEN) != 0)
{ {
/* Test conninfo string works */ /* Test conninfo string works */
conn = establish_db_connection(new_options.conninfo, false); conn = establish_db_connection(new_options.conninfo, false);
@@ -1375,14 +1186,11 @@ reload_config(t_configuration_options *orig_options, t_server_type server_type)
} }
else else
{ {
snprintf(orig_options->conninfo, sizeof(orig_options->conninfo), strncpy(orig_options->conninfo, new_options.conninfo, MAXLEN);
"%s", new_options.conninfo);
log_info(_("\"conninfo\" is now \"%s\""), new_options.conninfo); log_info(_("\"conninfo\" is now \"%s\""), new_options.conninfo);
} }
PQfinish(conn); PQfinish(conn);
config_changed = true;
} }
/* degraded_monitoring_timeout */ /* degraded_monitoring_timeout */
@@ -1395,20 +1203,18 @@ reload_config(t_configuration_options *orig_options, t_server_type server_type)
} }
/* event_notification_command */ /* event_notification_command */
if (strncmp(orig_options->event_notification_command, new_options.event_notification_command, sizeof(orig_options->event_notification_command)) != 0) if (strncmp(orig_options->event_notification_command, new_options.event_notification_command, MAXLEN) != 0)
{ {
snprintf(orig_options->event_notification_command, sizeof(orig_options->event_notification_command), strncpy(orig_options->event_notification_command, new_options.event_notification_command, MAXLEN);
"%s", new_options.event_notification_command);
log_info(_("\"event_notification_command\" is now \"%s\""), new_options.event_notification_command); log_info(_("\"event_notification_command\" is now \"%s\""), new_options.event_notification_command);
config_changed = true; config_changed = true;
} }
/* event_notifications */ /* event_notifications */
if (strncmp(orig_options->event_notifications_orig, new_options.event_notifications_orig, sizeof(orig_options->event_notifications_orig)) != 0) if (strncmp(orig_options->event_notifications_orig, new_options.event_notifications_orig, MAXLEN) != 0)
{ {
snprintf(orig_options->event_notifications_orig, sizeof(orig_options->event_notifications_orig), strncpy(orig_options->event_notifications_orig, new_options.event_notifications_orig, MAXLEN);
"%s", new_options.event_notifications_orig);
log_info(_("\"event_notifications\" is now \"%s\""), new_options.event_notifications_orig); log_info(_("\"event_notifications\" is now \"%s\""), new_options.event_notifications_orig);
clear_event_notification_list(orig_options); clear_event_notification_list(orig_options);
@@ -1426,10 +1232,9 @@ reload_config(t_configuration_options *orig_options, t_server_type server_type)
} }
/* follow_command */ /* follow_command */
if (strncmp(orig_options->follow_command, new_options.follow_command, sizeof(orig_options->follow_command)) != 0) if (strncmp(orig_options->follow_command, new_options.follow_command, MAXLEN) != 0)
{ {
snprintf(orig_options->follow_command, sizeof(orig_options->follow_command), strncpy(orig_options->follow_command, new_options.follow_command, MAXLEN);
"%s", new_options.follow_command);
log_info(_("\"follow_command\" is now \"%s\""), new_options.follow_command); log_info(_("\"follow_command\" is now \"%s\""), new_options.follow_command);
config_changed = true; config_changed = true;
@@ -1462,11 +1267,11 @@ reload_config(t_configuration_options *orig_options, t_server_type server_type)
config_changed = true; config_changed = true;
} }
/* promote_command */ /* promote_command */
if (strncmp(orig_options->promote_command, new_options.promote_command, sizeof(orig_options->promote_command)) != 0) if (strncmp(orig_options->promote_command, new_options.promote_command, MAXLEN) != 0)
{ {
snprintf(orig_options->promote_command, sizeof(orig_options->promote_command), strncpy(orig_options->promote_command, new_options.promote_command, MAXLEN);
"%s", new_options.promote_command);
log_info(_("\"promote_command\" is now \"%s\""), new_options.promote_command); log_info(_("\"promote_command\" is now \"%s\""), new_options.promote_command);
config_changed = true; config_changed = true;
@@ -1508,71 +1313,23 @@ reload_config(t_configuration_options *orig_options, t_server_type server_type)
config_changed = true; config_changed = true;
} }
/* standby_disconnect_on_failover */
if (orig_options->standby_disconnect_on_failover != new_options.standby_disconnect_on_failover)
{
orig_options->standby_disconnect_on_failover = new_options.standby_disconnect_on_failover;
log_info(_("\"standby_disconnect_on_failover\" is now \"%s\""),
new_options.standby_disconnect_on_failover == true ? "TRUE" : "FALSE");
config_changed = true;
}
/* sibling_nodes_disconnect_timeout */
if (orig_options->sibling_nodes_disconnect_timeout != new_options.sibling_nodes_disconnect_timeout)
{
orig_options->sibling_nodes_disconnect_timeout = new_options.sibling_nodes_disconnect_timeout;
log_info(_("\"sibling_nodes_disconnect_timeout\" is now \"%i\""),
new_options.sibling_nodes_disconnect_timeout);
config_changed = true;
}
/* connection_check_type */
if (orig_options->connection_check_type != new_options.connection_check_type)
{
orig_options->connection_check_type = new_options.connection_check_type;
log_info(_("\"connection_check_type\" is now \"%s\""),
print_connection_check_type(new_options.connection_check_type));
config_changed = true;
}
/* primary_visibility_consensus */
if (orig_options->primary_visibility_consensus != new_options.primary_visibility_consensus)
{
orig_options->primary_visibility_consensus = new_options.primary_visibility_consensus;
log_info(_("\"primary_visibility_consensus\" is now \"%s\""),
new_options.primary_visibility_consensus == true ? "TRUE" : "FALSE");
config_changed = true;
}
/* failover_validation_command */
if (strncmp(orig_options->failover_validation_command, new_options.failover_validation_command, sizeof(orig_options->failover_validation_command)) != 0)
{
snprintf(orig_options->failover_validation_command, sizeof(orig_options->failover_validation_command),
"%s", new_options.failover_validation_command);
log_info(_("\"failover_validation_command\" is now \"%s\""), new_options.failover_validation_command);
config_changed = true;
}
/* /*
* Handle changes to logging configuration * Handle changes to logging configuration
*/ */
/* log_facility */ /* log_facility */
if (strncmp(orig_options->log_facility, new_options.log_facility, sizeof(orig_options->log_facility)) != 0) if (strncmp(orig_options->log_facility, new_options.log_facility, MAXLEN) != 0)
{ {
snprintf(orig_options->log_facility, sizeof(orig_options->log_facility), strncpy(orig_options->log_facility, new_options.log_facility, MAXLEN);
"%s", new_options.log_facility);
log_info(_("\"log_facility\" is now \"%s\""), new_options.log_facility); log_info(_("\"log_facility\" is now \"%s\""), new_options.log_facility);
log_config_changed = true; log_config_changed = true;
} }
/* log_file */ /* log_file */
if (strncmp(orig_options->log_file, new_options.log_file, sizeof(orig_options->log_file)) != 0) if (strncmp(orig_options->log_file, new_options.log_file, MAXLEN) != 0)
{ {
snprintf(orig_options->log_file, sizeof(orig_options->log_file), strncpy(orig_options->log_file, new_options.log_file, MAXLEN);
"%s", new_options.log_file);
log_info(_("\"log_file\" is now \"%s\""), new_options.log_file); log_info(_("\"log_file\" is now \"%s\""), new_options.log_file);
log_config_changed = true; log_config_changed = true;
@@ -1580,10 +1337,9 @@ reload_config(t_configuration_options *orig_options, t_server_type server_type)
/* log_level */ /* log_level */
if (strncmp(orig_options->log_level, new_options.log_level, sizeof(orig_options->log_level)) != 0) if (strncmp(orig_options->log_level, new_options.log_level, MAXLEN) != 0)
{ {
snprintf(orig_options->log_level, sizeof(orig_options->log_level), strncpy(orig_options->log_level, new_options.log_level, MAXLEN);
"%s", new_options.log_level);
log_info(_("\"log_level\" is now \"%s\""), new_options.log_level); log_info(_("\"log_level\" is now \"%s\""), new_options.log_level);
log_config_changed = true; log_config_changed = true;
@@ -1768,7 +1524,7 @@ repmgr_atoi(const char *value, const char *config_item, ItemList *error_list, in
* *
* TODO: accept "any unambiguous prefix of one of these" as per postgresql.conf: * TODO: accept "any unambiguous prefix of one of these" as per postgresql.conf:
* *
* https://www.postgresql.org/docs/current/config-setting.html * https://www.postgresql.org/docs/current/static/config-setting.html
*/ */
bool bool
parse_bool(const char *s, const char *config_item, ItemList *error_list) parse_bool(const char *s, const char *config_item, ItemList *error_list)
@@ -2077,10 +1833,18 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
struct option *long_options = NULL; struct option *long_options = NULL;
/* /* We're only interested in these options */
* We're only interested in these options. static struct option long_options_9[] =
*/ {
{"slot", required_argument, NULL, 'S'},
{"xlog-method", required_argument, NULL, 'X'},
{NULL, 0, NULL, 0}
};
/*
* From PostgreSQL 10, --xlog-method is renamed --wal-method and there's
* also --no-slot, which we'll want to consider.
*/
static struct option long_options_10[] = static struct option long_options_10[] =
{ {
{"slot", required_argument, NULL, 'S'}, {"slot", required_argument, NULL, 'S'},
@@ -2089,17 +1853,6 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
/*
* Pre-PostgreSQL 10 options
*/
static struct option long_options_legacy[] =
{
{"slot", required_argument, NULL, 'S'},
{"xlog-method", required_argument, NULL, 'X'},
{NULL, 0, NULL, 0}
};
/* Don't attempt to tokenise an empty string */ /* Don't attempt to tokenise an empty string */
if (!strlen(pg_basebackup_options)) if (!strlen(pg_basebackup_options))
return backup_options_ok; return backup_options_ok;
@@ -2107,7 +1860,7 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
if (server_version_num >= 100000) if (server_version_num >= 100000)
long_options = long_options_10; long_options = long_options_10;
else else
long_options = long_options_legacy; long_options = long_options_9;
argc_item = parse_output_to_argv(pg_basebackup_options, &argv_array); argc_item = parse_output_to_argv(pg_basebackup_options, &argv_array);
@@ -2126,7 +1879,7 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
strncpy(backup_options->slot, optarg, MAXLEN); strncpy(backup_options->slot, optarg, MAXLEN);
break; break;
case 'X': case 'X':
strncpy(backup_options->wal_method, optarg, MAXLEN); strncpy(backup_options->xlog_method, optarg, MAXLEN);
break; break;
case 1: case 1:
backup_options->no_slot = true; backup_options->no_slot = true;
@@ -2157,21 +1910,3 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
return backup_options_ok; return backup_options_ok;
} }
const char *
print_connection_check_type(ConnectionCheckType type)
{
switch (type)
{
case CHECK_PING:
return "ping";
case CHECK_QUERY:
return "query";
case CHECK_CONNECTION:
return "connection";
}
/* should never reach here */
return "UNKNOWN";
}

View File

@@ -1,7 +1,7 @@
/* /*
* configfile.h * configfile.h
* *
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) 2ndQuadrant, 2010-2018
* *
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@@ -37,13 +37,6 @@ typedef enum
FAILOVER_AUTOMATIC FAILOVER_AUTOMATIC
} failover_mode_opt; } failover_mode_opt;
typedef enum
{
CHECK_PING,
CHECK_QUERY,
CHECK_CONNECTION
} ConnectionCheckType;
typedef struct EventNotificationListCell typedef struct EventNotificationListCell
{ {
struct EventNotificationListCell *next; struct EventNotificationListCell *next;
@@ -76,7 +69,7 @@ typedef struct
{ {
/* node information */ /* node information */
int node_id; int node_id;
char node_name[NAMEDATALEN]; char node_name[MAXLEN];
char conninfo[MAXLEN]; char conninfo[MAXLEN];
char replication_user[NAMEDATALEN]; char replication_user[NAMEDATALEN];
char data_directory[MAXPGPATH]; char data_directory[MAXPGPATH];
@@ -88,7 +81,7 @@ typedef struct
/* log settings */ /* log settings */
char log_level[MAXLEN]; char log_level[MAXLEN];
char log_facility[MAXLEN]; char log_facility[MAXLEN];
char log_file[MAXPGPATH]; char log_file[MAXLEN];
int log_status_interval; int log_status_interval;
/* standby clone settings */ /* standby clone settings */
@@ -113,7 +106,6 @@ typedef struct
/* standby switchover settings */ /* standby switchover settings */
int shutdown_check_timeout; int shutdown_check_timeout;
int standby_reconnect_timeout; int standby_reconnect_timeout;
int wal_receive_check_timeout;
/* node rejoin settings */ /* node rejoin settings */
int node_rejoin_timeout; int node_rejoin_timeout;
@@ -142,18 +134,6 @@ 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 standby_disconnect_on_failover;
int sibling_nodes_disconnect_timeout;
ConnectionCheckType connection_check_type;
bool primary_visibility_consensus;
char failover_validation_command[MAXPGPATH];
int election_rerun_interval;
int child_nodes_check_interval;
int child_nodes_disconnect_min_count;
int child_nodes_connected_min_count;
bool child_nodes_connected_include_witness;
int child_nodes_disconnect_timeout;
char child_nodes_disconnect_command[MAXPGPATH];
/* BDR settings */ /* BDR settings */
bool bdr_local_monitoring_only; bool bdr_local_monitoring_only;
@@ -161,18 +141,14 @@ typedef struct
/* service settings */ /* service settings */
char pg_ctl_options[MAXLEN]; char pg_ctl_options[MAXLEN];
char service_start_command[MAXPGPATH]; char service_stop_command[MAXLEN];
char service_stop_command[MAXPGPATH]; char service_start_command[MAXLEN];
char service_restart_command[MAXPGPATH]; char service_restart_command[MAXLEN];
char service_reload_command[MAXPGPATH]; char service_reload_command[MAXLEN];
char service_promote_command[MAXPGPATH]; char service_promote_command[MAXLEN];
/* repmgrd service settings */
char repmgrd_service_start_command[MAXPGPATH];
char repmgrd_service_stop_command[MAXPGPATH];
/* event notification settings */ /* event notification settings */
char event_notification_command[MAXPGPATH]; char event_notification_command[MAXLEN];
char event_notifications_orig[MAXLEN]; char event_notifications_orig[MAXLEN];
EventNotificationList event_notifications; EventNotificationList event_notifications;
@@ -198,7 +174,7 @@ typedef struct
/* node information */ \ /* node information */ \
UNKNOWN_NODE_ID, "", "", "", "", "", "", "", REPLICATION_TYPE_PHYSICAL, \ UNKNOWN_NODE_ID, "", "", "", "", "", "", "", REPLICATION_TYPE_PHYSICAL, \
/* log settings */ \ /* log settings */ \
"", "", "", DEFAULT_LOG_STATUS_INTERVAL, \ "", "", "", DEFAULT_LOG_STATUS_INTERVAL, \
/* standby clone settings */ \ /* standby clone settings */ \
false, "", "", { NULL, NULL }, "", false, "", false, "", \ false, "", "", { NULL, NULL }, "", false, "", false, "", \
/* standby promote settings */ \ /* standby promote settings */ \
@@ -209,7 +185,6 @@ typedef struct
/* standby switchover settings */ \ /* standby switchover settings */ \
DEFAULT_SHUTDOWN_CHECK_TIMEOUT, \ DEFAULT_SHUTDOWN_CHECK_TIMEOUT, \
DEFAULT_STANDBY_RECONNECT_TIMEOUT, \ DEFAULT_STANDBY_RECONNECT_TIMEOUT, \
DEFAULT_WAL_RECEIVE_CHECK_TIMEOUT, \
/* node rejoin settings */ \ /* node rejoin settings */ \
DEFAULT_NODE_REJOIN_TIMEOUT, \ DEFAULT_NODE_REJOIN_TIMEOUT, \
/* node check settings */ \ /* node check settings */ \
@@ -224,20 +199,12 @@ typedef struct
DEFAULT_RECONNECTION_INTERVAL, \ DEFAULT_RECONNECTION_INTERVAL, \
false, -1, \ false, -1, \
DEFAULT_ASYNC_QUERY_TIMEOUT, \ DEFAULT_ASYNC_QUERY_TIMEOUT, \
DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT, \ DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT, \
-1, "", false, DEFAULT_SIBLING_NODES_DISCONNECT_TIMEOUT, \ -1, "", \
CHECK_PING, true, "", DEFAULT_ELECTION_RERUN_INTERVAL, \
DEFAULT_CHILD_NODES_CHECK_INTERVAL, \
DEFAULT_CHILD_NODES_DISCONNECT_MIN_COUNT, \
DEFAULT_CHILD_NODES_CONNECTED_MIN_COUNT, \
DEFAULT_CHILD_NODES_CONNECTED_INCLUDE_WITNESS, \
DEFAULT_CHILD_NODES_DISCONNECT_TIMEOUT, "", \
/* BDR settings */ \ /* BDR settings */ \
false, DEFAULT_BDR_RECOVERY_TIMEOUT, \ false, DEFAULT_BDR_RECOVERY_TIMEOUT, \
/* service settings */ \ /* service settings */ \
"", "", "", "", "", "", \ "", "", "", "", "", "", \
/* repmgrd service settings */ \
"", "", \
/* event notification settings */ \ /* event notification settings */ \
"", "", { NULL, NULL }, \ "", "", { NULL, NULL }, \
/* barman settings */ \ /* barman settings */ \
@@ -253,7 +220,7 @@ typedef struct
typedef struct typedef struct
{ {
char slot[MAXLEN]; char slot[MAXLEN];
char wal_method[MAXLEN]; char xlog_method[MAXLEN];
bool no_slot; /* from PostgreSQL 10 */ bool no_slot; /* from PostgreSQL 10 */
} t_basebackup_options; } t_basebackup_options;
@@ -340,6 +307,5 @@ void free_parsed_argv(char ***argv_array);
/* 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_connection_check_type(ConnectionCheckType type);
#endif /* _REPMGR_CONFIGFILE_H_ */ #endif /* _REPMGR_CONFIGFILE_H_ */

41
configure vendored
View File

@@ -1,8 +1,8 @@
#! /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.4. # Generated by GNU Autoconf 2.69 for repmgr 4.2.
# #
# Report bugs to <repmgr@googlegroups.com>. # Report bugs to <pgsql-bugs@postgresql.org>.
# #
# #
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -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-2018, 2ndQuadrant Ltd.
## -------------------- ## ## -------------------- ##
## M4sh Initialization. ## ## M4sh Initialization. ##
## -------------------- ## ## -------------------- ##
@@ -269,7 +269,7 @@ fi
$as_echo "$0: be upgraded to zsh 4.3.4 or later." $as_echo "$0: be upgraded to zsh 4.3.4 or later."
else else
$as_echo "$0: Please tell bug-autoconf@gnu.org and $as_echo "$0: Please tell bug-autoconf@gnu.org and
$0: repmgr@googlegroups.com about your system, including $0: pgsql-bugs@postgresql.org about your system, including
$0: any error possibly output before this message. Then $0: any error possibly output before this message. Then
$0: install a modern shell, or manually run the script $0: install a modern shell, or manually run the script
$0: under such a shell if you do have one." $0: under such a shell if you do have one."
@@ -582,10 +582,10 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='repmgr' PACKAGE_NAME='repmgr'
PACKAGE_TARNAME='repmgr' PACKAGE_TARNAME='repmgr'
PACKAGE_VERSION='4.4' PACKAGE_VERSION='4.2'
PACKAGE_STRING='repmgr 4.4' PACKAGE_STRING='repmgr 4.2'
PACKAGE_BUGREPORT='repmgr@googlegroups.com' PACKAGE_BUGREPORT='pgsql-bugs@postgresql.org'
PACKAGE_URL='https://repmgr.org/' PACKAGE_URL='https://2ndquadrant.com/en/resources/repmgr/'
ac_subst_vars='LTLIBOBJS ac_subst_vars='LTLIBOBJS
LIBOBJS LIBOBJS
@@ -1178,7 +1178,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.4 to adapt to many kinds of systems. \`configure' configures repmgr 4.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1239,7 +1239,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.4:";; short | recursive ) echo "Configuration of repmgr 4.2:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1249,8 +1249,8 @@ Some influential environment variables:
Use these variables to override the choices made by `configure' or to help Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations. it to find libraries and programs with nonstandard names/locations.
Report bugs to <repmgr@googlegroups.com>. Report bugs to <pgsql-bugs@postgresql.org>.
repmgr home page: <https://repmgr.org/>. repmgr home page: <https://2ndquadrant.com/en/resources/repmgr/>.
_ACEOF _ACEOF
ac_status=$? ac_status=$?
fi fi
@@ -1313,14 +1313,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.4 repmgr configure 4.2
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-2018, 2ndQuadrant Ltd.
_ACEOF _ACEOF
exit exit
fi fi
@@ -1332,7 +1332,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.4, which was It was created by repmgr $as_me 4.2, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@@ -1851,6 +1851,8 @@ 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
@@ -2357,7 +2359,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.4, which was This file was extended by repmgr $as_me 4.2, 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
@@ -2413,14 +2415,14 @@ $config_files
Configuration headers: Configuration headers:
$config_headers $config_headers
Report bugs to <repmgr@googlegroups.com>. Report bugs to <pgsql-bugs@postgresql.org>.
repmgr home page: <https://repmgr.org/>." repmgr home page: <https://2ndquadrant.com/en/resources/repmgr/>."
_ACEOF _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.4 repmgr config.status 4.2
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\\"
@@ -2544,6 +2546,7 @@ 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.4], [repmgr@googlegroups.com], [repmgr], [https://repmgr.org/]) AC_INIT([repmgr], [4.2], [pgsql-bugs@postgresql.org], [repmgr], [https://2ndquadrant.com/en/resources/repmgr/])
AC_COPYRIGHT([Copyright (c) 2010-2019, 2ndQuadrant Ltd.]) AC_COPYRIGHT([Copyright (c) 2010-2018, 2ndQuadrant Ltd.])
AC_CONFIG_HEADER(config.h) AC_CONFIG_HEADER(config.h)
@@ -59,5 +59,6 @@ AC_SUBST(vpath_build)
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

@@ -1,12 +1,6 @@
/* /*
* controldata.c - functions for reading the pg_control file * controldata.c
* * Copyright (c) 2ndQuadrant, 2010-2018
* The functions provided here enable repmgr to read a pg_control file
* in a version-indepent way, even if the PostgreSQL instance is not
* running. For that reason we can't use on the pg_control_*() functions
* provided in PostgreSQL 9.6 and later.
*
* Copyright (c) 2ndQuadrant, 2010-2019
* *
* 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
@@ -36,53 +30,6 @@
static ControlFileInfo *get_controlfile(const char *DataDir); static ControlFileInfo *get_controlfile(const char *DataDir);
int
get_pg_version(const char *data_directory, char *version_string)
{
char PgVersionPath[MAXPGPATH] = "";
FILE *fp = NULL;
char *endptr = NULL;
char file_version_string[MAX_VERSION_STRING] = "";
long file_major, file_minor;
int ret;
snprintf(PgVersionPath, MAXPGPATH, "%s/PG_VERSION", data_directory);
fp = fopen(PgVersionPath, "r");
if (fp == NULL)
{
log_warning(_("could not open file \"%s\" for reading"),
PgVersionPath);
log_detail("%s", strerror(errno));
return UNKNOWN_SERVER_VERSION_NUM;
}
file_version_string[0] = '\0';
ret = fscanf(fp, "%23s", file_version_string);
fclose(fp);
if (ret != 1 || endptr == file_version_string)
{
log_warning(_("unable to determine major version number from PG_VERSION"));
return UNKNOWN_SERVER_VERSION_NUM;
}
file_major = strtol(file_version_string, &endptr, 10);
file_minor = 0;
if (*endptr == '.')
file_minor = strtol(endptr + 1, NULL, 10);
if (version_string != NULL)
strncpy(version_string, file_version_string, MAX_VERSION_STRING);
return ((int) file_major * 10000) + ((int) file_minor * 100);
}
uint64 uint64
get_system_identifier(const char *data_directory) get_system_identifier(const char *data_directory)
{ {
@@ -97,7 +44,6 @@ get_system_identifier(const char *data_directory)
return system_identifier; return system_identifier;
} }
DBState DBState
get_db_state(const char *data_directory) get_db_state(const char *data_directory)
{ {
@@ -114,7 +60,7 @@ get_db_state(const char *data_directory)
} }
XLogRecPtr extern XLogRecPtr
get_latest_checkpoint_location(const char *data_directory) get_latest_checkpoint_location(const char *data_directory)
{ {
ControlFileInfo *control_file_info = NULL; ControlFileInfo *control_file_info = NULL;
@@ -166,59 +112,10 @@ describe_db_state(DBState state)
case DB_IN_PRODUCTION: case DB_IN_PRODUCTION:
return _("in production"); return _("in production");
} }
return _("unrecognized status code"); return _("unrecognized status code");
} }
TimeLineID
get_timeline(const char *data_directory)
{
ControlFileInfo *control_file_info = NULL;
TimeLineID timeline = -1;
control_file_info = get_controlfile(data_directory);
timeline = (int) control_file_info->timeline;
pfree(control_file_info);
return timeline;
}
TimeLineID
get_min_recovery_end_timeline(const char *data_directory)
{
ControlFileInfo *control_file_info = NULL;
TimeLineID timeline = -1;
control_file_info = get_controlfile(data_directory);
timeline = (int) control_file_info->minRecoveryPointTLI;
pfree(control_file_info);
return timeline;
}
XLogRecPtr
get_min_recovery_location(const char *data_directory)
{
ControlFileInfo *control_file_info = NULL;
XLogRecPtr minRecoveryPoint = InvalidXLogRecPtr;
control_file_info = get_controlfile(data_directory);
minRecoveryPoint = control_file_info->minRecoveryPoint;
pfree(control_file_info);
return minRecoveryPoint;
}
/* /*
* We maintain our own version of get_controlfile() as we need cross-version * We maintain our own version of get_controlfile() as we need cross-version
* compatibility, and also don't care if the file isn't readable. * compatibility, and also don't care if the file isn't readable.
@@ -226,10 +123,14 @@ get_min_recovery_location(const char *data_directory)
static ControlFileInfo * static ControlFileInfo *
get_controlfile(const char *DataDir) get_controlfile(const char *DataDir)
{ {
char file_version_string[MAX_VERSION_STRING] = "";
ControlFileInfo *control_file_info; ControlFileInfo *control_file_info;
int fd, version_num; FILE *fp = NULL;
int fd, ret, version_num;
char PgVersionPath[MAXPGPATH] = "";
char ControlFilePath[MAXPGPATH] = ""; char ControlFilePath[MAXPGPATH] = "";
char file_version_string[64] = "";
long file_major, file_minor;
char *endptr = NULL;
void *ControlFileDataPtr = NULL; void *ControlFileDataPtr = NULL;
int expected_size = 0; int expected_size = 0;
@@ -241,32 +142,50 @@ get_controlfile(const char *DataDir)
control_file_info->state = DB_SHUTDOWNED; control_file_info->state = DB_SHUTDOWNED;
control_file_info->checkPoint = InvalidXLogRecPtr; control_file_info->checkPoint = InvalidXLogRecPtr;
control_file_info->data_checksum_version = -1; control_file_info->data_checksum_version = -1;
control_file_info->timeline = -1;
control_file_info->minRecoveryPointTLI = -1;
control_file_info->minRecoveryPoint = InvalidXLogRecPtr;
/* /*
* Read PG_VERSION, as we'll need to determine which struct to read * Read PG_VERSION, as we'll need to determine which struct to read
* the control file contents into * the control file contents into
*/ */
snprintf(PgVersionPath, MAXPGPATH, "%s/PG_VERSION", DataDir);
version_num = get_pg_version(DataDir, file_version_string); fp = fopen(PgVersionPath, "r");
if (version_num == UNKNOWN_SERVER_VERSION_NUM) if (fp == NULL)
{ {
log_warning(_("unable to determine server version number from PG_VERSION")); log_warning(_("could not open file \"%s\" for reading"),
PgVersionPath);
log_detail("%s", strerror(errno));
return control_file_info; return control_file_info;
} }
if (version_num < MIN_SUPPORTED_VERSION_NUM) file_version_string[0] = '\0';
ret = fscanf(fp, "%63s", file_version_string);
fclose(fp);
if (ret != 1 || endptr == file_version_string)
{ {
log_warning(_("data directory appears to be initialised for %s"), log_warning(_("unable to determine major version number from PG_VERSION"));
file_version_string);
log_detail(_("minimum supported PostgreSQL version is %s"),
MIN_SUPPORTED_VERSION);
return control_file_info; return control_file_info;
} }
file_major = strtol(file_version_string, &endptr, 10);
file_minor = 0;
if (*endptr == '.')
file_minor = strtol(endptr + 1, NULL, 10);
version_num = ((int) file_major * 10000) + ((int) file_minor * 100);
if (version_num < 90300)
{
log_warning(_("Data directory appears to be initialised for %s"), file_version_string);
return control_file_info;
}
snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir); snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1) if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
@@ -301,8 +220,6 @@ get_controlfile(const char *DataDir)
ControlFilePath); ControlFilePath);
log_detail("%s", strerror(errno)); log_detail("%s", strerror(errno));
close(fd);
return control_file_info; return control_file_info;
} }
@@ -310,27 +227,13 @@ get_controlfile(const char *DataDir)
control_file_info->control_file_processed = true; control_file_info->control_file_processed = true;
if (version_num >= 120000) if (version_num >= 110000)
{
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 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;
control_file_info->state = ptr->state; control_file_info->state = ptr->state;
control_file_info->checkPoint = ptr->checkPoint; control_file_info->checkPoint = ptr->checkPoint;
control_file_info->data_checksum_version = ptr->data_checksum_version; 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 if (version_num >= 90500) else if (version_num >= 90500)
{ {
@@ -339,9 +242,6 @@ get_controlfile(const char *DataDir)
control_file_info->state = ptr->state; control_file_info->state = ptr->state;
control_file_info->checkPoint = ptr->checkPoint; control_file_info->checkPoint = ptr->checkPoint;
control_file_info->data_checksum_version = ptr->data_checksum_version; 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 if (version_num >= 90400) else if (version_num >= 90400)
{ {
@@ -350,9 +250,6 @@ get_controlfile(const char *DataDir)
control_file_info->state = ptr->state; control_file_info->state = ptr->state;
control_file_info->checkPoint = ptr->checkPoint; control_file_info->checkPoint = ptr->checkPoint;
control_file_info->data_checksum_version = ptr->data_checksum_version; 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 if (version_num >= 90300) else if (version_num >= 90300)
{ {
@@ -361,9 +258,6 @@ get_controlfile(const char *DataDir)
control_file_info->state = ptr->state; control_file_info->state = ptr->state;
control_file_info->checkPoint = ptr->checkPoint; control_file_info->checkPoint = ptr->checkPoint;
control_file_info->data_checksum_version = ptr->data_checksum_version; 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);
@@ -371,7 +265,9 @@ get_controlfile(const char *DataDir)
/* /*
* We don't check the CRC here as we're potentially checking a pg_control * We don't check the CRC here as we're potentially checking a pg_control
* file from a different PostgreSQL version to the one repmgr was compiled * file from a different PostgreSQL version to the one repmgr was compiled
* against. * against. However we're only interested in the first few fields, which
* should be constant across supported versions
*
*/ */
return control_file_info; return control_file_info;

View File

@@ -1,6 +1,6 @@
/* /*
* controldata.h * controldata.h
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) 2ndQuadrant, 2010-2018
* *
* 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,7 +12,6 @@
#include "postgres_fe.h" #include "postgres_fe.h"
#include "catalog/pg_control.h" #include "catalog/pg_control.h"
#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
* required by repmgr. * required by repmgr.
@@ -24,9 +23,6 @@ typedef struct
DBState state; DBState state;
XLogRecPtr checkPoint; XLogRecPtr checkPoint;
uint32 data_checksum_version; uint32 data_checksum_version;
TimeLineID timeline;
TimeLineID minRecoveryPointTLI;
XLogRecPtr minRecoveryPoint;
} ControlFileInfo; } ControlFileInfo;
@@ -138,11 +134,13 @@ typedef struct ControlFileData93
/* /*
* Following field added since 9.3: * Following fields added since 9.3:
* *
* int max_worker_processes; * int max_worker_processes;
* int max_prepared_xacts;
* int max_locks_per_xact;
*
*/ */
typedef struct ControlFileData94 typedef struct ControlFileData94
{ {
uint64 system_identifier; uint64 system_identifier;
@@ -333,80 +331,11 @@ typedef struct ControlFileData11
} ControlFileData11; } ControlFileData11;
/*
* Following field added in Pg12:
*
* int max_wal_senders;
*
* Following fields removed:
*
* uint32 nextXidEpoch;
* TransactionId nextXid;
*
* and replaced by:
*
* FullTransactionId nextFullXid;
*/
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 */
CheckPoint 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;
extern int get_pg_version(const char *data_directory, char *version_string);
extern DBState get_db_state(const char *data_directory); extern DBState get_db_state(const char *data_directory);
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);
extern XLogRecPtr get_latest_checkpoint_location(const char *data_directory); extern XLogRecPtr get_latest_checkpoint_location(const char *data_directory);
extern TimeLineID get_timeline(const char *data_directory);
extern TimeLineID get_min_recovery_end_timeline(const char *data_directory);
extern XLogRecPtr get_min_recovery_location(const char *data_directory);
#endif /* _CONTROLDATA_H_ */ #endif /* _CONTROLDATA_H_ */

1793
dbutils.c

File diff suppressed because it is too large Load Diff

154
dbutils.h
View File

@@ -1,7 +1,7 @@
/* /*
* dbutils.h * dbutils.h
* *
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) 2ndQuadrant, 2010-2018
* *
* 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
@@ -20,7 +20,6 @@
#ifndef _REPMGR_DBUTILS_H_ #ifndef _REPMGR_DBUTILS_H_
#define _REPMGR_DBUTILS_H_ #define _REPMGR_DBUTILS_H_
#include "access/timeline.h"
#include "access/xlogdefs.h" #include "access/xlogdefs.h"
#include "pqexpbuffer.h" #include "pqexpbuffer.h"
#include "portability/instr_time.h" #include "portability/instr_time.h"
@@ -29,38 +28,7 @@
#include "strutil.h" #include "strutil.h"
#include "voting.h" #include "voting.h"
#define REPMGR_NODES_COLUMNS \ #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 "
"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, " \
"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 BDR2_NODES_COLUMNS "node_sysid, node_timeline, node_dboid, node_name, node_local_dsn, ''" #define BDR2_NODES_COLUMNS "node_sysid, node_timeline, node_dboid, node_name, node_local_dsn, ''"
#define BDR3_NODES_COLUMNS "ns.node_id, 0, 0, ns.node_name, ns.interface_connstr, ns.peer_state_name" #define BDR3_NODES_COLUMNS "ns.node_id, 0, 0, ns.node_name, ns.interface_connstr, ns.peer_state_name"
@@ -111,8 +79,7 @@ typedef enum
NODE_STATUS_UP, NODE_STATUS_UP,
NODE_STATUS_SHUTTING_DOWN, NODE_STATUS_SHUTTING_DOWN,
NODE_STATUS_DOWN, NODE_STATUS_DOWN,
NODE_STATUS_UNCLEAN_SHUTDOWN, NODE_STATUS_UNCLEAN_SHUTDOWN
NODE_STATUS_REJECTED
} NodeStatus; } NodeStatus;
typedef enum typedef enum
@@ -123,13 +90,6 @@ typedef enum
CONN_ERROR CONN_ERROR
} ConnectionStatus; } ConnectionStatus;
typedef enum
{
NODE_ATTACHED_UNKNOWN = -1,
NODE_DETACHED,
NODE_ATTACHED
} NodeAttached;
typedef enum typedef enum
{ {
SLOT_UNKNOWN = -1, SLOT_UNKNOWN = -1,
@@ -145,47 +105,22 @@ typedef enum
} BackupState; } BackupState;
/* /*
* Struct to store extension version information * Struct to store extension version information
*/ */
typedef struct s_extension_versions { typedef struct s_extension_versions {
char default_version[8]; char default_version[8];
int default_version_num;
char installed_version[8]; char installed_version[8];
int installed_version_num;
} t_extension_versions; } t_extension_versions;
#define T_EXTENSION_VERSIONS_INITIALIZER { \ #define T_EXTENSION_VERSIONS_INITIALIZER { \
"", \ "", \
UNKNOWN_SERVER_VERSION_NUM, \
"", \ "", \
UNKNOWN_SERVER_VERSION_NUM \
} }
typedef struct
{
char current_timestamp[MAXLEN];
bool in_recovery;
TimeLineID timeline_id;
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
{ {
@@ -193,8 +128,8 @@ typedef struct s_node_info
int node_id; int node_id;
int upstream_node_id; int upstream_node_id;
t_server_type type; t_server_type type;
char node_name[NAMEDATALEN]; char node_name[MAXLEN];
char upstream_node_name[NAMEDATALEN]; char upstream_node_name[MAXLEN];
char conninfo[MAXLEN]; char conninfo[MAXLEN];
char repluser[NAMEDATALEN]; char repluser[NAMEDATALEN];
char location[MAXLEN]; char location[MAXLEN];
@@ -211,7 +146,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;
NodeAttached attached; bool attached;
/* various statistics */ /* various statistics */
int max_wal_senders; int max_wal_senders;
int attached_wal_receivers; int attached_wal_receivers;
@@ -219,8 +154,6 @@ 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;
@@ -245,10 +178,9 @@ typedef struct s_node_info
MS_NORMAL, \ MS_NORMAL, \
NULL, \ NULL, \
/* 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 \
} }
@@ -361,6 +293,23 @@ typedef struct BdrNodeInfoList
0 \ 0 \
} }
typedef struct
{
char current_timestamp[MAXLEN];
uint64 last_wal_receive_lsn;
uint64 last_wal_replay_lsn;
char last_xact_replay_timestamp[MAXLEN];
int replication_lag_time;
bool receiving_streamed_wal;
} ReplInfo;
#define T_REPLINFO_INTIALIZER { \
"", \
InvalidXLogRecPtr, \
InvalidXLogRecPtr, \
"", \
0 \
}
typedef struct typedef struct
@@ -402,16 +351,16 @@ typedef struct RepmgrdInfo {
char pid_file[MAXLEN]; char pid_file[MAXLEN];
bool pg_running; bool pg_running;
char pg_running_text[MAXLEN]; char pg_running_text[MAXLEN];
RecoveryType recovery_type;
bool running; bool running;
char repmgrd_running[MAXLEN]; char repmgrd_running[MAXLEN];
bool paused; bool paused;
bool wal_paused_pending_wal;
int upstream_last_seen;
char upstream_last_seen_text[MAXLEN];
} RepmgrdInfo; } RepmgrdInfo;
/* global variables */
extern int server_version_num;
/* macros */ /* macros */
#define is_streaming_replication(x) (x == PRIMARY || x == STANDBY) #define is_streaming_replication(x) (x == PRIMARY || x == STANDBY)
@@ -452,7 +401,6 @@ void param_set_ine(t_conninfo_param_list *param_list, const char *param, const
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 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);
bool has_passfile(void); bool has_passfile(void);
@@ -465,35 +413,24 @@ 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_int(PGconn *conn, const char *setting, int *output);
bool alter_system_int(PGconn *conn, const char *name, int value);
bool pg_reload_conf(PGconn *conn);
/* server information functions */ /* server information functions */
bool get_cluster_size(PGconn *conn, char *size); bool get_cluster_size(PGconn *conn, char *size);
int get_server_version(PGconn *conn, char *server_version_buf); int get_server_version(PGconn *conn, char *server_version);
RecoveryType get_recovery_type(PGconn *conn); 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);
/* 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);
int repmgrd_get_local_node_id(PGconn *conn); int repmgrd_get_local_node_id(PGconn *conn);
bool repmgrd_check_local_node_id(PGconn *conn);
BackupState server_in_exclusive_backup_mode(PGconn *conn); BackupState server_in_exclusive_backup_mode(PGconn *conn);
void repmgrd_set_pid(PGconn *conn, pid_t repmgrd_pid, const char *pidfile); void repmgrd_set_pid(PGconn *conn, pid_t repmgrd_pid, const char *pidfile);
pid_t repmgrd_get_pid(PGconn *conn); 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);
@@ -501,16 +438,13 @@ ExtensionStatus get_repmgr_extension_status(PGconn *conn, t_extension_versions *
/* node management functions */ /* node management functions */
void checkpoint(PGconn *conn); void checkpoint(PGconn *conn);
bool vacuum_table(PGconn *conn, const char *table); bool vacuum_table(PGconn *conn, const char *table);
bool promote_standby(PGconn *conn, bool wait, int wait_seconds);
bool resume_wal_replay(PGconn *conn);
/* node record functions */ /* node record functions */
t_server_type parse_node_type(const char *type); t_server_type parse_node_type(const char *type);
const char *get_node_type_string(t_server_type type); const char *get_node_type_string(t_server_type type);
RecordStatus get_node_record(PGconn *conn, int node_id, t_node_info *node_info); RecordStatus get_node_record(PGconn *conn, int node_id, t_node_info *node_info);
RecordStatus refresh_node_record(PGconn *conn, int node_id, t_node_info *node_info);
RecordStatus get_node_record_with_upstream(PGconn *conn, int node_id, t_node_info *node_info); RecordStatus get_node_record_with_upstream(PGconn *conn, int node_id, t_node_info *node_info);
RecordStatus get_node_record_by_name(PGconn *conn, const char *node_name, t_node_info *node_info); RecordStatus get_node_record_by_name(PGconn *conn, const char *node_name, t_node_info *node_info);
@@ -522,7 +456,6 @@ 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);
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);
@@ -558,7 +491,7 @@ 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 create_replication_slot(PGconn *conn, char *slot_name, int server_version_num, PQExpBufferData *error_msg);
bool drop_replication_slot(PGconn *conn, char *slot_name); bool drop_replication_slot(PGconn *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);
@@ -569,14 +502,12 @@ bool get_tablespace_name_by_location(PGconn *conn, const char *location, char *
/* asynchronous query functions */ /* asynchronous query functions */
bool cancel_query(PGconn *conn, int timeout); bool cancel_query(PGconn *conn, int timeout);
int wait_connection_availability(PGconn *conn, int timeout); int wait_connection_availability(PGconn *conn, long long timeout);
/* node availability functions */ /* node availability functions */
bool is_server_available(const char *conninfo); bool is_server_available(const char *conninfo);
bool is_server_available_quiet(const char *conninfo);
bool is_server_available_params(t_conninfo_param_list *param_list); bool is_server_available_params(t_conninfo_param_list *param_list);
ExecStatusType connection_ping(PGconn *conn); ExecStatusType connection_ping(PGconn *conn);
ExecStatusType connection_ping_reconnect(PGconn *conn);
/* monitoring functions */ /* monitoring functions */
void void
@@ -607,19 +538,12 @@ bool get_new_primary(PGconn *conn, int *primary_node_id);
void reset_voting_status(PGconn *conn); void reset_voting_status(PGconn *conn);
/* replication status functions */ /* replication status functions */
XLogRecPtr get_primary_current_lsn(PGconn *conn); XLogRecPtr get_current_wal_lsn(PGconn *conn);
XLogRecPtr get_node_current_lsn(PGconn *conn);
XLogRecPtr get_last_wal_receive_location(PGconn *conn); XLogRecPtr get_last_wal_receive_location(PGconn *conn);
void init_replication_info(ReplInfo *replication_info); bool get_replication_info(PGconn *conn, 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); void get_node_replication_stats(PGconn *conn, int server_version_num, 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);
void set_upstream_last_seen(PGconn *conn, int upstream_node_id);
int get_upstream_last_seen(PGconn *conn, t_server_type node_type);
bool is_wal_replay_paused(PGconn *conn, bool check_pending_wal);
/* BDR functions */ /* BDR functions */
int get_bdr_version_num(void); int get_bdr_version_num(void);

View File

@@ -3,7 +3,7 @@
* dirmod.c * dirmod.c
* directory handling functions * directory handling functions
* *
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) 2ndQuadrant, 2010-2018
* *
* 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
@@ -50,7 +50,7 @@ typedef long pgpid_t;
* and tablespace directories. * and tablespace directories.
*/ */
DataDirState DataDirState
check_dir(const char *path) check_dir(char *path)
{ {
DIR *chkdir = NULL; DIR *chkdir = NULL;
struct dirent *file = NULL; struct dirent *file = NULL;
@@ -91,17 +91,12 @@ check_dir(const char *path)
* Create directory with error log message when failing * Create directory with error log message when failing
*/ */
bool bool
create_dir(const char *path) create_dir(char *path)
{ {
char create_dir_path[MAXPGPATH]; if (mkdir_p(path, 0700) == 0)
/* mkdir_p() may modify the supplied path */
strncpy(create_dir_path, path, MAXPGPATH);
if (mkdir_p(create_dir_path, 0700) == 0)
return true; return true;
log_error(_("unable to create directory \"%s\""), create_dir_path); log_error(_("unable to create directory \"%s\""), path);
log_detail("%s", strerror(errno)); log_detail("%s", strerror(errno));
return false; return false;
@@ -109,12 +104,13 @@ create_dir(const char *path)
bool bool
set_dir_permissions(const char *path) set_dir_permissions(char *path)
{ {
return (chmod(path, 0700) != 0) ? false : true; return (chmod(path, 0700) != 0) ? false : true;
} }
/* function from initdb.c */ /* function from initdb.c */
/* source adapted from FreeBSD /src/bin/mkdir/mkdir.c */ /* source adapted from FreeBSD /src/bin/mkdir/mkdir.c */
@@ -202,9 +198,9 @@ mkdir_p(char *path, mode_t omode)
bool bool
is_pg_dir(const char *path) is_pg_dir(char *path)
{ {
char dirpath[MAXPGPATH] = ""; char dirpath[MAXPGPATH];
struct stat sb; struct stat sb;
/* test pgdata */ /* test pgdata */
@@ -227,7 +223,7 @@ is_pg_dir(const char *path)
* any further useful progress can be made. * any further useful progress can be made.
*/ */
PgDirState PgDirState
is_pg_running(const char *path) is_pg_running(char *path)
{ {
long pid; long pid;
FILE *pidf; FILE *pidf;
@@ -276,8 +272,6 @@ is_pg_running(const char *path)
log_warning(_("invalid data in PostgreSQL PID file \"%s\""), path); log_warning(_("invalid data in PostgreSQL PID file \"%s\""), path);
} }
fclose(pidf);
return PG_DIR_NOT_RUNNING; return PG_DIR_NOT_RUNNING;
} }
@@ -297,7 +291,7 @@ is_pg_running(const char *path)
bool bool
create_pg_dir(const char *path, bool force) create_pg_dir(char *path, bool force)
{ {
/* Check this directory can be used as a PGDATA dir */ /* Check this directory can be used as a PGDATA dir */
switch (check_dir(path)) switch (check_dir(path))
@@ -336,15 +330,6 @@ create_pg_dir(const char *path, bool force)
{ {
log_notice(_("-F/--force provided - deleting existing data directory \"%s\""), path); log_notice(_("-F/--force provided - deleting existing data directory \"%s\""), path);
nftw(path, unlink_dir_callback, 64, FTW_DEPTH | FTW_PHYS); nftw(path, unlink_dir_callback, 64, FTW_DEPTH | FTW_PHYS);
/* recreate the directory ourselves to ensure permissions are correct */
if (!create_dir(path))
{
log_error(_("unable to create directory \"%s\"..."),
path);
return false;
}
return true; return true;
} }
@@ -356,24 +341,14 @@ create_pg_dir(const char *path, bool force)
{ {
log_notice(_("deleting existing directory \"%s\""), path); log_notice(_("deleting existing directory \"%s\""), path);
nftw(path, unlink_dir_callback, 64, FTW_DEPTH | FTW_PHYS); nftw(path, unlink_dir_callback, 64, FTW_DEPTH | FTW_PHYS);
/* recreate the directory ourselves to ensure permissions are correct */
if (!create_dir(path))
{
log_error(_("unable to create directory \"%s\"..."),
path);
return false;
}
return true; return true;
} }
return false; return false;
} }
break; break;
case DIR_ERROR: case DIR_ERROR:
log_error(_("could not access directory \"%s\"") log_error(_("could not access directory \"%s\": %s"),
, path); path, strerror(errno));
log_detail("%s", strerror(errno));
return false; return false;
} }
@@ -383,7 +358,7 @@ create_pg_dir(const char *path, bool force)
int int
rmdir_recursive(const char *path) rmdir_recursive(char *path)
{ {
return nftw(path, unlink_dir_callback, 64, FTW_DEPTH | FTW_PHYS); return nftw(path, unlink_dir_callback, 64, FTW_DEPTH | FTW_PHYS);
} }

View File

@@ -1,6 +1,6 @@
/* /*
* dirutil.h * dirutil.h
* Copyright (c) 2ndQuadrant, 2010-2019 * Copyright (c) 2ndQuadrant, 2010-2018
* *
* 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,13 +35,13 @@ 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(char *path);
extern DataDirState check_dir(const char *path); extern DataDirState check_dir(char *path);
extern bool create_dir(const char *path); extern bool create_dir(char *path);
extern bool is_pg_dir(const char *path); extern bool is_pg_dir(char *path);
extern PgDirState is_pg_running(const char *path); extern PgDirState is_pg_running(char *path);
extern bool create_pg_dir(const char *path, bool force); extern bool create_pg_dir(char *path, bool force);
extern int rmdir_recursive(const char *path); extern int rmdir_recursive(char *path);
#endif #endif

8
doc/.gitignore vendored
View File

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

View File

@@ -1,101 +0,0 @@
# 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)\">"; \
} > $@
##
## 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
maintainer-clean:
rm -rf html
.PHONY: html

76
doc/Makefile.in Normal file
View File

@@ -0,0 +1,76 @@
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 -rf 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,10 +1,9 @@
<appendix id="appendix-faq" xreflabel="FAQ"> <appendix id="appendix-faq" xreflabel="FAQ">
<indexterm>
<primary>FAQ (Frequently Asked Questions)</primary>
</indexterm>
<title>FAQ (Frequently Asked Questions)</title> <title>FAQ (Frequently Asked Questions)</title>
<indexterm>
<primary>FAQ (Frequently Asked Questions)</primary>
</indexterm>
<sect1 id="faq-general" xreflabel="General"> <sect1 id="faq-general" xreflabel="General">
<title>General</title> <title>General</title>
@@ -20,7 +19,7 @@
<para> <para>
&repmgr; 3.x builds on the improved replication facilities added &repmgr; 3.x builds on the improved replication facilities added
in PostgreSQL 9.3, as well as improved automated failover support in PostgreSQL 9.3, as well as improved automated failover support
via &repmgrd;, and is not compatible with PostgreSQL 9.2 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 and earlier. We recommend upgrading to &repmgr; 4, as the &repmgr; 3.x
series is no longer maintained. series is no longer maintained.
</para> </para>
@@ -77,7 +76,7 @@
<para> <para>
Before PostgreSQL 10, hash indexes were not WAL logged and are therefore not suitable 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 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> <ulink url="https://www.postgresql.org/docs/9.6/static/sql-createindex.html#AEN80279">PostgreSQL documentation</ulink>
for details. for details.
</para> </para>
<para> <para>
@@ -97,11 +96,12 @@
<para> <para>
For <emphasis>major</emphasis> version upgrades (e.g. from PostgreSQL 9.6 to PostgreSQL 10), 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 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> node with <ulink url="https://www.postgresql.org/docs/current/static/pgupgrade.html">pg_upgrade</ulink>
and recloning standbys from this. and recloning standbys from this.
</para> </para>
<para> <para>
To minimize downtime during major upgrades from PostgreSQL 9.4 and later, To minimize downtime during major upgrades, for more recent PostgreSQL
versions (PostgreSQL 9.4 and later),
<ulink url="https://www.2ndquadrant.com/en/resources/pglogical/">pglogical</ulink> <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, 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 which can be kept in sync with the existing production cluster until the
@@ -126,7 +126,7 @@
<sect2 id="faq-old-packages"> <sect2 id="faq-old-packages">
<title>How can I obtain old versions of &repmgr; packages?</title> <title>How can I obtain old versions of &repmgr; packages?</title>
<para> <para>
See appendix <xref linkend="packages-old-versions"/> for details. See appendix <xref linkend="packages-old-versions"> for details.
</para> </para>
</sect2> </sect2>
@@ -136,7 +136,7 @@
No. No.
</para> </para>
<para> <para>
&repmgr; (together with &repmgrd;) assists with &repmgr; (together with <application>repmgrd</application>) assists with
<emphasis>managing</emphasis> replication. It does not actually perform replication, which <emphasis>managing</emphasis> replication. It does not actually perform replication, which
is part of the core PostgreSQL functionality. is part of the core PostgreSQL functionality.
</para> </para>
@@ -153,8 +153,8 @@
<title>Does it matter if different &repmgr; versions are present in the replication cluster?</title> <title>Does it matter if different &repmgr; versions are present in the replication cluster?</title>
<para> <para>
Yes. If different &quot;major&quot; &repmgr; versions (e.g. 3.3.x and 4.1.x) are present, Yes. If different &quot;major&quot; &repmgr; versions (e.g. 3.3.x and 4.1.x) are present,
&repmgr; (in particular &repmgrd;) &repmgr; (in particular <application>repmgrd</application>)
may not run, or run properly, or in the worst case (if different &repmgrd; 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 versions are running and there are differences in the failover implementation) break
your replication cluster. your replication cluster.
</para> </para>
@@ -252,8 +252,8 @@
</para> </para>
<para> <para>
&repmgr; provides the command <command>repmgr node rejoin</command> which can &repmgr; provides the command <command>repmgr node rejoin</command> which can
optionally execute <command>pg_rewind</command>; see the <xref linkend="repmgr-node-rejoin"/> 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"/>. documentation for details, in particular the section <xref linkend="repmgr-node-rejoin-pg-rewind">.
</para> </para>
<para> <para>
If <command>pg_rewind</command> cannot be used, then the data directory will need If <command>pg_rewind</command> cannot be used, then the data directory will need
@@ -277,25 +277,25 @@
directory in <filename>/etc</filename>?</title> directory in <filename>/etc</filename>?</title>
<para> <para>
Use the command line option <literal>--copy-external-config-files</literal>. For more details Use the command line option <literal>--copy-external-config-files</literal>. For more details
see <xref linkend="repmgr-standby-clone-config-file-copying"/>. see <xref linkend="repmgr-standby-clone-config-file-copying">.
</para> </para>
</sect2> </sect2>
<sect2 id="faq-repmgr-shared-preload-libaries-no-repmgrd" xreflabel="shared_preload_libraries without repmgrd"> <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> <title>Do I need to include <literal>shared_preload_libraries = 'repmgr'</literal>
in <filename>postgresql.conf</filename> if I'm not using &repmgrd;?</title> in <filename>postgresql.conf</filename> if I'm not using <application>repmgrd</application>?</title>
<para> <para>
No, the <literal>repmgr</literal> shared library is only needed when running &repmgrd;. No, the <literal>repmgr</literal> shared library is only needed when running <application>repmgrd</application>.
If you later decide to run &repmgrd;, you just need to add If you later decide to run <application>repmgrd</application>, you just need to add
<literal>shared_preload_libraries = 'repmgr'</literal> and restart PostgreSQL. <literal>shared_preload_libraries = 'repmgr'</literal> and restart PostgreSQL.
</para> </para>
</sect2> </sect2>
<sect2 id="faq-repmgr-permissions" xreflabel="Replication permission problems"> <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> <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> but <command>repmgr</command>/<application>repmgrd</application> complains it can't connect to the server... Why?</title>
<para> <para>
<command>repmgr</command> and &repmgrd; need to be able to connect to the repmgr database <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 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). permission is for PostgreSQL's streaming replication (and doesn't necessarily need to be the <literal>repmgr</literal> user).
</para> </para>
@@ -318,7 +318,7 @@
<para> <para>
Provide the option <literal>--waldir</literal> (<literal>--xlogdir</literal> in PostgreSQL 9.6 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>. 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"/>. For more details see <xref linkend="cloning-advanced-pg-basebackup-options">.
</para> </para>
</sect2> </sect2>
@@ -350,7 +350,7 @@
</sect1> </sect1>
<sect1 id="faq-repmgrd" xreflabel="repmgrd"> <sect1 id="faq-repmgrd" xreflabel="repmgrd">
<title>&repmgrd;</title> <title><application>repmgrd</application></title>
<sect2 id="faq-repmgrd-prevent-promotion" xreflabel="Prevent standby from being promoted to primary"> <sect2 id="faq-repmgrd-prevent-promotion" xreflabel="Prevent standby from being promoted to primary">
@@ -366,12 +366,12 @@
</sect2> </sect2>
<sect2 id="faq-repmgrd-delayed-standby" xreflabel="Delayed standby support"> <sect2 id="faq-repmgrd-delayed-standby" xreflabel="Delayed standby support">
<title>Does &repmgrd; support delayed standbys?</title> <title>Does <application>repmgrd</application> support delayed standbys?</title>
<para> <para>
&repmgrd; can monitor delayed standbys - those set up with <application>repmgrd</application> can monitor delayed standbys - those set up with
<varname>recovery_min_apply_delay</varname> set to a non-zero value <varname>recovery_min_apply_delay</varname> set to a non-zero value
in <filename>recovery.conf</filename> - but as it's not currently possible in <filename>recovery.conf</filename> - but as it's not currently possible
to directly examine the value applied to the standby, &repmgrd; 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. may not be able to properly evaluate the node as a promotion candidate.
</para> </para>
<para> <para>
@@ -380,25 +380,25 @@
<filename>repmgr.conf</filename>. <filename>repmgr.conf</filename>.
</para> </para>
<para> <para>
Note that after registering a delayed standby, &repmgrd; will only start Note that after registering a delayed standby, <application>repmgrd</application> will only start
once the metadata added in the primary node has been replicated. once the metadata added in the primary node has been replicated.
</para> </para>
</sect2> </sect2>
<sect2 id="faq-repmgrd-logfile-rotate" xreflabel="repmgrd logfile rotation"> <sect2 id="faq-repmgrd-logfile-rotate" xreflabel="repmgrd logfile rotation">
<title>How can I get &repmgrd; to rotate its logfile?</title> <title>How can I get <application>repmgrd</application> to rotate its logfile?</title>
<para> <para>
Configure your system's <literal>logrotate</literal> service to do this; see <xref linkend="repmgrd-log-rotation"/>. Configure your system's <literal>logrotate</literal> service to do this; see <xref linkend="repmgrd-log-rotation">.
</para> </para>
</sect2> </sect2>
<sect2 id="faq-repmgrd-recloned-no-start" xreflabel="repmgrd not restarting after node cloned"> <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> <title>I've recloned a failed primary as a standby, but <application>repmgrd</application> refuses to start?</title>
<para> <para>
Check you registered the standby after recloning. If unregistered, the standby 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 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 <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 <varname>failover</varname> is set to <literal>manual</literal> so the node's replication status can still
be monitored, if desired. be monitored, if desired.
</para> </para>
@@ -406,24 +406,24 @@
<sect2 id="faq-repmgrd-pg-bindir" xreflabel="repmgrd does not apply pg_bindir to promote_command or follow_command"> <sect2 id="faq-repmgrd-pg-bindir" xreflabel="repmgrd does not apply pg_bindir to promote_command or follow_command">
<title> <title>
&repmgrd; ignores pg_bindir when executing <varname>promote_command</varname> or <varname>follow_command</varname> <application>repmgrd</application> ignores pg_bindir when executing <varname>promote_command</varname> or <varname>follow_command</varname>
</title> </title>
<para> <para>
<varname>promote_command</varname> or <varname>follow_command</varname> can be user-defined scripts, <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 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. path; see <xref linkend="repmgrd-automatic-failover-configuration"> for more details.
</para> </para>
</sect2> </sect2>
<sect2 id="faq-repmgrd-startup-no-upstream" xreflabel="repmgrd does not start if upstream node is not running"> <sect2 id="faq-repmgrd-startup-no-upstream" xreflabel="repmgrd does not start if upstream node is not running">
<title> <title>
&repmgrd; aborts startup with the error "<literal>upstream node must be running before repmgrd can start</literal>" <application>repmgrd</application> aborts startup with the error "<literal>upstream node must be running before repmgrd can start</literal>"
</title> </title>
<para> <para>
&repmgrd; does this to avoid starting up on a replication cluster <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, &repmgrd; 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, may initiate a failover immediately after starting up, which could have unintended side-effects,
particularly if &repmgrd; is not running on other nodes. particularly if <application>repmgrd</application> is not running on other nodes.
</para> </para>
<para> <para>
In particular, it's possible that the node's local copy of the <literal>repmgr.nodes</literal> copy In particular, it's possible that the node's local copy of the <literal>repmgr.nodes</literal> copy
@@ -431,7 +431,7 @@
</para> </para>
<para> <para>
The onus is therefore on the adminstrator to manually set the cluster to a stable, healthy state before The onus is therefore on the adminstrator to manually set the cluster to a stable, healthy state before
starting &repmgrd;. starting <application>repmgrd</application>.
</para> </para>
</sect2> </sect2>

View File

@@ -1,11 +1,9 @@
<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
@@ -295,7 +293,7 @@
</row> </row>
<row> <row>
<entry>Repository documentation:</entry> <entry>Repository documentation:</entry>
<entry><ulink url="https://wiki.postgresql.org/wiki/Apt">https://wiki.postgresql.org/wiki/Apt</ulink></entry> <entry><ulink url="https://wiki.postgresql.org/wiki/Apt)">https://wiki.postgresql.org/wiki/Apt)</ulink></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@@ -311,8 +309,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 &repmgrd; daemon. to configuring the <application>repmgrd</application> daemon.
</para> </para>
<table id="debian-9-packages"> <table id="debian-9-packages">
@@ -458,21 +456,14 @@ repmgr96-4.1.1-0.0git320.g5113ab0.1.el7.x86_64.rpm</programlisting>
<sect1 id="packages-old-versions" xreflabel="Installing old package versions"> <sect1 id="packages-old-versions" xreflabel="Installing old package versions">
<title>Installing old package versions</title> <title>Installing old package versions</title>
<indexterm> <indexterm>
<primary>old packages</primary> <primary>old packages</primary>
</indexterm> </indexterm>
<indexterm> <indexterm>
<primary>packages</primary> <primary>packages</primary>
<secondary>old versions</secondary> <secondary>old versions</secondary>
</indexterm> </indexterm>
<indexterm>
<primary>installation</primary>
<secondary>old package versions</secondary>
</indexterm>
<sect2 id="packages-old-versions-debian" xreflabel="old Debian package versions"> <sect2 id="packages-old-versions-debian" xreflabel="old Debian package versions">
<title>Debian/Ubuntu</title> <title>Debian/Ubuntu</title>
<para> <para>
@@ -483,12 +474,34 @@ repmgr96-4.1.1-0.0git320.g5113ab0.1.el7.x86_64.rpm</programlisting>
<sect2 id="packages-old-versions-rhel-centos" xreflabel="old RHEL/CentOS package versions"> <sect2 id="packages-old-versions-rhel-centos" xreflabel="old RHEL/CentOS package versions">
<title>RHEL/CentOS</title> <title>RHEL/CentOS</title>
<para>
Old RPM packages (<literal>3.2</literal> and later) can be retrieved from the
(deprecated) 2ndQuadrant repository at
<ulink url="http://packages.2ndquadrant.com/">http://packages.2ndquadrant.com/</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>
<para> <para>
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>)
@@ -500,32 +513,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>
@@ -552,13 +539,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 &repmgrd; PID file PID file location: the default <application>repmgrd</application> 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>
@@ -566,7 +553,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>

View File

@@ -12,557 +12,9 @@
</para> </para>
<para> <para>
See also: <xref linkend="upgrading-repmgr"/> See also: <xref linkend="upgrading-repmgr">
</para> </para>
<sect1 id="release-4.4">
<title>Release 4.4</title>
<para><emphasis>?? June, 2019</emphasis></para>
<sect2>
<title>repmgr client enhancements</title>
<para>
<itemizedlist>
<listitem>
<para>
<link linkend="repmgr-standby-clone"><command>repmgr standby clone</command></link>:
prevent a standby from being cloned from a witness server (PostgreSQL 9.6 and later only).
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-witness-register"><command>repmgr witness register</command></link>:
prevent a witness server from being registered on the replication cluster primary server
(PostgreSQL 9.6 and later only).
</para>
<para>
Registering a witness on the primary node would defeat the purpose of having a witness server,
which is intended to remain running even if the cluster's primary goes down.
</para>
</listitem>
<listitem>
<para>
&repmgr;: when executing <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>,
if <option>--siblings-follow</option> 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.
</para>
</listitem>
<listitem>
<para>
&repmgr;: when executing <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>,
ignore nodes which are unreachable and marked as inactive.
Previously it would abort if any node was unreachable,
as that means it was unable to check if repmgrd is running.
</para>
<para>
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.
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>
and <link linkend="repmgr-standby-promote"><command>repmgr standby promote</command></link>:
when executing with the <option>--dry-run</option> option, continue checks as far as possible
even if errors are encountered.
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-standby-promote"><command>repmgr standby promote</command></link>:
add <option>--siblings-follow</option> (similar to
<link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>).
</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 <link linkend="repmgr-standby-promote"><command>repmgr standby promote</command></link>.
</para>
</note>
</listitem>
<listitem>
<para>
<link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>:
add <option>--repmgrd-force-unpause</option> to 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>
</listitem>
<listitem>
<para>
<link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>:
make output similar to that of
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>
for consistency and to make it easier to identify nodes not in the expected
state.
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>:
display each node's timeline ID (PostgreSQL 9.6 and later only).
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>
and <link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>:
show the upstream node name as reported by each individual node - this helps visualise
situations where the cluster is in an unexpected state, and provide a better idea of the
actual cluster state.
</para>
<para>
For example, if a cluster has divided somehow and a set of nodes are
following a new primary, when running either of these commands, &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 &quot;split&quot;. A warning will also be issued
about the unexpected situation.
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>
and <link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>:
check if a node is attached to its advertised upstream node, and issue a
warning if the node is not attached.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2>
<title>repmgrd enhancements</title>
<para>
<itemizedlist>
<listitem>
<para>
On the primary node, &repmgrd; is now able to monitor standby connections and,
if the number of nodes connected falls below a certain (configurable) value,
execute a custom script.
</para>
<para>
This provided an additional method for fencing an isolated primary node, and/or taking
other action if one or more standys become disconnected.
</para>
<para>
See section <link linkend="repmgrd-primary-child-disconnection">Monitoring standby disconnections on the primary node</link>
for more details.
</para>
</listitem>
<listitem>
<para>
In a failover situation, &repmgrd; nodes on the standbys of the failed primary
are now able confirm among themselves that none can still see the primary
before continuing with the failover.
</para>
<para>
The <filename>repmgr.conf</filename> option <option>primary_visibility_consensus</option> must
be set to <literal>true</literal> to enable this functionality.
</para>
<para>
See section <xref linkend="repmgrd-primary-visibility-consensus"/>
for more details.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2>
<title>Bug fixes</title>
<para>
<itemizedlist>
<listitem>
<para>
Ensure BDR2-specific functionality cannot be used on BDR3 and later.
</para>
<para>
The BDR support present in &repmgr; is for specific BDR2 use cases.
</para>
</listitem>
<listitem>
<para>
&repmgr;: when executing <link linkend="repmgr-standby-clone"><command>repmgr standby clone</command></link>
in <option>--dry-run</option> mode, ensure provision of the <option>--force</option> option
does not result in an existing data directory being modified in any way.
</para>
</listitem>
<listitem>
<para>
&repmgr;: when executing <link linkend="repmgr-primary-register"><command>repmgr primary register</command></link>
with the <option>--force</option> option, if another primary record exists but the associated node is
unreachable (or running as a standby), set that node's record to inactive to enable the current node
to be registered as a primary.
</para>
</listitem>
<listitem>
<para>
&repmgr;: when executing <link linkend="repmgr-standby-clone"><command>repmgr standby clone</command></link>
with the <option>--upstream-conninfo</option>, ensure that <varname>application_name</varname>
is set correctly in <varname>primary_conninfo</varname>.
</para>
</listitem>
<listitem>
<para>
&repmgr;: when executing <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>,
don't abort if one or more nodes are not reachable <emphasis>and</emphasis>
they are marked as inactive.
</para>
</listitem>
<listitem>
<para>
&repmgr;: canonicalize the data directory path when parsing the configuration file, so
the provided path matches the path PostgreSQL reports as its data directory.
Otherwise, if e.g. the data directory is configured with a trailing slash,
<link linkend="repmgr-node-check"><command>repmgr node check --data-directory-config</command></link>
will return a spurious error.
</para>
</listitem>
<listitem>
<para>
&repmgrd;: fix memory leak which occurs while the monitored PostgreSQL node is <emphasis>not</emphasis>
running.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2>
<title>Other</title>
<para>
<itemizedlist>
<listitem>
<para>
The &repmgr; documentation has been converted to DocBook XML format,
as currently used by the main PostgreSQL project.
This means it can now be built against any PostgreSQL version from 9.5
(previously it was not possible to build the documentation against
PostgreSQL 10 or later), and makes it easier to provide the documentation
in other formats such as PDF.
</para>
<para>
For further details see: <xref linkend="installation-build-repmgr-docs"/>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
<sect1 id="release-4.3">
<title>Release 4.3</title>
<para><emphasis>Tue April 2, 2019</emphasis></para>
<para>
&repmgr; 4.3 is a major release.
</para>
<para>
For details on how to upgrade an existing &repmgr; instrallation, see
documentation section <link linkend="upgrading-major-version">Upgrading a major version release</link>.
</para>
<para>
If &repmgrd; is in use, a PostgreSQL restart <emphasis>is</emphasis> required;
in that case we suggest combining this &repmgr; upgrade with the next PostgreSQL
minor release, which will require a PostgreSQL restart in any case.
</para>
<important>
<para>
On Debian-based systems, including Ubuntu, if using &repmgrd;
please ensure that in the file <filename>/etc/init.d/repmgrd</filename>, the parameter
<varname>REPMGRD_OPTS</varname> contains &quot;<literal>--daemonize=false</literal>&quot;, e.g.:
<programlisting>
# additional options
REPMGRD_OPTS="--daemonize=false"</programlisting>
</para>
<para>
For further details, see <link linkend="repmgrd-configuration-debian-ubuntu">repmgrd configuration on Debian/Ubuntu</link>.
</para>
</important>
<sect2>
<title>repmgr client enhancements</title>
<para>
<itemizedlist>
<listitem>
<para>
<link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>:
option <option>--upstream-node-id</option> can now be used to specify another standby
to follow.
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>:
verify that it is actually possible to follow another node.
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-node-rejoin"><command>repmgr node rejoin</command></link>:
verify that it is actually possible to attach the node to the current primary.
</para>
</listitem>
<listitem>
<para>
New commands <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> and
<link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link>:
these provide a standardized way of starting and stopping &repmgrd;.
GitHub #528.
</para>
<note>
<para>
These commands require the configuration file settings
<varname>repmgrd_service_start_command</varname> and <varname>repmgrd_service_stop_command</varname>
in <filename>repmgr.conf</filename> to be set.
</para>
</note>
</listitem>
<listitem>
<para>
<link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>
additionally displays the node priority and the interval (in seconds) since the
&repmgrd; instance last verified its upstream node was available.
</para>
</listitem>
<listitem>
<para>
Add <option>--compact</option> option to <command><link linkend="repmgr-cluster-show">repmgr cluster show</link></command> (GitHub #521).
</para>
<para>
This makes it easier to copy the output into emails, chats etc. as a compact table.
</para>
</listitem>
<listitem>
<para>
<command><link linkend="repmgr-cluster-show">repmgr cluster show</link></command>:
differentiate between unreachable nodes and nodes which are running but rejecting connections.
</para>
<para>
This makes it possible to see whether a node is unreachable at network level,
or if it is running but rejecting connections for some reason.
</para>
</listitem>
<listitem>
<para>
Add <option>--dry-run</option> to <command><link linkend="repmgr-standby-promote">repmgr standby promote</link></command> (GitHub #522).
</para>
</listitem>
<listitem>
<para>
<command>repmgr --version-number</command> outputs the &quot;raw&quot;
repmgr version number (e.g. <literal>40300</literal>). This is intended
for use by scripts etc. requiring an easily parseable representation
of the &repmgr; version.
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-node-check"><command>repmgr node check --data-directory-config</command></link>
option added; this is to confirm &repmgr; is correctly configured. GitHub #523.
</para>
</listitem>
<listitem>
<para>
Add check to <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>
to ensure the data directory on the demotion candidate is configured correctly in <filename>repmgr.conf</filename>.
This is to ensure that &repmgr;, when remotely executed on the demotion candidate, can correctly verify
that PostgreSQL on the demotion candidate was shut down cleanly. GitHub #523.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2>
<title>repmgrd enhancements</title>
<para>
<itemizedlist>
<listitem>
<para>
&repmgrd; will no longer consider nodes where &repmgrd;
is not running as promotion candidates.
</para>
<para>
Previously, if &repmgrd; was not running on a node, but
that node qualified as the promotion candidate, it would never be promoted due to
the absence of a running &repmgrd;.
</para>
</listitem>
<listitem>
<para>
Add option <option>connection_check_type</option> to enable selection of the method
&repmgrd; uses to determine whether the upstream node is available.
</para>
<para>
Possible values are <literal>ping</literal> (default; uses <command>PQping()</command> to
determine server availability), <literal>connection</literal> (attempst to make a new connection to
the upstream node), and <literal>query</literal> (determines server availability
by executing an SQL statement on the node via the existing connection).
</para>
</listitem>
<listitem>
<para>
New configuration option <link linkend="repmgrd-failover-validation"><option>failover_validation_command</option></link>
to allow an external mechanism to validate the failover decision made by &repmgrd;.
</para>
</listitem>
<listitem>
<para>
New configuration option <link linkend="repmgrd-standby-disconnection-on-failover"><option>standby_disconnect_on_failover</option></link>
to force standbys to disconnect their WAL receivers before making a failover decision.
</para>
</listitem>
<listitem>
<para>
In a failover situation, &repmgrd; will not attempt to promote a
node if another primary has already appeared (e.g. by being promoted manually).
GitHub #420.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2>
<title>Bug fixes</title>
<para>
<itemizedlist>
<listitem>
<para>
<command><link linkend="repmgr-cluster-show">repmgr cluster show</link></command>:
fix display of node IDs with multiple digits.
</para>
</listitem>
<listitem>
<para>
ensure <command><link linkend="repmgr-primary-unregister">repmgr primary unregister</link></command>
behaves correctly when executed on a witness server. GitHub #548.
</para>
</listitem>
<listitem>
<para>
ensure <command><link linkend="repmgr-standby-register">repmgr standby register</link></command>
fails when <option>--upstream-node-id</option> is the same as the local node ID.
</para>
</listitem>
<listitem>
<para>
&repmgr;: when executing <link linkend="repmgr-standby-clone"><command>repmgr standby clone</command></link>,
recheck primary/upstream connection(s) after the data copy operation is complete, as these may
have gone away.
</para>
</listitem>
<listitem>
<para>
&repmgr;: when executing <command><link linkend="repmgr-standby-switchover">repmgr standby switchover</link></command>,
prevent escaping issues with connection URIs when executing <command><link linkend="repmgr-node-rejoin">repmgr node rejoin</link></command>
on the demotion candidate. GitHub #525.
</para>
</listitem>
<listitem>
<para>
&repmgr;: when executing <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>,
verify the standby (promotion candidate) is currently attached to the primary (demotion candidate). GitHub #519.
</para>
</listitem>
<listitem>
<para>
&repmgr;: when executing <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>,
avoid a potential race condition when comparing received WAL on the standby to the primary's shutdown location,
as the standby's walreceiver may not have yet flushed all received WAL to disk. GitHub #518.
</para>
</listitem>
<listitem>
<para>
&repmgr;: when executing <command><link linkend="repmgr-witness-register">repmgr witness register</link></command>,
check the node to connected is actually the primary (i.e. not the witness server). GitHub #528.
</para>
</listitem>
<listitem>
<para>
<command><link linkend="repmgr-node-check">repmgr node check</link></command>
will only consider physical replication slots, as the purpose
of slot checks is to warn about potential issues with
streaming replication standbys which are no longer attached.
</para>
</listitem>
<listitem>
<para>
&repmgrd;: on a cascaded standby, don't fail over if
<literal>failover=manual</literal>. GitHub #531.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
<sect1 id="release-4.2"> <sect1 id="release-4.2">
<title>Release 4.2</title> <title>Release 4.2</title>
<para><emphasis>Wed October 24, 2018</emphasis></para> <para><emphasis>Wed October 24, 2018</emphasis></para>
@@ -579,20 +31,6 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<link linkend="upgrading-major-version">Upgrading a major version release</link>. <link linkend="upgrading-major-version">Upgrading a major version release</link>.
</para> </para>
<important>
<para>
On Debian-based systems, including Ubuntu, if using &repmgrd;
please ensure that the in the file <filename>/etc/init.d/repmgrd</filename>, the parameter
<varname>REPMGRD_OPTS</varname> contains &quot;<literal>--daemonize=false</literal>&quot;, e.g.:
<programlisting>
# additional options
REPMGRD_OPTS="--daemonize=false"</programlisting>
</para>
<para>
For further details, see <link linkend="repmgrd-configuration-debian-ubuntu">repmgrd daemon configuration on Debian/Ubuntu</link>.
</para>
</important>
<sect2> <sect2>
<title>Configuration file changes</title> <title>Configuration file changes</title>
<para> <para>
@@ -676,12 +114,12 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
&repmgrd; can now be &quot;paused&quot;, i.e. instructed <application>repmgrd</application> can now be &quot;paused&quot;, i.e. instructed
not to take any action such as a failover, even if the prerequisites for such an not to take any action such as a failover, even if the prerequisites for such an
action are detected. action are detected.
</para> </para>
<para> <para>
This removes the need to stop &repmgrd; on all nodes when This removes the need to stop <application>repmgrd</application> on all nodes when
performing a planned operation such as a switchover. performing a planned operation such as a switchover.
</para> </para>
<para> <para>
@@ -705,9 +143,10 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
&repmgrd;: fix parsing of <option>-d/--daemonize</option> option. <application>repmgrd</application>: fix parsing of <option>-d/--daemonize</option> option.
</para> </para>
</listitem> </listitem>
@@ -725,8 +164,8 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<para> <para>
We recommend upgrading to this version as soon as possible. We recommend upgrading to this version as soon as possible.
This release can be installed as a simple package upgrade from repmgr 4.0 ~ 4.1.0; This release can be installed as a simple package upgrade from repmgr 4.0 ~ 4.1.0;
&repmgrd; (if running) should be restarted. <application>repmgrd</application> (if running) should be restarted.
See <xref linkend="upgrading-repmgr"/> for more details. See <xref linkend="upgrading-repmgr"> for more details.
</para> </para>
<sect2> <sect2>
@@ -807,8 +246,8 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<para> <para>
Check <varname>promote_command</varname> and <varname>follow_command</varname> Check <varname>promote_command</varname> and <varname>follow_command</varname>
are defined when reloading configuration. These were checked on startup but are defined when reloading configuration. These were checked on startup but
not reload by &repmgrd;, which made it possible to not reload by <application>repmgrd</application>, which made it possible to
make &repmgrd; with invalid values. It's unlikely make <application>repmgrd</application> with invalid values. It's unlikely
anyone would want to do this, but we should make it impossible anyway. anyone would want to do this, but we should make it impossible anyway.
(GitHub #486). (GitHub #486).
</para> </para>
@@ -849,7 +288,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
&repmgrd;: fix startup on witness node when local data is stale. (GitHub #488, #489). <application>repmgrd</application>: fix startup on witness node when local data is stale. (GitHub #488, #489).
</para> </para>
</listitem> </listitem>
@@ -875,7 +314,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<title>Release 4.1.0</title> <title>Release 4.1.0</title>
<para><emphasis>Tue July 31, 2018</emphasis></para> <para><emphasis>Tue July 31, 2018</emphasis></para>
<para> <para>
&repmgr; 4.1.0 introduces some changes to &repmgrd; &repmgr; 4.1.0 introduces some changes to <application>repmgrd</application>
behaviour and some additional configuration parameters. behaviour and some additional configuration parameters.
</para> </para>
<para> <para>
@@ -891,7 +330,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
&repmgrd; must be restarted on all nodes where it is running. <application>repmgrd</application> must be restarted on all nodes where it is running.
</para> </para>
</listitem> </listitem>
@@ -901,7 +340,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
for this release (unless upgrading from repmgr 3.x). for this release (unless upgrading from repmgr 3.x).
</para> </para>
<para> <para>
See <xref linkend="upgrading-repmgr-extension"/> for more details. See <xref linkend="upgrading-repmgr-extension"> for more details.
</para> </para>
<para> <para>
@@ -916,7 +355,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
</para> </para>
<para> <para>
Coinciding with this release, the 2ndQuadrant repository structure has changed. Coinciding with this release, the 2ndQuadrant repository structure has changed.
See section <xref linkend="installation-packages"/> for details, particularly See section <xref linkend="installation-packages"> for details, particularly
if you are using a RPM-based system. if you are using a RPM-based system.
</para> </para>
</note> </note>
@@ -929,7 +368,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
Default for <xref linkend="repmgr-conf-log-level"/> is now <option>INFO</option>. Default for <xref linkend="repmgr-conf-log-level"> is now <option>INFO</option>.
This produces additional informative log output, without creating excessive additional This produces additional informative log output, without creating excessive additional
log file volume, and matches the setting assumed for examples in the documentation. log file volume, and matches the setting assumed for examples in the documentation.
(GitHub #470). (GitHub #470).
@@ -1013,14 +452,14 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
&repmgrd;: create a PID file by default <application>repmgrd</application>: create a PID file by default
(GitHub #457). For details, see <xref linkend="repmgrd-pid-file"/>. (GitHub #457). For details, see <xref linkend="repmgrd-pid-file">.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
&repmgrd;: daemonize process by default. <application>repmgrd</application>: daemonize process by default.
In case, for whatever reason, the user does not wish to daemonize the In case, for whatever reason, the user does not wish to daemonize the
process, provide <option>--daemonize=false</option>. process, provide <option>--daemonize=false</option>.
(GitHub #458). (GitHub #458).
@@ -1089,7 +528,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<para> <para>
We recommend upgrading to this version as soon as possible. We recommend upgrading to this version as soon as possible.
This release can be installed as a simple package upgrade from repmgr 4.0 ~ 4.0.5; This release can be installed as a simple package upgrade from repmgr 4.0 ~ 4.0.5;
&repmgrd; (if running) should be restarted. See <xref linkend="upgrading-repmgr"/> <application>repmgrd</application> (if running) should be restarted. See <xref linkend="upgrading-repmgr">
for more details. for more details.
</para> </para>
@@ -1176,7 +615,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
&repmgrd;: ensure local node is counted as quorum member <application>repmgrd</application>: ensure local node is counted as quorum member
(GitHub #439) (GitHub #439)
</para> </para>
</listitem> </listitem>
@@ -1193,7 +632,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<para> <para>
&repmgr; 4.0.5 contains a number of usability enhancements related to &repmgr; 4.0.5 contains a number of usability enhancements related to
<application>pg_rewind</application> usage, <filename>recovery.conf</filename> <application>pg_rewind</application> usage, <filename>recovery.conf</filename>
generation and (in &repmgrd;) handling of various generation and (in <application>repmgrd</application>) handling of various
corner-case situations, as well as a number of bug fixes. corner-case situations, as well as a number of bug fixes.
</para> </para>
@@ -1225,7 +664,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
Add sanity check if <option>--upstream-node-id</option> not supplied when executing Add sanity check if <option>--upstream-node-id</option> not supplied when executing
<xref linkend="repmgr-standby-register"/> (GitHub #395). <xref linkend="repmgr-standby-register"> (GitHub #395).
</para> </para>
</listitem> </listitem>
@@ -1258,7 +697,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
&repmgrd;: set <literal>connect_timeout=2</literal> (if not explicitly set) <application>repmgrd</application>: set <literal>connect_timeout=2</literal> (if not explicitly set)
when pinging a server. when pinging a server.
</para> </para>
</listitem> </listitem>
@@ -1314,20 +753,20 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
&repmgrd;: handle <command>pg_ctl promote</command> timeout (GitHub #425). <application>repmgrd</application>: handle <command>pg_ctl promote</command> timeout (GitHub #425).
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
&repmgrd;: handle failover situation with only two nodes in the primary <application>repmgrd</application>: handle failover situation with only two nodes in the primary
location, and at least one node in another location (GitHub #407). location, and at least one node in another location (GitHub #407).
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
&repmgrd;: prevent standby connection handle from going stale. <application>repmgrd</application>: prevent standby connection handle from going stale.
</para> </para>
</listitem> </listitem>
@@ -1351,7 +790,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
</para> </para>
<para> <para>
This release can be installed as a simple package upgrade from repmgr 4.0 ~ 4.0.3; This release can be installed as a simple package upgrade from repmgr 4.0 ~ 4.0.3;
&repmgrd; (if running) should be restarted. See <xref linkend="upgrading-repmgr"/> <application>repmgrd</application> (if running) should be restarted. See <xref linkend="upgrading-repmgr">
for more details. for more details.
</para> </para>
@@ -1430,14 +869,14 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
&repmgrd;: improve detection of status change from primary to <application>repmgrd</application>: improve detection of status change from primary to
standby standby
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
&repmgrd;: improve reconnection to the local node after a <application>repmgrd</application>: improve reconnection to the local node after a
failover (previously a connection error due to the node starting up was being failover (previously a connection error due to the node starting up was being
interpreted as the node being unavailable) interpreted as the node being unavailable)
</para> </para>
@@ -1445,14 +884,14 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
&repmgrd;: when running on a witness server, correctly connect <application>repmgrd</application>: when running on a witness server, correctly connect
to new primary after a failover to new primary after a failover
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
&repmgrd;: add <link linkend="event-notifications">event notification</link> <application>repmgrd</application>: add <link linkend="event-notifications">event notification</link>
<literal>repmgrd_shutdown</literal> (GitHub #393) <literal>repmgrd_shutdown</literal> (GitHub #393)
</para> </para>
</listitem> </listitem>
@@ -1621,7 +1060,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
</para> </para>
<para> <para>
This release can be installed as a simple package upgrade from &repmgr; 4.0.1 or 4.0; This release can be installed as a simple package upgrade from &repmgr; 4.0.1 or 4.0;
&repmgrd; (if running) should be restarted. <application>repmgrd</application> (if running) should be restarted.
</para> </para>
<sect2> <sect2>
@@ -1738,14 +1177,14 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
Fix <xref linkend="repmgr-cluster-show"/> when <literal>repmgr</literal> schema not set in search path Fix <xref linkend="repmgr-cluster-show"> when <literal>repmgr</literal> schema not set in search path
(GitHub #341) (GitHub #341)
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
When using <literal>--force-rewind</literal> with <xref linkend="repmgr-node-rejoin"/> When using <literal>--force-rewind</literal> with <xref linkend="repmgr-node-rejoin">
delete any replication slots copied by <application>pg_rewind</application> delete any replication slots copied by <application>pg_rewind</application>
(GitHub #334) (GitHub #334)
</para> </para>
@@ -1801,7 +1240,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
</note> </note>
<para> <para>
For detailed instructions on upgrading from repmgr 3.x, see <xref linkend="upgrading-from-repmgr-3"/>. For detailed instructions on upgrading from repmgr 3.x, see <xref linkend="upgrading-from-repmgr-3">.
</para> </para>
<sect2> <sect2>
@@ -1815,7 +1254,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
the <command>switchover</command> process has been improved and streamlined, the <command>switchover</command> process has been improved and streamlined,
speeding up the switchover process and can also instruct other standbys speeding up the switchover process and can also instruct other standbys
to follow the new primary once the switchover has completed. See to follow the new primary once the switchover has completed. See
<xref linkend="performing-switchover"/> for more details. <xref linkend="performing-switchover"> for more details.
</para> </para>
</listitem> </listitem>
@@ -1833,7 +1272,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<emphasis>easier upgrades</emphasis>: &repmgr; is now implemented as a native <emphasis>easier upgrades</emphasis>: &repmgr; is now implemented as a native
PostgreSQL extension, which means future upgrades can be carried out by PostgreSQL extension, which means future upgrades can be carried out by
installing the upgraded package and issuing installing the upgraded package and issuing
<ulink url="https://www.postgresql.org/docs/current/sql-alterextension.html">ALTER EXTENSION repmgr UPDATE</ulink>. <ulink url="https://www.postgresql.org/docs/current/static/sql-alterextension.html">ALTER EXTENSION repmgr UPDATE</ulink>.
</para> </para>
</listitem> </listitem>
@@ -1841,10 +1280,10 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
<emphasis>improved logging output</emphasis>: <emphasis>improved logging output</emphasis>:
&repmgr; (and &repmgrd;) now provide more explicit &repmgr; (and <application>repmgrd</application>) now provide more explicit
logging output giving a better picture of what is going on. Where appropriate, logging output giving a better picture of what is going on. Where appropriate,
<literal>DETAIL</literal> and <literal>HINT</literal> log lines provide additional <literal>DETAIL</literal> and <literal>HINT</literal> log lines provide additional
detail and suggestions for resolving problems. Additionally, &repmgrd; detail and suggestions for resolving problems. Additionally, <application>repmgrd</application>
now emits informational log lines at regular, configurable intervals now emits informational log lines at regular, configurable intervals
to confirm that it's running correctly and which node(s) it's monitoring. to confirm that it's running correctly and which node(s) it's monitoring.
</para> </para>
@@ -1866,8 +1305,8 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
<emphasis>monitoring and status checks</emphasis>: <emphasis>monitoring and status checks</emphasis>:
New commands <xref linkend="repmgr-node-check"/> and New commands <xref linkend="repmgr-node-check"> and
<xref linkend="repmgr-node-status"/> providing information <xref linkend="repmgr-node-status"> providing information
about a node's status and replication-related monitoring about a node's status and replication-related monitoring
output. output.
</para> </para>
@@ -1877,7 +1316,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<para> <para>
<emphasis>node rejoin</emphasis>: <emphasis>node rejoin</emphasis>:
New commands <xref linkend="repmgr-node-rejoin"/> enables a failed New commands <xref linkend="repmgr-node-rejoin"> enables a failed
primary to be rejoined to a replication cluster, optionally using primary to be rejoined to a replication cluster, optionally using
<application>pg_rewind</application> to synchronise its data, <application>pg_rewind</application> to synchronise its data,
(note that <application>pg_rewind</application> may not be useable (note that <application>pg_rewind</application> may not be useable
@@ -1891,11 +1330,11 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<emphasis>automatic failover</emphasis>: <emphasis>automatic failover</emphasis>:
improved detection of node status; promotion decision based on a consensual improved detection of node status; promotion decision based on a consensual
model, with the promoted primary explicitly informing other standbys to model, with the promoted primary explicitly informing other standbys to
follow it. The &repmgrd; daemon will continue follow it. The <application>repmgrd</application> daemon will continue
functioning even if the monitored PostgreSQL instance is down, and resume functioning even if the monitored PostgreSQL instance is down, and resume
monitoring if it reappears. Additionally, if the instance's role has changed monitoring if it reappears. Additionally, if the instance's role has changed
(typically from a primary to a standby, e.g. following reintegration of a (typically from a primary to a standby, e.g. following reintegration of a
failed primary using <xref linkend="repmgr-node-rejoin"/>) &repmgrd; failed primary using <xref linkend="repmgr-node-rejoin">) <application>repmgrd</application>
will automatically resume monitoring it as a standby. will automatically resume monitoring it as a standby.
</para> </para>
</listitem> </listitem>
@@ -1959,7 +1398,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
by the configuration file option <varname>replication_user</varname>. by the configuration file option <varname>replication_user</varname>.
The value (which defaults to the user provided in the <varname>conninfo</varname> The value (which defaults to the user provided in the <varname>conninfo</varname>
string) will be stored in the &repmgr; metadata for use by string) will be stored in the &repmgr; metadata for use by
<xref linkend="repmgr-standby-clone"/> and <xref linkend="repmgr-standby-follow"/>. <xref linkend="repmgr-standby-clone"> and <xref linkend="repmgr-standby-follow">.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
@@ -1974,14 +1413,14 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
to <varname>primary_conninfo</varname> by default; to force the inclusion to <varname>primary_conninfo</varname> by default; to force the inclusion
of a password (not recommended), use the new configuration file parameter of a password (not recommended), use the new configuration file parameter
<varname>use_primary_conninfo_password</varname>. For details, ee section <varname>use_primary_conninfo_password</varname>. For details, ee section
<xref linkend="cloning-advanced-managing-passwords"/>. <xref linkend="cloning-advanced-managing-passwords">.
</para></listitem> </para></listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para> <para>
&repmgrd; <application>repmgrd</application>
<itemizedlist> <itemizedlist>
<listitem><para> <listitem><para>
@@ -2103,7 +1542,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem> <listitem>
<simpara> <simpara>
new parameter <varname>log_status_interval</varname>, which causes new parameter <varname>log_status_interval</varname>, which causes
&repmgrd; to emit a status log <application>repmgrd</application> to emit a status log
line at the specified interval line at the specified interval
</simpara> </simpara>
</listitem> </listitem>

View File

@@ -1,99 +0,0 @@
<appendix id="appendix-support" xreflabel="repmgr support">
<title>&repmgr; support</title>
<indexterm>
<primary>support</primary>
</indexterm>
<para>
<ulink url="https://2ndquadrant.com/">2ndQuadrant</ulink> provides 24x7
production support for &repmgr; and other PostgreSQL
products, including configuration assistance, installation
verification and training for running a robust replication cluster.
</para>
<para>
For further details see: <ulink url="https://2ndquadrant.com/en/support/">https://2ndquadrant.com/en/support/</ulink>
</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>.
</para>
<para>
Please report bugs and other issues to: <ulink url="https://github.com/2ndQuadrant/repmgr">https://github.com/2ndQuadrant/repmgr</ulink>.
</para>
<important>
<para>
Please read the <link linkend="appendix-support-reporting-issues">following section</link> before submitting questions or issue reports.
</para>
</important>
<sect1 id="appendix-support-reporting-issues" xreflabel="Reportins Issues">
<title>Reporting Issues</title>
<indexterm>
<primary>support</primary>
<secondary>reporting issues</secondary>
</indexterm>
<para>
When asking questions or reporting issues, it is extremely helpful if the following information is included:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
&repmgr; version
</simpara>
</listitem>
<listitem>
<simpara>
How was &repmgr; installed? From source? From packages? If
so from which repository?
</simpara>
</listitem>
<listitem>
<simpara>
<filename>repmpgr.conf</filename> files (suitably anonymized if necessary)
</simpara>
</listitem>
<listitem>
<simpara>
Contents of the <literal>repmgr.nodes</literal> table (suitably anonymized if necessary)
</simpara>
</listitem>
<listitem>
<simpara>
PostgreSQL version
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
If issues are encountered with a &repmgr; client command, please provide
the output of that command executed with the options
<option>-LDEBUG --verbose</option>, which will ensure &repmgr; emits
the maximum level of logging output.
</para>
<para>
If issues are encountered with &repmgrd;,
please provide relevant extracts from the &repmgr; log files
and if possible the PostgreSQL log itself. Please ensure these
logs do not contain any confidential data.
</para>
<para>
In all cases it is <emphasis>extremely</emphasis> useful to receive
information on how to reliably reproduce an issue with as much detail as
possible.
</para>
</sect1>
</appendix>

View File

@@ -2,8 +2,6 @@
<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>
@@ -13,8 +11,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.2ndquadrant.com/">2ndQuadrant</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).
@@ -74,7 +73,7 @@
<para> <para>
the <varname>restore_command</varname> setting in <filename>repmgr.conf</filename> is configured to the <varname>restore_command</varname> setting in <filename>repmgr.conf</filename> is configured to
use a copy of the <command>barman-wal-restore</command> script shipped with the use a copy of the <command>barman-wal-restore</command> script shipped with the
<literal>barman-cli</literal> package (see section <xref linkend="cloning-from-barman-restore-command"/> <literal>barman-cli</literal> package (see section <xref linkend="cloning-from-barman-restore-command">
below). below).
</para> </para>
</listitem> </listitem>
@@ -127,13 +126,12 @@
</para> </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">
<title>Using Barman as a WAL file source</title> <indexterm>
<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
@@ -174,9 +172,7 @@
</sect2> </sect2>
</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>
@@ -186,6 +182,7 @@
<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
@@ -247,27 +244,25 @@
<simpara> <simpara>
As an alternative we recommend using 2ndQuadrant's <ulink url="https://www.pgbarman.org/">Barman</ulink>, As an alternative we recommend using 2ndQuadrant'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 bandwith 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/static/warm-standby.html#CASCADING-REPLICATION">
PostgreSQL cascading replication documentation</ulink>. PostgreSQL cascading replication documentation</ulink>.
</para> </para>
<para> <para>
@@ -281,7 +276,7 @@
</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>
@@ -344,11 +339,11 @@
</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>
@@ -370,7 +365,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>
@@ -396,7 +391,7 @@
a symlink will automatically be created from the main data directory. a symlink will automatically be created from the main data directory.
</para> </para>
<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/static/app-pgbasebackup.html">PostgreSQL pg_basebackup documentation</ulink>
for more details of available options. for more details of available options.
</para> </para>
</sect2> </sect2>
@@ -418,7 +413,7 @@
user's <filename>~/.pgpass</filename> file. It's also possible to store the password in the user's <filename>~/.pgpass</filename> file. It's also possible to store the password in the
environment variable <varname>PGPASSWORD</varname>, however this is not recommended for environment variable <varname>PGPASSWORD</varname>, however this is not recommended for
security reasons. For more details see the security reasons. For more details see the
<ulink url="https://www.postgresql.org/docs/current/libpq-pgpass.html">PostgreSQL password file documentation</ulink>. <ulink url="https://www.postgresql.org/docs/current/static/libpq-pgpass.html">PostgreSQL password file documentation</ulink>.
</para> </para>
<note> <note>
@@ -438,7 +433,7 @@
(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 <filename>recovery.conf</filename>. 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 <filename>recovery.conf</filename> to be
rewritten, e.g. <xref linkend="repmgr-standby-follow"/>. rewritten, e.g. <xref linkend="repmgr-standby-follow">.
</para> </para>
<para> <para>
It is of course also possible to include the password value in the <varname>conninfo</varname> It is of course also possible to include the password value in the <varname>conninfo</varname>
@@ -465,7 +460,7 @@
replication connections and generating <filename>recovery.conf</filename>. This replication connections and generating <filename>recovery.conf</filename>. 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>
</sect1> </sect1>

View File

@@ -1,6 +1,4 @@
<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>
@@ -9,9 +7,10 @@
<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 &repmgrd; write log output to By default, &repmgr; and <application>repmgrd</application> 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>
@@ -25,7 +24,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 &repmgrd;, when &repmgr; is executed by another application, particularly <application>repmgrd</application>,
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>
@@ -33,11 +32,12 @@
<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> <term><varname>log_level</varname> (<type>string</type>)
<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 &repmgrd; to emit a status log This setting causes <application>repmgrd</application> 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 &repmgrd;'s current state, e.g.: describing <application>repmgrd</application>'s current state, e.g.:
</para> </para>
<programlisting> <programlisting>
[2018-07-12 00:47:32] [INFO] monitoring connection to upstream node "node1" (ID: 1)</programlisting> [2018-07-12 00:47:32] [INFO] monitoring connection to upstream node "node1" (node ID: 1)</programlisting>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@@ -1,12 +1,10 @@
<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>
@@ -41,10 +39,6 @@
called <varname>standby1</varname> (for example), things will be confusing called <varname>standby1</varname> (for example), things will be confusing
to say the least. to say the least.
</para> </para>
<para>
The string's maximum length is 63 characters and it should
contain only printable ASCII characters.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -62,7 +56,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</ulink> url="https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING">Connection Strings</>
in the PosgreSQL documentation. in the PosgreSQL documentation.
</para> </para>
<para> <para>
@@ -70,19 +64,19 @@
<varname>connect_timeout</varname> in the <varname>conninfo</varname> <varname>connect_timeout</varname> in the <varname>conninfo</varname>
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/static/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT">
the PostgreSQL documentation</ulink>. the PostgreSQL documentation</>.
</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> <term><varname>data_directory</varname> (<type>string</type>)
<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
@@ -96,6 +90,33 @@
</variablelist> </variablelist>
</para> </para>
<para>
For a full list of annotated configuration items, see the file
<ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink>.
</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,6 +1,4 @@
<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>
@@ -9,9 +7,10 @@
<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 &repmgrd;) need to In some circumstances, &repmgr; (and <application>repmgrd</application>) 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
@@ -69,7 +68,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 &repmgrd; to execute <xref linkend="repmgr-standby-promote"/>. by <application>repmgrd</application> to execute <xref linkend="repmgr-standby-promote">.
</para> </para>
</note> </note>

View File

@@ -1,7 +1,4 @@
<sect1 id="configuration-file" xreflabel="configuration file"> <sect1 id="configuration-file" xreflabel="configuration file">
<title>Configuration file</title>
<indexterm> <indexterm>
<primary>repmgr.conf</primary> <primary>repmgr.conf</primary>
</indexterm> </indexterm>
@@ -11,35 +8,37 @@
<secondary>repmgr.conf</secondary> <secondary>repmgr.conf</secondary>
</indexterm> </indexterm>
<title>Configuration file</title>
<para> <para>
<application>repmgr</application> and &repmgrd; <application>repmgr</application> and <application>repmgrd</application>
use a common configuration file, by default called 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> (although any name can be used if explicitly specified).
<filename>repmgr.conf</filename> must contain a number of required parameters, including <filename>repmgr.conf</filename> must contain a number of required parameters, including
the database connection string for the local node and the location the database connection string for the local node and the location
of its data directory; other values will be inferred from defaults if of its data directory; other values will be inferred from defaults if
not explicitly supplied. See section <xref linkend="configuration-file-settings"/> not explicitly supplied. See section <xref linkend="configuration-file-settings">
for more details. for more details.
</para> </para>
<sect2 id="configuration-file-format" xreflabel="configuration file format"> <sect2 id="configuration-file-format" xreflabel="configuration file format">
<title>Configuration file format</title>
<indexterm> <indexterm>
<primary>repmgr.conf</primary> <primary>repmgr.conf</primary>
<secondary>format</secondary> <secondary>format</secondary>
</indexterm> </indexterm>
<title>Configuration file format</title>
<para> <para>
<filename>repmgr.conf</filename> is a plain text file with one parameter/value <filename>repmgr.conf</filename> is a plain text file with one parameter/value
combination per line. combination per line.
</para> </para>
<para> <para>
Whitespace is insignificant (except within a quoted parameter value) and blank lines are ignored. 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. Hash marks (#) designate the remainder of the line as a comment. Parameter values that are not simple
Parameter values that are not simple identifiers or numbers should be single-quoted. identifiers or numbers should be single-quoted. Note that single quote can not be embedded
Note that single quote cannot be embedded in a parameter value. in a parameter value.
</para> </para>
<important> <important>
<para> <para>
@@ -62,79 +61,14 @@ data_directory = /var/lib/pgsql/11/data</programlisting>
</sect2> </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/2ndQuadrant/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"> <sect2 id="configuration-file-location" xreflabel="configuration file location">
<title>Configuration file location</title>
<indexterm> <indexterm>
<primary>repmgr.conf</primary> <primary>repmgr.conf</primary>
<secondary>location</secondary> <secondary>location</secondary>
</indexterm> </indexterm>
<title>Configuration file location</title>
<para> <para>
The configuration file will be searched for in the following locations: The configuration file will be searched for in the following locations:
@@ -171,10 +105,10 @@ data_directory = /var/lib/pgsql/11/data</programlisting>
<note> <note>
<para> <para>
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, particularly when executing <xref linkend="repmgr-primary-register"/> 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 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 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

View File

@@ -2,8 +2,6 @@
<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>
@@ -14,6 +12,7 @@
<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">
@@ -63,8 +62,6 @@
</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>
@@ -74,6 +71,7 @@
<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.
@@ -83,14 +81,13 @@
<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.
@@ -107,15 +104,13 @@
<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>).
@@ -128,15 +123,13 @@
<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
@@ -156,15 +149,13 @@
<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.
@@ -183,20 +174,19 @@
<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>.
@@ -206,15 +196,13 @@
<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)
@@ -237,15 +225,13 @@
<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
@@ -260,15 +246,13 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>wal_keep_segments</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>wal_keep_segments</option></term> <term><option>wal_keep_segments</option></term>
<listitem> <listitem>
<indexterm>
<primary>wal_keep_segments</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> (default: <literal>0</literal>), as it
is <emphasis>not</emphasis> a reliable way of ensuring that all required WAL segments are available to standbys. is <emphasis>not</emphasis> a reliable way of ensuring that all required WAL segments are available to standbys.
@@ -305,18 +289,16 @@
&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;
<sect1 id="configuration-permissions" xreflabel="Database user permissions"> <sect1 id="configuration-permissions" xreflabel="Database user permissions">
<title>repmgr database user permissions</title>
<indexterm> <indexterm>
<primary>configuration</primary> <primary>configuration</primary>
<secondary>database user permissions</secondary> <secondary>database user permissions</secondary>
</indexterm> </indexterm>
<title>repmgr database user permissions</title>
<para> <para>
&repmgr; will create an extension database containing objects &repmgr; will create an extension database containing objects
for administering &repmgr; metadata. The user defined in the <varname>conninfo</varname> for administering &repmgr; metadata. The user defined in the <varname>conninfo</varname>

View File

@@ -0,0 +1,93 @@
<chapter id="using-witness-server">
<indexterm>
<primary>witness server</primary>
<seealso>Using a witness server with repmgrd</seealso>
</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 the primary server
itself is unavailable.
</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 seen 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>
<sect1 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 *not* 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; for more details see <xref linkend="repmgrd-witness-server">.
</para>
<para>
To unregister a witness server, use <xref linkend="repmgr-witness-unregister">.
</para>
</sect1>
</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 &repmgrd; perform a significant event, a record Each time &repmgr; or <application>repmgrd</application> 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>
@@ -88,10 +88,11 @@
<para> <para>
The values provided for <literal>%t</literal> and <literal>%d</literal> The values provided for <literal>%t</literal> and <literal>%d</literal>
may contain spaces, so should be quoted in the provided command will probably 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"'</programlisting> event_notification_command='/path/to/some/script %n %e %s "%t" "%d"'
</programlisting>
</para> </para>
<para> <para>
@@ -103,10 +104,10 @@
<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>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -115,7 +116,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>
<para> <para>
<literal>conninfo</literal> string of the next available node <literal>conninfo</literal> string of the next available node
@@ -128,7 +129,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>
<para> <para>
name of the next available node (<varname>bdr_failover</varname> and <varname>bdr_recovery</varname>) name of the next available node (<varname>bdr_failover</varname> and <varname>bdr_recovery</varname>)
@@ -146,10 +147,7 @@
<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, e.g.: <varname>event_notifications</varname> parameter.
<programlisting>
event_notifications=primary_register,standby_register,witness_register</programlisting>
</para> </para>
<para> <para>
@@ -207,7 +205,7 @@
</para> </para>
<para> <para>
Events generated by &repmgrd; (streaming replication mode): Events generated by <application>repmgrd</application> (streaming replication mode):
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
@@ -257,24 +255,11 @@
<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> <para>
Events generated by &repmgrd; (BDR mode): Events generated by <application>repmgrd</application> (BDR mode):
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
<simpara><literal>bdr_failover</literal></simpara> <simpara><literal>bdr_failover</literal></simpara>

93
doc/filelist.sgml Normal file
View File

@@ -0,0 +1,93 @@
<!-- 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 configuring-witness-server SYSTEM "configuring-witness-server.sgml">
<!ENTITY event-notifications SYSTEM "event-notifications.sgml">
<!ENTITY upgrading-repmgr SYSTEM "upgrading-repmgr.sgml">
<!ENTITY repmgrd-automatic-failover SYSTEM "repmgrd-automatic-failover.sgml">
<!ENTITY repmgrd-configuration SYSTEM "repmgrd-configuration.sgml">
<!ENTITY repmgrd-demonstration SYSTEM "repmgrd-demonstration.sgml">
<!ENTITY repmgrd-monitoring SYSTEM "repmgrd-monitoring.sgml">
<!ENTITY repmgrd-degraded-monitoring SYSTEM "repmgrd-degraded-monitoring.sgml">
<!ENTITY repmgrd-cascading-replication SYSTEM "repmgrd-cascading-replication.sgml">
<!ENTITY repmgrd-network-split SYSTEM "repmgrd-network-split.sgml">
<!ENTITY repmgrd-witness-server SYSTEM "repmgrd-witness-server.sgml">
<!ENTITY repmgrd-pausing SYSTEM "repmgrd-pausing.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-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 bookindex SYSTEM "bookindex.sgml">

View File

@@ -1,70 +0,0 @@
<!-- 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 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 repmgrd-bdr SYSTEM "repmgrd-bdr.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-daemon-status SYSTEM "repmgr-daemon-status.xml">
<!ENTITY repmgr-daemon-start SYSTEM "repmgr-daemon-start.xml">
<!ENTITY repmgr-daemon-stop SYSTEM "repmgr-daemon-stop.xml">
<!ENTITY repmgr-daemon-pause SYSTEM "repmgr-daemon-pause.xml">
<!ENTITY repmgr-daemon-unpause SYSTEM "repmgr-daemon-unpause.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,22 +1,21 @@
<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 &quot;orphaned&quot; standbys server, <xref linkend="repmgr-standby-follow"> can be used to make 'orphaned' 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 repmgr standby follow
INFO: changing node 3's primary to node 2 INFO: changing node 3's primary to node 2
NOTICE: restarting server using "pg_ctl -l /var/log/postgresql/startup.log -w -D '/var/lib/postgresql/data' restart" NOTICE: restarting server using "pg_ctl -l /var/log/postgresql/startup.log -w -D '/var/lib/postgresql/data' restart"
waiting for server to shut down......... done waiting for server to shut down......... done

View File

@@ -1,11 +1,5 @@
<sect1 id="installation-packages" xreflabel="Installing from packages"> <sect1 id="installation-packages" xreflabel="Installing from packages">
<title>Installing &repmgr; from packages</title> <title>Installing &repmgr; from packages</title>
<indexterm>
<primary>installation</primary>
<secondary>from packages</secondary>
</indexterm>
<para> <para>
We recommend installing &repmgr; using the available packages for your We recommend installing &repmgr; using the available packages for your
system. system.
@@ -13,13 +7,12 @@
<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://2ndquadrant.com">2ndQuadrant</ulink>
@@ -47,7 +40,7 @@
<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>
@@ -106,7 +99,7 @@ sudo yum repolist</programlisting>
<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>repmgr10</literal>):
<programlisting> <programlisting>
sudo yum install repmgr10</programlisting> sudo yum install repmgr10</programlisting>
</para> </para>
@@ -167,28 +160,17 @@ yum search repmgr</programlisting>
<programlisting> <programlisting>
[root@localhost ~]# yum install repmgr10-4.0.3-1.rhel7</programlisting> [root@localhost ~]# yum install repmgr10-4.0.3-1.rhel7</programlisting>
</para> </para>
<para>
<emphasis>Installing old packages</emphasis>
</para>
<para>
See appendix <link linkend="packages-old-versions-rhel-centos">Installing old package versions</link>
for details on how to retrieve older package versions.
</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="http://apt.postgresql.org/">http://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
@@ -197,7 +179,7 @@ yum search repmgr</programlisting>
<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">
@@ -242,9 +224,10 @@ 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>repmgr10</literal>):
<programlisting> <programlisting>
sudo apt-get install postgresql-10-repmgr</programlisting> sudo apt-get install postgresql-10-repmgr</programlisting>
</para> </para>
@@ -261,15 +244,6 @@ sudo apt-get install postgresql-10-repmgr</programlisting>
</para> </para>
<para>
<emphasis>Installing old packages</emphasis>
</para>
<para>
See appendix <link linkend="packages-old-versions-debian">Installing old package versions</link>
for details on how to retrieve older package versions.
</para>
</sect3> </sect3>
</sect2> </sect2>

View File

@@ -1,12 +1,11 @@
<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
@@ -21,7 +20,7 @@
<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>
@@ -46,14 +45,14 @@
</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. 3.3.x and 4.1.x)
are installed on different nodes, in the best case &repmgr; (in particular &repmgrd;) are installed on different nodes, in the best case &repmgr; (in particular <application>repmgrd</application>)
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
&repmgrd; actions require direct access to the PostgreSQL data directory, <application>repmgrd</application> 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>
@@ -73,8 +72,6 @@
<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>
@@ -84,6 +81,7 @@
<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.
@@ -93,7 +91,7 @@
<table id="repmgr-compatibility-matrix"> <table id="repmgr-compatibility-matrix">
<title>&repmgr; compatibility matrix</title> <title>&repmgr; compatibility matrix</title>
<tgroup cols="3"> <tgroup cols="2">
<thead> <thead>
<row> <row>
<entry> <entry>

View File

@@ -1,20 +1,19 @@
<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>
To install &repmgr; the prerequisites for compiling To install &repmgr; the prerequisites for compiling
&postgres; must be installed. These are described in &postgres;'s &postgres; must be installed. These are described in &postgres;'s
documentation documentation
on <ulink url="https://www.postgresql.org/docs/current/install-requirements.html">build requirements</ulink> on <ulink url="https://www.postgresql.org/docs/current/static/install-requirements.html">build requirements</ulink>
and <ulink url="https://www.postgresql.org/docs/current/docguide-toolsets.html">build requirements for documentation</ulink>. and <ulink url="https://www.postgresql.org/docs/current/static/docguide-toolsets.html">build requirements for documentation</ulink>.
</para> </para>
<para> <para>
@@ -62,28 +61,28 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
<simpara><literal>libedit-dev</literal></simpara> <simpara><literal>llibedit-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>libkrb5-dev</literal></simpara> <simpara><literal>llibkrb5-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>libpam0g-dev</literal></simpara> <simpara><literal>llibpam0g-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>libreadline-dev</literal></simpara> <simpara><literal>llibreadline-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>libselinux1-dev</literal></simpara> <simpara><literal>llibselinux1-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>libssl-dev</literal></simpara> <simpara><literal>llibssl-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>libxml2-dev</literal></simpara> <simpara><literal>llibxml2-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>libxslt1-dev</literal></simpara> <simpara><literal>llibxslt1-dev</literal></simpara>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
@@ -137,16 +136,6 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
</itemizedlist> </itemizedlist>
</para> </para>
</note> </note>
<tip>
<para>
If building against PostgreSQL 11 or later configured with the <option>--with-llvm</option> option
(this is the case with the PGDG-provided packages) you'll also need to install the
<literal>llvm-toolset-7-clang</literal> package. This is available via the
<ulink url="https://wiki.centos.org/AdditionalResources/Repositories/SCL">Software Collections (SCL) Repository</ulink>.
</para>
</tip>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
@@ -201,7 +190,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>
@@ -209,11 +198,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 <command>tar xf</command> After you unpack the source code archives using <literal>tar xf</literal>
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>
@@ -228,7 +217,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 &amp;&amp; make install</programlisting> ./configure && 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>.
@@ -237,30 +226,16 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
<sect2 id="installation-build-repmgr-docs" xreflabel="Building repmgr documentation"> <sect2 id="installation-build-repmgr-docs">
<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 XML format. To build it locally as HTML, you'll need to written in DocBook 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/current/docguide-toolsets.html">PostgreSQL documentation</ulink>. <ulink url="https://www.postgresql.org/docs/9.6/static/docguide-toolsets.html">
</para> PostgreSQL documentation</ulink> then execute:
<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 &amp;&amp; make doc</programlisting> ./configure && make install-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>
@@ -268,20 +243,19 @@ 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, after configuring and building To build the documentation as a single HTML file, execute:
the main &repmgr; source as described above, execute:
<programlisting> <programlisting>
./configure &amp;&amp; make doc-repmgr.html</programlisting> cd doc/ && make repmgr.html</programlisting>
</para> </para>
<para> <note>
To build the documentation as a PDF file, after configuring and building <simpara>
the main &repmgr; source as described above, execute: Due to changes in PostgreSQL's documentation build system from PostgreSQL 10,
<programlisting> the documentation can currently only be built against PostgreSQL 9.6 or earlier.
./configure &amp;&amp; make doc-repmgr-A4.pdf</programlisting> This limitation will be fixed when time and resources permit.
</para> </simpara>
</note>
</sect2> </sect2>
</sect1> </sect1>

View File

@@ -1,11 +1,10 @@
<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.
@@ -19,7 +18,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,9 +1,9 @@
<!-- doc/legal.xml --> <!-- doc/legal.sgml -->
<date>2017</date> <date>2017</date>
<copyright> <copyright>
<year>2010-2019</year> <year>2010-2018</year>
<holder>2ndQuadrant, Ltd.</holder> <holder>2ndQuadrant, Ltd.</holder>
</copyright> </copyright>
@@ -11,7 +11,7 @@
<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-2018
by 2ndQuadrant, Ltd. All rights reserved. by 2ndQuadrant, Ltd. All rights reserved.
</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/warm-standby.html#STREAMING-REPLICATION"> url="https://www.postgresql.org/docs/current/interactive/warm-standby.html#STREAMING-REPLICATION">
streaming replication</ulink>. streaming replication</>.
</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 &repmgrd; daemon supports automatic failover is promoted as the new primary. The <application>repmgrd</application> 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 &repmgrd; A witness server only needs to be created if <application>repmgrd</application>
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 &repmgrd;</simpara> written by <application>repmgrd</application></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 &repmgrd;'s monitoring is enabled, shows <simpara>repmgr.replication_status: when <application>repmgrd</application>'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>
@@ -76,25 +76,19 @@
</para> </para>
<programlisting> <programlisting>
# Enable replication connections; set this value to at least one more # Enable replication connections; set this figure to at least one more
# than the number of standbys which will connect to this server # than the number of standbys which will connect to this server
# (note that repmgr will execute "pg_basebackup" in WAL streaming mode, # (note that repmgr will execute `pg_basebackup` in WAL streaming mode,
# which requires two free WAL senders). # which requires two free WAL senders)
#
# See: https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-MAX-WAL-SENDERS
max_wal_senders = 10 max_wal_senders = 10
# If using replication slots, set this value to at least one more # Enable replication slots; set this figure to at least one more
# than the number of standbys which will connect to this server. # than the number of standbys which will connect to this server.
# Note that repmgr will only make use of replication slots if # Note that repmgr will only make use of replication slots if
# "use_replication_slots" is set to "true" in "repmgr.conf". # "use_replication_slots" is set to "true" in repmgr.conf
# (If you are not intending to use replication slots, this value
# can be set to "0").
#
# See: https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-MAX-REPLICATION-SLOTS
max_replication_slots = 10 max_replication_slots = 0
# Ensure WAL files contain enough information to enable read-only queries # Ensure WAL files contain enough information to enable read-only queries
# on the standby. # on the standby.
@@ -103,47 +97,39 @@
# PostgreSQL 9.6 and later: one of 'replica' or 'logical' # PostgreSQL 9.6 and later: one of 'replica' or 'logical'
# ('hot_standby' will still be accepted as an alias for 'replica') # ('hot_standby' will still be accepted as an alias for 'replica')
# #
# See: https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LEVEL # See: https://www.postgresql.org/docs/current/static/runtime-config-wal.html#GUC-WAL-LEVEL
wal_level = 'hot_standby' wal_level = 'hot_standby'
# Enable read-only queries on a standby # Enable read-only queries on a standby
# (Note: this will be ignored on a primary but we recommend including # (Note: this will be ignored on a primary but we recommend including
# it anyway, in case the primary later becomes a standby) # it anyway)
#
# See: https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-HOT-STANDBY
hot_standby = on hot_standby = on
# Enable WAL file archiving # Enable WAL file archiving
#
# See: https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-ARCHIVE-MODE
archive_mode = on archive_mode = on
# Set archive command to a dummy command; this can later be changed without # Set archive command to a script or application that will safely store
# needing to restart the PostgreSQL instance. # you WALs in a secure place. /bin/true is an example of a command that
# # ignores archiving. Use something more sensible.
# See: https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-ARCHIVE-COMMAND
archive_command = '/bin/true' archive_command = '/bin/true'
</programlisting> </programlisting>
<tip> <tip>
<simpara> <simpara>
Rather than editing these settings in the default <filename>postgresql.conf</filename> Rather than editing these settings in the default <filename>postgresql.conf</filename>
file, create a separate file such as <filename>postgresql.replication.conf</filename> and file, create a separate file such as <filename>postgresql.replication.conf</filename> and
include it from the end of the main configuration file with: include it from the end of the main configuration file with:
<command>include 'postgresql.replication.conf'</command>. <command>include 'postgresql.replication.conf</command>.
</simpara> </simpara>
</tip> </tip>
<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 <link linkend="configuration">repmgr configuaration guide</link>.
<link linkend="configuration">repmgr configuration guide</link>.
</para> </para>
</sect1> </sect1>
@@ -238,7 +224,7 @@
<note> <note>
<para> <para>
&repmgr; stores connection information as <ulink &repmgr; stores connection information as <ulink
url="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING">libpq url="https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING">libpq
connection strings</ulink> throughout. This documentation refers to them as <literal>conninfo</literal> connection strings</ulink> throughout. This documentation refers to them as <literal>conninfo</literal>
strings; an alternative name is <literal>DSN</literal> (<literal>data source name</literal>). strings; an alternative name is <literal>DSN</literal> (<literal>data source name</literal>).
We'll use these in place of the <command>-h hostname -d databasename -U username</command> syntax. We'll use these in place of the <command>-h hostname -d databasename -U username</command> syntax.
@@ -262,7 +248,7 @@
<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>
@@ -303,7 +289,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> <ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</>
for details of all available configuration parameters. for details of all available configuration parameters.
</para> </para>
@@ -352,7 +338,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 &repmgrd; Each server in the replication cluster will have its own record. If <application>repmgrd</application>
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>
@@ -460,7 +446,7 @@
</para> </para>
<para> <para>
From PostgreSQL 9.6 you can also use the view From PostgreSQL 9.6 you can also use the view
<ulink url="https://www.postgresql.org/docs/current/monitoring-stats.html#PG-STAT-WAL-RECEIVER-VIEW"> <ulink url="https://www.postgresql.org/docs/current/static/monitoring-stats.html#PG-STAT-WAL-RECEIVER-VIEW">
<literal>pg_stat_wal_receiver</literal></ulink> to check the replication status from the standby. <literal>pg_stat_wal_receiver</literal></ulink> to check the replication status from the standby.
<programlisting> <programlisting>

View File

@@ -38,7 +38,7 @@
<title>Notes</title> <title>Notes</title>
<para> <para>
Monitoring history will only be written if &repmgrd; is active, and Monitoring history will only be written if <application>repmgrd</application> 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>
@@ -42,7 +42,7 @@
<refsect1> <refsect1>
<title>Exit codes</title> <title>Exit codes</title>
<para> <para>
One of the following exit codes will be emitted by <command>repmgr cluster crosscheck</command>: Following exit codes can be emitted by <command>repmgr cluster crosscheck</command>:
</para> </para>
<variablelist> <variablelist>

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 &quot;Details&quot; column can be omitted by providing <literal>--compact</literal>. The "Details" column can be omitted by providing <literal>--terse</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 | 2019-04-16 10:59:59 | standby registration succeeded; upstream node ID is 1 3 | node3 | standby_register | t | 2017-08-17 10:28:55 | standby registration succeeded
2 | node2 | standby_register | t | 2019-04-16 10:59:57 | standby registration succeeded; upstream node ID is 1</programlisting> 2 | node2 | standby_register | t | 2017-08-17 10:28:53 | standby registration succeeded</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>
@@ -102,7 +102,7 @@
<refsect1> <refsect1>
<title>Exit codes</title> <title>Exit codes</title>
<para> <para>
One of the following exit codes will be emitted by <command>repmgr cluster matrix</command>: Following exit codes can be emitted by <command>repmgr cluster matrix</command>:
</para> </para>
<variablelist> <variablelist>

View File

@@ -0,0 +1,192 @@
<refentry id="repmgr-cluster-show">
<indexterm>
<primary>repmgr cluster show</primary>
</indexterm>
<refmeta>
<refentrytitle>repmgr cluster show</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr cluster show</refname>
<refpurpose>display information about each registered node in the replication cluster</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
Displays information about each registered node in the replication cluster. This
command polls each registered server and shows its role (<literal>primary</literal> /
<literal>standby</literal> / <literal>bdr</literal>) and status. It polls each server
directly and can be run on any node in the cluster; this is also useful when analyzing
connectivity from a particular node.
</para>
</refsect1>
<refsect1>
<title>Execution</title>
<para>
This command requires either a valid <filename>repmgr.conf</filename> file or a database
connection string to one of the registered nodes; no additional arguments are needed.
</para>
<para>
To show database connection errors when polling nodes, run the command in
<literal>--verbose</literal> mode.
</para>
</refsect1>
<refsect1>
<title>Example</title>
<para>
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Connection string
----+-------+---------+-----------+----------+----------+-----------------------------------------
1 | node1 | primary | * running | | default | host=db_node1 dbname=repmgr user=repmgr
2 | node2 | standby | running | node1 | default | host=db_node2 dbname=repmgr user=repmgr
3 | node3 | standby | running | node1 | default | host=db_node3 dbname=repmgr user=repmgr</programlisting>
</para>
</refsect1>
<refsect1>
<title>Notes</title>
<para>
The column <literal>Role</literal> shows the expected server role according to the
&repmgr; metadata. <literal>Status</literal> shows whether the server is running or unreachable.
If the node has an unexpected role not reflected in the &repmgr; metadata, e.g. a node was manually
promoted to primary, this will be highlighted with an exclamation mark, e.g.:
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Connection string
----+-------+---------+----------------------+----------+----------+-----------------------------------------
1 | node1 | primary | ? unreachable | | default | host=db_node1 dbname=repmgr user=repmgr
2 | node2 | standby | ! running as primary | node1 | default | host=db_node2 dbname=repmgr user=repmgr
3 | node3 | standby | running | node1 | default | host=db_node3 dbname=repmgr user=repmgr
WARNING: following issues were detected
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</programlisting>
</para>
<para>
Node availability is tested by connecting from the node where
<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
a better overviews of connections between nodes.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--csv</option></term>
<listitem>
<para>
<command>repmgr cluster show</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 cluster show --csv
1,-1,-1
2,0,0
3,0,1</programlisting>
</para>
<para>
The columns have following meanings:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
node ID
</simpara>
</listitem>
<listitem>
<simpara>
availability (0 = available, -1 = unavailable)
</simpara>
</listitem>
<listitem>
<simpara>
recovery state (0 = not in recovery, 1 = in recovery, -1 = unknown)
</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>Exit codes</title>
<para>
Following exit codes can be emitted by <command>repmgr cluster show</command>:
</para>
<variablelist>
<varlistentry>
<term><option>SUCCESS (0)</option></term>
<listitem>
<para>
No issues were detected.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_BAD_CONFIG (1)</option></term>
<listitem>
<para>
An issue was encountered while attempting to retrieve
&repmgr; metadata.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_DB_CONN (6)</option></term>
<listitem>
<para>
&repmgr; was unable to connect to the local PostgreSQL instance.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_NODE_STATUS (25)</option></term>
<listitem>
<para>
One or more issues were detected with the replication configuration,
e.g. a node was not in its expected state.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-node-status">, <xref linkend="repmgr-node-check">, <xref linkend="repmgr-daemon-status">
</para>
</refsect1>
</refentry>

View File

@@ -1,240 +0,0 @@
<refentry id="repmgr-cluster-show">
<indexterm>
<primary>repmgr cluster show</primary>
</indexterm>
<refmeta>
<refentrytitle>repmgr cluster show</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr cluster show</refname>
<refpurpose>display information about each registered node in the replication cluster</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
Displays information about each registered node in the replication cluster. This
command polls each registered server and shows its role (<literal>primary</literal> /
<literal>standby</literal> / <literal>bdr</literal>) and status. It polls each server
directly and can be run on any node in the cluster; this is also useful when analyzing
connectivity from a particular node.
</para>
<para>
For PostgreSQL 9.6 and later, the output will also contain the node's current timeline ID.
</para>
<para>
Node availability is tested by connecting from the node where
<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
better overviews of connections between nodes.
</para>
</refsect1>
<refsect1>
<title>Execution</title>
<para>
This command requires either a valid <filename>repmgr.conf</filename> file or a database
connection string to one of the registered nodes; no additional arguments are needed.
</para>
<para>
To show database connection errors when polling nodes, run the command in
<literal>--verbose</literal> mode.
</para>
</refsect1>
<refsect1>
<title>Example</title>
<para>
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string
----+-------+---------+-----------+----------+----------+----------+-----------------------------------------
1 | node1 | primary | * running | | default | 100 | 1 | host=db_node1 dbname=repmgr user=repmgr
2 | node2 | standby | running | node1 | default | 100 | 1 | host=db_node2 dbname=repmgr user=repmgr
3 | node3 | standby | running | node1 | default | 100 | 1 | host=db_node3 dbname=repmgr user=repmgr</programlisting>
</para>
</refsect1>
<refsect1>
<title>Notes</title>
<para>
The column <literal>Role</literal> shows the expected server role according to the
&repmgr; metadata.
</para>
<para>
<literal>Status</literal> shows whether the server is running or unreachable.
If the node has an unexpected role not reflected in the &repmgr; metadata, e.g. a node was manually
promoted to primary, this will be highlighted with an exclamation mark.
If a connection to the node cannot be made, this will be highlighted with a question mark.
Note that the node will only be shown as <literal>? unreachable</literal>
if a connection is not possible at network level; if the PostgreSQL instance on the
node is pingable but not accepting connections, it will be shown as <literal>? running</literal>.
</para>
<para>
In the following example, executed on <literal>node3</literal>, <literal>node1</literal> is not reachable
at network level and assumed to be down; <literal>node2</literal> has been promoted to primary
(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).
<programlisting>
ID | Name | Role | Status | Upstream | Location | Priority | Connection string
----+-------+---------+----------------------+----------+----------+----------+-----------------------------------------
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
3 | node3 | standby | running | node1 | default | 100 | host=db_node3 dbname=repmgr user=repmgr
4 | node4 | standby | ? running | node1 | default | 100 | host=db_node4 dbname=repmgr user=repmgr
WARNING: following issues were detected
- unable to connect to node "node1" (ID: 1)
- 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
- unable to connect to node "node4" (ID: 4)
HINT: execute with --verbose option to see connection error messages</programlisting>
</para>
<para>
To diagnose connection issues, execute <command>repmgr cluster show</command>
with the <option>--verbose</option> option; this will display the error message
for each failed connection attempt.
</para>
<tip>
<para>
Use <xref linkend="repmgr-cluster-matrix"/> and <xref linkend="repmgr-cluster-crosscheck"/>
to diagnose connection issues across the whole replication cluster.
</para>
</tip>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--csv</option></term>
<listitem>
<para>
<command>repmgr cluster show</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 cluster show --csv
1,-1,-1
2,0,0
3,0,1</programlisting>
</para>
<para>
The columns have following meanings:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
node ID
</simpara>
</listitem>
<listitem>
<simpara>
availability (0 = available, -1 = unavailable)
</simpara>
</listitem>
<listitem>
<simpara>
recovery state (0 = not in recovery, 1 = in recovery, -1 = unknown)
</simpara>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--compact</option></term>
<listitem>
<para>
Suppress display of the <literal>conninfo</literal> column.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--terse</option></term>
<listitem>
<para>
Suppress warnings about connection issues.
</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>Exit codes</title>
<para>
One of the following exit codes will be emitted by <command>repmgr cluster show</command>:
</para>
<variablelist>
<varlistentry>
<term><option>SUCCESS (0)</option></term>
<listitem>
<para>
No issues were detected.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_BAD_CONFIG (1)</option></term>
<listitem>
<para>
An issue was encountered while attempting to retrieve
&repmgr; metadata.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_DB_CONN (6)</option></term>
<listitem>
<para>
&repmgr; was unable to connect to the local PostgreSQL instance.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_NODE_STATUS (25)</option></term>
<listitem>
<para>
One or more issues were detected with the replication configuration,
e.g. a node was not in its expected state.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-node-status"/>, <xref linkend="repmgr-node-check"/>, <xref linkend="repmgr-daemon-status"/>
</para>
</refsect1>
</refentry>

View File

@@ -3,41 +3,36 @@
<primary>repmgr daemon pause</primary> <primary>repmgr daemon pause</primary>
</indexterm> </indexterm>
<indexterm>
<primary>repmgrd</primary>
<secondary>pausing</secondary>
</indexterm>
<refmeta> <refmeta>
<refentrytitle>repmgr daemon pause</refentrytitle> <refentrytitle>repmgr daemon pause</refentrytitle>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
<refname>repmgr daemon pause</refname> <refname>repmgr daemon pause</refname>
<refpurpose>Instruct all &repmgrd; instances in the replication cluster to pause failover operations</refpurpose> <refpurpose>Instruct all <application>repmgrd</application> 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 &repmgrd; instances to &quot;pause&quot; themselves, i.e. take no running <application>repmgrd</application> 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 &repmgrd; or upgrades, which might otherwise trigger a failover if <application>repmgrd</application>
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 &repmgrd; instance <command>repmgr daemon pause</command>, as the <application>repmgrd</application> 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 &repmgrd; <xref linkend="repmgr-daemon-unpause"> will instruct all previously paused <application>repmgrd</application>
instances to resume normal failover operation. instances to resume normal failover operation.
</para> </para>
</refsect1> </refsect1>
@@ -69,7 +64,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 &repmgrd;. Check if nodes are reachable but don't pause <application>repmgrd</application>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -79,7 +74,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>: Following exit codes can be emitted by <command>repmgr daemon unpause</command>:
</para> </para>
<variablelist> <variablelist>
@@ -87,7 +82,7 @@ NOTICE: node 3 (node3) paused</programlisting>
<term><option>SUCCESS (0)</option></term> <term><option>SUCCESS (0)</option></term>
<listitem> <listitem>
<para> <para>
&repmgrd; could be paused on all nodes. <application>repmgrd</application> could be paused on all nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -96,7 +91,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>
&repmgrd; could not be paused on one or mode nodes. <application>repmgrd</application> could not be paused on one or mode nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -107,7 +102,7 @@ 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-daemon-unpause">, <xref linkend="repmgr-daemon-status">
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@@ -1,204 +0,0 @@
<refentry id="repmgr-daemon-start">
<indexterm>
<primary>repmgr daemon start</primary>
</indexterm>
<indexterm>
<primary>repmgrd</primary>
<secondary>starting</secondary>
</indexterm>
<refmeta>
<refentrytitle>repmgr daemon start</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr daemon start</refname>
<refpurpose>Start the &repmgrd; daemon</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
This command starts the &repmgrd; daemon on the
local node.
</para>
<para>
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>
option, or disabled altogether with the <option>--no-wait</option> option.
</para>
<important>
<para>
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
<xref linkend="repmgr-daemon-start-configuration"/> for details.
</para>
</important>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--dry-run</option></term>
<listitem>
<para>
Check prerequisites but don't actually attempt to start &repmgrd;.
</para>
<para>
This action will output the command which would be executed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-w</option></term>
<term><option>--wait</option></term>
<listitem>
<para>
Wait for the specified number of seconds to confirm that &repmgrd;
started successfully.
</para>
<para>
Note that providing <option>--wait=0</option> is the equivalent of <option>--no-wait</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--no-wait</option></term>
<listitem>
<para>
Don't wait to confirm that &repmgrd;
started successfully.
</para>
<para>
This is equivalent to providing <option>--wait=0</option>.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="repmgr-daemon-start-configuration" xreflabel="repmgr daemon start configuration">
<title>Configuration file settings</title>
<para>
The following parameter in <filename>repmgr.conf</filename> is relevant
to <command>repmgr daemon start</command>:
</para>
<variablelist>
<varlistentry>
<term><option>repmgrd_service_start_command</option></term>
<listitem>
<indexterm>
<primary>repmgrd_service_start_command</primary>
<secondary>with &quot;repmgr daemon start&quot;</secondary>
</indexterm>
<para>
<command>repmgr daemon start</command> will execute the command defined by the
<varname>repmgrd_service_start_command</varname> parameter in <filename>repmgr.conf</filename>.
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
package. For more details see <link linkend="appendix-packages">Appendix: &repmgr; package details</link>.
</para>
<important>
<para>
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
result in the system becoming confused about the state of the &repmgrd;
service; this is particularly the case with <literal>systemd</literal>.
</para>
</important>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Exit codes</title>
<para>
One of the following exit codes will be emitted by <command>repmgr daemon start</command>:
</para>
<variablelist>
<varlistentry>
<term><option>SUCCESS (0)</option></term>
<listitem>
<para>
The &repmgrd; start command (defined in
<varname>repmgrd_service_start_command</varname>) was successfully executed.
</para>
<para>
If the <option>--wait</option> option was provided, &repmgr; will confirm that
&repmgrd; has actually started up.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_BAD_CONFIG (1)</option></term>
<listitem>
<para>
<varname>repmgrd_service_start_command</varname> is not defined in
<filename>repmgr.conf</filename>.
</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 &repmgrd;
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
to determine the state of &repmgrd;.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_REPMGRD_SERVICE (27)</option></term>
<listitem>
<para>
The &repmgrd; start command (defined in
<varname>repmgrd_service_start_command</varname>) was not successfully executed.
</para>
<para>
This can also mean that &repmgr; was unable to confirm whether &repmgrd;
successfully started (unless the <option>--no-wait</option> option was provided).
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-daemon-stop"/>, <xref linkend="repmgr-daemon-status"/>, <xref linkend="repmgrd-daemon"/>
</para>
</refsect1>
</refentry>

View File

@@ -0,0 +1,165 @@
<refentry id="repmgr-daemon-status">
<indexterm>
<primary>repmgr daemon status</primary>
</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>
<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 | Status | repmgrd | PID | Paused?
----+-------+---------+---------+---------+------+---------
1 | node1 | primary | running | running | 7851 | no
2 | node2 | standby | running | running | 7889 | no
3 | node3 | standby | running | running | 7918 | no</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 | Status | repmgrd | PID | Paused?
----+-------+---------+---------+---------+------+---------
1 | node1 | primary | running | running | 7851 | yes
2 | node2 | standby | running | running | 7889 | yes
3 | node3 | standby | running | running | 7918 | yes</programlisting>
</para>
<para>
<application>repmgrd</application> not running on one node:
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
ID | Name | Role | Status | repmgrd | PID | Paused?
----+-------+---------+---------+-------------+------+---------
1 | node1 | primary | running | running | 7851 | yes
2 | node2 | standby | running | not running | n/a | n/a
3 | node3 | standby | running | running | 7918 | yes</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,10204,1
2,node2,standby,1,0,-1,1
3,node3,standby,1,1,10225,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
</simpara>
</listitem>
<listitem>
<simpara>
<application>repmgrd</application> running (1 = running, 0 = not running)
</simpara>
</listitem>
<listitem>
<simpara>
<application>repmgrd</application> PID (-1 if not running)
</simpara>
</listitem>
<listitem>
<simpara>
<application>repmgrd</application> paused (1 = paused, 0 = not paused)
</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

@@ -1,198 +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 &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-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 &repmgrd; instance.
</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 daemon 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-daemon-pause"/>):
<programlisting>$ repmgr -f /etc/repmgr.conf daemon 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 daemon 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 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,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-daemon-pause"/>, <xref linkend="repmgr-daemon-unpause"/>, <xref linkend="repmgr-cluster-show"/>
</para>
</refsect1>
</refentry>

View File

@@ -1,201 +0,0 @@
<refentry id="repmgr-daemon-stop">
<indexterm>
<primary>repmgr daemon stop</primary>
</indexterm>
<indexterm>
<primary>repmgrd</primary>
<secondary>stopping</secondary>
</indexterm>
<refmeta>
<refentrytitle>repmgr daemon stop</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr daemon stop</refname>
<refpurpose>Stop the &repmgrd; daemon</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
This command stops the &repmgrd; daemon on the
local node.
</para>
<para>
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>
option, or disabled altogether with the <option>--no-wait</option> option.
</para>
<note>
<para>
If PostgreSQL is not running on the local node, under some circumstances &repmgr; may not
be able to confirm if &repmgrd; has actually stopped.
</para>
</note>
<important>
<para>
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
<xref linkend="repmgr-daemon-stop-configuration"/> for details.
</para>
</important>
</refsect1>
<refsect1>
<title>Configuration</title>
<para>
<command>repmgr daemon stop</command> will execute the command defined by the
<varname>repmgrd_service_stop_command</varname> parameter in <filename>repmgr.conf</filename>.
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
package. For more details see <link linkend="appendix-packages">Appendix: &repmgr; package details</link>.
</para>
<important>
<para>
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
result in the system becoming confused about the state of the &repmgrd;
service; this is particularly the case with <literal>systemd</literal>.
</para>
</important>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--dry-run</option></term>
<listitem>
<para>
Check prerequisites but don't actually attempt to stop &repmgrd;.
</para>
<para>
This action will output the command which would be executed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-w</option></term>
<term><option>--wait</option></term>
<listitem>
<para>
Wait for the specified number of seconds to confirm that &repmgrd;
stopped successfully.
</para>
<para>
Note that providing <option>--wait=0</option> is the equivalent of <option>--no-wait</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--no-wait</option></term>
<listitem>
<para>
Don't wait to confirm that &repmgrd;
stopped successfully.
</para>
<para>
This is equivalent to providing <option>--wait=0</option>.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="repmgr-daemon-stop-configuration" xreflabel="repmgr daemon stop configuration">
<title>Configuration file settings</title>
<para>
The following parameter in <filename>repmgr.conf</filename> is relevant
to <command>repmgr daemon stop</command>:
</para>
<variablelist>
<varlistentry>
<term><option>repmgrd_service_stop_command</option></term>
<listitem>
<indexterm>
<primary>repmgrd_service_stop_command</primary>
<secondary>with &quot;repmgr daemon stop&quot;</secondary>
</indexterm>
<para>
<command>repmgr daemon stop</command> will execute the command defined by the
<varname>repmgrd_service_stop_command</varname> parameter in <filename>repmgr.conf</filename>.
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
package. For more details see <link linkend="appendix-packages">Appendix: &repmgr; package details</link>.
</para>
<important>
<para>
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
result in the system becoming confused about the state of the &repmgrd;
service; this is particularly the case with <literal>systemd</literal>.
</para>
</important>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Exit codes</title>
<para>
One of the following exit codes will be emitted by <command>repmgr daemon stop</command>:
</para>
<variablelist>
<varlistentry>
<term><option>SUCCESS (0)</option></term>
<listitem>
<para>
&repmgrd; could be stopped.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_BAD_CONFIG (1)</option></term>
<listitem>
<para>
<varname>repmgrd_service_stop_command</varname> is not defined in
<filename>repmgr.conf</filename>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_REPMGRD_SERVICE (27)</option></term>
<listitem>
<para>
&repmgrd; could not be stopped.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-daemon-start"/>, <xref linkend="repmgr-daemon-status"/>, <xref linkend="repmgrd-daemon"/>
</para>
</refsect1>
</refentry>

View File

@@ -3,34 +3,28 @@
<primary>repmgr daemon unpause</primary> <primary>repmgr daemon unpause</primary>
</indexterm> </indexterm>
<indexterm>
<primary>repmgrd</primary>
<secondary>unpausing</secondary>
</indexterm>
<refmeta> <refmeta>
<refentrytitle>repmgr daemon unpause</refentrytitle> <refentrytitle>repmgr daemon unpause</refentrytitle>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
<refname>repmgr daemon unpause</refname> <refname>repmgr daemon unpause</refname>
<refpurpose>Instruct all &repmgrd; instances in the replication cluster to resume failover operations</refpurpose> <refpurpose>Instruct all <application>repmgrd</application> 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 &repmgrd; instances to &quot;unpause&quot; running <application>repmgrd</application> instances to &quot;unpause&quot;
(following a previous execution of <xref linkend="repmgr-daemon-pause"/>) (following a previous execution of <xref linkend="repmgr-daemon-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 &repmgrd; instance <command>repmgr daemon pause</command>, as the <application>repmgrd</application> 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>
@@ -64,7 +58,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 &repmgrd;. Check if nodes are reachable but don't unpause <application>repmgrd</application>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -74,7 +68,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>: Following exit codes can be emitted by <command>repmgr daemon unpause</command>:
</para> </para>
<variablelist> <variablelist>
@@ -82,7 +76,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<term><option>SUCCESS (0)</option></term> <term><option>SUCCESS (0)</option></term>
<listitem> <listitem>
<para> <para>
&repmgrd; could be unpaused on all nodes. <application>repmgrd</application> could be unpaused on all nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -91,7 +85,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>
&repmgrd; could not be unpaused on one or mode nodes. <application>repmgrd</application> could not be unpaused on one or mode nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -102,7 +96,7 @@ 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-daemon-pause">, <xref linkend="repmgr-daemon-status">
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@@ -18,14 +18,6 @@
Performs some health checks on a node from a replication perspective. Performs some health checks on a node from a replication perspective.
This command must be run on the local node. This command must be run on the local node.
</para> </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>
<refsect1> <refsect1>
@@ -38,8 +30,8 @@
Replication lag: OK (N/A - node is primary) Replication lag: OK (N/A - node is primary)
WAL archiving: OK (0 pending files) WAL archiving: OK (0 pending files)
Downstream servers: OK (2 of 2 downstream nodes attached) Downstream servers: OK (2 of 2 downstream nodes attached)
Replication slots: OK (node has no physical replication slots) Replication slots: OK (node has no replication slots)
Missing replication slots: OK (node has no missing physical replication slots)</programlisting> Missing replication slots: OK (node has no missing replication slots)</programlisting>
</para> </para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@@ -52,7 +44,7 @@
OK (node is primary)</programlisting> OK (node is primary)</programlisting>
</para> </para>
<para> <para>
Parameters for individual checks are as follows: Parameters for individual checks are as follows:
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
@@ -84,26 +76,16 @@
<listitem> <listitem>
<simpara> <simpara>
<literal>--slots</literal>: checks there are no inactive physical replication slots <literal>--slots</literal>: checks there are no inactive replication slots
</simpara> </simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara> <simpara>
<literal>--missing-slots</literal>: checks there are no missing physical replication slots <literal>--missing-slots</literal>: checks there are no missing replication slots
</simpara> </simpara>
</listitem> </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> </itemizedlist>
</para> </para>
</refsect1> </refsect1>
@@ -123,7 +105,6 @@
<listitem> <listitem>
<simpara> <simpara>
<literal>--nagios</literal>: generate output in a Nagios-compatible format <literal>--nagios</literal>: generate output in a Nagios-compatible format
(for individual checks only)
</simpara> </simpara>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@@ -170,10 +151,9 @@
<para> <para>
One of the following exit codes will be emitted by <command>repmgr status check</command> Following exit codes can be emitted by <command>repmgr status check</command>
if no individual check was specified. if no individual check was specified.
</para> </para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
@@ -195,7 +175,6 @@
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
@@ -203,7 +182,7 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-node-status"/>, <xref linkend="repmgr-cluster-show"/> <xref linkend="repmgr-node-status">, <xref linkend="repmgr-cluster-show">
</para> </para>
</refsect1> </refsect1>

264
doc/repmgr-node-rejoin.sgml Normal file
View File

@@ -0,0 +1,264 @@
<refentry id="repmgr-node-rejoin">
<indexterm>
<primary>repmgr node rejoin</primary>
</indexterm>
<refmeta>
<refentrytitle>repmgr node rejoin</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr node rejoin</refname>
<refpurpose>rejoin a dormant (stopped) node to the replication cluster</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
Enables a dormant (stopped) node to be rejoined to the replication cluster.
</para>
<para>
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.
</para>
<tip>
<para>
If the node is running and needs to be attached to the current primary, use
<xref linkend="repmgr-standby-follow">.
</para>
<para>
Note <xref linkend="repmgr-standby-follow"> can only be used for standbys which have not diverged
from the rest of the cluster.
</para>
</tip>
</refsect1>
<refsect1>
<title>Usage</title>
<para>
<programlisting>
repmgr node rejoin -d '$conninfo'</programlisting>
where <literal>$conninfo</literal> is the conninfo string of any reachable node in the cluster.
<filename>repmgr.conf</filename> for the stopped node *must* be supplied explicitly if not
otherwise available.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--dry-run</option></term>
<listitem>
<para>
Check prerequisites but don't actually execute the rejoin.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--force-rewind[=/path/to/pg_rewind]</option></term>
<listitem>
<para>
Execute <application>pg_rewind</application>.
</para>
<para>
It is only necessary to provide the <application>pg_rewind</application> path
if using PostgreSQL 9.3 or 9.4, and <application>pg_rewind</application>
is not installed in the PostgreSQL <filename>bin</filename> directory.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--config-files</option></term>
<listitem>
<para>
comma-separated list of configuration files to retain after
executing <application>pg_rewind</application>.
</para>
<para>
Currently <application>pg_rewind</application> will overwrite
the local node's configuration files with the files from the source node,
so it's advisable to use this option to ensure they are kept.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--config-archive-dir</option></term>
<listitem>
<para>
Directory to temporarily store configuration files specified with
<option>--config-files</option>; default: <filename>/tmp</filename>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-W/--no-wait</option></term>
<listitem>
<para>
Don't wait for the node to rejoin cluster.
</para>
<para>
If this option is supplied, &repmgr; will restart the node but
not wait for it to connect to the primary.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Configuration file settings</title>
<para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<literal>node_rejoin_timeout</literal>:
the maximum length of time (in seconds) to wait for
the node to reconnect to the replication cluster (defaults to
the value set in <literal>standby_reconnect_timeout</literal>,
60 seconds).
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1 id="repmgr-node-rejoin-events">
<title>Event notifications</title>
<para>
A <literal>node_rejoin</literal> <link linkend="event-notifications">event notification</link> will be generated.
</para>
</refsect1>
<refsect1>
<title>Notes</title>
<para>
Currently <command>repmgr node rejoin</command> can only be used to attach
a standby to the current primary, not another standby.
</para>
<para>
The node must have been shut down cleanly; if this was not the case, it will
need to be manually started (remove any existing <filename>recovery.conf</filename> file first)
until it has reached a consistent recovery point, then shut down cleanly.
</para>
<tip>
<para>
If <application>PostgreSQL</application> is started in single-user mode and
input is directed from <filename>/dev/null/</filename>, it will perform recovery
then immediately quit, and will then be in a state suitable for use by
<application>pg_rewind</application>.
<programlisting>
rm -f /var/lib/pgsql/data/recovery.conf
postgres --single -D /var/lib/pgsql/data/ &lt; /dev/null</programlisting>
</para>
</tip>
</refsect1>
<refsect1 id="repmgr-node-rejoin-pg-rewind" xreflabel="Using pg_rewind">
<indexterm>
<primary>pg_rewind</primary>
<secondary>using with "repmgr node rejoin"</secondary>
</indexterm>
<title>Using <command>pg_rewind</command></title>
<para>
<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.
<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>
<note>
<para>
<command>pg_rewind</command> <emphasis>requires</emphasis> that either
<varname>wal_log_hints</varname> is enabled, or that
data checksums were enabled when the cluster was initialized. See the
<ulink url="https://www.postgresql.org/docs/current/static/app-pgrewind.html"><command>pg_rewind</command> documentation</ulink> for details.
</para>
</note>
<para>
To have <command>repmgr node rejoin</command> use <command>pg_rewind</command>,
pass the command line option <literal>--force-rewind</literal>, which will tell &repmgr;
to execute <command>pg_rewind</command> to ensure the node can be rejoined successfully.
</para>
<para>
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
overwritten with those from the source server.
</para>
<para>
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
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
complete.
</para>
<para>
Example, first using <literal>--dry-run</literal>, then actually executing the
<literal>node rejoin command</literal>.
<programlisting>
$ repmgr node rejoin -f /etc/repmgr.conf -d 'host=node1 dbname=repmgr user=repmgr' \
--force-rewind --config-files=postgresql.local.conf,postgresql.conf --verbose --dry-run
NOTICE: using provided configuration file "/etc/repmgr.conf"
INFO: prerequisites for using pg_rewind are met
INFO: file "postgresql.local.conf" would be copied to "/tmp/repmgr-config-archive-node1/postgresql.local.conf"
INFO: file "postgresql.conf" would be copied to "/tmp/repmgr-config-archive-node1/postgresql.local.conf"
INFO: 2 files would have been copied to "/tmp/repmgr-config-archive-node1"
INFO: directory "/tmp/repmgr-config-archive-node1" deleted
INFO: pg_rewind would now be executed
DETAIL: pg_rewind command is:
pg_rewind -D '/var/lib/postgresql/data' --source-server='host=node1 dbname=repmgr user=repmgr'</programlisting>
<note>
<para>
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 cannot
predict the outcome of actually executing <application>pg_rewind</application>.
</para>
</note>
<programlisting>
$ repmgr node rejoin -f /etc/repmgr.conf -d 'host=node1 dbname=repmgr user=repmgr' \
--force-rewind --config-files=postgresql.local.conf,postgresql.conf --verbose
NOTICE: using provided configuration file "/etc/repmgr.conf"
INFO: prerequisites for using pg_rewind are met
INFO: 2 files copied to "/tmp/repmgr-config-archive-node1"
NOTICE: executing pg_rewind
NOTICE: 2 files copied to /var/lib/pgsql/data
INFO: directory "/tmp/repmgr-config-archive-node1" deleted
INFO: deleting "recovery.done"
INFO: setting node 1's primary to node 2
NOTICE: starting server using "pg_ctl-l /var/log/postgres/startup.log -w -D '/var/lib/pgsql/data' start"
waiting for server to start.... done
server started
NOTICE: NODE REJOIN successful
DETAIL: node 1 is now attached to node 2</programlisting>
</para>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-standby-follow">
</para>
</refsect1>
</refentry>

View File

@@ -1,389 +0,0 @@
<refentry id="repmgr-node-rejoin">
<indexterm>
<primary>repmgr node rejoin</primary>
</indexterm>
<refmeta>
<refentrytitle>repmgr node rejoin</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr node rejoin</refname>
<refpurpose>rejoin a dormant (stopped) node to the replication cluster</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
Enables a dormant (stopped) node to be rejoined to the replication cluster.
</para>
<para>
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.
</para>
<tip>
<para>
If the node is running and needs to be attached to the current primary, use
<xref linkend="repmgr-standby-follow"/>.
</para>
<para>
Note <xref linkend="repmgr-standby-follow"/> can only be used for standbys which have not diverged
from the rest of the cluster.
</para>
</tip>
</refsect1>
<refsect1>
<title>Usage</title>
<para>
<programlisting>
repmgr node rejoin -d '$conninfo'</programlisting>
where <literal>$conninfo</literal> is the conninfo string of any reachable node in the cluster.
<filename>repmgr.conf</filename> for the stopped node *must* be supplied explicitly if not
otherwise available.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--dry-run</option></term>
<listitem>
<para>
Check prerequisites but don't actually execute the rejoin.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--force-rewind[=/path/to/pg_rewind]</option></term>
<listitem>
<para>
Execute <application>pg_rewind</application>.
</para>
<para>
It is only necessary to provide the <application>pg_rewind</application> path
if using PostgreSQL 9.3 or 9.4, and <application>pg_rewind</application>
is not installed in the PostgreSQL <filename>bin</filename> directory.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--config-files</option></term>
<listitem>
<para>
comma-separated list of configuration files to retain after
executing <application>pg_rewind</application>.
</para>
<para>
Currently <application>pg_rewind</application> will overwrite
the local node's configuration files with the files from the source node,
so it's advisable to use this option to ensure they are kept.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--config-archive-dir</option></term>
<listitem>
<para>
Directory to temporarily store configuration files specified with
<option>--config-files</option>; default: <filename>/tmp</filename>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-W/--no-wait</option></term>
<listitem>
<para>
Don't wait for the node to rejoin cluster.
</para>
<para>
If this option is supplied, &repmgr; will restart the node but
not wait for it to connect to the primary.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Configuration file settings</title>
<para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<literal>node_rejoin_timeout</literal>:
the maximum length of time (in seconds) to wait for
the node to reconnect to the replication cluster (defaults to
the value set in <literal>standby_reconnect_timeout</literal>,
60 seconds).
</simpara>
<simpara>
Note that <literal>standby_reconnect_timeout</literal> must be
set to a value equal to or greater than
<literal>node_rejoin_timeout</literal>.
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1 id="repmgr-node-rejoin-events">
<title>Event notifications</title>
<para>
A <literal>node_rejoin</literal> <link linkend="event-notifications">event notification</link> will be generated.
</para>
</refsect1>
<refsect1>
<title>Exit codes</title>
<para>
One of the following exit codes will be emitted by <command>repmgr node rejoin</command>:
</para>
<variablelist>
<varlistentry>
<term><option>SUCCESS (0)</option></term>
<listitem>
<para>
The node rejoin succeeded; or if <option>--dry-run</option> was provided,
no issues were detected which would prevent the node rejoin.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_BAD_CONFIG (1)</option></term>
<listitem>
<para>
A configuration issue was detected which prevented &repmgr; from
continuing with the node rejoin.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_NO_RESTART (4)</option></term>
<listitem>
<para>
The node could not be restarted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_REJOIN_FAIL (24)</option></term>
<listitem>
<para>
The node rejoin operation failed.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Notes</title>
<para>
Currently <command>repmgr node rejoin</command> can only be used to attach
a standby to the current primary, not another standby.
</para>
<para>
The node must have been shut down cleanly; if this was not the case, it will
need to be manually started (remove any existing <filename>recovery.conf</filename> file first)
until it has reached a consistent recovery point, then shut down cleanly.
</para>
<tip>
<para>
If <application>PostgreSQL</application> is started in single-user mode and
input is directed from <filename>/dev/null/</filename>, it will perform recovery
then immediately quit, and will then be in a state suitable for use by
<application>pg_rewind</application>.
<programlisting>
rm -f /var/lib/pgsql/data/recovery.conf
postgres --single -D /var/lib/pgsql/data/ &lt; /dev/null</programlisting>
</para>
</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 id="repmgr-node-rejoin-pg-rewind" xreflabel="Using pg_rewind">
<title>Using <command>pg_rewind</command></title>
<indexterm>
<primary>pg_rewind</primary>
<secondary>using with "repmgr node rejoin"</secondary>
</indexterm>
<para>
<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.
<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>
<note>
<para>
<command>pg_rewind</command> <emphasis>requires</emphasis> that either
<varname>wal_log_hints</varname> is enabled, or that
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.
</para>
</note>
<para>
We strongly recommend familiarizing yourself with <command>pg_rewind</command> before attempting
to use it with &repmgr;, as while it is an extremely useful tool, it is <emphasis>not</emphasis>
a &quot;magic bullet&quot; which can resolve all problematic replication situations.
</para>
<para>
A typical use-case for <command>pg_rewind</command> is when a scenario like the following
is encountered:
<programlisting>
$ 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
INFO: replication connection to the rejoin target node was successful
INFO: local and rejoin target system identifiers match
DETAIL: system identifier is 6652184002263212600
ERROR: this node cannot attach to rejoin target node 3
DETAIL: rejoin target server's timeline 2 forked off current database system timeline 1 before current recovery point 0/610D710
HINT: use --force-rewind to execute pg_rewind</programlisting>
Here, <literal>node3</literal> was promoted to a primary while the local node was
still attached to the previous primary; this can potentially happen during e.g. a
network split. <command>pg_rewind</command> can re-sync the local node with <literal>node3</literal>,
removing the need for a full reclone.
</para>
<para>
To have <command>repmgr node rejoin</command> use <command>pg_rewind</command>,
pass the command line option <literal>--force-rewind</literal>, which will tell &repmgr;
to execute <command>pg_rewind</command> to ensure the node can be rejoined successfully.
</para>
<important>
<para>
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
overwritten with those from the source server.
</para>
<para>
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
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
complete.
</para>
</important>
<para>
Example, first using <literal>--dry-run</literal>, then actually executing the
<literal>node rejoin command</literal>.
<programlisting>
$ 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
INFO: replication connection to the rejoin target node was successful
INFO: local and rejoin target system identifiers match
DETAIL: system identifier is 6652460429293670710
NOTICE: pg_rewind execution required for this node to attach to rejoin target node 3
DETAIL: rejoin target server's timeline 2 forked off current database system timeline 1 before current recovery point 0/610D710
INFO: prerequisites for using pg_rewind are met
INFO: file "postgresql.local.conf" would be copied to "/tmp/repmgr-config-archive-node2/postgresql.local.conf"
INFO: file "postgresql.replication-setup.conf" would be copied to "/tmp/repmgr-config-archive-node2/postgresql.replication-setup.conf"
INFO: pg_rewind would now be executed
DETAIL: pg_rewind command is:
pg_rewind -D '/var/lib/postgresql/data' --source-server='host=node3 dbname=repmgr user=repmgr'
INFO: prerequisites for executing NODE REJOIN are met</programlisting>
<note>
<para>
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
not an absolute guarantee that actually executing <application>pg_rewind</application>
will succeed. See also section <xref linkend="repmgr-node-rejoin-caveats"/> below.
</para>
</note>
<programlisting>
$ repmgr node rejoin -f /etc/repmgr.conf -d 'host=node3 dbname=repmgr user=repmgr' \
--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
DETAIL: rejoin target server's timeline 2 forked off current database system timeline 1 before current recovery point 0/610D710
NOTICE: executing pg_rewind
DETAIL: pg_rewind command is "pg_rewind -D '/var/lib/postgresql/data' --source-server='host=node3 dbname=repmgr user=repmgr'"
NOTICE: 2 files copied to /var/lib/postgresql/data
NOTICE: setting node 2's upstream to node 3
NOTICE: starting server using "pg_ctl -l /var/log/postgres/startup.log -w -D '/var/lib/pgsql/data' start"
NOTICE: NODE REJOIN successful
DETAIL: node 2 is now attached to node 3</programlisting>
</para>
</refsect1>
<refsect1 id="repmgr-node-rejoin-caveats" xreflabel="Caveats">
<title>Caveats when using <command>repmgr node rejoin</command></title>
<indexterm>
<primary>repmgr node rejoin</primary>
<secondary>caveats</secondary>
</indexterm>
<para>
<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
(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
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.
</para>
<para>
Currently it is <emphasis>not</emphasis> possible to detect a situation where the rejoin target
is a standby which has been &quot;promoted&quot; by removing <filename>recovery.conf</filename>
(PostgreSQL 12 and later: <filename>standby.signal</filename>) and restarting it.
In this case there will be no information about the point the rejoin target diverged
from the current standby; the rejoin operation will fail and
the current standby's PostgreSQL log will contain entries with the text
&quot;<literal>record with incorrect prev-link</literal>&quot;.
</para>
<para>
We strongly recommend running <command>repmgr node rejoin</command> with the
<option>--dry-run</option> option first. Additionally it might be a good idea
to execute the <application>pg_rewind</application> command displayed by
&repmgr; with the <application>pg_rewind</application> <option>--dry-run</option>
option. Note that <application>pg_rewind</application> does not indicate that it
is running in <option>--dry-run</option> mode.
</para>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-standby-follow"/>
</para>
</refsect1>
</refentry>

View File

@@ -84,7 +84,7 @@
<refsect1> <refsect1>
<title>Exit codes</title> <title>Exit codes</title>
<para> <para>
One of the following exit codes will be emitted by <command>repmgr node service</command>: Following exit codes can be emitted by <command>repmgr node service</command>:
</para> </para>
<variablelist> <variablelist>

View File

@@ -55,7 +55,7 @@
<refsect1> <refsect1>
<title>Exit codes</title> <title>Exit codes</title>
<para> <para>
One of the following exit codes will be emitted by <command>repmgr node status</command>: Following exit codes can be emitted by <command>repmgr node status</command>:
</para> </para>
<variablelist> <variablelist>
@@ -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

@@ -21,15 +21,6 @@
installing the &repmgr; extension. This command needs to be executed before any installing the &repmgr; extension. This command needs to be executed before any
standby nodes are registered. standby nodes are registered.
</para> </para>
<note>
<para>
It's possibly to install the &repmgr; extension manually before executing
<command>repmgr primary register</command>; in this case &repmgr; will
detect the presence of the extension and skip that step.
</para>
</note>
</refsect1> </refsect1>
<refsect1> <refsect1>
@@ -38,25 +29,23 @@
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>
<note>
<para>
If providing the configuration file location with <option>-f/--config-file</option>,
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
<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>
<para>
<command>repmgr master register</command> can be used as an alias for <command>repmgr master register</command> can be used as an alias for
<command>repmgr primary register</command>. <command>repmgr primary register</command>.
</para> </para>
<note>
<para>
If providing the configuration file location with <option>-f/--config-file</option>,
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
<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>
</refsect1> </refsect1>
<refsect1> <refsect1>

View File

@@ -85,13 +85,12 @@
</refsect1> </refsect1>
<refsect1 id="repmgr-standby-clone-recovery-conf"> <refsect1 id="repmgr-standby-clone-recovery-conf">
<title>Customising recovery.conf</title> <indexterm>
<indexterm>
<primary>recovery.conf</primary> <primary>recovery.conf</primary>
<secondary>customising with &quot;repmgr standby clone&quot;</secondary> <secondary>customising with "repmgr standby clone"</secondary>
</indexterm> </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 <filename>recovery.conf</filename>
containing following parameters: containing following parameters:
@@ -143,7 +142,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>
@@ -155,7 +154,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>--wal-method</literal> &repmgr; will set <command>pg_basebackup</command>'s <literal>--xlog-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
@@ -165,20 +164,21 @@
</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>--wal-method</literal> <command>pg_basebackup</command>'s <literal>--xlog-method</literal>
parameter to <literal>fetch</literal>: parameter to <literal>fetch</literal>:
<programlisting> <programlisting>
pg_basebackup_options='--wal-method=fetch'</programlisting> pg_basebackup_options='--xlog-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> is set to an appropriately high value.
See the <ulink url="https://www.postgresql.org/docs/current/app-pgbasebackup.html"> See the <ulink url="https://www.postgresql.org/docs/current/static/app-pgbasebackup.html">
pg_basebackup</ulink> documentation for details. pg_basebackup</ulink> documentation for details.
</para> </para>
<note> <note>
<simpara> <simpara>
If using PostgreSQL 9.6 or earlier, replace <literal>--wal-method</literal> From PostgreSQL 10, <command>pg_basebackup</command>'s
with <literal>--xlog-method</literal>. <literal>--xlog-method</literal> parameter has been renamed to
<literal>--wal-method</literal>.
</simpara> </simpara>
</note> </note>
</refsect1> </refsect1>
@@ -186,20 +186,18 @@
<refsect1 id="repmgr-standby-create-recovery-conf"> <refsect1 id="repmgr-standby-create-recovery-conf">
<title>Using a standby cloned by another method</title>
<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="http://docs.pgbarman.org/release/2.4/#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, 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>. Then execute the command <command>repmgr standby clone --recovery-conf-only</command>.
@@ -297,7 +295,7 @@
<term><option> --recovery-conf-only</option></term> <term><option> --recovery-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 <filename>recovery.conf</filename> file for a previously cloned instance. &repmgr 4.0.4 and later.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -326,13 +324,9 @@
<term><option>--upstream-conninfo</option></term> <term><option>--upstream-conninfo</option></term>
<listitem> <listitem>
<para> <para>
<literal>primary_conninfo</literal> value to write in <filename>recovery.conf</filename> <literal>primary_conninfo</literal> value to write in recovery.conf
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>
@@ -366,7 +360,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

@@ -0,0 +1,116 @@
<refentry id="repmgr-standby-follow">
<indexterm>
<primary>repmgr standby follow</primary>
</indexterm>
<refmeta>
<refentrytitle>repmgr standby follow</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr standby follow</refname>
<refpurpose>attach a standby to a new primary</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
Attaches the standby to a new primary. 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>
This command will force a restart of the standby server, which must be
running. It can only be used to attach an active standby to the current primary node
(and not to another standby).
</para>
<tip>
<para>
To re-add an inactive node to the replication cluster, use
<xref linkend="repmgr-node-rejoin">.
</para>
</tip>
<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 primary.
</para>
</refsect1>
<refsect1>
<title>Example</title>
<para>
<programlisting>
$ repmgr -f /etc/repmgr.conf standby follow
INFO: setting node 3's primary to node 2
NOTICE: restarting server using "pg_ctl -l /var/log/postgres/startup.log -w -D '/var/lib/postgres/data' restart"
waiting for server to shut down........ done
server stopped
waiting for server to start.... done
server started
NOTICE: STANDBY FOLLOW successful
DETAIL: node 3 is now attached to node 2</programlisting>
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--dry-run</option></term>
<listitem>
<para>
Check prerequisites but don't actually follow a new standby.
</para>
<important>
<para>
This does not guarantee the standby can follow the primary; in
particular, whether the primary and standby timelines have diverged,
can currently only be determined by actually attempting to
attach the standby to the primary.
</para>
</important>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-w</option></term>
<term><option>--wait</option></term>
<listitem>
<para>
Wait for a primary to appear. &repmgr; will wait for up to
<varname>primary_follow_timeout</varname> seconds
(default: 60 seconds) to verify that the standby is following the new primary.
This value can be defined in <filename>repmgr.conf</filename>.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="repmgr-standby-follow-events">
<title>Event notifications</title>
<para>
A <literal>standby_follow</literal> <link linkend="event-notifications">event notification</link> will be generated.
</para>
<para>
If provided, &repmgr; will substitute the placeholders <literal>%p</literal> with the node ID of the primary
being followed, <literal>%c</literal> with its <literal>conninfo</literal> string, and
<literal>%a</literal> with its node name.
</para>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-node-rejoin">
</para>
</refsect1>
</refentry>

View File

@@ -1,258 +0,0 @@
<refentry id="repmgr-standby-follow">
<indexterm>
<primary>repmgr standby follow</primary>
</indexterm>
<refmeta>
<refentrytitle>repmgr standby follow</refentrytitle>
</refmeta>
<refnamediv>
<refname>repmgr standby follow</refname>
<refpurpose>attach a running standby to a new upstream node</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
Attaches the standby (&quot;follow candidate&quot;) to a new upstream node
(&quot;follow target&quot;). Typically this will be the primary, but this
command can also be used to attach the standby to another standby.
</para>
<para>
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>
By default &repmgr; will attempt to attach the standby to the current primary.
If <option>--upstream-node-id</option> is provided, &repmgr; will attempt
to attach the standby to the specified node, which can be another standby.
</para>
<para>
This command will force a restart of the standby server, which must be
running.
</para>
<tip>
<para>
To re-add an inactive node to the replication cluster, use
<xref linkend="repmgr-node-rejoin"/>.
</para>
</tip>
<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>
<title>Example</title>
<para>
<programlisting>
$ repmgr -f /etc/repmgr.conf standby follow
INFO: setting node 3's primary to node 2
NOTICE: restarting server using "pg_ctl -l /var/log/postgres/startup.log -w -D '/var/lib/postgres/data' restart"
waiting for server to shut down........ done
server stopped
waiting for server to start.... done
server started
NOTICE: STANDBY FOLLOW successful
DETAIL: node 3 is now attached to node 2</programlisting>
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>--dry-run</option></term>
<listitem>
<para>
Check prerequisites but don't actually follow a new upstream node.
</para>
<para>
This will also verify whether the standby is capable of following the new upstream node.
</para>
<important>
<para>
If a standby was turned into a primary by removing <filename>recovery.conf</filename>
(<application>PostgreSQL 12</application> and later: <filename>standby.signal</filename>),
&repmgr; will <emphasis>not</emphasis> be able to determine whether that primary's timeline
has diverged from the timeline of the standby (&quot;follow candidate&quot;).
</para>
<para>
We recommend always to use <link linkend="repmgr-standby-promote"><command>repmgr standby promote</command></link>
to promote a standby to primary, as this will ensure that the new primary
will perform a timeline switch (making it practical to check for timeline divergence)
and also that &repmgr; metadata is updated correctly.
</para>
</important>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--upstream-node-id</option></term>
<listitem>
<para>
Node ID of the new upstream node (&quot;follow target&quot;).
</para>
<para>
If not provided, &repmgr; will attempt to follow the current primary node.
</para>
<para>
Note that when using &repmgrd;, <option>--upstream-node-id</option>
should always be configured;
see <link linkend="repmgrd-automatic-failover-configuration">Automatic failover configuration</link>
for details.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-w</option></term>
<term><option>--wait</option></term>
<listitem>
<para>
Wait for a primary to appear. &repmgr; will wait for up to
<varname>primary_follow_timeout</varname> seconds
(default: 60 seconds) to verify that the standby is following the new primary.
This value can be defined in <filename>repmgr.conf</filename>.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Execution</title>
<para>
Execute with the <literal>--dry-run</literal> option to test the follow operation as
far as possible, without actually changing the status of the node.
</para>
<para>
Note that &repmgr; will first attempt to determine whether the standby
(&quot;follow candidate&quot;) is capable of following the
new upstream node (&quot;follow target&quot;).
</para>
<para>
If, for example, the new upstream node has diverged from this node's timeline,
for example if the new upstream node was promoted to primary while this node
was still attached to the original primary, it will <emphasis>not</emphasis>
be possible to follow the new upstream node, and &repmgr; will emit an error
message like this:
<programlisting>
ERROR: this node cannot attach to follow target node 3
DETAIL: follow target server's timeline 2 forked off current database system timeline 1 before current recovery point 0/6108880</programlisting>
</para>
<para>
In this case, it may be possible to have this node follow the new upstream
using <command><link linkend="repmgr-node-rejoin">repmgr node rejoin</link></command>
with the <option>--force-rewind</option> to execute <command>pg_rewind</command>.
This does mean that transactions which exist on this node, but not the new upstream,
will be lost.
</para>
</refsect1>
<refsect1>
<title>Exit codes</title>
<para>
One of the following exit codes will be emitted by <command>repmgr standby follow</command>:
</para>
<variablelist>
<varlistentry>
<term><option>SUCCESS (0)</option></term>
<listitem>
<para>
The follow operation succeeded; or if <option>--dry-run</option> was provided,
no issues were detected which would prevent the follow operation.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_BAD_CONFIG (1)</option></term>
<listitem>
<para>
A configuration issue was detected which prevented &repmgr; from
continuing with the follow operation.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_NO_RESTART (4)</option></term>
<listitem>
<para>
The node could not be restarted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_DB_CONN (6)</option></term>
<listitem>
<para>
&repmgr; was unable to establish a database connection to one of the nodes.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ERR_FOLLOW_FAIL (23)</option></term>
<listitem>
<para>
&repmgr; was unable to complete the follow command.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="repmgr-standby-follow-events">
<title>Event notifications</title>
<para>
A <literal>standby_follow</literal> <link linkend="event-notifications">event notification</link> will be generated.
</para>
<para>
If provided, &repmgr; will substitute the placeholders <literal>%p</literal> with the node ID of the node
being followed, <literal>%c</literal> with its <literal>conninfo</literal> string, and
<literal>%a</literal> with its node name.
</para>
</refsect1>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-node-rejoin"/>
</para>
</refsect1>
</refentry>

View File

@@ -0,0 +1,60 @@
<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>
</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 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

@@ -1,254 +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>
<important>
<para>
If &repmgrd; is active, you must execute
<command><link linkend="repmgr-daemon-pause">repmgr daemon 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>
<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>
<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>
</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

@@ -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 &repmgrd; to work with the node. promote/follow operations and to allow <application>repmgrd</application> 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
&repmgrd;) require that the standby's node record <application>repmgrd</application>) 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>

View File

@@ -22,13 +22,11 @@
passwordless SSH connection to the current primary. passwordless SSH connection to the current primary.
</para> </para>
<para> <para>
If other nodes are connected to the demotion candidate, &repmgr; can instruct If other standbys are connected to the demotion candidate, &repmgr; can instruct
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 standbys attached to the demotion candidate
(existing primary). Note that a witness server, if in use, is also (existing primary).
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>
@@ -39,23 +37,23 @@
</para> </para>
<para> <para>
&repmgr; will refuse to perform the switchover if an exclusive backup is running on &repmgr; will refuse to perform the switchover if an exclusive backup is running on
the current primary, or if WAL replay is paused on the standby. the current primary.
</para> </para>
</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
&repmgrd; instances to pause operations while the switchover <application>repmgrd</application> instances to pause operations while the switchover
is being carried out, to prevent &repmgrd; from is being carried out, to prevent <application>repmgrd</application> 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 &repmgrd; Users of &repmgr; versions prior to 4.2 should ensure that <application>repmgrd</application>
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>
@@ -117,7 +115,7 @@
(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> If using PostgreSQL 9.3 or 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">.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -136,52 +134,23 @@
<term><option>--repmgrd-no-pause</option></term> <term><option>--repmgrd-no-pause</option></term>
<listitem> <listitem>
<para> <para>
Don't pause &repmgrd; while executing a switchover. Don't pause <application>repmgrd</application> 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 &repmgrd; is paused or not to ensure <application>repmgrd</application> 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>
<varlistentry> <varlistentry>
<term><option>--siblings-follow</option></term> <term><option>--siblings-follow</option></term>
<listitem> <listitem>
<para> <para>
Have nodes attached to the old primary follow the new primary. Have standbys attached to the old primary follow the new primary.
</para> </para>
<para>
This will also ensure that a witness node, if in use, is updated
with the new primary's data.
</para>
<note>
<para>
In a future &repmgr; release, <option>--siblings-follow</option> will be applied
by default.
</para>
</note>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
@@ -192,47 +161,29 @@
<title>Configuration file settings</title> <title>Configuration file settings</title>
<para> <para>
The following parameters in <filename>repmgr.conf</filename> are relevant to the Note that following parameters in <filename>repmgr.conf</filename> are relevant to the
switchover operation: switchover operation:
</para> <itemizedlist spacing="compact" mark="bullet">
<variablelist> <listitem>
<simpara>
<literal>replication_lag_critical</literal>:
if replication lag (in seconds) on the standby exceeds this value, the
switchover will be aborted (unless the <literal>-F/--force</literal> option
is provided)
</simpara>
</listitem>
<varlistentry> <listitem>
<term><option>replication_lag_critical</option></term> <simpara>
<listitem> <literal>shutdown_check_timeout</literal>: maximum number of seconds to wait for the
demotion candidate (current primary) to shut down, before aborting the switchover.
<indexterm> </simpara>
<primary>replication_lag_critical</primary> <simpara>
<secondary>with &quot;repmgr standby switchover&quot;</secondary> Note that this parameter is set on the node where <command>repmgr standby switchover</command>
</indexterm> is executed (promotion candidate); setting it on the demotion candidate (former primary) will
have no effect.
<para> </simpara>
If replication lag (in seconds) on the standby exceeds this value, the
switchover will be aborted (unless the <literal>-F/--force</literal> option
is provided)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>shutdown_check_timeout</option></term>
<listitem>
<indexterm>
<primary>shutdown_check_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para>
The maximum number of seconds to wait for the
demotion candidate (current primary) to shut down, before aborting the switchover.
</para>
<para>
Note that this parameter is set on the node where <command>repmgr standby switchover</command>
is executed (promotion candidate); setting it on the demotion candidate (former primary) will
have no effect.
</para>
<note> <note>
<para> <para>
In versions prior to <link linkend="release-4.2">&repmgr; 4.2</link>, <command>repmgr standby switchover</command> would In versions prior to <link linkend="release-4.2">&repmgr; 4.2</link>, <command>repmgr standby switchover</command> would
@@ -240,76 +191,18 @@
to determine the timeout for demotion candidate shutdown. to determine the timeout for demotion candidate shutdown.
</para> </para>
</note> </note>
</listitem> </listitem>
</varlistentry>
<listitem>
<simpara>
<literal>standby_reconnect_timeout</literal>:
maximum number of seconds to attempt to wait for the demotion candidate (former primary)
to reconnect to the promoted primary (default: 60 seconds)
</simpara>
</listitem>
<varlistentry> </itemizedlist>
<term><option>wal_receive_check_timeout</option></term> </para>
<listitem>
<indexterm>
<primary>wal_receive_check_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para>
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
with the primary's shut down location.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>standby_reconnect_timeout</option></term>
<listitem>
<indexterm>
<primary>standby_reconnect_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para>
The maximum number of seconds to attempt to wait for the demotion candidate (former primary)
to reconnect to the promoted primary (default: 60 seconds)
</para>
<para>
Note that this parameter is set on the node where <command>repmgr standby switchover</command>
is executed (promotion candidate); setting it on the demotion candidate (former primary) will
have no effect.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>node_rejoin_timeout</option></term>
<listitem>
<indexterm>
<primary>node_rejoin_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para>
maximum number of seconds to attempt to wait for the demotion candidate (former primary)
to reconnect to the promoted primary (default: 60 seconds)
</para>
<para>
Note that this parameter is set on the the demotion candidate (former primary);
setting it on the node where <command>repmgr standby switchover</command> is
executed will have no effect.
</para>
<para>
However, this value <emphasis>must</emphasis> be less than <option>standby_reconnect_timeout</option> on the
promotion candidate (the node where <command>repmgr standby switchover</command> is executed).
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1> </refsect1>
@@ -345,7 +238,7 @@
<refsect1> <refsect1>
<title>Exit codes</title> <title>Exit codes</title>
<para> <para>
One of the following exit codes will be emitted by <command>repmgr standby switchover</command>: Following exit codes can be emitted by <command>repmgr standby switchover</command>:
</para> </para>
<variablelist> <variablelist>
@@ -353,8 +246,7 @@
<term><option>SUCCESS (0)</option></term> <term><option>SUCCESS (0)</option></term>
<listitem> <listitem>
<para> <para>
The switchover completed successfully; or if <option>--dry-run</option> was provided, The switchover completed successfully.
no issues were detected which would prevent the switchover operation.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -385,10 +277,7 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-standby-follow"/>, <xref linkend="repmgr-node-rejoin"/> For more details see the section <xref linkend="performing-switchover">.
</para>
<para>
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 &repmgrd;. use of the witness server with <application>repmgrd</application>.
</para> </para>
<para> <para>
When executing <command>repmgr witness register</command>, database connection When executing <command>repmgr witness register</command>, database connection
@@ -34,14 +34,6 @@
witness node's <filename>repmgr.conf</filename>, unless these are explicitly witness node's <filename>repmgr.conf</filename>, unless these are explicitly
provided as command line options. provided as command line options.
</para> </para>
<note>
<para>
The primary server must be registered with <command><link linkend="repmgr-primary-register">repmgr primary register</link></command> before the witness
server can be registered.
</para>
</note>
<para> <para>
Execute with the <option>--dry-run</option> option to check what would happen Execute with the <option>--dry-run</option> option to check what would happen
without actually registering the witness server. without actually registering the witness server.

View File

@@ -1,16 +1,14 @@
<!-- doc/repmgr.xml --> <!-- doc/src/sgml/postgres.sgml -->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook 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.xml"> <!ENTITY % filelist SYSTEM "filelist.sgml">
%filelist; %filelist;
<!ENTITY repmgr "<productname>repmgr</productname>"> <!ENTITY repmgr "<productname>repmgr</productname>">
<!ENTITY repmgrd "<productname>repmgrd</productname>">
<!ENTITY postgres "<productname>PostgreSQL</productname>"> <!ENTITY postgres "<productname>PostgreSQL</productname>">
]> ]>
@@ -33,25 +31,25 @@
latest version. Please check the latest version. Please check the
<ulink url="https://repmgr.org/">repmgr website</ulink> for details <ulink url="https://repmgr.org/">repmgr website</ulink> for details
about the current &repmgr; version as well as the about the current &repmgr; version as well as the
<ulink url="https://repmgr.org/docs/current/index.html">current repmgr documentation</ulink>. <ulink url="https://repmgr.org/docs/current/index.html">current documentation</ulink>.
</para> </para>
<para> <para>
&repmgr; is developed by &repmgr; was developed by
<ulink url="https://2ndquadrant.com">2ndQuadrant</ulink> <ulink url="https://2ndquadrant.com">2ndQuadrant</ulink>
along with contributions from other individuals and organisations. along with contributions from other individuals and companies.
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/2ndQuadrant/repmgr">github</>
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</>.
Multiple 2ndQuadrant customers contribute funding Multiple 2ndQuadrant customers contribute funding
to make repmgr development possible. to make repmgr development possible.
</para> </para>
<para> <para>
&repmgr; is fully supported by 2ndQuadrant's 2ndQuadrant, a Platinum sponsor of the PostgreSQL project,
<ulink url="https://www.2ndquadrant.com/en/support/support-postgresql/">24/7 Production Support</ulink>. continues to develop repmgr to meet internal needs and those of customers.
2ndQuadrant, a Major Sponsor of the PostgreSQL project, continues to develop and maintain &repmgr;. Other companies as well as individual developers
Other organisations as well as individual developers are welcome to participate in the efforts. are welcome to participate in the efforts.
</para> </para>
</abstract> </abstract>
@@ -81,16 +79,22 @@
&promoting-standby; &promoting-standby;
&follow-new-primary; &follow-new-primary;
&switchover; &switchover;
&configuring-witness-server;
&event-notifications; &event-notifications;
&upgrading-repmgr; &upgrading-repmgr;
</part> </part>
<part id="using-repmgrd"> <part id="using-repmgrd">
<title>Using repmgrd</title> <title>Using repmgrd</title>
&repmgrd-overview;
&repmgrd-automatic-failover; &repmgrd-automatic-failover;
&repmgrd-configuration; &repmgrd-configuration;
&repmgrd-operation; &repmgrd-demonstration;
&repmgrd-cascading-replication;
&repmgrd-network-split;
&repmgrd-witness-server;
&repmgrd-pausing;
&repmgrd-degraded-monitoring;
&repmgrd-monitoring;
&repmgrd-bdr; &repmgrd-bdr;
</part> </part>
@@ -117,8 +121,6 @@
&repmgr-cluster-event; &repmgr-cluster-event;
&repmgr-cluster-cleanup; &repmgr-cluster-cleanup;
&repmgr-daemon-status; &repmgr-daemon-status;
&repmgr-daemon-start;
&repmgr-daemon-stop;
&repmgr-daemon-pause; &repmgr-daemon-pause;
&repmgr-daemon-unpause; &repmgr-daemon-unpause;
</part> </part>
@@ -127,8 +129,8 @@
&appendix-signatures; &appendix-signatures;
&appendix-faq; &appendix-faq;
&appendix-packages; &appendix-packages;
&appendix-support;
<index id="bookindex"></index> <![%include-index;[&bookindex;]]>
<![%include-xslt-index;[<index id="bookindex"></index>]]>
</book> </book>

View File

@@ -0,0 +1,17 @@
<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>
</chapter>

View File

@@ -1,925 +0,0 @@
<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>
&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
&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 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-daemon-status"><command>repmgr daemon status</command></link>,
which includes this in its output, e.g.:
<programlisting>$ repmgr -f /etc/repmgr.conf daemon 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>
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 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
&repmgrd; proceeds with the failover decision.
</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 %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 &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 follwing 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,6 +1,4 @@
<chapter id="repmgrd-bdr"> <chapter id="repmgrd-bdr">
<title>BDR failover with repmgrd</title>
<indexterm> <indexterm>
<primary>repmgrd</primary> <primary>repmgrd</primary>
<secondary>BDR</secondary> <secondary>BDR</secondary>
@@ -10,6 +8,7 @@
<primary>BDR</primary> <primary>BDR</primary>
</indexterm> </indexterm>
<title>BDR failover with repmgrd</title>
<para> <para>
&repmgr; 4.x provides support for monitoring a pair of BDR 2.x nodes and taking action in &repmgr; 4.x provides support for monitoring a pair of BDR 2.x nodes and taking action in
case one of the nodes fails. case one of the nodes fails.
@@ -25,10 +24,10 @@
<para> <para>
In contrast to streaming replication, there's no concept of "promoting" a new In contrast to streaming replication, there's no concept of "promoting" a new
primary node with BDR. Instead, "failover" involves monitoring both nodes primary node with BDR. Instead, "failover" involves monitoring both nodes
with &repmgrd; and redirecting queries from the failed node to the remaining with <application>repmgrd</application> and redirecting queries from the failed node to the remaining
active node. This can be done by using an active node. This can be done by using an
<link linkend="event-notifications">event notification</link> script <link linkend="event-notifications">event notification</link> script
which is called by &repmgrd; to dynamically which is called by <application>repmgrd</application> to dynamically
reconfigure a proxy server/connection pooler such as <application>PgBouncer</application>. reconfigure a proxy server/connection pooler such as <application>PgBouncer</application>.
</para> </para>
@@ -61,7 +60,7 @@
<para> <para>
Application database connections *must* be passed through a proxy server/ Application database connections *must* be passed through a proxy server/
connection pooler such as <application>PgBouncer</application>, and it must be possible to dynamically connection pooler such as <application>PgBouncer</application>, and it must be possible to dynamically
reconfigure that from &repmgrd;. The example demonstrated in this document reconfigure that from <application>repmgrd</application>. The example demonstrated in this document
will use <application>PgBouncer</application> will use <application>PgBouncer</application>
</para> </para>
<para> <para>
@@ -95,7 +94,7 @@
# Event notification configuration # Event notification configuration
event_notifications=bdr_failover event_notifications=bdr_failover
event_notification_command='/path/to/bdr-pgbouncer.sh %n %e %s "%c" "%a" >> /tmp/bdr-failover.log 2>&amp;1' event_notification_command='/path/to/bdr-pgbouncer.sh %n %e %s "%c" "%a" >> /tmp/bdr-failover.log 2>&1'
# repmgrd options # repmgrd options
monitor_interval_secs=5 monitor_interval_secs=5
@@ -121,7 +120,7 @@
<simpara> <simpara>
<varname>event_notification_command</varname> is the script which does the actual "heavy lifting" <varname>event_notification_command</varname> is the script which does the actual "heavy lifting"
of reconfiguring the proxy server/ connection pooler. It is fully of reconfiguring the proxy server/ connection pooler. It is fully
user-definable; see section <xref linkend="bdr-event-notification-command"/> for a reference user-definable; see section <xref linkend="bdr-event-notification-command"> for a reference
implementation. implementation.
</simpara> </simpara>
</note> </note>
@@ -159,7 +158,7 @@
</important> </important>
<para> <para>
At this point the meta data for both nodes has been created; executing 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: <xref linkend="repmgr-cluster-show"> (on either node) should produce output like this:
<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
@@ -169,7 +168,7 @@
</para> </para>
<para> <para>
Additionally it's possible to display log of significant events; executing Additionally it's possible to display log of significant events; executing
<xref linkend="repmgr-cluster-event"/> (on either node) should produce output like this: <xref linkend="repmgr-cluster-event"> (on either node) should produce output like this:
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf cluster event $ repmgr -f /etc/repmgr.conf cluster event
Node ID | Event | OK | Timestamp | Details Node ID | Event | OK | Timestamp | Details
@@ -297,7 +296,7 @@
</listitem> </listitem>
<listitem> <listitem>
<simpara>recreates the <application>PgBouncer</application> configuration file on each <simpara>recreates the <application>PgBouncer</application> configuration file on each
node using the information provided by &repmgrd; node using the information provided by <application>repmgrd</application>
(primarily the <varname>conninfo</varname> string) to configure (primarily the <varname>conninfo</varname> string) to configure
<application>PgBouncer</application></simpara> <application>PgBouncer</application></simpara>
</listitem> </listitem>
@@ -319,21 +318,21 @@
<title>Node monitoring and failover</title> <title>Node monitoring and failover</title>
<para> <para>
At the intervals specified by <varname>monitor_interval_secs</varname> At the intervals specified by <varname>monitor_interval_secs</varname>
in <filename>repmgr.conf</filename>, &repmgrd; in <filename>repmgr.conf</filename>, <application>repmgrd</application>
will ping each node to check if it's available. If a node isn't available, will ping each node to check if it's available. If a node isn't available,
&repmgrd; will enter failover mode and check <varname>reconnect_attempts</varname> <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. 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 This buffer period is necessary to avoid false positives caused by transient
network outages. network outages.
</para> </para>
<para> <para>
If the node is still unavailable, &repmgrd; will enter failover mode and execute 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 the script defined in <varname>event_notification_command</varname>; an entry will be logged
in the <literal>repmgr.events</literal> table and &repmgrd; will 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. (unless otherwise configured) resume monitoring of the node in "degraded" mode until it reappears.
</para> </para>
<para> <para>
&repmgrd; logfile output during a failover event will look something like this <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>): on one node (usually the node which has failed, here <literal>node2</literal>):
<programlisting> <programlisting>
... ...
@@ -389,8 +388,8 @@
</para> </para>
<para> <para>
This assumes only the PostgreSQL instance on <literal>node2</literal> has failed. In this case the This assumes only the PostgreSQL instance on <literal>node2</literal> has failed. In this case the
&repmgrd; instance running on <literal>node2</literal> has performed the failover. However if <application>repmgrd</application> instance running on <literal>node2</literal> has performed the failover. However if
the entire server becomes unavailable, &repmgrd; on <literal>node1</literal> will perform the entire server becomes unavailable, <application>repmgrd</application> on <literal>node1</literal> will perform
the failover. the failover.
</para> </para>
</sect1> </sect1>
@@ -405,7 +404,7 @@
</para> </para>
<para> <para>
If the failed node comes back up and connects correctly, output similar to this If the failed node comes back up and connects correctly, output similar to this
will be visible in the &repmgrd; log: will be visible in the <application>repmgrd</application> log:
<programlisting> <programlisting>
[2017-07-27 21:25:30] [DETAIL] monitoring node "node2" (ID: 2) in degraded mode [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] [INFO] monitoring BDR replication status on node "node2" (ID: 2)
@@ -418,10 +417,10 @@
<sect1 id="bdr-complete-shutdown" xreflabel="Shutdown of both nodes"> <sect1 id="bdr-complete-shutdown" xreflabel="Shutdown of both nodes">
<title>Shutdown of both nodes</title> <title>Shutdown of both nodes</title>
<para> <para>
If both PostgreSQL instances are shut down, &repmgrd; will try and handle the 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 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 there's not much it can do. Should this case ever occur, we recommend shutting
down &repmgrd; on both nodes and restarting it once the PostgreSQL instances down <application>repmgrd</application> on both nodes and restarting it once the PostgreSQL instances
are running properly. are running properly.
</para> </para>
</sect1> </sect1>

View File

@@ -0,0 +1,22 @@
<chapter id="repmgrd-cascading-replication">
<indexterm>
<primary>repmgrd</primary>
<secondary>cascading replication</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 "cascaded standby" will attempt to reconnect to that node's parent.
</para>
</chapter>

View File

@@ -0,0 +1,554 @@
<chapter id="repmgrd-configuration">
<indexterm>
<primary>repmgrd</primary>
<secondary>configuration</secondary>
</indexterm>
<title>repmgrd configuration</title>
<para>
<application>repmgrd</application> is a daemon which runs on each PostgreSQL node,
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
connected to.
</para>
<para>
<application>repmgrd</application> can be configured to provide failover
capability in case the primary upstream node becomes unreachable, and/or
provide monitoring data to the &repmgr; metadatabase.
</para>
<sect1 id="repmgrd-basic-configuration">
<title>repmgrd basic configuration</title>
<para>
To use <application>repmgrd</application>, its associated function library <emphasis>must</emphasis> be
included via <filename>postgresql.conf</filename> with:
<programlisting>
shared_preload_libraries = 'repmgr'</programlisting>
</para>
<para>
Changing this setting requires a restart of PostgreSQL; for more details see
the <ulink url="https://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">PostgreSQL documentation</ulink>.
</para>
<sect2 id="repmgrd-automatic-failover-configuration">
<title>automatic failover configuration</title>
<para>
If using automatic failover, the following <application>repmgrd</application> options *must* be set in
<filename>repmgr.conf</filename> :
<programlisting>
failover=automatic
promote_command='/usr/bin/repmgr standby promote -f /etc/repmgr.conf --log-to-file'
follow_command='/usr/bin/repmgr standby follow -f /etc/repmgr.conf --log-to-file --upstream-node-id=%n'</programlisting>
</para>
<para>
Adjust file paths as appropriate; alway specify the full path to the &repmgr; binary.
</para>
<note>
<para>
&repmgr; will not apply <option>pg_bindir</option> when executing <option>promote_command</option>
or <option>follow_command</option>; these can be user-defined scripts so must always be
specified with the full path.
</para>
</note>
<para>
Note that the <literal>--log-to-file</literal> option will cause
output generated by the &repmgr; command, when executed by <application>repmgrd</application>,
to be logged to the same destination configured to receive log output for <application>repmgrd</application>.
See <filename><ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink></filename>
for further <application>repmgrd</application>-specific settings.
</para>
<para>
When <varname>failover</varname> is set to <literal>automatic</literal>, upon detecting failure
of the current primary, <application>repmgrd</application> will execute one of:
</para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<varname>promote_command</varname> (if the current server is to become the new primary)
</simpara>
</listitem>
<listitem>
<simpara>
<varname>follow_command</varname> (if the current server needs to follow another server which has
become the new primary)
</simpara>
</listitem>
</itemizedlist>
<note>
<para>
These commands can be any valid shell script which results in one of these
two actions happening, but if &repmgr;'s <command>standby follow</command> or
<command>standby promote</command>
commands are not executed (either directly as shown here, or from a script which
performs other actions), the &repmgr; metadata will not be updated and
&repmgr; will no longer function reliably.
</para>
</note>
<para>
The <varname>follow_command</varname> should provide the <literal>--upstream-node-id=%n</literal>
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, &repmgr;
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
<command>repmgr standby follow</command> will result in the node continuing to follow
the original primary.
</para>
</sect2>
<sect2 id="repmgrd-service-configuration">
<indexterm>
<primary>repmgrd</primary>
<secondary>PostgreSQL service configuration</secondary>
</indexterm>
<title>PostgreSQL service configuration</title>
<para>
If using automatic failover, currently <application>repmgrd</application> will need to execute
<link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>
to restart PostgreSQL on standbys to have them follow a new primary.
</para>
<para>
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>
in <filename>repmgr.conf</filename>. If you don't do this, <application>repmgrd</application>
will default to using <command>pg_ctl</command>, which can result in unexpected problems,
particularly on <application>systemd</application>-based systems.
</para>
<para>
For more details, see <xref linkend="configuration-file-service-commands">.
</para>
</sect2>
<sect2 id="repmgrd-monitoring-configuration" xreflabel="repmgrd monitoring configuration">
<indexterm>
<primary>repmgrd</primary>
<secondary>monitoring configuration</secondary>
</indexterm>
<title>Monitoring configuration</title>
<para>
To enable monitoring, set:
<programlisting>
monitoring_history=yes</programlisting>
in <filename>repmgr.conf</filename>.
</para>
<para>
The default monitoring interval is 2 seconds; this value can be explicitly set using:
<programlisting>
monitor_interval_secs=&lt;seconds&gt;</programlisting>
in <filename>repmgr.conf</filename>.
</para>
<para>
For more details on monitoring, see <xref linkend="repmgrd-monitoring">.
</para>
</sect2>
<sect2 id="repmgrd-reloading-configuration"xreflabel="reloading repmgrd configuration">
<indexterm>
<primary>repmgrd</primary>
<secondary>applying configuration changes</secondary>
</indexterm>
<title>Applying configuration changes to repmgrd</title>
<para>
To apply configuration file changes to a running <application>repmgrd</application>
daemon, execute the operating system's <application>repmgrd</application> service reload command
(see <xref linkend="appendix-packages"> for examples),
or for instances which were manually started, execute <command>kill -HUP</command>, e.g.
<command>kill -HUP `cat /tmp/repmgrd.pid`</command>.
</para>
<tip>
<para>
Check the <application>repmgrd</application> log to see what changes were
applied, or if any issues were encountered when reloading the configuration.
</para>
</tip>
<para>
Note that only the following subset of configuration file parameters can be changed on a
running <application>repmgrd</application> daemon:
</para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<varname>async_query_timeout</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>bdr_local_monitoring_only</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>bdr_recovery_timeout</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>conninfo</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>degraded_monitoring_timeout</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>event_notification_command</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>event_notifications</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>failover</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>follow_command</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>log_facility</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>log_file</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>log_level</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>log_status_interval</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>monitor_interval_secs</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>monitoring_history</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>primary_notification_timeout</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>promote_command</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>reconnect_attempts</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>reconnect_interval</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>repmgrd_standby_startup_timeout</varname>
</simpara>
</listitem>
</itemizedlist>
<para>
The following set of configuration file parameters must be updated via
<command><link linkend="repmgr-standby-register">repmgr standby register --force</link></command>,
as they require changes to the <literal>repmgr.nodes</literal> table so they are visible to
all nodes in the replication cluster:
</para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<varname>node_id</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>node_name</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>data_directory</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>location</varname>
</simpara>
</listitem>
<listitem>
<simpara>
<varname>priority</varname>
</simpara>
</listitem>
</itemizedlist>
<note>
<para>
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.
</para>
</note>
</sect2>
</sect1>
<sect1 id="repmgrd-daemon">
<indexterm>
<primary>repmgrd</primary>
<secondary>starting and stopping</secondary>
</indexterm>
<title>repmgrd daemon</title>
<para>
If installed from a package, the <application>repmgrd</application> can be started
via the operating system's service command, e.g. in <application>systemd</application>
using <command>systemctl</command>.
</para>
<para>
See appendix <xref linkend="appendix-packages"> for details of service commands
for different distributions.
</para>
<para>
<application>repmgrd</application> can be started manually like this:
<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.
</para>
<sect2 id="repmgrd-pid-file" xreflabel="repmgrd's PID file">
<indexterm>
<primary>repmgrd</primary>
<secondary>PID file</secondary>
</indexterm>
<indexterm>
<primary>PID file</primary>
<secondary>repmgrd</secondary>
</indexterm>
<title>repmgrd's PID file</title>
<para>
<application>repmgrd</application> will generate a PID file by default.
</para>
<note>
<simpara>
This is a behaviour change from previous versions (earlier than 4.1), where
the PID file had to be explicitly specified with the command line
parameter <option> --pid-file</option>.
</simpara>
</note>
<para>
The PID file can be specified in <filename>repmgr.conf</filename> with the configuration
parameter <varname>repmgrd_pid_file</varname>.
</para>
<para>
It can also be specified on the command line (as in previous versions) with
the command line parameter <option>--pid-file</option>. Note this will override
any value set in <filename>repmgr.conf</filename> with <varname>repmgrd_pid_file</varname>.
<option>--pid-file</option> may be deprecated in future releases.
</para>
<para>
If a PID file location was specified by the package maintainer, <application>repmgrd</application>
will use that. This only applies if &repmgr; was installed from a package and the package
maintainer has specified the PID file location.
</para>
<para>
If none of the above apply, <application>repmgrd</application> will create a PID file
in the operating system's temporary directory (das etermined by the environment variable
<varname>TMPDIR</varname>, or if that is not set, will use <filename>/tmp</filename>).
</para>
<para>
To prevent a PID file being generated at all, provide the command line option
<option>--no-pid-file</option>.
</para>
<para>
To see which PID file <application>repmgrd</application> would use, execute <application>repmgrd</application>
with the option <option>--show-pid-file</option>. <application>repmgrd</application>
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
not necessarily the PID file currently in use.
</para>
</sect2>
<sect2 id="repmgrd-configuration-debian-ubuntu">
<indexterm>
<primary>repmgrd</primary>
<secondary>Debian/Ubuntu and daemon configuration</secondary>
</indexterm>
<indexterm>
<primary>Debian/Ubuntu</primary>
<secondary>repmgrd daemon configuration</secondary>
</indexterm>
<title>repmgrd daemon configuration on Debian/Ubuntu</title>
<para>
If &repmgr; was installed from Debian/Ubuntu packages, additional configuration
is required before <application>repmgrd</application> is started as a daemon.
</para>
<para>
This is done via the file <filename>/etc/default/repmgrd</filename>, which by default
looks like this:
<programlisting>
# default settings for repmgrd. This file is source by /bin/sh from
# /etc/init.d/repmgrd
# disable repmgrd by default so it won't get started upon installation
# valid values: yes/no
REPMGRD_ENABLED=no
# configuration file (required)
#REPMGRD_CONF="/path/to/repmgr.conf"
# additional options
REPMGRD_OPTS="--daemonize=false"
# user to run repmgrd as
#REPMGRD_USER=postgres
# repmgrd binary
#REPMGRD_BIN=/usr/bin/repmgrd
# pid file
#REPMGRD_PIDFILE=/var/run/repmgrd.pid</programlisting>
</para>
<para>
Set <varname>REPMGRD_ENABLED</varname> to <literal>yes</literal>, and <varname>REPMGRD_CONF</varname>
to the <filename>repmgr.conf</filename> file you are using.
</para>
<tip>
<para>
See <xref linkend="packages-debian-ubuntu"> for details of the Debian/Ubuntu packages and
typical file locations (including <filename>repmgr.conf</filename>).
</para>
</tip>
<para>
From <application>repmgrd</application> 4.1, ensure <varname>REPMGRD_OPTS</varname> includes
<option>--daemonize=false</option>, as daemonization is handled by the service command.
</para>
<para>
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>,
you'll need to execute <command>systemctl stop repmgrd</command>. Because that's how <application>systemd</application>
rolls.
</para>
</sect2>
</sect1>
<sect1 id="repmgrd-connection-settings">
<title>repmgrd connection settings</title>
<para>
In addition to the &repmgr; configuration settings, parameters in the
<varname>conninfo</varname> string influence how &repmgr; makes a network connection to
PostgreSQL. In particular, if another server in the replication cluster
is unreachable at network level, system network settings will influence
the length of time it takes to determine that the connection is not possible.
</para>
<para>
In particular explicitly setting a parameter for <literal>connect_timeout</literal>
should be considered; the effective minimum value of <literal>2</literal>
(seconds) will ensure that a connection failure at network level is reported
as soon as possible, otherwise depending on the system settings (e.g.
<varname>tcp_syn_retries</varname> in Linux) a delay of a minute or more
is possible.
</para>
<para>
For further details on <varname>conninfo</varname> network connection
parameters, see the
<ulink url="https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS">PostgreSQL documentation</ulink>.
</para>
</sect1>
<sect1 id="repmgrd-log-rotation">
<indexterm>
<primary>log rotation</primary>
<secondary>repmgrd</secondary>
</indexterm>
<indexterm>
<primary>repmgrd</primary>
<secondary>log rotation</secondary>
</indexterm>
<title>repmgrd log rotation</title>
<para>
To ensure the current <application>repmgrd</application> logfile
(specified in <filename>repmgr.conf</filename> with the parameter
<option>log_file</option>) does not grow indefinitely, configure your
system's <command>logrotate</command> to regularly rotate it.
</para>
<para>
Sample configuration to rotate logfiles weekly with retention for
up to 52 weeks and rotation forced if a file grows beyond 100Mb:
<programlisting>
/var/log/repmgr/repmgrd.log {
missingok
compress
rotate 52
maxsize 100M
weekly
create 0600 postgres postgres
postrotate
/usr/bin/killall -HUP repmgrd
endscript
}</programlisting>
</para>
</sect1>
</chapter>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,83 @@
<chapter id="repmgrd-degraded-monitoring" xreflabel="repmgrd degraded monitoring">
<indexterm>
<primary>repmgrd</primary>
<secondary>degraded monitoring</secondary>
</indexterm>
<title>"degraded monitoring" mode</title>
<para>
In certain circumstances, <application>repmgrd</application> is not able to fulfill its primary mission
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
to be resolved.
</para>
<para>
Situations where this happens are:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>a failover situation has occurred, no nodes in the primary node's location are visible</simpara>
</listitem>
<listitem>
<simpara>a failover situation has occurred, but no promotion candidate is available</simpara>
</listitem>
<listitem>
<simpara>a failover situation has occurred, but the promotion candidate could not be promoted</simpara>
</listitem>
<listitem>
<simpara>a failover situation has occurred, but the node was unable to follow the new primary</simpara>
</listitem>
<listitem>
<simpara>a failover situation has occurred, but no primary has become available</simpara>
</listitem>
<listitem>
<simpara>a failover situation has occurred, but automatic failover is not enabled for the node</simpara>
</listitem>
<listitem>
<simpara>repmgrd is monitoring the primary node, but it is not available (and no other node has been promoted as primary)</simpara>
</listitem>
</itemizedlist>
</para>
<para>
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):
<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:33] [WARNING] unable to connect to upstream node "node1" (node 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] sleeping 1 seconds until next reconnection attempt
(...)
[2017-08-29 10:59:37] [INFO] checking state of node 1, 5 of 5 attempts
[2017-08-29 10:59:37] [WARNING] unable to reconnect to node 1 after 5 attempts
[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] [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:53] [INFO] node "node2" (node ID: 2) monitoring upstream node "node1" (node 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:57] [INFO] node "node2" (node ID: 2) monitoring upstream node "node1" (node ID: 1) in normal state (automatic failover disabled)</programlisting>
</para>
<para>
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>,
after which <application>repmgrd</application> will terminate.
</para>
<note>
<para>
If <application>repmgrd</application> is monitoring a primary mode which has been stopped
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
as an active standby. It will then resume monitoring the node as a standby.
</para>
</note>
</chapter>

View File

@@ -0,0 +1,96 @@
<chapter id="repmgrd-demonstration">
<title>repmgrd demonstration</title>
<para>
To demonstrate automatic failover, set up a 3-node replication cluster (one primary
and two standbys streaming directly from the primary) so that the cluster looks
something like this:
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Connection string
----+-------+---------+-----------+----------+----------+--------------------------------------
1 | node1 | primary | * running | | default | host=node1 dbname=repmgr user=repmgr
2 | node2 | standby | running | node1 | default | host=node2 dbname=repmgr user=repmgr
3 | node3 | standby | running | node1 | default | host=node3 dbname=repmgr user=repmgr</programlisting>
</para>
<para>
Start <application>repmgrd</application> 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:
<programlisting>
[2017-08-24 17:31:00] [NOTICE] using configuration file "/etc/repmgr.conf"
[2017-08-24 17:31:00] [INFO] connecting to database "host=node2 dbname=repmgr user=repmgr"
[2017-08-24 17:31:00] [NOTICE] starting monitoring of node <literal>node2</literal> (ID: 2)
[2017-08-24 17:31:00] [INFO] monitoring connection to upstream node "node1" (node ID: 1)</programlisting>
</para>
<para>
Each <application>repmgrd</application> should also have recorded its successful startup as an event:
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster event --event=repmgrd_start
Node ID | Name | Event | OK | Timestamp | Details
---------+-------+---------------+----+---------------------+-------------------------------------------------------------
3 | node3 | repmgrd_start | t | 2017-08-24 17:35:54 | monitoring connection to upstream node "node1" (node ID: 1)
2 | node2 | repmgrd_start | t | 2017-08-24 17:35:50 | monitoring connection to upstream node "node1" (node ID: 1)
1 | node1 | repmgrd_start | t | 2017-08-24 17:35:46 | monitoring cluster primary "node1" (node ID: 1) </programlisting>
</para>
<para>
Now stop the current primary server with e.g.:
<programlisting>
pg_ctl -D /var/lib/postgresql/data -m immediate stop</programlisting>
</para>
<para>
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
files as each <application>repmgrd</application> 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>)
which has promoted to new primary after failure of the original primary (<literal>node1</literal>).
<programlisting>
[2017-08-24 23:32:01] [INFO] node "node2" (node ID: 2) monitoring upstream node "node1" (node ID: 1) in normal state
[2017-08-24 23:32:08] [WARNING] unable to connect to upstream node "node1" (node ID: 1)
[2017-08-24 23:32:08] [INFO] checking state of node 1, 1 of 5 attempts
[2017-08-24 23:32:08] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-08-24 23:32:09] [INFO] checking state of node 1, 2 of 5 attempts
[2017-08-24 23:32:09] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-08-24 23:32:10] [INFO] checking state of node 1, 3 of 5 attempts
[2017-08-24 23:32:10] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-08-24 23:32:11] [INFO] checking state of node 1, 4 of 5 attempts
[2017-08-24 23:32:11] [INFO] sleeping 1 seconds until next reconnection attempt
[2017-08-24 23:32:12] [INFO] checking state of node 1, 5 of 5 attempts
[2017-08-24 23:32:12] [WARNING] unable to reconnect to node 1 after 5 attempts
INFO: setting voting term to 1
INFO: node 2 is candidate
INFO: node 3 has received request from node 2 for electoral term 1 (our term: 0)
[2017-08-24 23:32:12] [NOTICE] this node is the winner, will now promote self and inform other nodes
INFO: connecting to standby database
NOTICE: promoting standby
DETAIL: promoting server using 'pg_ctl -l /var/log/postgres/startup.log -w -D '/var/lib/pgsql/data' promote'
INFO: reconnecting to promoted server
NOTICE: STANDBY PROMOTE successful
DETAIL: node 2 was successfully promoted to primary
INFO: node 3 received notification to follow node 2
[2017-08-24 23:32:13] [INFO] switching to primary monitoring mode</programlisting>
</para>
<para>
The cluster status will now look like this, with the original primary (<literal>node1</literal>)
marked as inactive, and standby <literal>node3</literal> now following the new primary
(<literal>node2</literal>):
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Connection string
----+-------+---------+-----------+----------+----------+----------------------------------------------------
1 | node1 | primary | - failed | | default | host=node1 dbname=repmgr user=repmgr
2 | node2 | primary | * running | | default | host=node2 dbname=repmgr user=repmgr
3 | node3 | standby | running | node2 | default | host=node3 dbname=repmgr user=repmgr</programlisting>
</para>
<para>
<command>repmgr cluster event</command> will display a summary of what happened to each server
during the failover:
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster event
Node ID | Name | Event | OK | Timestamp | Details
---------+-------+--------------------------+----+---------------------+-----------------------------------------------------------------------------------
3 | node3 | repmgrd_failover_follow | t | 2017-08-24 23:32:16 | node 3 now following new upstream node 2
3 | node3 | standby_follow | t | 2017-08-24 23:32:16 | node 3 is now attached to node 2
2 | node2 | repmgrd_failover_promote | t | 2017-08-24 23:32:13 | node 2 promoted to primary; old primary 1 marked as failed
2 | node2 | standby_promote | t | 2017-08-24 23:32:13 | node 2 was successfully promoted to primary</programlisting>
</para>
</chapter>

View File

@@ -0,0 +1,80 @@
<chapter id="repmgrd-monitoring" xreflabel="Monitoring with repmgrd">
<indexterm>
<primary>repmgrd</primary>
<secondary>monitoring</secondary>
</indexterm>
<indexterm>
<primary>monitoring</primary>
<secondary>with repmgrd</secondary>
</indexterm>
<title>Monitoring with repmgrd</title>
<para>
When <application>repmgrd</application> is running with the option <literal>monitoring_history=true</literal>,
it will constantly write standby node status information to the
<varname>monitoring_history</varname> table, providing a near-real time
overview of replication status on all nodes
in the cluster.
</para>
<para>
The view <literal>replication_status</literal> shows the most recent state
for each node, e.g.:
<programlisting>
repmgr=# select * from repmgr.replication_status;
-[ RECORD 1 ]-------------+------------------------------
primary_node_id | 1
standby_node_id | 2
standby_name | node2
node_type | standby
active | t
last_monitor_time | 2017-08-24 16:28:41.260478+09
last_wal_primary_location | 0/6D57A00
last_wal_standby_location | 0/5000000
replication_lag | 29 MB
replication_time_lag | 00:00:11.736163
apply_lag | 15 MB
communication_time_lag | 00:00:01.365643</programlisting>
</para>
<para>
The interval in which monitoring history is written is controlled by the
configuration parameter <varname>monitor_interval_secs</varname>;
default is 2.
</para>
<para>
As this can generate a large amount of monitoring data in the table
<literal>repmgr.monitoring_history</literal>. it's advisable to regularly
purge historical data using the <xref linkend="repmgr-cluster-cleanup">
command; use the <literal>-k/--keep-history</literal> option to
specify how many day's worth of data should be retained.
</para>
<para>
It's possible to use <application>repmgrd</application> to run in monitoring
mode only (without automatic failover capability) for some or all
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,
no failover action will be taken and the node will require manual intervention to
be reattached to replication. If this occurs, an
<link linkend="event-notifications">event notification</link>
<varname>standby_disconnect_manual</varname> will be created.
</para>
<para>
Note that when a standby node is not streaming directly from its upstream
node, e.g. recovering WAL from an archive, <varname>apply_lag</varname> will always appear as
<literal>0 bytes</literal>.
</para>
<tip>
<para>
If monitoring history is enabled, the contents of the <literal>repmgr.monitoring_history</literal>
table will be replicated to attached standbys. This means there will be a small but
constant stream of replication activity which may not be desirable. To prevent
this, convert the table to an <literal>UNLOGGED</literal> one with:
<programlisting>
ALTER TABLE repmgr.monitoring_history SET UNLOGGED;</programlisting>
</para>
<para>
This will however mean that monitoring history will not be available on
another node following a failover, and the view <literal>repmgr.replication_status</literal>
will not work on standbys.
</para>
</tip>
</chapter>

View File

@@ -0,0 +1,48 @@
<chapter id="repmgrd-network-split" xreflabel="Handling network splits with repmgrd">
<indexterm>
<primary>repmgrd</primary>
<secondary>network splits</secondary>
</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>
</chapter>

View File

@@ -1,388 +0,0 @@
<chapter id="repmgrd-operation" xreflabel="repmgrd operation">
<title>repmgrd operation</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>operation</secondary>
</indexterm>
<sect1 id="repmgrd-pausing">
<title>Pausing repmgrd</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>pausing</secondary>
</indexterm>
<indexterm>
<primary>pausing repmgrd</primary>
</indexterm>
<para>
In normal operation, &repmgrd; monitors the state of the
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
primary has been determined as failed.
</para>
<para>
However, &repmgrd; is unable to distinguish between
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
&repmgr; 4.2 it was necessary to stop &repmgrd; on all nodes (or at least
on all nodes where &repmgrd; is
<link linkend="repmgrd-automatic-failover">configured for automatic failover</link>)
to prevent &repmgrd; from making unintentional changes to the
replication cluster.
</para>
<para>
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.
This can be done from any node in the cluster, removing the need to stop/restart
each &repmgrd; individually.
</para>
<note>
<para>
For major PostgreSQL upgrades, e.g. from PostgreSQL 10 to PostgreSQL 11,
&repmgrd; should be shut down completely and only started up
once the &repmgr; packages for the new PostgreSQL major version have been installed.
</para>
</note>
<sect2 id="repmgrd-pausing-prerequisites">
<title>Prerequisites for pausing &repmgrd;</title>
<para>
In order to be able to pause/unpause &repmgrd;, following
prerequisites must be met:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara><link linkend="release-4.2">&repmgr; 4.2</link> or later must be installed on all nodes.</simpara>
</listitem>
<listitem>
<simpara>The same major &repmgr; version (e.g. 4.2) must be installed on all nodes (and preferably the same minor version).</simpara>
</listitem>
<listitem>
<simpara>
PostgreSQL on all nodes must be accessible from the node where the
<literal>pause</literal>/<literal>unpause</literal> operation is executed, using the
<varname>conninfo</varname> string shown by <link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>.
</simpara>
</listitem>
</itemizedlist>
</para>
<note>
<para>
These conditions are required for normal &repmgr; operation in any case.
</para>
</note>
</sect2>
<sect2 id="repmgrd-pausing-execution">
<title>Pausing/unpausing &repmgrd;</title>
<para>
To pause &repmgrd;, execute <link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link>, e.g.:
<programlisting>
$ repmgr -f /etc/repmgr.conf daemon pause
NOTICE: node 1 (node1) paused
NOTICE: node 2 (node2) paused
NOTICE: node 3 (node3) paused</programlisting>
</para>
<para>
The state of &repmgrd; on each node can be checked with
<link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>, e.g.:
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
ID | Name | Role | Status | repmgrd | PID | Paused?
----+-------+---------+---------+---------+------+---------
1 | node1 | primary | running | running | 7851 | yes
2 | node2 | standby | running | running | 7889 | yes
3 | node3 | standby | running | running | 7918 | yes</programlisting>
</para>
<note>
<para>
If executing a switchover with <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>,
&repmgr; will automatically pause/unpause &repmgrd; as part of the switchover process.
</para>
</note>
<para>
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:
<programlisting>
[2018-09-20 12:22:21] [WARNING] unable to connect to upstream node "node1" (ID: 1)
[2018-09-20 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
...
[2018-09-20 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
[2018-09-20 12:22:25] [WARNING] unable to reconnect to node 1 after 5 attempts
[2018-09-20 12:22:25] [NOTICE] node is paused
[2018-09-20 12:22:33] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (ID: 1) in degraded state
[2018-09-20 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>
</para>
<para>
If the primary becomes available again (e.g. following a software upgrade), &repmgrd;
will automatically reconnect, e.g.:
<programlisting>
[2018-09-20 13:12:41] [NOTICE] reconnected to upstream node 1 after 8 seconds, resuming monitoring</programlisting>
</para>
<para>
To unpause &repmgrd;, execute <link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>, e.g.:
<programlisting>
$ repmgr -f /etc/repmgr.conf daemon unpause
NOTICE: node 1 (node1) unpaused
NOTICE: node 2 (node2) unpaused
NOTICE: node 3 (node3) unpaused</programlisting>
</para>
<note>
<para>
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
<link linkend="repmgr-standby-promote"><command>repmgr standby promote</command></link>,
and any standbys attached to the new primary with
<link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>.
</para>
<para>
This is to prevent <link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>
resulting in the automatic promotion of a new primary, which may be a problem particularly
in larger clusters, where &repmgrd; could select a different promotion
candidate to the one intended by the administrator.
</para>
</note>
</sect2>
<sect2 id="repmgrd-pausing-details">
<title>Details on the &repmgrd; pausing mechanism</title>
<para>
The pause state of each node will be stored over a PostgreSQL restart.
</para>
<para>
<link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link> and
<link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link> can be
executed even if &repmgrd; is not running; in this case,
&repmgrd; will start up in whichever pause state has been set.
</para>
<note>
<para>
<link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link> and
<link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>
<emphasis>do not</emphasis> stop/start &repmgrd;.
</para>
</note>
</sect2>
</sect1>
<sect1 id="repmgrd-wal-replay-pause">
<title>repmgrd and paused WAL replay</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>paused WAL replay</secondary>
</indexterm>
<para>
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>),
in a failover situation &repmgrd; will
automatically resume WAL replay.
</para>
<para>
This is because if WAL replay is paused, but WAL is pending replay,
PostgreSQL cannot be promoted until WAL replay is resumed.
</para>
<note>
<para>
<command><link linkend="repmgr-standby-promote">repmgr standby promote</link></command>
will refuse to promote a node in this state, as the PostgreSQL
<command>promote</command> command will not be acted on until
WAL replay is resumed, leaving the cluster in a potentially
unstable state. In this case it is up to the user to
decide whether to resume WAL replay.
</para>
</note>
</sect1>
<sect1 id="repmgrd-degraded-monitoring" xreflabel="repmgrd degraded monitoring">
<title>"degraded monitoring" mode</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>degraded monitoring</secondary>
</indexterm>
<indexterm>
<primary>degraded monitoring</primary>
</indexterm>
<para>
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;
mode, where &repmgrd; remains active but is waiting for the situation
to be resolved.
</para>
<para>
Situations where this happens are:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>a failover situation has occurred, no nodes in the primary node's location are visible</simpara>
</listitem>
<listitem>
<simpara>a failover situation has occurred, but no promotion candidate is available</simpara>
</listitem>
<listitem>
<simpara>a failover situation has occurred, but the promotion candidate could not be promoted</simpara>
</listitem>
<listitem>
<simpara>a failover situation has occurred, but the node was unable to follow the new primary</simpara>
</listitem>
<listitem>
<simpara>a failover situation has occurred, but no primary has become available</simpara>
</listitem>
<listitem>
<simpara>a failover situation has occurred, but automatic failover is not enabled for the node</simpara>
</listitem>
<listitem>
<simpara>repmgrd is monitoring the primary node, but it is not available (and no other node has been promoted as primary)</simpara>
</listitem>
</itemizedlist>
</para>
<para>
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):
<programlisting>
[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" (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] sleeping 1 seconds until next reconnection attempt
(...)
[2017-08-29 10:59:37] [INFO] checking state of node 1, 5 of 5 attempts
[2017-08-29 10:59:37] [WARNING] unable to reconnect to node 1 after 5 attempts
[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] [HINT] use "repmgr standby promote" to manually promote this node
[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" (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:57] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (ID: 1) in normal state (automatic failover disabled)</programlisting>
</para>
<para>
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>,
after which &repmgrd; will terminate.
</para>
<note>
<para>
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
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.
</para>
</note>
</sect1>
<sect1 id="repmgrd-monitoring" xreflabel="Storing monitoring data">
<title>Storing monitoring data</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>monitoring</secondary>
</indexterm>
<indexterm>
<primary>monitoring</primary>
<secondary>with repmgrd</secondary>
</indexterm>
<para>
When &repmgrd; is running with the option <literal>monitoring_history=true</literal>,
it will constantly write standby node status information to the
<varname>monitoring_history</varname> table, providing a near-real time
overview of replication status on all nodes
in the cluster.
</para>
<para>
The view <literal>replication_status</literal> shows the most recent state
for each node, e.g.:
<programlisting>
repmgr=# select * from repmgr.replication_status;
-[ RECORD 1 ]-------------+------------------------------
primary_node_id | 1
standby_node_id | 2
standby_name | node2
node_type | standby
active | t
last_monitor_time | 2017-08-24 16:28:41.260478+09
last_wal_primary_location | 0/6D57A00
last_wal_standby_location | 0/5000000
replication_lag | 29 MB
replication_time_lag | 00:00:11.736163
apply_lag | 15 MB
communication_time_lag | 00:00:01.365643</programlisting>
</para>
<para>
The interval in which monitoring history is written is controlled by the
configuration parameter <varname>monitor_interval_secs</varname>;
default is 2.
</para>
<para>
As this can generate a large amount of monitoring data in the table
<literal>repmgr.monitoring_history</literal>. it's advisable to regularly
purge historical data using the <xref linkend="repmgr-cluster-cleanup"/>
command; use the <literal>-k/--keep-history</literal> option to
specify how many day's worth of data should be retained.
</para>
<para>
It's possible to use &repmgrd; to run in monitoring
mode only (without automatic failover capability) for some or all
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,
no failover action will be taken and the node will require manual intervention to
be reattached to replication. If this occurs, an
<link linkend="event-notifications">event notification</link>
<varname>standby_disconnect_manual</varname> will be created.
</para>
<para>
Note that when a standby node is not streaming directly from its upstream
node, e.g. recovering WAL from an archive, <varname>apply_lag</varname> will always appear as
<literal>0 bytes</literal>.
</para>
<tip>
<para>
If monitoring history is enabled, the contents of the <literal>repmgr.monitoring_history</literal>
table will be replicated to attached standbys. This means there will be a small but
constant stream of replication activity which may not be desirable. To prevent
this, convert the table to an <literal>UNLOGGED</literal> one with:
<programlisting>
ALTER TABLE repmgr.monitoring_history SET UNLOGGED;</programlisting>
</para>
<para>
This will however mean that monitoring history will not be available on
another node following a failover, and the view <literal>repmgr.replication_status</literal>
will not work on standbys.
</para>
</tip>
</sect1>
</chapter>

View File

@@ -1,187 +0,0 @@
<chapter id="repmgrd-overview" xreflabel="repmgrd overview">
<title>repmgrd overview</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>overview</secondary>
</indexterm>
<para>
&repmgrd; (&quot;<literal>replication manager daemon</literal>&quot;)
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>
<para>
&repmgrd; is designed to be straightforward to set up
and does not require additional external infrastructure.
</para>
<para>
Functionality provided by &repmgrd; includes:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
wide range of <link linkend="repmgrd-basic-configuration">configuration options</link>
</simpara>
</listitem>
<listitem>
<simpara>
option to execute custom scripts (&quot;<link linkend="event-notifications">event notifications</link>
at different points in the failover sequence
</simpara>
</listitem>
<listitem>
<simpara>
ability to <link linkend="repmgrd-pausing">pause repmgrd</link>
operation on all nodes with a
<link linkend="repmgr-daemon-pause"><command>single command</command></link>
</simpara>
</listitem>
<listitem>
<simpara>
optional <link linkend="repmgrd-witness-server">witness server</link>
</simpara>
</listitem>
<listitem>
<simpara>
&quot;location&quot; configuration option to restrict
potential promotion candidates to a single location
(e.g. when nodes are spread over multiple data centres)
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="connection-check-type">choice of method</link> to determine node availability
(PostgreSQL ping, query execution or new connection)
</simpara>
</listitem>
<listitem>
<simpara>
retention of monitoring statistics (optional)
</simpara>
</listitem>
</itemizedlist>
</para>
<sect1 id="repmgrd-demonstration">
<title>repmgrd demonstration</title>
<para>
To demonstrate automatic failover, set up a 3-node replication cluster (one primary
and two standbys streaming directly from the primary) so that the cluster looks
something like this:
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster show --compact
ID | Name | Role | Status | Upstream | Location | Prio.
----+-------+---------+-----------+----------+----------+-------
1 | node1 | primary | * running | | default | 100
2 | node2 | standby | running | node1 | default | 100
3 | node3 | standby | running | node1 | default | 100</programlisting>
</para>
<tip>
<para>
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 &repmgrd;.
</para>
</tip>
<para>
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:
<programlisting>
[2019-03-15 06:32:05] [NOTICE] repmgrd (repmgrd 4.3) starting up
[2019-03-15 06:32:05] [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
[2019-03-15 06:32:05] [NOTICE] starting monitoring of node "node2" (ID: 2)
[2019-03-15 06:32:05] [INFO] monitoring connection to upstream node "node1" (ID: 1)</programlisting>
</para>
<para>
Each &repmgrd; should also have recorded its successful startup as an event:
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster event --event=repmgrd_start
Node ID | Name | Event | OK | Timestamp | Details
---------+-------+---------------+----+---------------------+--------------------------------------------------------
3 | node3 | repmgrd_start | t | 2019-03-14 04:17:30 | 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" (ID: 1)
1 | node1 | repmgrd_start | t | 2019-03-14 04:04:31 | monitoring cluster primary "node1" (ID: 1)</programlisting>
</para>
<para>
Now stop the current primary server with e.g.:
<programlisting>
pg_ctl -D /var/lib/postgresql/data -m immediate stop</programlisting>
</para>
<para>
This will force the primary to shut down straight away, aborting all processes
and transactions. This will cause a flurry of activity in the &repmgrd; log
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>)
which has promoted to new primary after failure of the original primary (<literal>node1</literal>).
<programlisting>
[2019-03-15 06:37: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-03-15 06:37: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-03-15 06:37: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-03-15 06:38: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-03-15 06:38: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-03-15 06:38: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-03-15 06:38: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-03-15 06:38: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:
"/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf standby promote"
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"
NOTICE: waiting up to 60 seconds (parameter "promote_check_timeout") for promotion to complete
NOTICE: STANDBY PROMOTE successful
DETAIL: server "node2" (ID: 2) was successfully promoted to primary
[2019-03-15 06:38:01] [INFO] 3 followers to notify
[2019-03-15 06:38:01] [NOTICE] notifying node "node3" (ID: 3) 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-03-15 06:38:01] [NOTICE] monitoring cluster primary "node2" (ID: 2)</programlisting>
</para>
<para>
The cluster status will now look like this, with the original primary (<literal>node1</literal>)
marked as inactive, and standby <literal>node3</literal> now following the new primary
(<literal>node2</literal>):
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster show --compact
ID | Name | Role | Status | Upstream | Location | Prio.
----+-------+---------+-----------+----------+----------+-------
1 | node1 | primary | - failed | | default | 100
2 | node2 | primary | * running | | default | 100
3 | node3 | standby | running | node2 | default | 100</programlisting>
</para>
<para>
<link linkend="repmgr-cluster-event"><command>repmgr cluster event</command></link> will display a summary of
what happened to each server during the failover:
<programlisting>
$ repmgr -f /etc/repmgr.conf cluster event
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 | standby_follow | t | 2019-03-15 06: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" (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 | standby_promote | t | 2019-03-15 06:38:01 | server "node2" (ID: 2) was successfully promoted to primary</programlisting>
</para>
</sect1>
</chapter>

178
doc/repmgrd-pausing.sgml Normal file
View File

@@ -0,0 +1,178 @@
<chapter id="repmgrd-pausing" xreflabel="Pausing repmgrd">
<indexterm>
<primary>repmgrd</primary>
<secondary>pausing</secondary>
</indexterm>
<indexterm>
<primary>pausing repmgrd</primary>
</indexterm>
<title>Pausing repmgrd</title>
<para>
In normal operation, <application>repmgrd</application> monitors the state of the
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
primary has been determined as failed.
</para>
<para>
However, <application>repmgrd</application> is unable to distinguish between
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
&repmgr; 4.2 it was necessary to stop <application>repmgrd</application> on all nodes (or at least
on all nodes where <application>repmgrd</application> is
<link linkend="repmgrd-automatic-failover">configured for automatic failover</link>)
to prevent <application>repmgrd</application> from making unintentional changes to the
replication cluster.
</para>
<para>
From <link linkend="release-4.2">&repmgr; 4.2</link>, <application>repmgrd</application>
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
each <application>repmgrd</application> individually.
</para>
<note>
<para>
For major PostgreSQL upgrades, e.g. from PostgreSQL 10 to PostgreSQL 11,
<application>repmgrd</application> should be shut down completely and only started up
once the &repmgr; packages for the new PostgreSQL major version have been installed.
</para>
</note>
<sect1 id="repmgrd-pausing-prerequisites">
<title>Prerequisites for pausing <application>repmgrd</application></title>
<para>
In order to be able to pause/unpause <application>repmgrd</application>, following
prerequisites must be met:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara><link linkend="release-4.2">&repmgr; 4.2</link> or later must be installed on all nodes.</simpara>
</listitem>
<listitem>
<simpara>The same major &repmgr; version (e.g. 4.2) must be installed on all nodes (and preferably the same minor version).</simpara>
</listitem>
<listitem>
<simpara>
PostgreSQL on all nodes must be accessible from the node where the
<literal>pause</literal>/<literal>unpause</literal> operation is executed, using the
<varname>conninfo</varname> string shown by <link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>.
</simpara>
</listitem>
</itemizedlist>
</para>
<note>
<para>
These conditions are required for normal &repmgr; operation in any case.
</para>
</note>
</sect1>
<sect1 id="repmgrd-pausing-execution">
<title>Pausing/unpausing <application>repmgrd</application></title>
<para>
To pause <application>repmgrd</application>, execute <link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link>, e.g.:
<programlisting>
$ repmgr -f /etc/repmgr.conf daemon pause
NOTICE: node 1 (node1) paused
NOTICE: node 2 (node2) paused
NOTICE: node 3 (node3) paused</programlisting>
</para>
<para>
The state of <application>repmgrd</application> on each node can be checked with
<link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>, e.g.:
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
ID | Name | Role | Status | repmgrd | PID | Paused?
----+-------+---------+---------+---------+------+---------
1 | node1 | primary | running | running | 7851 | yes
2 | node2 | standby | running | running | 7889 | yes
3 | node3 | standby | running | running | 7918 | yes</programlisting>
</para>
<note>
<para>
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.
</para>
</note>
<para>
If the primary (in this example, <literal>node1</literal>) is stopped, <application>repmgrd</application>
running on one of the standbys (here: <literal>node2</literal>) will react like this:
<programlisting>
[2018-09-20 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
[2018-09-20 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
[2018-09-20 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
[2018-09-20 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
[2018-09-20 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>
</para>
<para>
If the primary becomes available again (e.g. following a software upgrade), <application>repmgrd</application>
will automatically reconnect, e.g.:
<programlisting>
[2018-09-20 13:12:41] [NOTICE] reconnected to upstream node 1 after 8 seconds, resuming monitoring</programlisting>
</para>
<para>
To unpause <application>repmgrd</application>, execute <link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>, e.g.:
<programlisting>
$ repmgr -f /etc/repmgr.conf daemon unpause
NOTICE: node 1 (node1) unpaused
NOTICE: node 2 (node2) unpaused
NOTICE: node 3 (node3) unpaused</programlisting>
</para>
<note>
<para>
If the previous primary is no longer accessible when <application>repmgrd</application>
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>,
and any standbys attached to the new primary with
<link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>.
</para>
<para>
This is to prevent <link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>
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
candidate to the one intended by the administrator.
</para>
</note>
<sect2 id="repmgrd-pausing-details">
<title>Details on the <application>repmgrd</application> pausing mechanism</title>
<para>
The pause state of each node will be stored over a PostgreSQL restart.
</para>
<para>
<link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link> and
<link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link> can be
executed even if <application>repmgrd</application> is not running; in this case,
<application>repmgrd</application> will start up in whichever pause state has been set.
</para>
<note>
<para>
<link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link> and
<link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>
<emphasis>do not</emphasis> stop/start <application>repmgrd</application>.
</para>
</note>
</sect2>
</sect1>
</chapter>

View File

@@ -0,0 +1,31 @@
<chapter id="repmgrd-witness-server" xreflabel="Using a witness server with repmgrd">
<indexterm>
<primary>repmgrd</primary>
<secondary>witness server</secondary>
</indexterm>
<title>Using a witness server with repmgrd</title>
<para>
In a situation caused e.g. by a network interruption between two
data centres, it's important to avoid a "split-brain" situation where
both sides of the network assume they are the active segment and the
side without an active primary unilaterally promotes one of its standbys.
</para>
<para>
To prevent this situation happening, it's essential to ensure that one
network segment has a "voting majority", so other segments will know
they're in the minority and not attempt to promote a new primary. Where
an odd number of servers exists, this is not an issue. However, if each
network has an even number of nodes, it's necessary to provide some way
of ensuring a majority, which is where the witness server becomes useful.
</para>
<para>
This is not a fully-fledged standby node and is not integrated into
replication, but it effectively represents the "casting vote" when
deciding which network segment has a majority. A witness server can
be set up using <xref linkend="repmgr-witness-register">. Note that it only
makes sense to create a witness server in conjunction with running
<application>repmgrd</application>; the witness server will require its own
<application>repmgrd</application> instance.
</para>
</chapter>

View File

@@ -1,89 +0,0 @@
<?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>

View File

@@ -1,97 +0,0 @@
<?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

@@ -1,292 +0,0 @@
<?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

@@ -1,23 +0,0 @@
<?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

@@ -1,100 +0,0 @@
<?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

@@ -1,345 +0,0 @@
<?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,471 +1,96 @@
/* PostgreSQL.org Documentation Style */ /* doc/src/sgml/stylesheet.css */
@import 'website-docs.css'; /* color scheme similar to www.postgresql.org */
/* requires global.css, table.css and text.css to be loaded before this file! */ BODY {
body { color: #000000;
font-family: verdana, sans-serif; background: #FFFFFF;
font-size: 76%; font-family: verdana, sans-serif;
background: url("/resources/background.png") repeat-x scroll left top transparent;
padding: 15px 4%;
margin: 0;
} }
/* monospace font size fix */ A:link { color:#0066A2; }
pre, code, kbd, samp, tt { A:visited { color:#004E66; }
font-family: monospace,monospace; A:active { color:#0066A2; }
font-size: 1em; A:hover { color:#000000; }
}
div.NAVHEADER table {
margin-left: 0;
}
/* Container Definitions */
#docContainerWrap {
text-align: center; /* Win IE5 */
}
#docContainer {
margin: 0 auto;
width: 90%;
padding-bottom: 2em;
display: block;
text-align: left; /* Win IE5 */
}
#docHeader {
background-image: url("/media/img/docs/bg_hdr.png");
height: 83px;
margin: 0px;
padding: 0px;
display: block;
}
#docHeaderLogo {
position: relative;
width: 206px;
height: 83px;
border: 0px;
padding: 0px;
margin: 0 0 0 20px;
}
#docHeaderLogo img {
border: 0px;
}
#docNavSearchContainer {
padding-bottom: 2px;
}
#docNav, #docVersions {
position: relative;
text-align: left;
margin-left: 10px;
margin-top: 5px;
color: #666;
font-size: 0.95em;
}
#docSearch {
position: relative;
text-align: right;
padding: 0;
margin: 0;
color: #666;
}
#docTextSize {
text-align: right;
white-space: nowrap;
margin-top: 7px;
font-size: 0.95em;
}
#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 */
}
#docSearch form label {
color: #666;
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 { H1 {
line-height: 1.5em; font-size: 1.4em;
font-weight: bold;
margin-top: 0em;
margin-bottom: 0em;
color: #EC5800;
} }
.txtCommentsWrap { H2 {
border: 2px solid #F5F5F5; font-size: 1.2em;
width: 100%; margin: 1.2em 0em 1.2em 0em;
font-weight: bold;
color: #666;
} }
.txtCommentsContent { H3 {
background: #F5F5F5; font-size: 1.1em;
padding: 3px; margin: 1.2em 0em 1.2em 0em;
font-weight: bold;
color: #666;
} }
.txtCommentsPoster { H4 {
float: left; font-size: 0.95em;
margin: 1.2em 0em 1.2em 0em;
font-weight: normal;
color: #666;
} }
.txtCommentsDate { H5 {
float: right; font-size: 0.9em;
margin: 1.2em 0em 1.2em 0em;
font-weight: normal;
} }
.txtCommentsComment { H6 {
padding: 3px; font-size: 0.85em;
margin: 1.2em 0em 1.2em 0em;
font-weight: normal;
} }
#docContainer pre code, /* center some titles */
#docContainer pre tt,
#docContainer pre pre,
#docContainer tt tt,
#docContainer tt code,
#docContainer tt pre {
font-size: 1em;
}
pre.LITERALLAYOUT, .BOOK .TITLE, .BOOK .CORPAUTHOR, .BOOK .COPYRIGHT {
.SCREEN, text-align: center;
.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, /* decoration for formal examples */
.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, DIV.EXAMPLE {
pre.SYNOPSIS, padding-left: 15px;
pre.PROGRAMLISTING, border-style: solid;
.REFSYNOPSISDIV p, border-width: 0px;
.SCREEN { border-left-width: 2px;
border-color: #CFCFCF; border-color: black;
background-color: #F7F7F7; margin: 0.5ex;
} }
blockquote.NOTE, /* less dense spacing of TOC */
blockquote.TIP {
border-color: #DBDBCC;
background-color: #EEEEDD;
padding: 14px;
width: 572px;
}
blockquote.NOTE, .BOOK .TOC DL DT {
blockquote.TIP, padding-top: 1.5ex;
table.CAUTION, padding-bottom: 1.5ex;
table.WARNING {
margin: 4ex auto;
} }
blockquote.NOTE p, .BOOK .TOC DL DL DT {
blockquote.TIP p { padding-top: 0ex;
margin: 0; padding-bottom: 0ex;
} }
blockquote.NOTE pre, /* miscellaneous */
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, PRE.LITERALLAYOUT, .SCREEN, .SYNOPSIS, .PROGRAMLISTING {
.c2 { margin-left: 4ex;
font-weight: bold;
} }
.REPLACEABLE { .COMMENT { color: red; }
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, VAR { font-family: monospace; font-style: italic; }
table.CAUTION th, /* Konqueror's standard style for ACRONYM is italic. */
table.WARNING td, ACRONYM { font-style: inherit; }
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;
}

View File

@@ -1,174 +0,0 @@
<?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/chunk.xsl"/>
<xsl:include href="stylesheet-common.xsl" />
<xsl:include href="stylesheet-html-common.xsl" />
<xsl:include href="stylesheet-speedup-xhtml.xsl" />
<!-- Parameters -->
<xsl:param name="base.dir" select="'html/'"></xsl:param>
<xsl:param name="use.id.as.filename" select="'1'"></xsl:param>
<xsl:param name="generate.legalnotice.link" select="1"></xsl:param>
<xsl:param name="chunk.first.sections" select="1"/>
<xsl:param name="chunk.quietly" select="1"></xsl:param>
<xsl:param name="admon.style"></xsl:param> <!-- handled by CSS stylesheet -->
<xsl:param name="website.stylesheet" select="0"/>
<xsl:param name="html.stylesheet">
<xsl:choose>
<xsl:when test="$website.stylesheet = 0">stylesheet.css</xsl:when>
<xsl:otherwise>https://www.postgresql.org/media/css/docs.css</xsl:otherwise>
</xsl:choose>
</xsl:param>
<!-- strip directory name from image filerefs -->
<xsl:template match="imagedata/@fileref">
<xsl:value-of select="substring-after(., '/')"/>
</xsl:template>
<!--
Customization of header
- add Up and Home links
- add tool tips to links
(overrides html/chunk-common.xsl)
-->
<xsl:template name="header.navigation">
<xsl:param name="prev" select="/foo"/>
<xsl:param name="next" select="/foo"/>
<xsl:param name="nav.context"/>
<xsl:variable name="home" select="/*[1]"/>
<xsl:variable name="up" select="parent::*"/>
<xsl:variable name="row1" select="$navig.showtitles != 0"/>
<xsl:variable name="row2" select="count($prev) &gt; 0
or (count($up) &gt; 0
and generate-id($up) != generate-id($home)
and $navig.showtitles != 0)
or count($next) &gt; 0"/>
<xsl:if test="$suppress.navigation = '0' and $suppress.header.navigation = '0'">
<div class="navheader">
<xsl:if test="$row1 or $row2">
<table width="100%" summary="Navigation header">
<xsl:if test="$row1">
<tr>
<th colspan="5" align="center">
<xsl:apply-templates select="." mode="object.title.markup"/>
</th>
</tr>
</xsl:if>
<xsl:if test="$row2">
<tr>
<td width="10%" align="{$direction.align.start}">
<xsl:if test="count($prev)>0">
<a accesskey="p">
<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"/>
</xsl:attribute>
<xsl:call-template name="navig.content">
<xsl:with-param name="direction" select="'prev'"/>
</xsl:call-template>
</a>
</xsl:if>
<xsl:text>&#160;</xsl:text>
</td>
<td width="10%" align="{$direction.align.start}">
<xsl:choose>
<xsl:when test="count($up)&gt;0
and generate-id($up) != generate-id($home)">
<a accesskey="u">
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$up"/>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="title">
<xsl:apply-templates select="$up" mode="object.title.markup"/>
</xsl:attribute>
<xsl:call-template name="navig.content">
<xsl:with-param name="direction" select="'up'"/>
</xsl:call-template>
</a>
</xsl:when>
<xsl:otherwise>&#160;</xsl:otherwise>
</xsl:choose>
</td>
<th width="60%" align="center">
<xsl:choose>
<xsl:when test="count($up) > 0
and generate-id($up) != generate-id($home)
and $navig.showtitles != 0">
<xsl:apply-templates select="$up" mode="object.title.markup"/>
</xsl:when>
<xsl:otherwise>&#160;</xsl:otherwise>
</xsl:choose>
</th>
<td width="10%" align="{$direction.align.end}">
<xsl:choose>
<xsl:when test="$home != . or $nav.context = 'toc'">
<a accesskey="h">
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$home"/>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="title">
<xsl:apply-templates select="$home" mode="object.title.markup"/>
</xsl:attribute>
<xsl:call-template name="navig.content">
<xsl:with-param name="direction" select="'home'"/>
</xsl:call-template>
</a>
<xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'">
<xsl:text>&#160;|&#160;</xsl:text>
</xsl:if>
</xsl:when>
<xsl:otherwise>&#160;</xsl:otherwise>
</xsl:choose>
</td>
<td width="10%" align="{$direction.align.end}">
<xsl:text>&#160;</xsl:text>
<xsl:if test="count($next)>0">
<a accesskey="n">
<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"/>
</xsl:attribute>
<xsl:call-template name="navig.content">
<xsl:with-param name="direction" select="'next'"/>
</xsl:call-template>
</a>
</xsl:if>
</td>
</tr>
</xsl:if>
</table>
</xsl:if>
<xsl:if test="$header.rule != 0">
<hr/>
</xsl:if>
</div>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

View File

@@ -1,10 +1,10 @@
<chapter id="performing-switchover" xreflabel="Performing a switchover with repmgr"> <chapter id="performing-switchover" xreflabel="Performing a switchover with repmgr">
<title>Performing a switchover with repmgr</title>
<indexterm> <indexterm>
<primary>switchover</primary> <primary>switchover</primary>
</indexterm> </indexterm>
<title>Performing a switchover with repmgr</title>
<para> <para>
A typical use-case for replication is a combination of primary and standby A typical use-case for replication is a combination of primary and standby
server, with the standby serving as a backup which can easily be activated server, with the standby serving as a backup which can easily be activated
@@ -15,7 +15,7 @@
<para> <para>
In some cases however it's desirable to promote the standby in a planned In some cases however it's desirable to promote the standby in a planned
way, e.g. so maintenance can be performed on the primary; this kind of switchover way, e.g. so maintenance can be performed on the primary; this kind of switchover
is supported by the <xref linkend="repmgr-standby-switchover"/> command. is supported by the <xref linkend="repmgr-standby-switchover"> command.
</para> </para>
<para> <para>
<command>repmgr standby switchover</command> differs from other &repmgr; <command>repmgr standby switchover</command> differs from other &repmgr;
@@ -44,18 +44,17 @@
and capturing all output to assist troubleshooting any problems. and capturing all output to assist troubleshooting any problems.
</simpara> </simpara>
<simpara> <simpara>
Please also read carefully the sections <xref linkend="preparing-for-switchover"/> and Please also read carefully the sections <xref linkend="preparing-for-switchover"> and
<xref linkend="switchover-caveats"/> below. <xref linkend="switchover-caveats"> below.
</simpara> </simpara>
</note> </note>
<sect1 id="preparing-for-switchover" xreflabel="Preparing for switchover"> <sect1 id="preparing-for-switchover" xreflabel="Preparing for switchover">
<title>Preparing for switchover</title>
<indexterm> <indexterm>
<primary>switchover</primary> <primary>switchover</primary>
<secondary>preparation</secondary> <secondary>preparation</secondary>
</indexterm> </indexterm>
<title>Preparing for switchover</title>
<para> <para>
As mentioned in the previous section, success of the switchover operation depends on As mentioned in the previous section, success of the switchover operation depends on
@@ -73,8 +72,7 @@
Ensure that a passwordless SSH connection is possible from the promotion candidate Ensure that a passwordless SSH connection is possible from the promotion candidate
(standby) to the demotion candidate (current primary). If <literal>--siblings-follow</literal> (standby) to the demotion candidate (current primary). If <literal>--siblings-follow</literal>
will be used, ensure that passwordless SSH connections are possible from the will be used, ensure that passwordless SSH connections are possible from the
promotion candidate to all nodes attached to the demotion candidate promotion candidate to all standbys attached to the demotion candidate.
(including the witness server, if in use).
</para> </para>
<note> <note>
@@ -115,7 +113,7 @@
server. server.
</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>
</important> </important>
@@ -139,8 +137,8 @@
<note> <note>
<para> <para>
If an exclusive backup is running on the current primary, or if WAL replay is paused on the standby, If an exclusive backup is running on the current primary, &repmgr; will not perform the
&repmgr; will <emphasis>not</emphasis> perform the switchover. switchover.
</para> </para>
</note> </note>
@@ -160,12 +158,12 @@
<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
&repmgrd; instances to pause operations while the switchover <application>repmgrd</application> instances to pause operations while the switchover
is being carried out, to prevent &repmgrd; from is being carried out, to prevent <application>repmgrd</application> 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 &repmgrd; Users of &repmgr; versions prior to 4.2 should ensure that <application>repmgrd</application>
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>
@@ -205,19 +203,18 @@
<note> <note>
<simpara> <simpara>
See <xref linkend="repmgr-standby-switchover"/> for a full list of available See <xref linkend="repmgr-standby-switchover"> for a full list of available
command line options and <filename>repmgr.conf</filename> settings relevant command line options and <filename>repmgr.conf</filename> settings relevant
to performing a switchover. to performing a switchover.
</simpara> </simpara>
</note> </note>
<sect2 id="switchover-pg-rewind" xreflabel="Switchover and pg_rewind"> <sect2 id="switchover-pg-rewind" xreflabel="Switchover and pg_rewind">
<title>Switchover and pg_rewind</title>
<indexterm> <indexterm>
<primary>pg_rewind</primary> <primary>pg_rewind</primary>
<secondary>using with "repmgr standby switchover"</secondary> <secondary>using with "repmgr standby switchover"</secondary>
</indexterm> </indexterm>
<title>Switchover and pg_rewind</title>
<para> <para>
If the demotion candidate does not shut down smoothly or cleanly, there's a risk it If the demotion candidate does not shut down smoothly or cleanly, there's a risk it
will have a slightly divergent timeline and will not be able to attach to the new will have a slightly divergent timeline and will not be able to attach to the new
@@ -239,7 +236,7 @@
</note> </note>
<para> <para>
For more details on <application>pg_rewind</application>, see: For more details on <application>pg_rewind</application>, see:
<ulink url="https://www.postgresql.org/docs/current/app-pgrewind.html">https://www.postgresql.org/docs/current/app-pgrewind.html</ulink>. <ulink url="https://www.postgresql.org/docs/current/static/app-pgrewind.html">https://www.postgresql.org/docs/current/static/app-pgrewind.html</ulink>.
</para> </para>
<para> <para>
<application>pg_rewind</application> has been part of the core PostgreSQL distribution since <application>pg_rewind</application> has been part of the core PostgreSQL distribution since
@@ -260,12 +257,11 @@
</sect1> </sect1>
<sect1 id="switchover-execution" xreflabel="Executing the switchover command"> <sect1 id="switchover-execution" xreflabel="Executing the switchover command">
<title>Executing the switchover command</title>
<indexterm> <indexterm>
<primary>switchover</primary> <primary>switchover</primary>
<secondary>execution</secondary> <secondary>execution</secondary>
</indexterm> </indexterm>
<title>Executing the switchover command</title>
<para> <para>
To demonstrate switchover, we will assume a replication cluster with a To demonstrate switchover, we will assume a replication cluster with a
primary (<literal>node1</literal>) and one standby (<literal>node2</literal>); primary (<literal>node1</literal>) and one standby (<literal>node2</literal>);
@@ -316,13 +312,13 @@
</programlisting> </programlisting>
</para> </para>
<para> <para>
If &repmgrd; is in use, it's worth double-checking that If <application>repmgrd</application> is in use, it's worth double-checking that
all nodes are unpaused by executing <command><link linkend="repmgr-daemon-status">repmgr-daemon-status</link></command>. all nodes are unpaused by executing <command><link linkend="repmgr-daemon-status">repmgr-daemon-status</link></command>.
</para> </para>
<note> <note>
<para> <para>
Users of &repmgr; versions prior to 4.2 will need to manually restart &repmgrd; Users of &repmgr; versions prior to 4.2 will need to manually restart <application>repmgrd</application>
on all nodes after the switchover is completed. on all nodes after the switchover is completed.
</para> </para>
</note> </note>
@@ -331,11 +327,11 @@
<sect1 id="switchover-caveats" xreflabel="Caveats"> <sect1 id="switchover-caveats" xreflabel="Caveats">
<title>Caveats</title>
<indexterm> <indexterm>
<primary>switchover</primary> <primary>switchover</primary>
<secondary>caveats</secondary> <secondary>caveats</secondary>
</indexterm> </indexterm>
<title>Caveats</title>
<para> <para>
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
@@ -351,7 +347,7 @@
<simpara> <simpara>
<command>pg_rewind</command> *requires* that either <varname>wal_log_hints</varname> is enabled, or that <command>pg_rewind</command> *requires* that either <varname>wal_log_hints</varname> is enabled, or that
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">pg_rewind documentation</ulink> <ulink url="https://www.postgresql.org/docs/current/static/app-pgrewind.html">pg_rewind documentation</ulink>
for details. for details.
</simpara> </simpara>
</listitem> </listitem>
@@ -360,12 +356,11 @@
</sect1> </sect1>
<sect1 id="switchover-troubleshooting" xreflabel="Troubleshooting"> <sect1 id="switchover-troubleshooting" xreflabel="Troubleshooting">
<title>Troubleshooting switchover issues</title>
<indexterm> <indexterm>
<primary>switchover</primary> <primary>switchover</primary>
<secondary>troubleshooting</secondary> <secondary>troubleshooting</secondary>
</indexterm> </indexterm>
<title>Troubleshooting switchover issues</title>
<para> <para>
As <link linkend="performing-switchover">emphasised previously</link>, performing a switchover As <link linkend="performing-switchover">emphasised previously</link>, performing a switchover
@@ -423,7 +418,7 @@ HINT: stop backup before attempting the switchover</programlisting>
To proceed, either wait until the backup has finished, or cancel it with the command To proceed, either wait until the backup has finished, or cancel it with the command
<command>SELECT pg_stop_backup()</command>. For more details see the PostgreSQL <command>SELECT pg_stop_backup()</command>. For more details see the PostgreSQL
documentation section documentation section
<ulink url="https://www.postgresql.org/docs/current/continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP-EXCLUSIVE">Making an exclusive low level backup</ulink>. <ulink url="https://www.postgresql.org/docs/current/static/continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP-EXCLUSIVE">Making an exclusive low level backup</ulink>.
</para> </para>
</sect2> </sect2>
</sect1> </sect1>

View File

@@ -1,10 +1,10 @@
<chapter id="upgrading-repmgr" xreflabel="Upgrading repmgr"> <chapter id="upgrading-repmgr" xreflabel="Upgrading repmgr">
<title>Upgrading repmgr</title>
<indexterm> <indexterm>
<primary>upgrading</primary> <primary>upgrading</primary>
</indexterm> </indexterm>
<title>Upgrading repmgr</title>
<para> <para>
&repmgr; is updated regularly with minor releases (e.g. 4.0.1 to 4.0.2) &repmgr; is updated regularly with minor releases (e.g. 4.0.1 to 4.0.2)
@@ -13,19 +13,18 @@
</para> </para>
<sect1 id="upgrading-repmgr-extension" xreflabel="Upgrading repmgr 4.x and later"> <sect1 id="upgrading-repmgr-extension" xreflabel="Upgrading repmgr 4.x and later">
<title>Upgrading repmgr 4.x and later</title>
<indexterm> <indexterm>
<primary>upgrading</primary> <primary>upgrading</primary>
<secondary>repmgr 4.x and later</secondary> <secondary>repmgr 4.x and later</secondary>
</indexterm> </indexterm>
<title>Upgrading repmgr 4.x and later</title>
<para> <para>
From version 4, &repmgr; consists of three elements: From version 4, &repmgr; consists of three elements:
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
<simpara> <simpara>
the <application>repmgr</application> and &repmgrd; executables the <application>repmgr</application> and <application>repmgrd</application> executables
</simpara> </simpara>
</listitem> </listitem>
@@ -38,7 +37,7 @@
<listitem> <listitem>
<simpara> <simpara>
the shared library module used by &repmgrd; which the shared library module used by <application>repmgrd</application> which
is resident in the PostgreSQL backend is resident in the PostgreSQL backend
</simpara> </simpara>
</listitem> </listitem>
@@ -46,8 +45,8 @@
</para> </para>
<para> <para>
With <emphasis>minor releases</emphasis>, usually changes are only made to the <application>repmgr</application> With <emphasis>minor releases</emphasis>, usually changes are only made to the <application>repmgr</application>
and &repmgrd; executables. In this case, the upgrade is quite straightforward, and <application>repmgrd</application> executables. In this case, the upgrade is quite straightforward,
and is simply a case of installing the new version, and restarting &repmgrd; and is simply a case of installing the new version, and restarting <application>repmgrd</application>
(if running). (if running).
</para> </para>
@@ -64,12 +63,11 @@
</important> </important>
<sect2 id="upgrading-minor-version" xreflabel="Upgrading a minor version release"> <sect2 id="upgrading-minor-version" xreflabel="Upgrading a minor version release">
<title>Upgrading a minor version release</title>
<indexterm> <indexterm>
<primary>upgrading</primary> <primary>upgrading</primary>
<secondary>minor release</secondary> <secondary>minor release</secondary>
</indexterm> </indexterm>
<title>Upgrading a minor version release</title>
<para> <para>
The process for installing minor version upgrades is quite straightforward: The process for installing minor version upgrades is quite straightforward:
@@ -84,7 +82,7 @@
<listitem> <listitem>
<simpara> <simpara>
restart &repmgrd; on all nodes where it is running restart <application>repmgrd</application> on all nodes where it is running
</simpara> </simpara>
</listitem> </listitem>
@@ -95,7 +93,7 @@
<note> <note>
<para> <para>
Some packaging systems (e.g. <link linkend="packages-debian-ubuntu">Debian/Ubuntu</link> Some packaging systems (e.g. <link linkend="packages-debian-ubuntu">Debian/Ubuntu</link>
may restart &repmgrd; as part of the package upgrade process. may restart <application>repmgrd</application> as part of the package upgrade process.
</para> </para>
</note> </note>
@@ -120,17 +118,15 @@
</sect2> </sect2>
<sect2 id="upgrading-major-version" xreflabel="Upgrading a major version release"> <sect2 id="upgrading-major-version" xreflabel="Upgrading a major version release">
<title>Upgrading a major version release</title>
<indexterm> <indexterm>
<primary>upgrading</primary> <primary>upgrading</primary>
<secondary>major release</secondary> <secondary>major release</secondary>
</indexterm> </indexterm>
<title>Upgrading a major version release</title>
<para> <para>
&quot;major version&quot; upgrades need to be planned more carefully, as they may include &quot;major version&quot; upgrades need to be planned more carefully, as they may include
changes to the &repmgr; metadata (which need to be propagated from the primary to all changes to the &repmgr; metadata (which need to be propagated from the primary to all
standbys) and/or changes to the shared object file used by &repmgrd; standbys) and/or changes to the shared object file used by <application>repmgrd</application>
(which require a PostgreSQL restart). (which require a PostgreSQL restart).
</para> </para>
<para> <para>
@@ -142,14 +138,14 @@
<listitem> <listitem>
<simpara> <simpara>
Stop &repmgrd; (if in use) on all nodes where it is running. Stop <application>repmgrd</application> (if in use) on all nodes where it is running.
</simpara> </simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara> <simpara>
Disable the &repmgrd; service on all nodes where it is in use; Disable the <application>repmgrd</application> service on all nodes where it is in use;
this is to prevent packages from prematurely restarting &repmgrd;. this is to prevent packages from prematurely restarting <application>repmgrd</application>.
</simpara> </simpara>
</listitem> </listitem>
@@ -171,12 +167,12 @@ systemctl daemon-reload</programlisting>
<listitem> <listitem>
<simpara> <simpara>
If the &repmgr; shared library module has been updated (check the <link linkend="appendix-release-notes">release notes</link>!), If the &repmgr; shared library module has been updated (check the <link linkend="appendix-release-notes">release notes</link>!),
restart PostgreSQL, then &repmgrd; (if in use) on each node, restart PostgreSQL, then <application>repmgrd</application> (if in use) on each node,
The order in which this is applied to individual nodes is not critical, The order in which this is applied to individual nodes is not critical,
and it's also fine to restart PostgreSQL on all nodes first before starting &repmgrd;. and it's also fine to restart PostgreSQL on all nodes first before starting <application>repmgrd</application>.
</simpara> </simpara>
<simpara> <simpara>
Note that if the upgrade requires a PostgreSQL restart, &repmgrd; Note that if the upgrade requires a PostgreSQL restart, <application>repmgrd</application>
will only function correctly once all nodes have been restarted. will only function correctly once all nodes have been restarted.
</simpara> </simpara>
</listitem> </listitem>
@@ -192,7 +188,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
<listitem> <listitem>
<simpara> <simpara>
Reenable the &repmgrd; service on all nodes where it is in use, and Reenable the <application>repmgrd</application> service on all nodes where it is in use, and
ensure it is running. ensure it is running.
</simpara> </simpara>
</listitem> </listitem>
@@ -209,22 +205,19 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
</sect2> </sect2>
<sect2 id="upgrading-check-repmgrd" xreflabel="Checking repmgrd status after an upgrade"> <sect2 id="upgrading-check-repmgrd" xreflabel="Checking repmgrd status after an upgrade">
<title>Checking repmgrd status after an upgrade</title>
<indexterm> <indexterm>
<primary>upgrading</primary> <primary>upgrading</primary>
<secondary>checking repmgrd status</secondary> <secondary>checking repmgrd status</secondary>
</indexterm> </indexterm>
<title>Checking repmgrd status after an upgrade</title>
<para> <para>
From <link linkend="release-4.2">repmgr 4.2</link>, once the upgrade is complete, execute the <command><link linkend="repmgr-daemon-status">repmgr daemon status</link></command> From <link linkend="release-4.2">repmgr 4.2</link>, once the upgrade is complete, execute the <command><link linkend="repmgr-daemon-status">repmgr daemon status</link></command>
command (on any node) to show an overview of the status of &repmgrd; on all nodes. command (on any node) to show an overview of the status of <application>repmgrd</application> on all nodes.
</para> </para>
</sect2> </sect2>
</sect1> </sect1>
<sect1 id="upgrading-and-pg-upgrade" xreflabel="pg_upgrade and repmgr"> <sect1 id="upgrading-and-pg-upgrade" xreflabel="pg_upgrade and repmgr">
<title>pg_upgrade and repmgr</title>
<indexterm> <indexterm>
<primary>upgrading</primary> <primary>upgrading</primary>
<secondary>pg_upgrade</secondary> <secondary>pg_upgrade</secondary>
@@ -232,6 +225,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
<indexterm> <indexterm>
<primary>pg_upgrade</primary> <primary>pg_upgrade</primary>
</indexterm> </indexterm>
<title>pg_upgrade and repmgr</title>
<para> <para>
<application>pg_upgrade</application> requires that if any functions are <application>pg_upgrade</application> requires that if any functions are
@@ -253,7 +247,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
</simpara> </simpara>
</note> </note>
<para> <para>
For further details please see the <ulink url="https://www.postgresql.org/docs/current/pgupgrade.html">pg_upgrade documentation</ulink>. For further details please see the <ulink url="https://www.postgresql.org/docs/current/static/pgupgrade.html">pg_upgrade documentation</ulink>.
</para> </para>
<para> <para>
If replication slots are in use, bear in mind these will <emphasis>not</emphasis> If replication slots are in use, bear in mind these will <emphasis>not</emphasis>
@@ -271,13 +265,12 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
<sect1 id="upgrading-from-repmgr-3" xreflabel="Upgrading from repmgr 3.x"> <sect1 id="upgrading-from-repmgr-3" xreflabel="Upgrading from repmgr 3.x">
<title>Upgrading from repmgr 3.x</title>
<indexterm> <indexterm>
<primary>upgrading</primary> <primary>upgrading</primary>
<secondary>from repmgr 3.x</secondary> <secondary>from repmgr 3.x</secondary>
</indexterm> </indexterm>
<title>Upgrading from repmgr 3.x</title>
<para> <para>
The upgrade process consists of two steps: The upgrade process consists of two steps:
<orderedlist> <orderedlist>
@@ -339,7 +332,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
</listitem> </listitem>
<listitem> <listitem>
<simpara><varname>monitoring_history</varname>: this replaces the <simpara><varname>monitoring_history</varname>: this replaces the
&repmgrd; command line option <application>repmgrd</application> command line option
<literal>--monitoring-history</literal></simpara> <literal>--monitoring-history</literal></simpara>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@@ -390,7 +383,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
to the server configured in Barman (in &repmgr; 3, the deprecated to the server configured in Barman (in &repmgr; 3, the deprecated
<literal>cluster</literal> parameter was used for this); <literal>cluster</literal> parameter was used for this);
the physical Barman hostname is configured with the physical Barman hostname is configured with
<literal>barman_host</literal> (see <xref linkend="cloning-from-barman-prerequisites"/> <literal>barman_host</literal> (see <xref linkend="cloning-from-barman-prerequisites">
for details). for details).
</para> </para>
</note> </note>
@@ -440,7 +433,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
<sect2> <sect2>
<title>Upgrading the repmgr schema</title> <title>Upgrading the repmgr schema</title>
<para> <para>
Ensure &repmgrd; is not running, or any cron jobs which execute the Ensure <application>repmgrd</application> is not running, or any cron jobs which execute the
<command>repmgr</command> binary. <command>repmgr</command> binary.
</para> </para>
<para> <para>
@@ -506,7 +499,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
</para> </para>
<para> <para>
Check the data is updated as expected by examining the <structname>repmgr.nodes</structname> Check the data is updated as expected by examining the <structname>repmgr.nodes</structname>
table; restart &repmgrd; if required. table; restart <application>repmgrd</application> if required.
</para> </para>
<para> <para>
The original <literal>repmgr_$cluster</literal> schema can be dropped at any time. The original <literal>repmgr_$cluster</literal> schema can be dropped at any time.

1
doc/version.sgml Normal file
View File

@@ -0,0 +1 @@
<!ENTITY repmgrversion "4.2">

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