Compare commits

...

272 Commits

Author SHA1 Message Date
Ian Barwick
1337f68caf doc: note downstream node (dis)connection monitoring in more places 2020-06-09 16:42:45 +09:00
Ian Barwick
00494f1a15 repmgr 4.4.x is not compatible with PostgreSQL 12 or later 2020-02-14 10:42:38 +09:00
Ian Barwick
1460e6400a Add optional check for unsupported future PostgreSQL releases
This is for backbranches to prevent them running against newer
PostgreSQL versions with which they are not compatible, for example
4.4.x with PostgreSQL 12 and later.
2020-02-14 10:39:28 +09:00
Ian Barwick
daa7de1cd0 standby follow: don't attempt to delete slot if new upstream is same as current
An attempt will be made to delete an existing replication slot on the
old upstream node (this is important during e.g. a switchover operation
or when attaching a cascaded standby to a new upstream). However if the
standby is currently attached to the follow target node anyway, the
replication slot should never be deleted.
2019-12-10 15:58:45 +09:00
Ian Barwick
0fbc0f42b5 Prevent use of backend string functions
From PostgreSQL 12, port.h forcibly redefines printf() et al to use
the versions defined by PostgreSQL (pg_printf() et al). As this
causes linking issues in build environments which build pre-Pg12
versions against Pg12's libpq, ensure relevant macros defined
in port.h are undefined.
2019-10-09 09:12:58 +09:00
Ian Barwick
34aa54b766 doc: clarify use of --recovery-conf-only 2019-10-08 10:04:23 +09:00
Ian Barwick
01ec64c330 doc: fix minor formatting error 2019-10-08 10:04:19 +09:00
Ian Barwick
41637f0c43 doc: improve instructions for cloning from Barman 2019-10-07 11:58:04 +09:00
Ian Barwick
b61989bafe doc: improve Barman standby clone example 2019-10-07 11:58:01 +09:00
Ian Barwick
c2987b6c9b doc: clarify barman-cli package usage
As of Barman 2.8, the barman-cli package has been merged with the core
Barman code, so is only requires an explicit mention for Barman 2.0 ~ 2.7.
2019-10-07 11:57:58 +09:00
Ian Barwick
c6d151ef56 doc: remove reference to Barman 1.x.
Barman 1.x is very outdated and should no longer be used anyway.
2019-10-07 11:57:54 +09:00
Ian Barwick
867ebcb52d repmgr: note that --dry-run is not effective with "repmgr daemon status" 2019-08-28 15:17:01 +09:00
Ian Barwick
9abf72af07 doc: fix link text 2019-08-28 15:12:45 +09:00
Ian Barwick
2256c0a81f repmgrd: fix pidfile handling at shutdown 2019-08-19 20:16:21 +09:00
Ian Barwick
701fdd9622 Use appendPQExpBufferStr where appropriate 2019-08-13 16:32:56 +09:00
Ian Barwick
5c1ca6cba5 doc: mention not to use --siblings-follow in the repmgrd promote command
This is noted on the "repmgr standby promote" page but needs repeating
on the repmgrd configuration page.
2019-08-13 11:36:15 +09:00
Ian Barwick
2dce4b06b4 repmgrd: emit node name when reporting follow target attach error
This is consistent with other error messages.
2019-08-13 11:07:07 +09:00
Ian Barwick
f1716a67b0 "standby clone": improve error messages related to extension status
Previously repmgr would emit the "repmgr extension not found on source node"
which depending on context is somewhat misleading, as it may exist
but not be installed, or the user may be attempting to clone from the
wrong database.
2019-08-07 16:45:42 +09:00
Ian Barwick
1d43f1cdb5 Simplify pg_has_role() call
Specifying CURRENT_USER is superfluous here.
2019-08-07 14:42:11 +09:00
Ian Barwick
7cc12f08ed "node check": check role membership when trying to read pg_settings
From PostgreSQL 10, a member of the default roles "pg_monitor" and/or
"pg_read_all_settings" can read pg_settings without requiring superuser
privileges.

Previously, a hint was being emitted about making the repmgr user a
member of one of those groups, but no check for membership was being
made, meaning the check could only be run by a superuser.
2019-08-07 14:27:26 +09:00
Ian Barwick
8484bc6687 Add missing field in init_replication_info()
"upstream_node_id" was not being initialised.
2019-08-07 13:22:54 +09:00
Ian Barwick
d92d008cb3 doc: add note about parallel restore from Barman 2019-07-18 09:26:27 +09:00
Ian Barwick
38adf5daca Add 4.4 release date 2019-07-09 11:32:18 +09:00
Ian Barwick
4a8684e37b doc: define entity &releasedate;
This should be used wherever we need to show the latest release
date.

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

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

Per notification from the mailing list.
2019-07-09 11:10:15 +09:00
Ian Barwick
0e1319d788 doc: update release notes 2019-07-04 11:22:06 +09:00
Ian Barwick
9c784f804e doc: update "repmgr cluster show" examples 2019-06-27 15:36:09 +09:00
Ian Barwick
13097e30f0 doc: fix typo 2019-06-27 15:33:49 +09:00
Ian Barwick
40b6c92129 doc: update release notes
Finalize release date.
2019-06-26 15:57:17 +09:00
Ian Barwick
761d65526c Finalize version number
4.4
2019-06-26 15:56:33 +09:00
Ian Barwick
a13a1232e9 doc: document optional configuration settings 2019-06-20 16:50:30 +09:00
Ian Barwick
65965b3ba4 4.4rc1 2019-06-20 16:21:54 +09:00
Ian Barwick
629d2b8f85 doc: clean up release notes
Remove tabs.
2019-06-20 16:18:41 +09:00
Ian Barwick
23c285b73b doc: fix typo 2019-06-12 16:29:17 +09:00
Ian Barwick
915fb7d617 note that "standby follow" requires a primary to be available
While it's technically possible to have a standby follow another
standby while the primary is not available, repmgr will not be able
to update its metadata, which will cause Confusion and Chaos.

Update the documentation to make this clear, and provide a more helpful
error message if this situation occurs. The operation previously
failed anyway, but with an unhelpful message about not being able to
find a node record.
2019-06-11 15:18:41 +09:00
Ian Barwick
ae141b9d32 4.4beta2 2019-06-10 15:18:41 +09:00
Ian Barwick
d035550723 doc: add missing space 2019-06-10 09:02:51 +09:00
Ian Barwick
c7692b5d84 doc: improve repmgr.conf settings documentation 2019-06-07 12:50:05 +09:00
Ian Barwick
08b7f1294b doc: improve configuration documentation 2019-06-07 12:17:49 +09:00
Ian Barwick
81d01bf0e8 Canonicalize the data directory path when parsing the configuration file
This ensures the provided path matches the path PostgreSQL reports as its
data directory.
2019-06-07 09:53:44 +09:00
Ian Barwick
089c778e49 Fix extension version number query 2019-06-06 12:46:30 +09:00
Ian Barwick
b4b5681762 standby follow: remove some ineffective code
For some reason we were taking the trouble to extract an appliction_name
from the local node's conninfo, but this was being subsequently overwritten
with the node name (which is what we want anyway).
2019-06-06 12:15:23 +09:00
Ian Barwick
e5ef549aa7 doc: update release notes 2019-06-06 11:30:43 +09:00
Ian Barwick
cfc41392c3 Ensure parsed value of --upstream-conninfo is written to recovery.conf
Previously it was being parsed (a step which ensures any "application_name"
set by the caller is changed to the node name), but the original string
was being copied to "primary_conninfo" anyway.
2019-06-06 11:30:40 +09:00
Ian Barwick
55dc4f7a5f Remove redundant comment in .sql files 2019-06-04 13:46:30 +09:00
Ian Barwick
6616712346 4.4beta1 2019-06-04 13:22:56 +09:00
Ian Barwick
d893ce227b repmgrd: optionally exclude/include witness server from child node checks 2019-06-03 16:04:54 +09:00
Ian Barwick
e8731f8159 doc: update child node monitoring documentation 2019-06-03 16:04:51 +09:00
Ian Barwick
20d710e34c doc: update filename referenced in code comment 2019-06-03 15:30:02 +09:00
Ian Barwick
7e8710b1e9 doc: remove redundant entity definitions 2019-06-03 15:29:08 +09:00
Ian Barwick
19e8387d8f doc: remove mistakenly committed .sgml file 2019-05-30 19:58:06 +09:00
Ian Barwick
b5ff2ec120 repmgrd: update log text 2019-05-30 16:08:04 +09:00
Ian Barwick
0a4072b8f7 witness (un)register: add event details
Also create an actual event notification for both actions, rather
than just creating the event record.

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

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

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

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

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

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

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

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

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

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

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

Main formatting changes are:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Before:

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

After:

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

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

3. Don't delete configure.

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

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

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

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

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

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

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

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

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

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

This feature is experimental.
2019-02-23 13:03:22 +09:00
128 changed files with 12620 additions and 4659 deletions

5
.gitignore vendored
View File

@@ -42,11 +42,12 @@ 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

74
HISTORY
View File

@@ -1,9 +1,46 @@
4.3 2019-?? 4.4.1 2019-??-??
repmgr: improve data directory check (Ian)
repmgr: improve extension check during "standby clone" (Ian)
4.4 2019-06-27
repmgr: improve "daemon status" output (Ian)
repmgr: add "--siblings-follow" option to "standby promote" (Ian)
repmgr: add "--repmgrd-force-unpause" option to "standby switchover" (Ian)
repmgr: fix data directory permissions issue in barman mode where
an existing directory is being overwritten (Ian)
repmgr: improve "--dry-run" behaviour for "standby promote" and
"standby switchover" (Ian)
repmgr: when running "standby clone" with the "--upstream-conninfo" option
ensure that "application_name" is set correctly in "primary_conninfo" (Ian)
repmgr: ensure "--dry-run" together with --force when running "standby clone"
in barman mode does not modify an existing data directory (Ian)
repmgr: improve "--dry-run" output when running "standby clone" in
basebackup mode (Ian)
repmgr: improve upstream walsender checks when running "standby clone" (Ian)
repmgr: display node timeline ID in "cluster show" output (Ian)
repmgr: in "cluster show" and "daemon status", show upstream node name
as reported by each individual node (Ian)
repmgr: in "cluster show" and "daemon status", check if a node is attached
to its advertised upstream node
repmgr: use --compact rather than --terse option in "cluster event" (Ian)
repmgr: prevent a standby being cloned from a witness server (Ian)
repmgr: prevent a witness server being registered on the cluster primary (John)
repmgr: ensure BDR2-specific functionality cannot be used on
BDR3 and later (Ian)
repmgr: canonicalize the data directory path (Ian)
repmgr: note that "standby follow" requires a primary to be available (Ian)
repmgrd: monitor standbys attached to primary (Ian)
repmgrd: add "primary visibility consensus" functionality (Ian)
repmgrd: fix memory leak which occurs while the monitored PostgreSQL
node is not running (Ian)
general: documentation converted to DocBook XML format (Ian)
4.3 2019-04-02
repmgr: add "daemon (start|stop)" command; GitHub #528 (Ian) repmgr: add "daemon (start|stop)" command; GitHub #528 (Ian)
repmgr: add --version-number command line option (Ian) repmgr: add --version-number command line option (Ian)
repmgr: add --compact option to "cluster show"; GitHub #521 (Ian) repmgr: add --compact option to "cluster show"; GitHub #521 (Ian)
repmgr: cluster show - differentiate between unreachable nodes repmgr: cluster show - differentiate between unreachable nodes
and nodes which are running but rejecting connections (Ian) and nodes which are running but rejecting connections (Ian)
repmgr: add --dry-run option to "standby promote"; GitHub #522 (Ian) repmgr: add --dry-run option to "standby promote"; GitHub #522 (Ian)
repmgr: add "node check --data-directory-config"; GitHub #523 (Ian) repmgr: add "node check --data-directory-config"; GitHub #523 (Ian)
repmgr: prevent potential race condition in "standby switchover" repmgr: prevent potential race condition in "standby switchover"
@@ -11,29 +48,22 @@
repmgr: ensure "standby switchover" verifies repmgr can read the repmgr: ensure "standby switchover" verifies repmgr can read the
data directory on the demotion candidate; GitHub #523 (Ian) data directory on the demotion candidate; GitHub #523 (Ian)
repmgr: ensure "standby switchover" verifies replication connection repmgr: ensure "standby switchover" verifies replication connection
exists; GitHub #519 (Ian) exists; GitHub #519 (Ian)
repmgr: ensure "primary unregister" behaves correctly when executed
on a witness server; GitHub #548 (Ian)
repmgr: when executing "standby follow" and "node rejoin", check that
it will actually be possible to stream from the target node (Ian)
repmgr: "standby switchover": improve handling of connection URIs when
executing "node rejoin" on the demotion candidate; GitHub #525 (Ian)
repmgr: fix long node ID display in "cluster show" (Ian)
repmgr: check for primary server before executing "witness register";
GitHub #538 (Ian)
repmgr: show "upstream last seen" interval in "daemon status" output (Ian)
repmgr: "node check" will only consider physical replication slots (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)
4.2.1 2018-??-??
repmgr: add sanity check for correct extension version (Ian) repmgr: add sanity check for correct extension version (Ian)
repmgr: ensure "witness register --dry-run" does not attempt to read node repmgr: ensure "witness register --dry-run" does not attempt to read node
tables if repmgr extension not installed; GitHub #513 (Ian) 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: 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";

View File

@@ -24,4 +24,5 @@ include $(PGXS)
-include ${repmgr_abs_srcdir}/Makefile.custom -include ${repmgr_abs_srcdir}/Makefile.custom
REPMGR_VERSION=$(shell awk '/^\#define REPMGR_VERSION / { print $3; }' ${repmgr_abs_srcdir}/repmgr_version.h.in | cut -d '"' -f 2) REPMGR_VERSION=$(shell awk '/^\#define REPMGR_VERSION / { print $3; }' ${repmgr_abs_srcdir}/repmgr_version.h.in | cut -d '"' -f 2)
REPMGR_RELEASE_DATE=$(shell awk '/^\#define REPMGR_RELEASE_DATE / { print $3; }' ${repmgr_abs_srcdir}/repmgr_version.h.in | cut -d '"' -f 2)

View File

@@ -17,7 +17,9 @@ DATA = \
repmgr--4.1--4.2.sql \ repmgr--4.1--4.2.sql \
repmgr--4.2.sql \ repmgr--4.2.sql \
repmgr--4.2--4.3.sql \ repmgr--4.2--4.3.sql \
repmgr--4.3.sql repmgr--4.3.sql \
repmgr--4.3--4.4.sql \
repmgr--4.4.sql
REGRESS = repmgr_extension REGRESS = repmgr_extension
@@ -50,8 +52,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 configfile.o log.o strutil.o controldata.o dirutil.o compat.o dbutils.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 REPMGRD_OBJS = repmgrd.o repmgrd-physical.o repmgrd-bdr.o configfile.o log.o dbutils.o strutil.o controldata.o compat.o sysutils.o
DATE=$(shell date "+%Y-%m-%d") DATE=$(shell date "+%Y-%m-%d")
repmgr_version.h: repmgr_version.h.in repmgr_version.h: repmgr_version.h.in
@@ -75,10 +77,19 @@ Makefile: Makefile.in config.status configure
Makefile.global: Makefile.global.in config.status configure Makefile.global: Makefile.global.in config.status configure
./config.status $@ ./config.status $@
doc: doc: repmgr_version.h
$(MAKE) -C doc all $(MAKE) -C doc html
install-doc: doc-repmgr.html: repmgr_version.h
$(MAKE) -C doc repmgr.html
doc-repmgr-A4.pdf: repmgr_version.h
$(MAKE) -C doc repmgr-A4.pdf
doc-repmgr-US.pdf: repmgr_version.h
$(MAKE) -C doc repmgr-US.pdf
install-doc: doc
$(MAKE) -C doc install $(MAKE) -C doc install
clean: additional-clean clean: additional-clean
@@ -86,29 +97,16 @@ clean: additional-clean
maintainer-clean: additional-maintainer-clean maintainer-clean: additional-maintainer-clean
additional-clean: additional-clean:
rm -f repmgr-client.o rm -f *.o
rm -f repmgr-action-primary.o $(MAKE) -C doc clean
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
maintainer-additional-clean: clean additional-maintainer-clean: clean
rm -f configure $(MAKE) -C doc maintainer-clean
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))
@@ -123,3 +121,4 @@ installdirs-scripts:
.PHONY: installdirs-scripts .PHONY: installdirs-scripts
endif endif
.PHONY: doc doc-repmgr.html doc-repmgr-A4.pdf doc-repmgr-US.pdf install-doc

View File

@@ -27,7 +27,7 @@ Documentation
The main `repmgr` documentation is available here: The main `repmgr` documentation is available here:
> [repmgr 4 documentation](https://repmgr.org/docs/4.2/index.html) > [repmgr documentation](https://repmgr.org/docs/current/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://www.repmgr.org/ Further information is available at https://repmgr.org/
We'd love to hear from you about how you use repmgr. Case studies and We'd love to hear from you about how you use repmgr. Case studies and
news are always welcome. Send us an email at info@2ndQuadrant.com, or news are always welcome. Send us an email at info@2ndQuadrant.com, or
@@ -97,6 +97,7 @@ 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

@@ -344,7 +344,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, MAXLEN); strncpy(options->location, DEFAULT_LOCATION, sizeof(options->location));
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,6 +358,19 @@ _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
@@ -478,21 +491,34 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
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) < NAMEDATALEN) if (strlen(value) < sizeof(options->replication_user))
strncpy(options->replication_user, value, NAMEDATALEN); strncpy(options->replication_user, value, sizeof(options->replication_user));
else else
item_list_append(error_list, item_list_append_format(error_list,
_("value for \"replication_user\" must contain fewer than " STR(NAMEDATALEN) " characters")); _("value for \"replication_user\" must contain fewer than %lu 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);
@@ -618,6 +644,48 @@ _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)
@@ -792,15 +860,16 @@ _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)
{ {
char error_message_buf[MAXLEN] = ""; PQExpBufferData error_message_buf;
initPQExpBuffer(&error_message_buf);
snprintf(error_message_buf, appendPQExpBuffer(&error_message_buf,
MAXLEN, _("\"conninfo\": %s (provided: \"%s\")"),
_("\"conninfo\": %s (provided: \"%s\")"), conninfo_errmsg,
conninfo_errmsg, options->conninfo);
options->conninfo);
item_list_append(error_list, error_message_buf); item_list_append(error_list, error_message_buf.data);
termPQExpBuffer(&error_message_buf);
} }
PQconninfoFree(conninfo_options); PQconninfoFree(conninfo_options);
@@ -1049,15 +1118,25 @@ 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: * changeable options (keep the list in "doc/repmgrd-configuration.xml" in sync
* 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
@@ -1065,12 +1144,19 @@ 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)
@@ -1149,13 +1235,12 @@ 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, MAXLEN) != 0) if (strncmp(new_options.node_name, orig_options->node_name, sizeof(orig_options->node_name)) != 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
* *
@@ -1192,8 +1277,95 @@ 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, MAXLEN) != 0) if (strncmp(orig_options->conninfo, new_options.conninfo, sizeof(orig_options->conninfo)) != 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);
@@ -1203,11 +1375,14 @@ reload_config(t_configuration_options *orig_options, t_server_type server_type)
} }
else else
{ {
strncpy(orig_options->conninfo, new_options.conninfo, MAXLEN); snprintf(orig_options->conninfo, sizeof(orig_options->conninfo),
"%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 */
@@ -1220,18 +1395,20 @@ 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, MAXLEN) != 0) if (strncmp(orig_options->event_notification_command, new_options.event_notification_command, sizeof(orig_options->event_notification_command)) != 0)
{ {
strncpy(orig_options->event_notification_command, new_options.event_notification_command, MAXLEN); snprintf(orig_options->event_notification_command, sizeof(orig_options->event_notification_command),
"%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, MAXLEN) != 0) if (strncmp(orig_options->event_notifications_orig, new_options.event_notifications_orig, sizeof(orig_options->event_notifications_orig)) != 0)
{ {
strncpy(orig_options->event_notifications_orig, new_options.event_notifications_orig, MAXLEN); snprintf(orig_options->event_notifications_orig, sizeof(orig_options->event_notifications_orig),
"%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);
@@ -1249,9 +1426,10 @@ 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, MAXLEN) != 0) if (strncmp(orig_options->follow_command, new_options.follow_command, sizeof(orig_options->follow_command)) != 0)
{ {
strncpy(orig_options->follow_command, new_options.follow_command, MAXLEN); snprintf(orig_options->follow_command, sizeof(orig_options->follow_command),
"%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;
@@ -1284,11 +1462,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, MAXLEN) != 0) if (strncmp(orig_options->promote_command, new_options.promote_command, sizeof(orig_options->promote_command)) != 0)
{ {
strncpy(orig_options->promote_command, new_options.promote_command, MAXLEN); snprintf(orig_options->promote_command, sizeof(orig_options->promote_command),
"%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;
@@ -1330,23 +1508,71 @@ 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, MAXLEN) != 0) if (strncmp(orig_options->log_facility, new_options.log_facility, sizeof(orig_options->log_facility)) != 0)
{ {
strncpy(orig_options->log_facility, new_options.log_facility, MAXLEN); snprintf(orig_options->log_facility, sizeof(orig_options->log_facility),
"%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, MAXLEN) != 0) if (strncmp(orig_options->log_file, new_options.log_file, sizeof(orig_options->log_file)) != 0)
{ {
strncpy(orig_options->log_file, new_options.log_file, MAXLEN); snprintf(orig_options->log_file, sizeof(orig_options->log_file),
"%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;
@@ -1354,9 +1580,10 @@ 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, MAXLEN) != 0) if (strncmp(orig_options->log_level, new_options.log_level, sizeof(orig_options->log_level)) != 0)
{ {
strncpy(orig_options->log_level, new_options.log_level, MAXLEN); snprintf(orig_options->log_level, sizeof(orig_options->log_level),
"%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;
@@ -1850,18 +2077,10 @@ 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 */
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 * We're only interested in these options.
* 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'},
@@ -1870,6 +2089,17 @@ 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;
@@ -1877,7 +2107,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_9; long_options = long_options_legacy;
argc_item = parse_output_to_argv(pg_basebackup_options, &argv_array); argc_item = parse_output_to_argv(pg_basebackup_options, &argv_array);
@@ -1896,7 +2126,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->xlog_method, optarg, MAXLEN); strncpy(backup_options->wal_method, optarg, MAXLEN);
break; break;
case 1: case 1:
backup_options->no_slot = true; backup_options->no_slot = true;
@@ -1927,3 +2157,21 @@ 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

@@ -37,6 +37,13 @@ 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;
@@ -69,7 +76,7 @@ typedef struct
{ {
/* node information */ /* node information */
int node_id; int node_id;
char node_name[MAXLEN]; char node_name[NAMEDATALEN];
char conninfo[MAXLEN]; char conninfo[MAXLEN];
char replication_user[NAMEDATALEN]; char replication_user[NAMEDATALEN];
char data_directory[MAXPGPATH]; char data_directory[MAXPGPATH];
@@ -81,7 +88,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[MAXLEN]; char log_file[MAXPGPATH];
int log_status_interval; int log_status_interval;
/* standby clone settings */ /* standby clone settings */
@@ -135,6 +142,18 @@ 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;
@@ -179,7 +198,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 */ \
@@ -205,8 +224,14 @@ 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, "", \ -1, "", false, DEFAULT_SIBLING_NODES_DISCONNECT_TIMEOUT, \
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 */ \
@@ -228,7 +253,7 @@ typedef struct
typedef struct typedef struct
{ {
char slot[MAXLEN]; char slot[MAXLEN];
char xlog_method[MAXLEN]; char wal_method[MAXLEN];
bool no_slot; /* from PostgreSQL 10 */ bool no_slot; /* from PostgreSQL 10 */
} t_basebackup_options; } t_basebackup_options;
@@ -315,5 +340,6 @@ 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_ */

21
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for repmgr 4.3. # Generated by GNU Autoconf 2.69 for repmgr 4.4.
# #
# Report bugs to <repmgr@googlegroups.com>. # Report bugs to <repmgr@googlegroups.com>.
# #
@@ -582,8 +582,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='repmgr' PACKAGE_NAME='repmgr'
PACKAGE_TARNAME='repmgr' PACKAGE_TARNAME='repmgr'
PACKAGE_VERSION='4.3' PACKAGE_VERSION='4.4'
PACKAGE_STRING='repmgr 4.3' PACKAGE_STRING='repmgr 4.4'
PACKAGE_BUGREPORT='repmgr@googlegroups.com' PACKAGE_BUGREPORT='repmgr@googlegroups.com'
PACKAGE_URL='https://repmgr.org/' PACKAGE_URL='https://repmgr.org/'
@@ -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.3 to adapt to many kinds of systems. \`configure' configures repmgr 4.4 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.3:";; short | recursive ) echo "Configuration of repmgr 4.4:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1313,7 +1313,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
repmgr configure 4.3 repmgr configure 4.4
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.
@@ -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.3, which was It was created by repmgr $as_me 4.4, 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,8 +1851,6 @@ ac_config_files="$ac_config_files Makefile"
ac_config_files="$ac_config_files Makefile.global" ac_config_files="$ac_config_files Makefile.global"
ac_config_files="$ac_config_files doc/Makefile"
cat >confcache <<\_ACEOF cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure # This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure # tests run on this system so they can be shared between configure
@@ -2359,7 +2357,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by repmgr $as_me 4.3, which was This file was extended by repmgr $as_me 4.4, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -2422,7 +2420,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
repmgr config.status 4.3 repmgr config.status 4.4
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"
@@ -2546,7 +2544,6 @@ do
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"Makefile.global") CONFIG_FILES="$CONFIG_FILES Makefile.global" ;; "Makefile.global") CONFIG_FILES="$CONFIG_FILES Makefile.global" ;;
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac esac

View File

@@ -1,4 +1,4 @@
AC_INIT([repmgr], [4.3], [repmgr@googlegroups.com], [repmgr], [https://repmgr.org/]) AC_INIT([repmgr], [4.4], [repmgr@googlegroups.com], [repmgr], [https://repmgr.org/])
AC_COPYRIGHT([Copyright (c) 2010-2019, 2ndQuadrant Ltd.]) AC_COPYRIGHT([Copyright (c) 2010-2019, 2ndQuadrant Ltd.])
@@ -59,6 +59,5 @@ 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

@@ -301,6 +301,8 @@ 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;
} }
@@ -308,7 +310,18 @@ get_controlfile(const char *DataDir)
control_file_info->control_file_processed = true; control_file_info->control_file_processed = true;
if (version_num >= 110000) if (version_num >= 120000)
{
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;

View File

@@ -333,6 +333,72 @@ 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 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);

746
dbutils.c

File diff suppressed because it is too large Load Diff

109
dbutils.h
View File

@@ -29,7 +29,38 @@
#include "strutil.h" #include "strutil.h"
#include "voting.h" #include "voting.h"
#define REPMGR_NODES_COLUMNS "n.node_id, n.type, n.upstream_node_id, n.node_name, n.conninfo, n.repluser, n.slot_name, n.location, n.priority, n.active, n.config_file, '' AS upstream_node_name " #define REPMGR_NODES_COLUMNS \
"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"
@@ -92,6 +123,13 @@ 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,
@@ -107,6 +145,7 @@ typedef enum
} BackupState; } BackupState;
/* /*
* Struct to store extension version information * Struct to store extension version information
*/ */
@@ -125,8 +164,28 @@ typedef struct s_extension_versions {
UNKNOWN_SERVER_VERSION_NUM \ UNKNOWN_SERVER_VERSION_NUM \
} }
typedef struct
{
char current_timestamp[MAXLEN];
bool in_recovery;
TimeLineID timeline_id;
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
{ {
@@ -134,8 +193,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[MAXLEN]; char node_name[NAMEDATALEN];
char upstream_node_name[MAXLEN]; char upstream_node_name[NAMEDATALEN];
char conninfo[MAXLEN]; char conninfo[MAXLEN];
char repluser[NAMEDATALEN]; char repluser[NAMEDATALEN];
char location[MAXLEN]; char location[MAXLEN];
@@ -152,7 +211,7 @@ typedef struct s_node_info
/* for ad-hoc use e.g. when working with a list of nodes */ /* for ad-hoc use e.g. when working with a list of nodes */
char details[MAXLEN]; char details[MAXLEN];
bool reachable; bool reachable;
bool attached; NodeAttached attached;
/* various statistics */ /* various statistics */
int max_wal_senders; int max_wal_senders;
int attached_wal_receivers; int attached_wal_receivers;
@@ -160,6 +219,8 @@ typedef struct s_node_info
int total_replication_slots; int total_replication_slots;
int active_replication_slots; int active_replication_slots;
int inactive_replication_slots; int inactive_replication_slots;
/* replication info */
ReplInfo *replication_info;
} t_node_info; } t_node_info;
@@ -186,7 +247,8 @@ typedef struct s_node_info
/* for ad-hoc use e.g. when working with a list of nodes */ \ /* for ad-hoc use e.g. when working with a list of nodes */ \
"", true, true, \ "", true, true, \
/* various statistics */ \ /* various statistics */ \
-1, -1, -1, -1, -1, -1 \ -1, -1, -1, -1, -1, -1, \
NULL \
} }
@@ -299,16 +361,7 @@ typedef struct BdrNodeInfoList
0 \ 0 \
} }
typedef struct
{
char current_timestamp[MAXLEN];
XLogRecPtr last_wal_receive_lsn;
XLogRecPtr last_wal_replay_lsn;
char last_xact_replay_timestamp[MAXLEN];
int replication_lag_time;
bool receiving_streamed_wal;
bool wal_replay_paused;
} ReplInfo;
typedef struct typedef struct
{ {
@@ -385,6 +438,7 @@ PGconn *get_primary_connection(PGconn *standby_conn, int *primary_id, char *p
PGconn *get_primary_connection_quiet(PGconn *standby_conn, int *primary_id, char *primary_conninfo_out); PGconn *get_primary_connection_quiet(PGconn *standby_conn, int *primary_id, char *primary_conninfo_out);
bool is_superuser_connection(PGconn *conn, t_connection_user *userinfo); bool is_superuser_connection(PGconn *conn, t_connection_user *userinfo);
bool connection_has_pg_settings(PGconn *conn);
void close_connection(PGconn **conn); void close_connection(PGconn **conn);
/* conninfo manipulation functions */ /* conninfo manipulation functions */
@@ -412,8 +466,10 @@ 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);
@@ -423,6 +479,7 @@ RecoveryType get_recovery_type(PGconn *conn);
int get_primary_node_id(PGconn *conn); int get_primary_node_id(PGconn *conn);
int get_ready_archive_files(PGconn *conn, const char *data_directory); int get_ready_archive_files(PGconn *conn, const char *data_directory);
bool identify_system(PGconn *repl_conn, t_system_identification *identification); bool identify_system(PGconn *repl_conn, t_system_identification *identification);
uint64 system_identifier(PGconn *conn);
TimeLineHistoryEntry *get_timeline_history(PGconn *repl_conn, TimeLineID tli); TimeLineHistoryEntry *get_timeline_history(PGconn *repl_conn, TimeLineID tli);
/* repmgrd shared memory functions */ /* repmgrd shared memory functions */
@@ -435,6 +492,9 @@ 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);
@@ -463,6 +523,7 @@ 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);
@@ -509,12 +570,14 @@ 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, long long timeout); int wait_connection_availability(PGconn *conn, int 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
@@ -549,12 +612,14 @@ XLogRecPtr get_primary_current_lsn(PGconn *conn);
XLogRecPtr get_node_current_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); 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, 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_primary_last_seen(PGconn *conn); void set_upstream_last_seen(PGconn *conn, int upstream_node_id);
int get_primary_last_seen(PGconn *conn); int get_upstream_last_seen(PGconn *conn, t_server_type node_type);
bool is_wal_replay_paused(PGconn *conn, bool check_pending_wal); bool is_wal_replay_paused(PGconn *conn, bool check_pending_wal);
/* BDR functions */ /* BDR functions */

View File

@@ -276,6 +276,8 @@ 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;
} }
@@ -334,6 +336,15 @@ 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;
} }
@@ -345,6 +356,15 @@ 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;

8
doc/.gitignore vendored
View File

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

102
doc/Makefile Normal file
View File

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

View File

@@ -1,76 +0,0 @@
repmgr_subdir = doc
repmgr_top_builddir = ..
include $(repmgr_top_builddir)/Makefile.global
ifndef JADE
JADE = $(missing) jade
endif
SGMLINCLUDE = -D . -D ${srcdir}
SPFLAGS += -wall -wno-unused-param -wno-empty -wfully-tagged
JADE.html.call = $(JADE) $(JADEFLAGS) $(SPFLAGS) $(SGMLINCLUDE) $(CATALOG) -t sgml -i output-html
ALLSGML := $(wildcard $(srcdir)/*.sgml)
# to build bookindex
ALMOSTALLSGML := $(filter-out %bookindex.sgml,$(ALLSGML))
GENERATED_SGML = version.sgml bookindex.sgml
Makefile: Makefile.in
cd $(repmgr_top_builddir) && ./config.status doc/Makefile
all: html
html: html-stamp
html-stamp: repmgr.sgml $(ALLSGML) $(GENERATED_SGML) stylesheet.dsl website-docs.css
$(MKDIR_P) html
$(JADE.html.call) -d stylesheet.dsl -i include-index $<
cp $(srcdir)/stylesheet.css $(srcdir)/website-docs.css html/
touch $@
repmgr.html: repmgr.sgml $(ALLSGML) $(GENERATED_SGML) stylesheet.dsl website-docs.css
sed '/html-index-filename/a\
(define nochunks #t)' <stylesheet.dsl >nochunks.dsl
$(JADE.html.call) -d nochunks.dsl -i include-index $< >repmgr.html
version.sgml: ${repmgr_top_builddir}/repmgr_version.h
{ \
echo "<!ENTITY repmgrversion \"$(REPMGR_VERSION)\">"; \
} > $@
HTML.index: repmgr.sgml $(ALMOSTALLSGML) stylesheet.dsl
@$(MKDIR_P) html
$(JADE.html.call) -d stylesheet.dsl -V html-index $<
website-docs.css:
@$(MKDIR_P) html
curl http://www.postgresql.org/media/css/docs.css > ${srcdir}/website-docs.css
bookindex.sgml: HTML.index
ifdef COLLATEINDEX
LC_ALL=C $(PERL) $(COLLATEINDEX) -f -g -i 'bookindex' -o $@ $<
else
@$(missing) collateindex.pl $< $@
endif
clean:
rm -f html-stamp
rm -f HTML.index $(GENERATED_SGML)
maintainer-clean:
rm -rf html
rm -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,9 +1,10 @@
<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>
@@ -19,7 +20,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 <application>repmgrd</application>, and is not compatible with PostgreSQL 9.2 via &repmgrd;, 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>
@@ -100,8 +101,7 @@
and recloning standbys from this. and recloning standbys from this.
</para> </para>
<para> <para>
To minimize downtime during major upgrades, for more recent PostgreSQL To minimize downtime during major upgrades from PostgreSQL 9.4 and later,
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 <application>repmgrd</application>) assists with &repmgr; (together with &repmgrd;) 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 <application>repmgrd</application>) &repmgr; (in particular &repmgrd;)
may not run, or run properly, or in the worst case (if different <application>repmgrd</application> may not run, or run properly, or in the worst case (if different &repmgrd;
versions are running and there are differences in the failover implementation) break 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 <application>repmgrd</application>?</title> in <filename>postgresql.conf</filename> if I'm not using &repmgrd;?</title>
<para> <para>
No, the <literal>repmgr</literal> shared library is only needed when running <application>repmgrd</application>. No, the <literal>repmgr</literal> shared library is only needed when running &repmgrd;.
If you later decide to run <application>repmgrd</application>, you just need to add If you later decide to run &repmgrd;, 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>/<application>repmgrd</application> complains it can't connect to the server... Why?</title> but <command>repmgr</command>/&repmgrd; complains it can't connect to the server... Why?</title>
<para> <para>
<command>repmgr</command> and <application>repmgrd</application> need to be able to connect to the repmgr database <command>repmgr</command> and &repmgrd; need to be able to connect to the repmgr database
with a normal connection to query metadata. The <literal>replication</literal> connection 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><application>repmgrd</application></title> <title>&repmgrd;</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 <application>repmgrd</application> support delayed standbys?</title> <title>Does &repmgrd; support delayed standbys?</title>
<para> <para>
<application>repmgrd</application> can monitor delayed standbys - those set up with &repmgrd; 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, <application>repmgrd</application> to directly examine the value applied to the standby, &repmgrd;
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, <application>repmgrd</application> will only start Note that after registering a delayed standby, &repmgrd; 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 <application>repmgrd</application> to rotate its logfile?</title> <title>How can I get &repmgrd; 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 <application>repmgrd</application> refuses to start?</title> <title>I've recloned a failed primary as a standby, but &repmgrd; 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. <application>repmgrd</application> will start if <literal>automatic</literal>, which is probably not what you want. &repmgrd; will start if
<varname>failover</varname> is set to <literal>manual</literal> so the node's replication status can still <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>
<application>repmgrd</application> ignores pg_bindir when executing <varname>promote_command</varname> or <varname>follow_command</varname> &repmgrd; 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>
<application>repmgrd</application> aborts startup with the error "<literal>upstream node must be running before repmgrd can start</literal>" &repmgrd; aborts startup with the error "<literal>upstream node must be running before repmgrd can start</literal>"
</title> </title>
<para> <para>
<application>repmgrd</application> does this to avoid starting up on a replication cluster &repmgrd; does this to avoid starting up on a replication cluster
which is not in a healthy state. If the upstream is unavailable, <application>repmgrd</application> which is not in a healthy state. If the upstream is unavailable, &repmgrd;
may initiate a failover immediately after starting up, which could have unintended side-effects, may initiate a failover immediately after starting up, which could have unintended side-effects,
particularly if <application>repmgrd</application> is not running on other nodes. particularly if &repmgrd; 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 <application>repmgrd</application>. starting &repmgrd;.
</para> </para>
</sect2> </sect2>

View File

@@ -1,9 +1,11 @@
<appendix id="appendix-packages" xreflabel="Package details"> <appendix id="appendix-packages" xreflabel="Package details">
<title>&repmgr; package details</title>
<indexterm> <indexterm>
<primary>packages</primary> <primary>packages</primary>
</indexterm> </indexterm>
<title>&repmgr; package details</title>
<para> <para>
This section provides technical details about various &repmgr; binary This section provides technical details about various &repmgr; binary
packages, such as location of the installed binaries and packages, such as location of the installed binaries and
@@ -309,8 +311,8 @@
version number for your installation. version number for your installation.
</para> </para>
<para> <para>
See also <xref linkend="repmgrd-configuration-debian-ubuntu"> for some specifics related See also <xref linkend="repmgrd-configuration-debian-ubuntu"/> for some specifics related
to configuring the <application>repmgrd</application> daemon. to configuring the &repmgrd; daemon.
</para> </para>
<table id="debian-9-packages"> <table id="debian-9-packages">
@@ -481,34 +483,12 @@ 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>)
@@ -520,6 +500,32 @@ 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>
@@ -546,13 +552,13 @@ repmgr96-4.1.1-0.0git320.g5113ab0.1.el7.x86_64.rpm</programlisting>
char package_conf_file[MAXPGPATH] = "";</programlisting> char package_conf_file[MAXPGPATH] = "";</programlisting>
</para> </para>
<para> <para>
See also: <xref linkend="configuration-file"> See also: <xref linkend="configuration-file"/>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
PID file location: the default <application>repmgrd</application> PID file PID file location: the default &repmgrd; PID file
location can be hard-coded by patching <varname>package_pid_file</varname> location can be hard-coded by patching <varname>package_pid_file</varname>
in <filename>repmgrd.c</filename>: in <filename>repmgrd.c</filename>:
<programlisting> <programlisting>
@@ -560,7 +566,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

@@ -1,9 +1,11 @@
<appendix id="appendix-support" xreflabel="repmgr support"> <appendix id="appendix-support" xreflabel="repmgr support">
<title>&repmgr; support</title>
<indexterm> <indexterm>
<primary>support</primary> <primary>support</primary>
</indexterm> </indexterm>
<title>&repmgr; support</title>
<para> <para>
<ulink url="https://2ndquadrant.com/">2ndQuadrant</ulink> provides 24x7 <ulink url="https://2ndquadrant.com/">2ndQuadrant</ulink> provides 24x7
production support for &repmgr; and other PostgreSQL production support for &repmgr; and other PostgreSQL
@@ -28,12 +30,13 @@
</important> </important>
<sect1 id="appendix-support-reporting-issues" xreflabel="Reportins Issues"> <sect1 id="appendix-support-reporting-issues" xreflabel="Reportins Issues">
<title>Reporting Issues</title>
<indexterm> <indexterm>
<primary>support</primary> <primary>support</primary>
<secondary>reporting issues</secondary> <secondary>reporting issues</secondary>
</indexterm> </indexterm>
<title>Reporting Issues</title>
<para> <para>
When asking questions or reporting issues, it is extremely helpful if the following information is included: When asking questions or reporting issues, it is extremely helpful if the following information is included:
@@ -48,7 +51,7 @@
<listitem> <listitem>
<simpara> <simpara>
How was &repmgr installed? From source? From packages? If How was &repmgr; installed? From source? From packages? If
so from which repository? so from which repository?
</simpara> </simpara>
</listitem> </listitem>
@@ -80,7 +83,7 @@
the maximum level of logging output. the maximum level of logging output.
</para> </para>
<para> <para>
If issues are encountered with <application>repmgrd</application>, If issues are encountered with &repmgrd;,
please provide relevant extracts from the &repmgr; log files please provide relevant extracts from the &repmgr; log files
and if possible the PostgreSQL log itself. Please ensure these and if possible the PostgreSQL log itself. Please ensure these
logs do not contain any confidential data. logs do not contain any confidential data.

View File

@@ -2,6 +2,8 @@
<title>Cloning standbys</title> <title>Cloning standbys</title>
<sect1 id="cloning-from-barman" xreflabel="Cloning from Barman"> <sect1 id="cloning-from-barman" xreflabel="Cloning from Barman">
<title>Cloning a standby from Barman</title>
<indexterm> <indexterm>
<primary>cloning</primary> <primary>cloning</primary>
<secondary>from Barman</secondary> <secondary>from Barman</secondary>
@@ -11,9 +13,8 @@
<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).
@@ -51,6 +52,24 @@
</itemizedlist> </itemizedlist>
</para> </para>
<note>
<para>
Currently &repmgr;'s support for cloning from Barman is implemented by using
<productname>rsync</productname> to clone from the Barman server.
</para>
<para>
It is therefore not able to make use of Barman's parallel restore facility, which
is executed on the Barman server and clones to the target server.
</para>
<para>
Barman's parallel restore facility can be used by executing it manually on
the Barman server and integrating the resulting cloned standby using
<command><link linkend="repmgr-standby-clone">repmgr standby clone --recovery-conf-only</link></command>.
</para>
</note>
<sect2 id="cloning-from-barman-prerequisites"> <sect2 id="cloning-from-barman-prerequisites">
<title>Prerequisites for cloning from Barman</title> <title>Prerequisites for cloning from Barman</title>
<para> <para>
@@ -59,8 +78,7 @@
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
<para> <para>
the <varname>barman_server</varname> setting in <filename>repmgr.conf</filename> is the same as the the Barman catalogue must include at least one valid backup for this server;
server configured in Barman;
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@@ -71,19 +89,68 @@
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
the <varname>restore_command</varname> setting in <filename>repmgr.conf</filename> is configured to the <varname>barman_server</varname> setting in <filename>repmgr.conf</filename> is the same as the
use a copy of the <command>barman-wal-restore</command> script shipped with the server configured in Barman.
<literal>barman-cli</literal> package (see section <xref linkend="cloning-from-barman-restore-command">
below).
</para>
</listitem>
<listitem>
<para>
the Barman catalogue includes at least one valid backup for this server.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para>
For example, assuming Barman is located on the host &quot;<literal>barmansrv</literal>&quot;
under the &quot;<literal>barman</literal>&quot; user account,
<filename>repmgr.conf</filename> should contain the following entries:
<programlisting>
barman_host=barman@barmansrv
barman_server=somedb</programlisting>
</para>
<note>
<para>
To use a non-default Barman configuration file on the Barman server,
specify this in <filename>repmgr.conf</filename> with <filename>barman_config</filename>:
<programlisting>
barman_config=/path/to/barman.conf</programlisting>
</para>
</note>
<para>
We also recommend configuring the <varname>restore_command</varname> setting in <filename>repmgr.conf</filename>
to use the <command>barman-wal-restore</command> script
(see section <xref linkend="cloning-from-barman-restore-command"/> below).
</para>
<tip>
<simpara>
If you have a non-default SSH configuration on the Barman
server, e.g. using a port other than 22, then you can set those
parameters in a dedicated Host section in <filename>~/.ssh/config</filename>
corresponding to the value of <varname>barman_host</varname> in
<filename>repmgr.conf</filename>. See the <literal>Host</literal>
section in <command>man 5 ssh_config</command> for more details.
</simpara>
</tip>
<para>
It's now possible to clone a standby from Barman, e.g.:
<programlisting>
$ repmgr -f /etc/repmgr.conf -h node1 -U repmgr -d repmgr standby clone
NOTICE: destination directory "/var/lib/postgresql/data" provided
INFO: connecting to Barman server to verify backup for "test_cluster"
INFO: checking and correcting permissions on existing directory "/var/lib/postgresql/data"
INFO: creating directory "/var/lib/postgresql/data/repmgr"...
INFO: connecting to Barman server to fetch server parameters
INFO: connecting to source node
DETAIL: current installation size is 30 MB
NOTICE: retrieving backup from Barman...
(...)
NOTICE: standby clone (from Barman) complete
NOTICE: you can now start your PostgreSQL server
HINT: for example: pg_ctl -D /var/lib/postgresql/data start</programlisting>
</para>
<note> <note>
<simpara> <simpara>
Barman support is automatically enabled if <varname>barman_server</varname> Barman support is automatically enabled if <varname>barman_server</varname>
@@ -93,45 +160,16 @@
command line option. command line option.
</simpara> </simpara>
</note> </note>
<tip>
<simpara>
If you have a non-default SSH configuration on the Barman
server, e.g. using a port other than 22, then you can set those
parameters in a dedicated Host section in <filename>~/.ssh/config</filename>
corresponding to the value of<varname>barman_host</varname> in
<filename>repmgr.conf</filename>. See the <literal>Host</literal>
section in <command>man 5 ssh_config</command> for more details.
</simpara>
</tip>
<para>
It's now possible to clone a standby from Barman, e.g.:
<programlisting>
NOTICE: using configuration file "/etc/repmgr.conf"
NOTICE: destination directory "/var/lib/postgresql/data" provided
INFO: connecting to Barman server to verify backup for test_cluster
INFO: checking and correcting permissions on existing directory "/var/lib/postgresql/data"
INFO: creating directory "/var/lib/postgresql/data/repmgr"...
INFO: connecting to Barman server to fetch server parameters
INFO: connecting to upstream node
INFO: connected to source node, checking its state
INFO: successfully connected to source node
DETAIL: current installation size is 29 MB
NOTICE: retrieving backup from Barman...
receiving file list ...
(...)
NOTICE: standby clone (from Barman) complete
NOTICE: you can now start your PostgreSQL server
HINT: for example: pg_ctl -D /var/lib/postgresql/data start</programlisting>
</para>
</sect2> </sect2>
<sect2 id="cloning-from-barman-restore-command" xreflabel="Using Barman as a WAL file source"> <sect2 id="cloning-from-barman-restore-command" xreflabel="Using Barman as a WAL file source">
<indexterm> <title>Using Barman as a WAL file source</title>
<indexterm>
<primary>Barman</primary> <primary>Barman</primary>
<secondary>fetching archived WAL</secondary> <secondary>fetching archived WAL</secondary>
</indexterm> </indexterm>
<title>Using Barman as a WAL file source</title>
<para> <para>
As a fallback in case streaming replication is interrupted, PostgreSQL can optionally As a fallback in case streaming replication is interrupted, PostgreSQL can optionally
retrieve WAL files from an archive, such as that provided by Barman. This is done by retrieve WAL files from an archive, such as that provided by Barman. This is done by
@@ -140,39 +178,34 @@
</para> </para>
<para> <para>
<command>barman-wal-restore</command> is a Python script provided as part of the <literal>barman-cli</literal> <command>barman-wal-restore</command> is a Python script provided as part of the <literal>barman-cli</literal>
package (Barman 2.0 and later; for Barman 1.x the script is provided separately as package (Barman 2.0 ~ 2.7) or as part of the core Barman distribution (Barman 2.8 and later).
<command>barman-wal-restore.py</command>) which performs this function for Barman.
</para> </para>
<para> <para>
To use <command>barman-wal-restore</command> with &repmgr; To use <command>barman-wal-restore</command> with &repmgr;,
and assuming Barman is located on the <literal>barmansrv</literal> host assuming Barman is located on the host &quot;<literal>barmansrv</literal>&quot;
under the &quot;<literal>barman</literal>&quot; user account,
and that <command>barman-wal-restore</command> is located as an executable at and that <command>barman-wal-restore</command> is located as an executable at
<filename>/usr/bin/barman-wal-restore</filename>, <filename>/usr/bin/barman-wal-restore</filename>,
<filename>repmgr.conf</filename> should include the following lines: <filename>repmgr.conf</filename> should include the following lines:
<programlisting> <programlisting>
barman_host=barmansrv barman_host=barman@barmansrv
barman_server=somedb barman_server=somedb
restore_command=/usr/bin/barman-wal-restore barmansrv somedb %f %p</programlisting> restore_command=/usr/bin/barman-wal-restore barmansrv somedb %f %p</programlisting>
</para> </para>
<note> <note>
<simpara> <simpara>
<command>barman-wal-restore</command> supports command line switches to <command>barman-wal-restore</command> supports command line switches to
control parallelism (<literal>--parallel=N</literal>) and compression ( control parallelism (<literal>--parallel=N</literal>) and compression
<literal>--bzip2</literal>, <literal>--gzip</literal>). (<literal>--bzip2</literal>, <literal>--gzip</literal>).
</simpara> </simpara>
</note> </note>
<note>
<para>
To use a non-default Barman configuration file on the Barman server,
specify this in <filename>repmgr.conf</filename> with <filename>barman_config</filename>:
<programlisting>
barman_config=/path/to/barman.conf</programlisting>
</para>
</note>
</sect2> </sect2>
</sect1> </sect1>
<sect1 id="cloning-replication-slots" xreflabel="Cloning and replication slots"> <sect1 id="cloning-replication-slots" xreflabel="Cloning and replication slots">
<title>Cloning and replication slots</title>
<indexterm> <indexterm>
<primary>cloning</primary> <primary>cloning</primary>
<secondary>replication slots</secondary> <secondary>replication slots</secondary>
@@ -182,7 +215,6 @@
<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
@@ -244,18 +276,20 @@
<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,
@@ -276,7 +310,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>
@@ -339,11 +373,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>
@@ -365,7 +399,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>
@@ -433,7 +467,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>
@@ -460,7 +494,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,4 +1,6 @@
<sect1 id="configuration-file-log-settings" xreflabel="log settings"> <sect1 id="configuration-file-log-settings" xreflabel="log settings">
<title>Log settings</title>
<indexterm> <indexterm>
<primary>repmgr.conf</primary> <primary>repmgr.conf</primary>
<secondary>log settings</secondary> <secondary>log settings</secondary>
@@ -7,10 +9,9 @@
<primary>log settings</primary> <primary>log settings</primary>
<secondary>configuration in repmgr.conf</secondary> <secondary>configuration in repmgr.conf</secondary>
</indexterm> </indexterm>
<title>Log settings</title>
<para> <para>
By default, &repmgr; and <application>repmgrd</application> write log output to By default, &repmgr; and &repmgrd; write log output to
<literal>STDERR</literal>. An alternative log destination can be specified <literal>STDERR</literal>. An alternative log destination can be specified
(either a file or <literal>syslog</literal>). (either a file or <literal>syslog</literal>).
</para> </para>
@@ -24,7 +25,7 @@
<para> <para>
This behaviour can be overriden with the command line option <option>--log-to-file</option>, This behaviour can be overriden with the command line option <option>--log-to-file</option>,
which will redirect all logging output to the configured log destination. This is recommended which will redirect all logging output to the configured log destination. This is recommended
when &repmgr; is executed by another application, particularly <application>repmgrd</application>, when &repmgr; is executed by another application, particularly &repmgrd;,
to enable log output generated by the &repmgr; application to be stored for later reference. to enable log output generated by the &repmgr; application to be stored for later reference.
</para> </para>
</note> </note>
@@ -32,12 +33,11 @@
<variablelist> <variablelist>
<varlistentry id="repmgr-conf-log-level" xreflabel="log_level"> <varlistentry id="repmgr-conf-log-level" xreflabel="log_level">
<term><varname>log_level</varname> (<type>string</type>) <term><varname>log_level</varname> (<type>string</type>)</term>
<listitem>
<indexterm> <indexterm>
<primary><varname>log_level</varname> configuration file parameter</primary> <primary><varname>log_level</varname> configuration file parameter</primary>
</indexterm> </indexterm>
</term>
<listitem>
<para> <para>
One of <option>DEBUG</option>, <option>INFO</option>, <option>NOTICE</option>, One of <option>DEBUG</option>, <option>INFO</option>, <option>NOTICE</option>,
<option>WARNING</option>, <option>ERROR</option>, <option>ALERT</option>, <option>CRIT</option> <option>WARNING</option>, <option>ERROR</option>, <option>ALERT</option>, <option>CRIT</option>
@@ -76,11 +76,11 @@
</term> </term>
<listitem> <listitem>
<para> <para>
If <xref linkend="repmgr-conf-log-facility"> is set to <option>STDERR</option>, log output If <xref linkend="repmgr-conf-log-facility"/> is set to <option>STDERR</option>, log output
can be redirected to the specified file. can be redirected to the specified file.
</para> </para>
<para> <para>
See <xref linkend="repmgrd-log-rotation"> for information on configuring log rotation. See <xref linkend="repmgrd-log-rotation"/> for information on configuring log rotation.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -93,12 +93,12 @@
</term> </term>
<listitem> <listitem>
<para> <para>
This setting causes <application>repmgrd</application> to emit a status log This setting causes &repmgrd; to emit a status log
line at the specified interval (in seconds, default <literal>300</literal>) line at the specified interval (in seconds, default <literal>300</literal>)
describing <application>repmgrd</application>'s current state, e.g.: describing &repmgrd;'s current state, e.g.:
</para> </para>
<programlisting> <programlisting>
[2018-07-12 00:47:32] [INFO] monitoring connection to upstream node "node1" (node ID: 1)</programlisting> [2018-07-12 00:47:32] [INFO] monitoring connection to upstream node "node1" (ID: 1)</programlisting>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@@ -0,0 +1,124 @@
<sect1 id="configuration-file-optional-settings" xreflabel="optional configuration file settings">
<title>Optional configuration file settings</title>
<indexterm>
<primary>repmgr.conf</primary>
<secondary>optional settings</secondary>
</indexterm>
<variablelist>
<varlistentry id="repmgr-conf-config-directory" xreflabel="config_directory">
<term><varname>config_directory</varname> (<type>string</type>)
<indexterm>
<primary><varname>config_directory</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
If PostgreSQL configuration files are located outside the data
directory, specify the directory where the main
<filename>postgresql.conf</filename> file is located.
</para>
<para>
This enables explicit provision of an external configuration file
directory, which if set will be passed to <command>pg_ctl</command> as the
<option>-D</option> parameter. Otherwise <command>pg_ctl</command> will
default to using the data directory, which will cause some operations
to fail if the configuration files are not present there.
</para>
<note>
<para>
This is implemented primarily for feature completeness and for
development/testing purposes. Users who have installed &repmgr; from
a package should <emphasis>not</emphasis> rely on to stop/start/restart PostgreSQL,
instead they should set the appropriate <option>service_..._command</option>
for their operating system. For more details see
<xref linkend="configuration-file-service-commands"/>.
</para>
</note>
</listitem>
</varlistentry>
<varlistentry id="repmgr-conf-replication-user" xreflabel="replication_user">
<term><varname>replication_user</varname> (<type>string</type>)
<indexterm>
<primary><varname>replication_user</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
PostgreSQL user to make replication connections with.
If not set defaults, to the user defined in <xref linkend="repmgr-conf-conninfo"/>.
</para>
</listitem>
</varlistentry>
<varlistentry id="repmgr-conf-replication-type" xreflabel="replication_type">
<term><varname>replication_type</varname> (<type>string</type>)
<indexterm>
<primary><varname>replication_type</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
Must be one of <literal>physical</literal> (for standard streaming replication)
or <literal>bdr</literal>.
</para>
<note>
<para>
Replication type <literal>bdr</literal> can only be used with BDR 2.x
</para>
<para>
BDR 3.x users should use <literal>physical</literal>.
</para>
</note>
</listitem>
</varlistentry>
<varlistentry id="repmgr-conf-location" xreflabel="location">
<term><varname>location</varname> (<type>string</type>)
<indexterm>
<primary><varname>location</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
An arbitrary string defining the location of the node; this
is used during failover to check visibility of the
current primary node.
</para>
<para>
For more details see <xref linkend="repmgrd-network-split"/>.
</para>
</listitem>
</varlistentry>
<varlistentry id="repmgr-conf-use-replication-slots" xreflabel="use_replication_slots">
<term><varname>use_replication_slots</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>use_replication_slots</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
Whether to use physical replication slots.
</para>
<note>
<para>
When using replication slots,
<varname>max_replication_slots</varname> should be configured for
at least the number of standbys which will connect
to the primary.
</para>
</note>
</listitem>
</varlistentry>
</variablelist>
</sect1>

View File

@@ -1,10 +1,12 @@
<sect1 id="configuration-file-settings" xreflabel="required configuration file settings"> <sect1 id="configuration-file-settings" xreflabel="required configuration file settings">
<title>Required configuration file settings</title>
<indexterm> <indexterm>
<primary>repmgr.conf</primary> <primary>repmgr.conf</primary>
<secondary>required settings</secondary> <secondary>required settings</secondary>
</indexterm> </indexterm>
<title>Required configuration file settings</title>
<para> <para>
Each <filename>repmgr.conf</filename> file must contain the following parameters: Each <filename>repmgr.conf</filename> file must contain the following parameters:
</para> </para>
@@ -39,6 +41,10 @@
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>
@@ -56,7 +62,7 @@
</para> </para>
<para> <para>
For details on conninfo strings, see section <ulink For details on conninfo strings, see section <ulink
url="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING">Connection Strings</> url="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING">Connection Strings</ulink>
in the PosgreSQL documentation. in the PosgreSQL documentation.
</para> </para>
<para> <para>
@@ -65,18 +71,18 @@
string to determine the length of time which elapses before a network string to determine the length of time which elapses before a network
connection attempt is abandoned; for details see <ulink connection attempt is abandoned; for details see <ulink
url="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT"> url="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT">
the PostgreSQL documentation</>. the PostgreSQL documentation</ulink>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="repmgr-conf-data-directory" xreflabel="data_directory"> <varlistentry id="repmgr-conf-data-directory" xreflabel="data_directory">
<term><varname>data_directory</varname> (<type>string</type>) <term><varname>data_directory</varname> (<type>string</type>)</term>
<indexterm>
<primary><varname>data_directory</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem> <listitem>
<indexterm>
<primary><varname>data_directory</varname> configuration file parameter</primary>
</indexterm>
<para> <para>
The node's data directory. This is needed by repmgr The node's data directory. This is needed by repmgr
when performing operations when the PostgreSQL instance when performing operations when the PostgreSQL instance
@@ -90,33 +96,6 @@
</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,4 +1,6 @@
<sect1 id="configuration-file-service-commands" xreflabel="service command settings"> <sect1 id="configuration-file-service-commands" xreflabel="service command settings">
<title>Service command settings</title>
<indexterm> <indexterm>
<primary>repmgr.conf</primary> <primary>repmgr.conf</primary>
<secondary>service command settings</secondary> <secondary>service command settings</secondary>
@@ -7,10 +9,9 @@
<primary>service command settings</primary> <primary>service command settings</primary>
<secondary>configuration in repmgr.conf</secondary> <secondary>configuration in repmgr.conf</secondary>
</indexterm> </indexterm>
<title>Service command settings</title>
<para> <para>
In some circumstances, &repmgr; (and <application>repmgrd</application>) need to In some circumstances, &repmgr; (and &repmgrd;) need to
be able to stop, start or restart PostgreSQL. &repmgr; commands which need to do this be able to stop, start or restart PostgreSQL. &repmgr; commands which need to do this
include <link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>, include <link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>,
<link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link> and <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link> and
@@ -68,7 +69,7 @@
</para> </para>
<para> <para>
Do not confuse this with <varname>promote_command</varname>, which is used Do not confuse this with <varname>promote_command</varname>, which is used
by <application>repmgrd</application> to execute <xref linkend="repmgr-standby-promote">. by &repmgrd; to execute <xref linkend="repmgr-standby-promote"/>.
</para> </para>
</note> </note>

View File

@@ -1,69 +0,0 @@
<sect1 id="configuration-file" xreflabel="configuration file location">
<indexterm>
<primary>repmgr.conf</primary>
<secondary>location</secondary>
</indexterm>
<indexterm>
<primary>configuration</primary>
<secondary>repmgr.conf location</secondary>
</indexterm>
<title>Configuration file location</title>
<para>
<application>repmgr</application> and <application>repmgrd</application>
use a common configuration file, by default called
<filename>repmgr.conf</filename> (although any name can be used if explicitly specified).
<filename>repmgr.conf</filename> must contain a number of required parameters, including
the database connection string for the local node and the location
of its data directory; other values will be inferred from defaults if
not explicitly supplied. See section <xref linkend="configuration-file-settings">
for more details.
</para>
<para>
The configuration file will be searched for in the following locations:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<para>a configuration file specified by the <literal>-f/--config-file</literal> command line option</para>
</listitem>
<listitem>
<para>
a location specified by the package maintainer (if <application>repmgr</application>
as installed from a package and the package maintainer has specified the configuration
file location)
</para>
</listitem>
<listitem>
<para><filename>repmgr.conf</filename> in the local directory</para>
</listitem>
<listitem>
<para><filename>/etc/repmgr.conf</filename></para>
</listitem>
<listitem>
<para>the directory reported by <application>pg_config --sysconfdir</application></para>
</listitem>
</itemizedlist>
</para>
<para>
Note that if a file is explicitly specified with <literal>-f/--config-file</literal>,
an error will be raised if it is not found or not readable, and no attempt will be made to
check default locations; this is to prevent <application>repmgr</application> unexpectedly
reading the wrong configuraton file.
</para>
<note>
<para>
If providing the configuration file location with <literal>-f/--config-file</literal>,
avoid using a relative path, particularly when executing <xref linkend="repmgr-primary-register">
and <xref linkend="repmgr-standby-register">, as &repmgr; stores the configuration file location
in the repmgr metadata for use when &repmgr; is executed remotely (e.g. during
<xref linkend="repmgr-standby-switchover">). &repmgr; will attempt to convert the
a relative path into an absolute one, but this may not be the same as the path you
would explicitly provide (e.g. <filename>./repmgr.conf</filename> might be converted
to <filename>/path/to/./repmgr.conf</filename>, whereas you'd normally write
<filename>/path/to/repmgr.conf</filename>).
</para>
</note>
</sect1>

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

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

View File

@@ -2,6 +2,8 @@
<title>repmgr configuration</title> <title>repmgr configuration</title>
<sect1 id="configuration-prerequisites" xreflabel="Prerequisites for configuration"> <sect1 id="configuration-prerequisites" xreflabel="Prerequisites for configuration">
<title>Prerequisites for configuration</title>
<indexterm> <indexterm>
<primary>configuration</primary> <primary>configuration</primary>
<secondary>prerequisites</secondary> <secondary>prerequisites</secondary>
@@ -12,7 +14,6 @@
<secondary>ssh</secondary> <secondary>ssh</secondary>
</indexterm> </indexterm>
<title>Prerequisites for configuration</title>
<para> <para>
Following software must be installed on both servers: Following software must be installed on both servers:
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
@@ -62,6 +63,8 @@
</tip> </tip>
<sect2 id="configuration-postgresql" xreflabel="PostgreSQL configuration"> <sect2 id="configuration-postgresql" xreflabel="PostgreSQL configuration">
<title>PostgreSQL configuration for &repmgr;</title>
<indexterm> <indexterm>
<primary>configuration</primary> <primary>configuration</primary>
<secondary>PostgreSQL</secondary> <secondary>PostgreSQL</secondary>
@@ -71,7 +74,6 @@
<primary>PostgreSQL configuration</primary> <primary>PostgreSQL configuration</primary>
</indexterm> </indexterm>
<title>PostgreSQL configuration for &repmgr;</title>
<para> <para>
The following PostgreSQL configuration parameters may need to be changed in order The following PostgreSQL configuration parameters may need to be changed in order
for &repmgr; (and replication itself) to function correctly. for &repmgr; (and replication itself) to function correctly.
@@ -81,13 +83,14 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>hot_standby</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>hot_standby</option></term> <term><option>hot_standby</option></term>
<listitem> <listitem>
<indexterm>
<primary>hot_standby</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
<option>hot_standby</option> must always be set to <literal>on</literal>, as &repmgr; needs <option>hot_standby</option> must always be set to <literal>on</literal>, as &repmgr; needs
to be able to connect to each server it manages. to be able to connect to each server it manages.
@@ -104,13 +107,15 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>wal_level</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>wal_level</option></term> <term><option>wal_level</option></term>
<listitem> <listitem>
<indexterm>
<primary>wal_level</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
<option>wal_level</option> must be one of <option>replica</option> or <option>logical</option> <option>wal_level</option> must be one of <option>replica</option> or <option>logical</option>
(PostgreSQL 9.5 and earlier: one of <option>hot_standby</option> or <option>logical</option>). (PostgreSQL 9.5 and earlier: one of <option>hot_standby</option> or <option>logical</option>).
@@ -123,13 +128,15 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>max_wal_senders</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>max_wal_senders</option></term> <term><option>max_wal_senders</option></term>
<listitem> <listitem>
<indexterm>
<primary>max_wal_senders</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
<option>max_wal_senders</option> must be set to a value of <literal>2</literal> or greater. <option>max_wal_senders</option> must be set to a value of <literal>2</literal> or greater.
In general you will need one WAL sender for each standby which will attach to the PostgreSQL In general you will need one WAL sender for each standby which will attach to the PostgreSQL
@@ -149,13 +156,15 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>max_replication_slots</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>max_replication_slots</option></term> <term><option>max_replication_slots</option></term>
<listitem> <listitem>
<indexterm>
<primary>max_replication_slots</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
If you are intending to use replication slots, <option>max_replication_slots</option> If you are intending to use replication slots, <option>max_replication_slots</option>
must be set to a non-zero value. must be set to a non-zero value.
@@ -174,19 +183,20 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>wal_log_hints</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>wal_log_hints</option></term> <term><option>wal_log_hints</option></term>
<listitem> <listitem>
<indexterm>
<primary>wal_log_hints</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para>If you are intending to use <application>pg_rewind</application>, <para>If you are intending to use <application>pg_rewind</application>,
and the cluster was not initialised using data checksums, you may want to consider enabling and the cluster was not initialised using data checksums, you may want to consider enabling
<option>wal_log_hints</option>. <option>wal_log_hints</option>.
</para> </para>
<para> <para>
For more details see <xref linkend="repmgr-node-rejoin-pg-rewind">. For more details see <xref linkend="repmgr-node-rejoin-pg-rewind"/>.
</para> </para>
<para> <para>
PostgreSQL documentation: <ulink url="https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LOG-HINTS">wal_log_hints</ulink>. PostgreSQL documentation: <ulink url="https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LOG-HINTS">wal_log_hints</ulink>.
@@ -196,13 +206,15 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>archive_mode</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>archive_mode</option></term> <term><option>archive_mode</option></term>
<listitem> <listitem>
<indexterm>
<primary>archive_mode</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
We suggest setting <option>archive_mode</option> to <literal>on</literal> (and We suggest setting <option>archive_mode</option> to <literal>on</literal> (and
<option>archive_command</option> to <literal>/bin/true</literal>; see below) <option>archive_command</option> to <literal>/bin/true</literal>; see below)
@@ -225,13 +237,15 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>archive_command</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<term><option>archive_command</option></term> <term><option>archive_command</option></term>
<listitem> <listitem>
<indexterm>
<primary>archive_command</primary>
<secondary>PostgreSQL configuration</secondary>
</indexterm>
<para> <para>
If you have set <option>archive_mode</option> to <literal>on</literal> but are not currently planning If you have set <option>archive_mode</option> to <literal>on</literal> but are not currently planning
to use WAL file archiving, set <option>archive_command</option> to a command which does nothing but returns to use WAL file archiving, set <option>archive_command</option> to a command which does nothing but returns
@@ -246,13 +260,15 @@
<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.
@@ -289,16 +305,18 @@
&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

@@ -1,93 +0,0 @@
<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 <application>repmgrd</application> perform a significant event, a record Each time &repmgr; or &repmgrd; perform a significant event, a record
of that event is written into the <literal>repmgr.events</literal> table together with of that event is written into the <literal>repmgr.events</literal> table together with
a timestamp, an indication of failure or success, and further details a timestamp, an indication of failure or success, and further details
if appropriate. This is useful for gaining an overview of events if appropriate. This is useful for gaining an overview of events
@@ -27,7 +27,7 @@
(3 rows)</programlisting> (3 rows)</programlisting>
</para> </para>
<para> <para>
Alternatively, use <xref linkend="repmgr-cluster-event"> to output a Alternatively, use <xref linkend="repmgr-cluster-event"/> to output a
formatted list of events. formatted list of events.
</para> </para>
<para> <para>
@@ -88,11 +88,10 @@
<para> <para>
The values provided for <literal>%t</literal> and <literal>%d</literal> The values provided for <literal>%t</literal> and <literal>%d</literal>
will probably contain spaces, so should be quoted in the provided command may contain spaces, so should be quoted in the provided command
configuration, e.g.: configuration, e.g.:
<programlisting> <programlisting>
event_notification_command='/path/to/some/script %n %e %s "%t" "%d"' event_notification_command='/path/to/some/script %n %e %s "%t" "%d"'</programlisting>
</programlisting>
</para> </para>
<para> <para>
@@ -104,10 +103,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>
@@ -116,7 +115,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
@@ -129,7 +128,7 @@
<term><option>%a</option></term> <term><option>%a</option></term>
<listitem> <listitem>
<para> <para>
name of the current primary node (<xref linkend="repmgr-standby-register"> and <xref linkend="repmgr-standby-follow">) name of the current primary node (<xref linkend="repmgr-standby-register"/> and <xref linkend="repmgr-standby-follow"/>)
</para> </para>
<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>)
@@ -147,7 +146,10 @@
<para> <para>
By default, all notification types will be passed to the designated script; By default, all notification types will be passed to the designated script;
the notification types can be filtered to explicitly named ones using the the notification types can be filtered to explicitly named ones using the
<varname>event_notifications</varname> parameter. <varname>event_notifications</varname> parameter, e.g.:
<programlisting>
event_notifications=primary_register,standby_register,witness_register</programlisting>
</para> </para>
<para> <para>
@@ -205,7 +207,7 @@
</para> </para>
<para> <para>
Events generated by <application>repmgrd</application> (streaming replication mode): Events generated by &repmgrd; (streaming replication mode):
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">
<listitem> <listitem>
@@ -255,11 +257,24 @@
<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 <application>repmgrd</application> (BDR mode): Events generated by &repmgrd; (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>

View File

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

70
doc/filelist.xml Normal file
View File

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

View File

@@ -13,12 +13,13 @@
<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>
@@ -46,7 +47,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>
@@ -105,7 +106,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>
@@ -181,12 +182,13 @@ yum search repmgr</programlisting>
<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
@@ -195,7 +197,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,7 +244,7 @@ curl https://dl.2ndquadrant.com/default/release/get/deb | sudo bash</programlist
<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>

View File

@@ -1,11 +1,12 @@
<sect1 id="install-requirements" xreflabel="installation requirements"> <sect1 id="install-requirements" xreflabel="installation requirements">
<title>Requirements for installing repmgr</title>
<indexterm> <indexterm>
<primary>installation</primary> <primary>installation</primary>
<secondary>requirements</secondary> <secondary>requirements</secondary>
</indexterm> </indexterm>
<title>Requirements for installing repmgr</title>
<para> <para>
repmgr is developed and tested on Linux and OS X, but should work on any repmgr is developed and tested on Linux and OS X, but should work on any
UNIX-like system supported by PostgreSQL itself. There is no support for UNIX-like system supported by PostgreSQL itself. There is no support for
@@ -13,14 +14,14 @@
</para> </para>
<para> <para>
&repmgr; 4.x is compatible with all PostgreSQL versions from 9.3. See &repmgr; &repmgrversion; is compatible with all PostgreSQL versions from 9.3. See
section <link linkend="install-compatibility-matrix">&repmgr; compatibility matrix</link> section <link linkend="install-compatibility-matrix">&repmgr; compatibility matrix</link>
for an overview of version compatibility. for an overview of version compatibility.
</para> </para>
<note> <note>
<simpara> <simpara>
If upgrading from &repmgr; 3.x, please see the section <xref linkend="upgrading-from-repmgr-3">. If upgrading from &repmgr; 3.x, please see the section <xref linkend="upgrading-from-repmgr-3"/>.
</simpara> </simpara>
</note> </note>
@@ -38,21 +39,21 @@
<note> <note>
<simpara> <simpara>
The same &quot;major&quot; &repmgr; version (e.g. <literal>4.2.x</literal>) <emphasis>must</emphasis> The same &quot;major&quot; &repmgr; version (e.g. <literal>&repmgrversion;.x</literal>) <emphasis>must</emphasis>
be installed on all node in the replication cluster. We strongly recommend keeping all be installed on all node in the replication cluster. We strongly recommend keeping all
nodes on the same (preferably latest) &quot;minor&quot; &repmgr; version to minimize the risk nodes on the same (preferably latest) &quot;minor&quot; &repmgr; version to minimize the risk
of incompatibilities. of incompatibilities.
</simpara> </simpara>
<simpara> <simpara>
If different &quot;major&quot; &repmgr; versions (e.g. 3.3.x and 4.1.x) If different &quot;major&quot; &repmgr; versions (e.g. 4.1.x and &repmgrversion;.x)
are installed on different nodes, in the best case &repmgr; (in particular <application>repmgrd</application>) are installed on different nodes, in the best case &repmgr; (in particular &repmgrd;)
will not run. In the worst case, you will end up with a broken cluster. will not run. In the worst case, you will end up with a broken cluster.
</simpara> </simpara>
</note> </note>
<para> <para>
A dedicated system user for &repmgr; is <emphasis>not</emphasis> required; as many &repmgr; and A dedicated system user for &repmgr; is <emphasis>not</emphasis> required; as many &repmgr; and
<application>repmgrd</application> actions require direct access to the PostgreSQL data directory, &repmgrd; actions require direct access to the PostgreSQL data directory,
these commands should be executed by the <literal>postgres</literal> user. these commands should be executed by the <literal>postgres</literal> user.
</para> </para>
@@ -72,6 +73,8 @@
<sect2 id="install-compatibility-matrix"> <sect2 id="install-compatibility-matrix">
<title>&repmgr; compatibility matrix</title>
<indexterm> <indexterm>
<primary>repmgr</primary> <primary>repmgr</primary>
<secondary>compatibility matrix</secondary> <secondary>compatibility matrix</secondary>
@@ -81,7 +84,6 @@
<primary>compatibility matrix</primary> <primary>compatibility matrix</primary>
</indexterm> </indexterm>
<title>&repmgr; compatibility matrix</title>
<para> <para>
The following table provides an overview of which &repmgr; version supports The following table provides an overview of which &repmgr; version supports
which PostgreSQL version. which PostgreSQL version.
@@ -91,7 +93,7 @@
<table id="repmgr-compatibility-matrix"> <table id="repmgr-compatibility-matrix">
<title>&repmgr; compatibility matrix</title> <title>&repmgr; compatibility matrix</title>
<tgroup cols="2"> <tgroup cols="3">
<thead> <thead>
<row> <row>
<entry> <entry>
@@ -112,7 +114,7 @@
&repmgr; 4.x &repmgr; 4.x
</entry> </entry>
<entry> <entry>
<link linkend="release-4.2">4.2</link> (2018-10-24) <link linkend="release-current">&repmgrversion;</link> (&releasedate;)
</entry> </entry>
<entry> <entry>
9.3, 9.4, 9.5, 9.6, 10, 11 9.3, 9.4, 9.5, 9.6, 10, 11
@@ -156,7 +158,7 @@
<para> <para>
Note that some &repmgr; functionality is not available in PostgreSQL 9.3 and PostgreSQL 9.4. Note that some &repmgr; functionality is not available in PostgreSQL 9.3 and PostgreSQL 9.4:
</para> </para>
<itemizedlist spacing="compact" mark="bullet"> <itemizedlist spacing="compact" mark="bullet">

View File

@@ -1,11 +1,12 @@
<sect1 id="installation-source" xreflabel="Installing from source code"> <sect1 id="installation-source" xreflabel="Installing from source code">
<indexterm>
<primary>installation</primary>
<secondary>from source</secondary>
</indexterm>
<title>Installing &repmgr; from source</title> <title>Installing &repmgr; from source</title>
<indexterm>
<primary>installation</primary>
<secondary>from source</secondary>
</indexterm>
<sect2 id="installation-source-prereqs"> <sect2 id="installation-source-prereqs">
<title>Prerequisites for installing from source</title> <title>Prerequisites for installing from source</title>
<para> <para>
@@ -61,28 +62,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>llibedit-dev</literal></simpara> <simpara><literal>libedit-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>llibkrb5-dev</literal></simpara> <simpara><literal>libkrb5-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>llibpam0g-dev</literal></simpara> <simpara><literal>libpam0g-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>llibreadline-dev</literal></simpara> <simpara><literal>libreadline-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>llibselinux1-dev</literal></simpara> <simpara><literal>libselinux1-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>llibssl-dev</literal></simpara> <simpara><literal>libssl-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>llibxml2-dev</literal></simpara> <simpara><literal>libxml2-dev</literal></simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><literal>llibxslt1-dev</literal></simpara> <simpara><literal>libxslt1-dev</literal></simpara>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
@@ -136,6 +137,16 @@ 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>
@@ -190,7 +201,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>
@@ -198,11 +209,11 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
You will need to download the repmgr source, e.g. <filename>repmgr-4.0.tar.gz</filename>. You will need to download the repmgr source, e.g. <filename>repmgr-4.0.tar.gz</filename>.
You may optionally verify the package checksums from the You may optionally verify the package checksums from the
<literal>.md5</literal> files and/or verify the GnuPG signatures <literal>.md5</literal> files and/or verify the GnuPG signatures
per <xref linkend="appendix-signatures">. per <xref linkend="appendix-signatures"/>.
</para> </para>
<para> <para>
After you unpack the source code archives using <literal>tar xf</literal> After you unpack the source code archives using <command>tar xf</command>
the installation process is the same as if you were installing from a git the installation process is the same as if you were installing from a git
clone. clone.
</para> </para>
@@ -217,7 +228,7 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
To installing &repmgr; from source, simply execute: To installing &repmgr; from source, simply execute:
<programlisting> <programlisting>
./configure && make install</programlisting> ./configure &amp;&amp; make install</programlisting>
Ensure <command>pg_config</command> for the target PostgreSQL version is in Ensure <command>pg_config</command> for the target PostgreSQL version is in
<varname>$PATH</varname>. <varname>$PATH</varname>.
@@ -226,16 +237,30 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
<sect2 id="installation-build-repmgr-docs"> <sect2 id="installation-build-repmgr-docs" xreflabel="Building repmgr documentation">
<title>Building &repmgr; documentation</title> <title>Building &repmgr; documentation</title>
<para> <para>
The &repmgr; documentation is (like the main PostgreSQL project) The &repmgr; documentation is (like the main PostgreSQL project)
written in DocBook format. To build it locally as HTML, you'll need to written in DocBook XML format. To build it locally as HTML, you'll need to
install the required packages as described in the install the required packages as described in the
<ulink url="https://www.postgresql.org/docs/9.6/docguide-toolsets.html"> <ulink url="https://www.postgresql.org/docs/current/docguide-toolsets.html">PostgreSQL documentation</ulink>.
PostgreSQL documentation</ulink> then execute: </para>
<para>
The minimum PostgreSQL version for building the &repmgr; documentation is
PostgreSQL 9.5.
</para>
<note>
<simpara>
In &repmgr; 4.3 and earlier, the documentation can only be built against
PostgreSQL 9.6 or earlier.
</simpara>
</note>
<para>
To build the documentation as HTML, execute:
<programlisting> <programlisting>
./configure && make install-doc</programlisting> ./configure &amp;&amp; make doc</programlisting>
</para> </para>
<para> <para>
The generated HTML files will be placed in the <filename>doc/html</filename> The generated HTML files will be placed in the <filename>doc/html</filename>
@@ -243,19 +268,20 @@ deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlisti
</para> </para>
<para> <para>
To build the documentation as a single HTML file, execute: To build the documentation as a single HTML file, after configuring and building
the main &repmgr; source as described above, execute:
<programlisting> <programlisting>
cd doc/ && make repmgr.html</programlisting> ./configure &amp;&amp; make doc-repmgr.html</programlisting>
</para> </para>
<note> <para>
<simpara> To build the documentation as a PDF file, after configuring and building
Due to changes in PostgreSQL's documentation build system from PostgreSQL 10, the main &repmgr; source as described above, execute:
the documentation can currently only be built against PostgreSQL 9.6 or earlier. <programlisting>
This limitation will be fixed when time and resources permit. ./configure &amp;&amp; make doc-repmgr-A4.pdf</programlisting>
</simpara> </para>
</note>
</sect2> </sect2>
</sect1> </sect1>

View File

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

View File

@@ -1,4 +1,4 @@
<!-- doc/legal.sgml --> <!-- doc/legal.xml -->
<date>2017</date> <date>2017</date>

View File

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

View File

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

View File

@@ -17,7 +17,7 @@
<note> <note>
<simpara> <simpara>
To upgrade an existing &repmgr; 3.x installation, see section To upgrade an existing &repmgr; 3.x installation, see section
<xref linkend="upgrading-from-repmgr-3">. <xref linkend="upgrading-from-repmgr-3"/>.
</simpara> </simpara>
</note> </note>
@@ -76,19 +76,25 @@
</para> </para>
<programlisting> <programlisting>
# Enable replication connections; set this figure to at least one more # Enable replication connections; set this value 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
# Enable replication slots; set this figure to at least one more # If using replication slots, set this value 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 = 0 max_replication_slots = 10
# 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,33 +109,41 @@
# 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) # it anyway, in case the primary later becomes a standby)
#
# 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 script or application that will safely store # Set archive command to a dummy command; this can later be changed without
# you WALs in a secure place. /bin/true is an example of a command that # needing to restart the PostgreSQL instance.
# 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 <link linkend="configuration">repmgr configuaration guide</link>. See also the <link linkend="configuration-postgresql">PostgreSQL configuration</link> section in the
<link linkend="configuration">repmgr configuration guide</link>.
</para> </para>
</sect1> </sect1>
@@ -248,7 +262,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>
@@ -289,7 +303,7 @@
<para> <para>
See the file See the file
<ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</> <ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink>
for details of all available configuration parameters. for details of all available configuration parameters.
</para> </para>
@@ -338,7 +352,7 @@
slot_name | slot_name |
config_file | /etc/repmgr.conf</programlisting> config_file | /etc/repmgr.conf</programlisting>
<para> <para>
Each server in the replication cluster will have its own record. If <application>repmgrd</application> Each server in the replication cluster will have its own record. If &repmgrd;
is in use, the fields <literal>upstream_node_id</literal>, <literal>active</literal> and is in use, the fields <literal>upstream_node_id</literal>, <literal>active</literal> and
<literal>type</literal> will be updated when the node's status or role changes. <literal>type</literal> will be updated when the node's status or role changes.
</para> </para>

View File

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

View File

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

View File

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

View File

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

View File

@@ -22,11 +22,13 @@
directly and can be run on any node in the cluster; this is also useful when analyzing directly and can be run on any node in the cluster; this is also useful when analyzing
connectivity from a particular node. connectivity from a particular node.
</para> </para>
<para>
For PostgreSQL 9.6 and later, the output will also contain the node's current timeline ID.
</para>
<para> <para>
Node availability is tested by connecting from the node where Node availability is tested by connecting from the node where
<command>repmgr cluster show</command> is executed, and does not necessarily imply the node <command>repmgr cluster show</command> is executed, and does not necessarily imply the node
is down. See <xref linkend="repmgr-cluster-matrix"> and <xref linkend="repmgr-cluster-crosscheck"> to get is down. See <xref linkend="repmgr-cluster-matrix"/> and <xref linkend="repmgr-cluster-crosscheck"/> to get
better overviews of connections between nodes. better overviews of connections between nodes.
</para> </para>
@@ -52,11 +54,11 @@
<programlisting> <programlisting>
$ repmgr -f /etc/repmgr.conf cluster show $ repmgr -f /etc/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Priority | Connection string ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string
----+-------+---------+-----------+----------+----------+----------+----------------------------------------- ----+-------+---------+-----------+----------+----------+----------+----------+-----------------------------------------
1 | node1 | primary | * running | | default | 100 | host=db_node1 dbname=repmgr user=repmgr 1 | node1 | primary | * running | | default | 100 | 1 | host=db_node1 dbname=repmgr user=repmgr
2 | node2 | standby | running | node1 | default | 100 | host=db_node2 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 | host=db_node3 dbname=repmgr user=repmgr</programlisting> 3 | node3 | standby | running | node1 | default | 100 | 1 | host=db_node3 dbname=repmgr user=repmgr</programlisting>
</para> </para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@@ -80,18 +82,18 @@
(but <literal>node3</literal> is not attached to it, and its metadata has not yet been updated); (but <literal>node3</literal> is not attached to it, and its metadata has not yet been updated);
<literal>node4</literal> is running but rejecting connections (from <literal>node3</literal> at least). <literal>node4</literal> is running but rejecting connections (from <literal>node3</literal> at least).
<programlisting> <programlisting>
ID | Name | Role | Status | Upstream | Location | Priority | Connection string ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string
----+-------+---------+----------------------+----------+----------+----------+----------------------------------------- ----+-------+---------+----------------------+----------+----------+----------+----------+-----------------------------------------
1 | node1 | primary | ? unreachable | | default | 100 | host=db_node1 dbname=repmgr user=repmgr 1 | node1 | primary | ? unreachable | | default | 100 | 1 | host=db_node1 dbname=repmgr user=repmgr
2 | node2 | standby | ! running as primary | node1 | default | 100 | host=db_node2 dbname=repmgr user=repmgr 2 | node2 | standby | ! running as primary | node1 | default | 100 | 2 | host=db_node2 dbname=repmgr user=repmgr
3 | node3 | standby | running | node1 | default | 100 | host=db_node3 dbname=repmgr user=repmgr 3 | node3 | standby | running | node1 | default | 100 | 1 | host=db_node3 dbname=repmgr user=repmgr
4 | node4 | standby | ? running | node1 | default | 100 | host=db_node4 dbname=repmgr user=repmgr 4 | node4 | standby | ? running | node1 | default | 100 | ? | host=db_node4 dbname=repmgr user=repmgr
WARNING: following issues were detected WARNING: following issues were detected
- unable to connect to node "node1" (ID: 1) - unable to connect to node "node1" (ID: 1)
- node "node1" (ID: 1) is registered as an active primary but is unreachable - node "node1" (ID: 1) is registered as an active primary but is unreachable
- node "node2" (ID: 2) is registered as standby but running as primary - node "node2" (ID: 2) is registered as standby but running as primary
- unable to connect to node "node4" (ID: 4) - unable to connect to node "node4" (ID: 4)
HINT: execute with --verbose option to see connection error messages</programlisting> HINT: execute with --verbose option to see connection error messages</programlisting>
</para> </para>
<para> <para>
@@ -101,7 +103,7 @@
</para> </para>
<tip> <tip>
<para> <para>
Use <xref linkend="repmgr-cluster-matrix"> and <xref linkend="repmgr-cluster-crosscheck"> Use <xref linkend="repmgr-cluster-matrix"/> and <xref linkend="repmgr-cluster-crosscheck"/>
to diagnose connection issues across the whole replication cluster. to diagnose connection issues across the whole replication cluster.
</para> </para>
</tip> </tip>
@@ -196,11 +198,31 @@
</listitem> </listitem>
</varlistentry> </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> <varlistentry>
<term><option>ERR_NODE_STATUS (25)</option></term> <term><option>ERR_NODE_STATUS (25)</option></term>
<listitem> <listitem>
<para> <para>
One or more issues were detected. One or more issues were detected with the replication configuration,
e.g. a node was not in its expected state.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -211,7 +233,7 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-node-status">, <xref linkend="repmgr-node-check">, <xref linkend="repmgr-daemon-status"> <xref linkend="repmgr-node-status"/>, <xref linkend="repmgr-node-check"/>, <xref linkend="repmgr-daemon-status"/>
</para> </para>
</refsect1> </refsect1>

View File

@@ -14,30 +14,30 @@
<refnamediv> <refnamediv>
<refname>repmgr daemon pause</refname> <refname>repmgr daemon pause</refname>
<refpurpose>Instruct all <application>repmgrd</application> instances in the replication cluster to pause failover operations</refpurpose> <refpurpose>Instruct all &repmgrd; instances in the replication cluster to pause failover operations</refpurpose>
</refnamediv> </refnamediv>
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para> <para>
This command can be run on any active node in the replication cluster to instruct all This command can be run on any active node in the replication cluster to instruct all
running <application>repmgrd</application> instances to &quot;pause&quot; themselves, i.e. take no running &repmgrd; instances to &quot;pause&quot; themselves, i.e. take no
action (such as promoting themselves or following a new primary) if a failover event is detected. action (such as promoting themselves or following a new primary) if a failover event is detected.
</para> </para>
<para> <para>
This functionality is useful for performing maintenance operations, such as switchovers This functionality is useful for performing maintenance operations, such as switchovers
or upgrades, which might otherwise trigger a failover if <application>repmgrd</application> or upgrades, which might otherwise trigger a failover if &repmgrd;
is running normally. is running normally.
</para> </para>
<note> <note>
<para> <para>
It's important to wait a few seconds after restarting PostgreSQL on any node before running It's important to wait a few seconds after restarting PostgreSQL on any node before running
<command>repmgr daemon pause</command>, as the <application>repmgrd</application> instance <command>repmgr daemon pause</command>, as the &repmgrd; instance
on the restarted node will take a second or two before it has updated its status. on the restarted node will take a second or two before it has updated its status.
</para> </para>
</note> </note>
<para> <para>
<xref linkend="repmgr-daemon-unpause"> will instruct all previously paused <application>repmgrd</application> <xref linkend="repmgr-daemon-unpause"/> will instruct all previously paused &repmgrd;
instances to resume normal failover operation. instances to resume normal failover operation.
</para> </para>
</refsect1> </refsect1>
@@ -69,7 +69,7 @@ NOTICE: node 3 (node3) paused</programlisting>
<term><option>--dry-run</option></term> <term><option>--dry-run</option></term>
<listitem> <listitem>
<para> <para>
Check if nodes are reachable but don't pause <application>repmgrd</application>. Check if nodes are reachable but don't pause &repmgrd;.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -87,7 +87,7 @@ NOTICE: node 3 (node3) paused</programlisting>
<term><option>SUCCESS (0)</option></term> <term><option>SUCCESS (0)</option></term>
<listitem> <listitem>
<para> <para>
<application>repmgrd</application> could be paused on all nodes. &repmgrd; could be paused on all nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -96,7 +96,7 @@ NOTICE: node 3 (node3) paused</programlisting>
<term><option>ERR_REPMGRD_PAUSE (26)</option></term> <term><option>ERR_REPMGRD_PAUSE (26)</option></term>
<listitem> <listitem>
<para> <para>
<application>repmgrd</application> could not be paused on one or mode nodes. &repmgrd; could not be paused on one or mode nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -107,7 +107,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

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

View File

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

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

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

View File

@@ -15,22 +15,22 @@
<refnamediv> <refnamediv>
<refname>repmgr daemon unpause</refname> <refname>repmgr daemon unpause</refname>
<refpurpose>Instruct all <application>repmgrd</application> instances in the replication cluster to resume failover operations</refpurpose> <refpurpose>Instruct all &repmgrd; instances in the replication cluster to resume failover operations</refpurpose>
</refnamediv> </refnamediv>
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para> <para>
This command can be run on any active node in the replication cluster to instruct all This command can be run on any active node in the replication cluster to instruct all
running <application>repmgrd</application> instances to &quot;unpause&quot; running &repmgrd; instances to &quot;unpause&quot;
(following a previous execution of <xref linkend="repmgr-daemon-pause">) (following a previous execution of <xref linkend="repmgr-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 <application>repmgrd</application> instance <command>repmgr daemon pause</command>, as the &repmgrd; instance
on the restarted node will take a second or two before it has updated its status. on the restarted node will take a second or two before it has updated its status.
</para> </para>
</note> </note>
@@ -64,7 +64,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<term><option>--dry-run</option></term> <term><option>--dry-run</option></term>
<listitem> <listitem>
<para> <para>
Check if nodes are reachable but don't unpause <application>repmgrd</application>. Check if nodes are reachable but don't unpause &repmgrd;.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -82,7 +82,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<term><option>SUCCESS (0)</option></term> <term><option>SUCCESS (0)</option></term>
<listitem> <listitem>
<para> <para>
<application>repmgrd</application> could be unpaused on all nodes. &repmgrd; could be unpaused on all nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -91,7 +91,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<term><option>ERR_REPMGRD_PAUSE (26)</option></term> <term><option>ERR_REPMGRD_PAUSE (26)</option></term>
<listitem> <listitem>
<para> <para>
<application>repmgrd</application> could not be unpaused on one or mode nodes. &repmgrd; could not be unpaused on one or mode nodes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -102,7 +102,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

@@ -203,7 +203,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>

View File

@@ -26,10 +26,10 @@
<tip> <tip>
<para> <para>
If the node is running and needs to be attached to the current primary, use If the node is running and needs to be attached to the current primary, use
<xref linkend="repmgr-standby-follow">. <xref linkend="repmgr-standby-follow"/>.
</para> </para>
<para> <para>
Note <xref linkend="repmgr-standby-follow"> can only be used for standbys which have not diverged Note <xref linkend="repmgr-standby-follow"/> can only be used for standbys which have not diverged
from the rest of the cluster. from the rest of the cluster.
</para> </para>
</tip> </tip>
@@ -230,12 +230,13 @@
<refsect1 id="repmgr-node-rejoin-pg-rewind" xreflabel="Using pg_rewind"> <refsect1 id="repmgr-node-rejoin-pg-rewind" xreflabel="Using pg_rewind">
<title>Using <command>pg_rewind</command></title>
<indexterm> <indexterm>
<primary>pg_rewind</primary> <primary>pg_rewind</primary>
<secondary>using with "repmgr node rejoin"</secondary> <secondary>using with "repmgr node rejoin"</secondary>
</indexterm> </indexterm>
<title>Using <command>pg_rewind</command></title>
<para> <para>
<command>repmgr node rejoin</command> can optionally use <command>pg_rewind</command> to re-integrate a <command>repmgr node rejoin</command> can optionally use <command>pg_rewind</command> to re-integrate a
node which has diverged from the rest of the cluster, typically a failed primary. node which has diverged from the rest of the cluster, typically a failed primary.
@@ -321,7 +322,7 @@
If <option>--force-rewind</option> is used with the <option>--dry-run</option> option, If <option>--force-rewind</option> is used with the <option>--dry-run</option> option,
this checks the prerequisites for using <application>pg_rewind</application>, but is this checks the prerequisites for using <application>pg_rewind</application>, but is
not an absolute guarantee that actually executing <application>pg_rewind</application> not an absolute guarantee that actually executing <application>pg_rewind</application>
will succeed. See also section <xref linkend="repmgr-node-rejoin-caveats"> below. will succeed. See also section <xref linkend="repmgr-node-rejoin-caveats"/> below.
</para> </para>
</note> </note>
@@ -344,12 +345,13 @@
<refsect1 id="repmgr-node-rejoin-caveats" xreflabel="Caveats"> <refsect1 id="repmgr-node-rejoin-caveats" xreflabel="Caveats">
<indexterm>
<primary>repmgr node rejoin</primary>
<secondary>caveats</secondary>
</indexterm>
<title>Caveats when using <command>repmgr node rejoin</command></title> <title>Caveats when using <command>repmgr node rejoin</command></title>
<indexterm>
<primary>repmgr node rejoin</primary>
<secondary>caveats</secondary>
</indexterm>
<para> <para>
<command>repmgr node rejoin</command> attempts to determine whether it will succeed by <command>repmgr node rejoin</command> attempts to determine whether it will succeed by
comparing the timelines and relative WAL positions of the local node (rejoin candidate) and primary comparing the timelines and relative WAL positions of the local node (rejoin candidate) and primary
@@ -381,7 +383,7 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-standby-follow"> <xref linkend="repmgr-standby-follow"/>
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

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

View File

@@ -38,23 +38,25 @@
Execute with the <option>--dry-run</option> option to check what would happen without Execute with the <option>--dry-run</option> option to check what would happen without
actually registering the primary. actually registering the primary.
</para> </para>
<para>
<command>repmgr master register</command> can be used as an alias for
<command>repmgr primary register</command>.
</para>
<note> <note>
<para> <para>
If providing the configuration file location with <option>-f/--config-file</option>, If providing the configuration file location with <option>-f/--config-file</option>,
avoid using a relative path, as &repmgr; stores the configuration file location avoid using a relative path, as &repmgr; stores the configuration file location
in the repmgr metadata for use when &repmgr; is executed remotely (e.g. during in the repmgr metadata for use when &repmgr; is executed remotely (e.g. during
<xref linkend="repmgr-standby-switchover">). &repmgr; will attempt to convert the <xref linkend="repmgr-standby-switchover"/>). &repmgr; will attempt to convert the
a relative path into an absolute one, but this may not be the same as the path you a relative path into an absolute one, but this may not be the same as the path you
would explicitly provide (e.g. <filename>./repmgr.conf</filename> might be converted would explicitly provide (e.g. <filename>./repmgr.conf</filename> might be converted
to <filename>/path/to/./repmgr.conf</filename>, whereas you'd normally write to <filename>/path/to/./repmgr.conf</filename>, whereas you'd normally write
<filename>/path/to/repmgr.conf</filename>). <filename>/path/to/repmgr.conf</filename>).
</para> </para>
</note> </note>
<para>
<command>repmgr master register</command> can be used as an alias for
<command>repmgr primary register</command>.
</para>
</refsect1> </refsect1>
<refsect1> <refsect1>

View File

@@ -85,12 +85,13 @@
</refsect1> </refsect1>
<refsect1 id="repmgr-standby-clone-recovery-conf"> <refsect1 id="repmgr-standby-clone-recovery-conf">
<indexterm> <title>Customising recovery.conf</title>
<indexterm>
<primary>recovery.conf</primary> <primary>recovery.conf</primary>
<secondary>customising with &quot;repmgr standby clone&quot;</secondary> <secondary>customising with &quot;repmgr standby clone&quot;</secondary>
</indexterm> </indexterm>
<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:
@@ -142,7 +143,7 @@
We recommend using <ulink url="https://www.pgbarman.org/">Barman</ulink> to manage We recommend using <ulink url="https://www.pgbarman.org/">Barman</ulink> to manage
WAL file archiving. For more details on combining &repmgr; and <application>Barman</application>, WAL file archiving. For more details on combining &repmgr; and <application>Barman</application>,
in particular using <varname>restore_command</varname> to configure Barman as a backup source of in particular using <varname>restore_command</varname> to configure Barman as a backup source of
WAL files, see <xref linkend="cloning-from-barman">. WAL files, see <xref linkend="cloning-from-barman"/>.
</para> </para>
</note> </note>
@@ -154,7 +155,7 @@
When initially cloning a standby, you will need to ensure When initially cloning a standby, you will need to ensure
that all required WAL files remain available while the cloning is taking that all required WAL files remain available while the cloning is taking
place. To ensure this happens when using the default <command>pg_basebackup</command> method, place. To ensure this happens when using the default <command>pg_basebackup</command> method,
&repmgr; will set <command>pg_basebackup</command>'s <literal>--xlog-method</literal> &repmgr; will set <command>pg_basebackup</command>'s <literal>--wal-method</literal>
parameter to <literal>stream</literal>, parameter to <literal>stream</literal>,
which will ensure all WAL files generated during the cloning process are which will ensure all WAL files generated during the cloning process are
streamed in parallel with the main backup. Note that this requires two streamed in parallel with the main backup. Note that this requires two
@@ -164,10 +165,10 @@
</para> </para>
<para> <para>
To override this behaviour, in <filename>repmgr.conf</filename> set To override this behaviour, in <filename>repmgr.conf</filename> set
<command>pg_basebackup</command>'s <literal>--xlog-method</literal> <command>pg_basebackup</command>'s <literal>--wal-method</literal>
parameter to <literal>fetch</literal>: parameter to <literal>fetch</literal>:
<programlisting> <programlisting>
pg_basebackup_options='--xlog-method=fetch'</programlisting> pg_basebackup_options='--wal-method=fetch'</programlisting>
and ensure that <literal>wal_keep_segments</literal> is set to an appropriately high value. and ensure that <literal>wal_keep_segments</literal> 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/app-pgbasebackup.html">
@@ -176,9 +177,8 @@
<note> <note>
<simpara> <simpara>
From PostgreSQL 10, <command>pg_basebackup</command>'s If using PostgreSQL 9.6 or earlier, replace <literal>--wal-method</literal>
<literal>--xlog-method</literal> parameter has been renamed to with <literal>--xlog-method</literal>.
<literal>--wal-method</literal>.
</simpara> </simpara>
</note> </note>
</refsect1> </refsect1>
@@ -186,12 +186,13 @@
<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.5/#recover">barman recover</ulink></command> command).
@@ -201,6 +202,18 @@
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>.
</para>
<tip>
<para>
To register a standby which is not running, execute
<link linkend="repmgr-standby-register">repmgr standby register --force</link>
and provide the connection details for the primary.
</para>
<para>
See <xref linkend="repmgr-standby-register-inactive-node"/> for more details.
</para>
</tip>
<para>
Then execute the command <command>repmgr standby clone --recovery-conf-only</command>. Then execute the command <command>repmgr standby clone --recovery-conf-only</command>.
This will create the <filename>recovery.conf</filename> file needed to attach This will create the <filename>recovery.conf</filename> file needed to attach
the node to its upstream, and will also create a replication slot on the the node to its upstream, and will also create a replication slot on the
@@ -296,7 +309,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>
@@ -325,9 +338,13 @@
<term><option>--upstream-conninfo</option></term> <term><option>--upstream-conninfo</option></term>
<listitem> <listitem>
<para> <para>
<literal>primary_conninfo</literal> value to write in recovery.conf <literal>primary_conninfo</literal> value to write in <filename>recovery.conf</filename>
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>
@@ -361,7 +378,7 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
See <xref linkend="cloning-standbys"> for details about various aspects of cloning. See <xref linkend="cloning-standbys"/> for details about various aspects of cloning.
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

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

View File

@@ -17,18 +17,50 @@
<para> <para>
Promotes a standby to a primary if the current primary has failed. This 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 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 specified explicitly with <literal>-f/--config-file</literal> or located in a
default location; no additional arguments are required. default location; no additional arguments are required.
</para> </para>
<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> <para>
If the standby promotion succeeds, the server will not need to be If the standby promotion succeeds, the server will not need to be
restarted. However any other standbys will need to follow the new server, restarted. However any other standbys will need to follow the new primary,
by using <xref linkend="repmgr-standby-follow">; if <application>repmgrd</application> and will need to be restarted to do this.
is active, it will handle this automatically.
</para> </para>
<para> <para>
Note that &repmgr; will wait for up to <varname>promote_check_timeout</varname> seconds Beginning with <link linkend="release-4.4">repmgr 4.4</link>,
(default: 60 seconds) to verify that the standby has been promoted, and will 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). check the promotion every <varname>promote_check_interval</varname> seconds (default: 1 second).
Both values can be defined in <filename>repmgr.conf</filename>. Both values can be defined in <filename>repmgr.conf</filename>.
</para> </para>
@@ -72,13 +104,36 @@
<title>Options</title> <title>Options</title>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><option>--dry-run</option></term> <term><option>--dry-run</option></term>
<listitem> <listitem>
<para> <para>
Check if this node can be promoted, but don't carry out the promotion Check if this node can be promoted, but don't carry out the promotion.
</para> </para>
</listitem> </listitem>
</varlistentry> </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> </variablelist>
</refsect1> </refsect1>
@@ -99,7 +154,7 @@
</indexterm> </indexterm>
<simpara> <simpara>
<literal>promote_check_interval</literal>: <literal>promote_check_interval</literal>:
interval (in seconds, default: 1 seconds) to wait between each check interval (in seconds, default: 1 second) to wait between each check
to determine whether the standby has been promoted. to determine whether the standby has been promoted.
</simpara> </simpara>
</listitem> </listitem>

View File

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

View File

@@ -22,11 +22,13 @@
passwordless SSH connection to the current primary. passwordless SSH connection to the current primary.
</para> </para>
<para> <para>
If other standbys are connected to the demotion candidate, &repmgr; can instruct If other nodes 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 standbys attached to the demotion candidate candidate (new primary) and the nodes attached to the demotion candidate
(existing primary). (existing primary). Note that a witness server, if in use, is also
counted as a &quot;sibling node&quot; as it needs to be instructed to
synchronise its metadata with the new primary.
</para> </para>
<note> <note>
<para> <para>
@@ -42,18 +44,18 @@
</note> </note>
<para> <para>
For more details on performing a switchover, including preparation and configuration, For more details on performing a switchover, including preparation and configuration,
see section <xref linkend="performing-switchover">. see section <xref linkend="performing-switchover"/>.
</para> </para>
<note> <note>
<para> <para>
From <link linkend="release-4.2">repmgr 4.2</link>, &repmgr; will instruct any running From <link linkend="release-4.2">repmgr 4.2</link>, &repmgr; will instruct any running
<application>repmgrd</application> instances to pause operations while the switchover &repmgrd; instances to pause operations while the switchover
is being carried out, to prevent <application>repmgrd</application> from is being carried out, to prevent &repmgrd; from
unintentionally promoting a node. For more details, see <xref linkend="repmgrd-pausing">. unintentionally promoting a node. For more details, see <xref linkend="repmgrd-pausing"/>.
</para> </para>
<para> <para>
Users of &repmgr; versions prior to 4.2 should ensure that <application>repmgrd</application> Users of &repmgr; versions prior to 4.2 should ensure that &repmgrd;
is not running on any nodes while a switchover is being executed. is not running on any nodes while a switchover is being executed.
</para> </para>
</note> </note>
@@ -115,7 +117,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>
@@ -134,12 +136,30 @@
<term><option>--repmgrd-no-pause</option></term> <term><option>--repmgrd-no-pause</option></term>
<listitem> <listitem>
<para> <para>
Don't pause <application>repmgrd</application> while executing a switchover. Don't pause &repmgrd; while executing a switchover.
</para> </para>
<para> <para>
This option should not be used unless you take steps by other means This option should not be used unless you take steps by other means
to ensure <application>repmgrd</application> is paused or not to ensure &repmgrd; is paused or not
running on all nodes. running on all nodes.
</para>
<para>
This option cannot be used together with <option>--repmgrd-force-unpause</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--repmgrd-force-unpause</option></term>
<listitem>
<para>
Always unpause all &repmgrd; instances after executing a switchover. This will ensure that
any &repmgrd; instances which were paused before the switchover will be
unpaused.
</para>
<para>
This option cannot be used together with <option>--repmgrd-no-pause</option>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -150,8 +170,18 @@
<term><option>--siblings-follow</option></term> <term><option>--siblings-follow</option></term>
<listitem> <listitem>
<para> <para>
Have standbys attached to the old primary follow the new primary. Have nodes 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>
@@ -169,13 +199,14 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<indexterm>
<primary>replication_lag_critical</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<term><option>replication_lag_critical</option></term> <term><option>replication_lag_critical</option></term>
<listitem> <listitem>
<indexterm>
<primary>replication_lag_critical</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para> <para>
If replication lag (in seconds) on the standby exceeds this value, the If replication lag (in seconds) on the standby exceeds this value, the
switchover will be aborted (unless the <literal>-F/--force</literal> option switchover will be aborted (unless the <literal>-F/--force</literal> option
@@ -185,13 +216,14 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<indexterm>
<primary>shutdown_check_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<term><option>shutdown_check_timeout</option></term> <term><option>shutdown_check_timeout</option></term>
<listitem> <listitem>
<indexterm>
<primary>shutdown_check_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para> <para>
The maximum number of seconds to wait for the The maximum number of seconds to wait for the
demotion candidate (current primary) to shut down, before aborting the switchover. demotion candidate (current primary) to shut down, before aborting the switchover.
@@ -213,13 +245,13 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>wal_receive_check_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<term><option>wal_receive_check_timeout</option></term> <term><option>wal_receive_check_timeout</option></term>
<listitem> <listitem>
<indexterm>
<primary>wal_receive_check_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para> <para>
After the primary has shut down, the maximum number of seconds to wait for the After the primary has shut down, the maximum number of seconds to wait for the
walreceiver on the standby to flush WAL to disk before comparing WAL receive location walreceiver on the standby to flush WAL to disk before comparing WAL receive location
@@ -230,13 +262,14 @@
<varlistentry> <varlistentry>
<indexterm>
<primary>standby_reconnect_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<term><option>standby_reconnect_timeout</option></term> <term><option>standby_reconnect_timeout</option></term>
<listitem> <listitem>
<indexterm>
<primary>standby_reconnect_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para> <para>
The maximum number of seconds to attempt to wait for the demotion candidate (former primary) The maximum number of seconds to attempt to wait for the demotion candidate (former primary)
to reconnect to the promoted primary (default: 60 seconds) to reconnect to the promoted primary (default: 60 seconds)
@@ -249,14 +282,16 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<indexterm>
<primary>node_rejoin_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<term><option>node_rejoin_timeout</option></term> <term><option>node_rejoin_timeout</option></term>
<listitem> <listitem>
<indexterm>
<primary>node_rejoin_timeout</primary>
<secondary>with &quot;repmgr standby switchover&quot;</secondary>
</indexterm>
<para> <para>
maximum number of seconds to attempt to wait for the demotion candidate (former primary) maximum number of seconds to attempt to wait for the demotion candidate (former primary)
to reconnect to the promoted primary (default: 60 seconds) to reconnect to the promoted primary (default: 60 seconds)
@@ -350,10 +385,10 @@
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>
<para> <para>
<xref linkend="repmgr-standby-follow">, <xref linkend="repmgr-node-rejoin"> <xref linkend="repmgr-standby-follow"/>, <xref linkend="repmgr-node-rejoin"/>
</para> </para>
<para> <para>
For more details on performing a switchover operation, see the section <xref linkend="performing-switchover">. For more details on performing a switchover operation, see the section <xref linkend="performing-switchover"/>.
</para> </para>
</refsect1> </refsect1>

View File

@@ -20,7 +20,7 @@
record to the &repmgr; metadata, and if necessary initialises the witness record to the &repmgr; metadata, and if necessary initialises the witness
node by installing the &repmgr; extension and copying the &repmgr; metadata node by installing the &repmgr; extension and copying the &repmgr; metadata
to the witness server. This command needs to be executed to enable to the witness server. This command needs to be executed to enable
use of the witness server with <application>repmgrd</application>. use of the witness server with &repmgrd;.
</para> </para>
<para> <para>
When executing <command>repmgr witness register</command>, database connection When executing <command>repmgr witness register</command>, database connection

View File

@@ -1,14 +1,16 @@
<!-- doc/src/sgml/postgres.sgml --> <!-- doc/repmgr.xml -->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [ <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
<!ENTITY % version SYSTEM "version.sgml"> [
<!ENTITY % version SYSTEM "version.xml">
%version; %version;
<!ENTITY % filelist SYSTEM "filelist.sgml"> <!ENTITY % filelist SYSTEM "filelist.xml">
%filelist; %filelist;
<!ENTITY repmgr "<productname>repmgr</productname>"> <!ENTITY repmgr "<productname>repmgr</productname>">
<!ENTITY repmgrd "<productname>repmgrd</productname>">
<!ENTITY postgres "<productname>PostgreSQL</productname>"> <!ENTITY postgres "<productname>PostgreSQL</productname>">
]> ]>
@@ -25,25 +27,31 @@
<para> <para>
This is the official documentation of &repmgr; &repmgrversion; for This is the official documentation of &repmgr; &repmgrversion; for
use with PostgreSQL 9.3 - PostgreSQL 11. use with PostgreSQL 9.3 - PostgreSQL 11.
It describes the functionality supported by the current version of &repmgr;. </para>
<para>
&repmgr; is being continually developed and we strongly recommend using the
latest version. Please check the
<ulink url="https://repmgr.org/">repmgr website</ulink> for details
about the current &repmgr; version as well as the
<ulink url="https://repmgr.org/docs/current/index.html">current repmgr documentation</ulink>.
</para> </para>
<para> <para>
&repmgr; was developed by &repmgr; is developed by
<ulink url="https://2ndquadrant.com">2ndQuadrant</ulink> <ulink url="https://2ndquadrant.com">2ndQuadrant</ulink>
along with contributions from other individuals and companies. along with contributions from other individuals and organisations.
Contributions from the community are appreciated and welcome - get Contributions from the community are appreciated and welcome - get
in touch via <ulink url="https://github.com/2ndQuadrant/repmgr">github</> in touch via <ulink url="https://github.com/2ndQuadrant/repmgr">github</ulink>
or <ulink url="https://groups.google.com/group/repmgr">the mailing list/forum</>. or <ulink url="https://groups.google.com/group/repmgr">the mailing list/forum</ulink>.
Multiple 2ndQuadrant customers contribute funding Multiple 2ndQuadrant customers contribute funding
to make repmgr development possible. to make repmgr development possible.
</para> </para>
<para> <para>
2ndQuadrant, a Platinum sponsor of the PostgreSQL project, &repmgr; is fully supported by 2ndQuadrant's
continues to develop repmgr to meet internal needs and those of customers. <ulink url="https://www.2ndquadrant.com/en/support/support-postgresql/">24/7 Production Support</ulink>.
Other companies as well as individual developers 2ndQuadrant, a Major Sponsor of the PostgreSQL project, continues to develop and maintain &repmgr;.
are welcome to participate in the efforts. Other organisations as well as individual developers are welcome to participate in the efforts.
</para> </para>
</abstract> </abstract>
@@ -73,23 +81,16 @@
&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-demonstration; &repmgrd-operation;
&repmgrd-cascading-replication;
&repmgrd-network-split;
&repmgrd-witness-server;
&repmgrd-pausing;
&repmgrd-degraded-monitoring;
&repmgrd-monitoring;
&repmgrd-notes;
&repmgrd-bdr; &repmgrd-bdr;
</part> </part>
@@ -128,7 +129,6 @@
&appendix-packages; &appendix-packages;
&appendix-support; &appendix-support;
<![%include-index;[&bookindex;]]> <index id="bookindex"></index>
<![%include-xslt-index;[<index id="bookindex"></index>]]>
</book> </book>

View File

@@ -1,17 +0,0 @@
<chapter id="repmgrd-automatic-failover" xreflabel="Automatic failover with repmgrd">
<indexterm>
<primary>repmgrd</primary>
<secondary>automatic failover</secondary>
</indexterm>
<title>Automatic failover with repmgrd</title>
<para>
<application>repmgrd</application> is a management and monitoring daemon which runs
on each node in a replication cluster. It can automate actions such as
failover and updating standbys to follow the new primary, as well as
providing monitoring information about the state of each standby.
</para>
</chapter>

View File

@@ -0,0 +1,925 @@
<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,4 +1,6 @@
<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>
@@ -8,9 +10,8 @@
<primary>BDR</primary> <primary>BDR</primary>
</indexterm> </indexterm>
<title>BDR failover with repmgrd</title>
<para> <para>
&repmgr; 4.x provides support for monitoring BDR 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.
</para> </para>
<note> <note>
@@ -24,15 +25,28 @@
<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 <application>repmgrd</application> and redirecting queries from the failed node to the remaining with &repmgrd; 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 <application>repmgrd</application> to dynamically which is called by &repmgrd; 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>
<note>
<simpara>
This &repmgr; functionality is for BDR 2.x only running on PostgreSQL 9.4/9.6.
It is <emphasis>not</emphasis> required for later BDR versions.
</simpara>
</note>
<sect1 id="bdr-prerequisites" xreflabel="BDR prequisites"> <sect1 id="bdr-prerequisites" xreflabel="BDR prequisites">
<title>Prerequisites</title> <title>Prerequisites</title>
<important>
<para>
This &repmgr; functionality is for BDR 2.x only running on PostgreSQL 9.4/9.6.
It is <emphasis>not</emphasis> required for later BDR versions.
</para>
</important>
<para> <para>
&repmgr; 4 requires PostgreSQL 9.4 or 9.6 with the BDR 2 extension &repmgr; 4 requires PostgreSQL 9.4 or 9.6 with the BDR 2 extension
enabled and configured for a two-node BDR network. &repmgr; 4 packages enabled and configured for a two-node BDR network. &repmgr; 4 packages
@@ -47,7 +61,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 <application>repmgrd</application>. The example demonstrated in this document reconfigure that from &repmgrd;. The example demonstrated in this document
will use <application>PgBouncer</application> will use <application>PgBouncer</application>
</para> </para>
<para> <para>
@@ -81,7 +95,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>&1' event_notification_command='/path/to/bdr-pgbouncer.sh %n %e %s "%c" "%a" >> /tmp/bdr-failover.log 2>&amp;1'
# repmgrd options # repmgrd options
monitor_interval_secs=5 monitor_interval_secs=5
@@ -107,7 +121,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>
@@ -145,7 +159,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
@@ -155,7 +169,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
@@ -283,7 +297,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 <application>repmgrd</application> node using the information provided by &repmgrd;
(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>
@@ -305,21 +319,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>, <application>repmgrd</application> in <filename>repmgr.conf</filename>, &repmgrd;
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,
<application>repmgrd</application> will enter failover mode and check <varname>reconnect_attempts</varname> &repmgrd; 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, <application>repmgrd</application> will enter failover mode and execute If the node is still unavailable, &repmgrd; 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 <application>repmgrd</application> will in the <literal>repmgr.events</literal> table and &repmgrd; 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>
<application>repmgrd</application> logfile output during a failover event will look something like this &repmgrd; 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>
... ...
@@ -375,8 +389,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
<application>repmgrd</application> instance running on <literal>node2</literal> has performed the failover. However if &repmgrd; instance running on <literal>node2</literal> has performed the failover. However if
the entire server becomes unavailable, <application>repmgrd</application> on <literal>node1</literal> will perform the entire server becomes unavailable, &repmgrd; on <literal>node1</literal> will perform
the failover. the failover.
</para> </para>
</sect1> </sect1>
@@ -391,7 +405,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 <application>repmgrd</application> log: will be visible in the &repmgrd; 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)
@@ -404,10 +418,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, <application>repmgrd</application> will try and handle the If both PostgreSQL instances are shut down, &repmgrd; 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 <application>repmgrd</application> on both nodes and restarting it once the PostgreSQL instances down &repmgrd; on both nodes and restarting it once the PostgreSQL instances
are running properly. are running properly.
</para> </para>
</sect1> </sect1>

View File

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

View File

@@ -1,604 +0,0 @@
<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/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="postgresql-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-service-configuration">
<indexterm>
<primary>repmgrd</primary>
<secondary>repmgrd service configuration</secondary>
</indexterm>
<title>repmgrd service configuration</title>
<para>
If you are intending to use the <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link>
and <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> commands, the following
parameters <emphasis>must</emphasis> be set in <filename>repmgr.conf</filename>:
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara><varname>repmgrd_service_start_command</varname></simpara>
</listitem>
<listitem>
<simpara><varname>repmgrd_service_stop_command</varname></simpara>
</listitem>
</itemizedlist>
</para>
<para>
Example (for &repmgr; with PostgreSQL 11 on CentOS 7):
<programlisting>
repmgrd_service_start_command='sudo systemctl repmgr11 start'
repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
</programlisting>
</para>
<para>
For more details see the reference page for each command.
</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" xreflabel="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>
The commands <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> and
<link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> can be used
as convenience wrappers to start and stop <application>repmgrd</application>.
</para>
<important>
<para>
<link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> and
<link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> require
that the appropriate start/stop commands are configured as
<varname>repmgrd_service_start_command</varname> and <varname>repmgrd_service_stop_command</varname>
in <filename>repmgr.conf</filename>.
</para>
</important>
<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 (as setermined 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/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

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

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

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

@@ -1,48 +0,0 @@
<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,38 +0,0 @@
<chapter id="repmgrd-notes" xreflabel="repmgrd notes">
<indexterm>
<primary>repmgrd</primary>
<secondary>notes</secondary>
</indexterm>
<title>repmgrd notes</title>
<sect1 id="repmgrd-wal-replay-pause">
<indexterm>
<primary>repmgrd</primary>
<secondary>paused WAL replay</secondary>
</indexterm>
<title>repmgrd and paused WAL replay</title>
<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 <application>repmgrd</application> 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>
</chapter>

388
doc/repmgrd-operation.xml Normal file
View File

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

187
doc/repmgrd-overview.xml Normal file
View File

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

View File

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

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

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

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

174
doc/stylesheet.xsl Normal file
View File

@@ -0,0 +1,174 @@
<?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,17 +44,18 @@
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
@@ -72,7 +73,8 @@
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 standbys attached to the demotion candidate. promotion candidate to all nodes attached to the demotion candidate
(including the witness server, if in use).
</para> </para>
<note> <note>
@@ -113,7 +115,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>
@@ -158,12 +160,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
<application>repmgrd</application> instances to pause operations while the switchover &repmgrd; instances to pause operations while the switchover
is being carried out, to prevent <application>repmgrd</application> from is being carried out, to prevent &repmgrd; from
unintentionally promoting a node. For more details, see <xref linkend="repmgrd-pausing">. unintentionally promoting a node. For more details, see <xref linkend="repmgrd-pausing"/>.
</para> </para>
<para> <para>
Users of &repmgr; versions prior to 4.2 should ensure that <application>repmgrd</application> Users of &repmgr; versions prior to 4.2 should ensure that &repmgrd;
is not running on any nodes while a switchover is being executed. is not running on any nodes while a switchover is being executed.
</para> </para>
</note> </note>
@@ -203,18 +205,19 @@
<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
@@ -257,11 +260,12 @@
</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>);
@@ -312,13 +316,13 @@
</programlisting> </programlisting>
</para> </para>
<para> <para>
If <application>repmgrd</application> is in use, it's worth double-checking that If &repmgrd; 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 <application>repmgrd</application> Users of &repmgr; versions prior to 4.2 will need to manually restart &repmgrd;
on all nodes after the switchover is completed. on all nodes after the switchover is completed.
</para> </para>
</note> </note>
@@ -327,11 +331,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>
@@ -356,11 +360,12 @@
</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

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,18 +13,19 @@
</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 <application>repmgrd</application> executables the <application>repmgr</application> and &repmgrd; executables
</simpara> </simpara>
</listitem> </listitem>
@@ -37,7 +38,7 @@
<listitem> <listitem>
<simpara> <simpara>
the shared library module used by <application>repmgrd</application> which the shared library module used by &repmgrd; which
is resident in the PostgreSQL backend is resident in the PostgreSQL backend
</simpara> </simpara>
</listitem> </listitem>
@@ -45,8 +46,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 <application>repmgrd</application> executables. In this case, the upgrade is quite straightforward, and &repmgrd; executables. In this case, the upgrade is quite straightforward,
and is simply a case of installing the new version, and restarting <application>repmgrd</application> and is simply a case of installing the new version, and restarting &repmgrd;
(if running). (if running).
</para> </para>
@@ -63,11 +64,12 @@
</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:
@@ -82,7 +84,7 @@
<listitem> <listitem>
<simpara> <simpara>
restart <application>repmgrd</application> on all nodes where it is running restart &repmgrd; on all nodes where it is running
</simpara> </simpara>
</listitem> </listitem>
@@ -93,7 +95,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 <application>repmgrd</application> as part of the package upgrade process. may restart &repmgrd; as part of the package upgrade process.
</para> </para>
</note> </note>
@@ -118,15 +120,17 @@
</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 <application>repmgrd</application> standbys) and/or changes to the shared object file used by &repmgrd;
(which require a PostgreSQL restart). (which require a PostgreSQL restart).
</para> </para>
<para> <para>
@@ -138,14 +142,14 @@
<listitem> <listitem>
<simpara> <simpara>
Stop <application>repmgrd</application> (if in use) on all nodes where it is running. Stop &repmgrd; (if in use) on all nodes where it is running.
</simpara> </simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara> <simpara>
Disable the <application>repmgrd</application> service on all nodes where it is in use; Disable the &repmgrd; service on all nodes where it is in use;
this is to prevent packages from prematurely restarting <application>repmgrd</application>. this is to prevent packages from prematurely restarting &repmgrd;.
</simpara> </simpara>
</listitem> </listitem>
@@ -167,12 +171,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 <application>repmgrd</application> (if in use) on each node, restart PostgreSQL, then &repmgrd; (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 <application>repmgrd</application>. and it's also fine to restart PostgreSQL on all nodes first before starting &repmgrd;.
</simpara> </simpara>
<simpara> <simpara>
Note that if the upgrade requires a PostgreSQL restart, <application>repmgrd</application> Note that if the upgrade requires a PostgreSQL restart, &repmgrd;
will only function correctly once all nodes have been restarted. will only function correctly once all nodes have been restarted.
</simpara> </simpara>
</listitem> </listitem>
@@ -188,7 +192,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
<listitem> <listitem>
<simpara> <simpara>
Reenable the <application>repmgrd</application> service on all nodes where it is in use, and Reenable the &repmgrd; service on all nodes where it is in use, and
ensure it is running. ensure it is running.
</simpara> </simpara>
</listitem> </listitem>
@@ -205,19 +209,22 @@ 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 <application>repmgrd</application> on all nodes. command (on any node) to show an overview of the status of &repmgrd; 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>
@@ -225,7 +232,6 @@ 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
@@ -257,7 +263,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
<tip> <tip>
<para> <para>
Use <command><link linkend="repmgr-node-check">repmgr node check</link></command> Use <command><link linkend="repmgr-node-check">repmgr node check</link></command>
to determine which replacation slots need to be recreated. to determine which replication slots need to be recreated.
</para> </para>
</tip> </tip>
@@ -265,12 +271,13 @@ 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>
@@ -332,7 +339,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
<application>repmgrd</application> command line option &repmgrd; command line option
<literal>--monitoring-history</literal></simpara> <literal>--monitoring-history</literal></simpara>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@@ -383,7 +390,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>
@@ -433,7 +440,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
<sect2> <sect2>
<title>Upgrading the repmgr schema</title> <title>Upgrading the repmgr schema</title>
<para> <para>
Ensure <application>repmgrd</application> is not running, or any cron jobs which execute the Ensure &repmgrd; is not running, or any cron jobs which execute the
<command>repmgr</command> binary. <command>repmgr</command> binary.
</para> </para>
<para> <para>
@@ -499,7 +506,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 <application>repmgrd</application> if required. table; restart &repmgrd; 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.

View File

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

View File

@@ -1,21 +1,20 @@
/* PostgreSQL.org Documentation Style */ /* PostgreSQL.org Documentation Style */
/*
* Documentation generated by XSL stylesheets has lower-case class
* names, older documentation generated by DSSSL stylesheets has
* upper-case class names, so we need to support both for a while. In
* some cases, the elements and classes differ further between the two
* stylesheets.
*/
/* requires global.css, table.css and text.css to be loaded before this file! */ /* requires global.css, table.css and text.css to be loaded before this file! */
body { body {
font-family: verdana, sans-serif;
font-size: 76%; font-size: 76%;
background: url("/resources/background.png") repeat-x scroll left top transparent;
padding: 15px 4%;
margin: 0;
} }
/* monospace font size fix */ .navheader table,
pre, code, kbd, samp, tt { .NAVHEADER table {
font-family: monospace,monospace;
font-size: 1em;
}
div.NAVHEADER table {
margin-left: 0; margin-left: 0;
} }
@@ -99,7 +98,7 @@ div.NAVHEADER table {
#docSearch form input { #docSearch form input {
font-size: 0.95em; font-size: 0.95em;
} }
#docSearch form #submit { #docSearch form #submit {
font-size: 0.95em; font-size: 0.95em;
background: #7A7A7A; background: #7A7A7A;
@@ -107,7 +106,7 @@ div.NAVHEADER table {
border: 1px solid #7A7A7A; border: 1px solid #7A7A7A;
padding: 1px 4px; padding: 1px 4px;
} }
#docSearch form #q { #docSearch form #q {
width: 170px; width: 170px;
font-size: 0.95em; font-size: 0.95em;
@@ -138,9 +137,9 @@ div.NAVHEADER table {
#docFooter { #docFooter {
position: relative; position: relative;
font-size: 0.9em; font-size: 0.9em;
color: #666; color: #666;
line-height: 1.3em; line-height: 1.3em;
margin-left: 10px; margin-left: 10px;
margin-right: 10px; margin-right: 10px;
} }
@@ -160,7 +159,6 @@ div.NAVHEADER table {
h1, h2, h3 { h1, h2, h3 {
font-weight: bold; font-weight: bold;
margin-top: 2ex; margin-top: 2ex;
color: #444;
} }
h1 { h1 {
@@ -175,20 +173,35 @@ h3 {
font-size: 1.1em; font-size: 1.1em;
} }
h1 a:hover, h1 a:hover {
color: #EC5800;
text-decoration: none;
}
h2 a:hover, h2 a:hover,
h3 a:hover, h3 a:hover,
h4 a:hover { h4 a:hover {
color: #444; color: #666666;
text-decoration: none; text-decoration: none;
} }
/*
* Change color of h2 chunk titles in XSL build. (In DSSSL build,
* these will be h1, which is already handled elsewhere.)
*/
.titlepage h2.title,
.refnamediv h2 {
color: #EC5800;
}
/* Text Styles */ /* Text Styles */
div.sect2,
div.SECT2 { div.SECT2 {
margin-top: 4ex; margin-top: 4ex;
} }
div.sect3,
div.SECT3 { div.SECT3 {
margin-top: 3ex; margin-top: 3ex;
margin-left: 3ex; margin-left: 3ex;
@@ -203,7 +216,7 @@ p, ol, ul, li {
} }
.txtCommentsWrap { .txtCommentsWrap {
border: 2px solid #F5F5F5; border: 2px solid #F5F5F5;
width: 100%; width: 100%;
} }
@@ -233,6 +246,17 @@ p, ol, ul, li {
font-size: 1em; font-size: 1em;
} }
pre.literallayout,
.screen,
.synopsis,
.programlisting,
.refsynopsisdiv p,
.caution,
.warning,
.note,
.tip,
.table table,
.informaltable table,
pre.LITERALLAYOUT, pre.LITERALLAYOUT,
.SCREEN, .SCREEN,
.SYNOPSIS, .SYNOPSIS,
@@ -250,6 +274,15 @@ table.CALSTABLE {
box-shadow: 3px 3px 5px #DFDFDF; box-shadow: 3px 3px 5px #DFDFDF;
} }
pre.literallayout,
.screen,
.synopsis,
.programlisting,
.refsynopsisdiv p,
.caution,
.warning,
.note,
.tip,
pre.LITERALLAYOUT, pre.LITERALLAYOUT,
.SCREEN, .SCREEN,
.SYNOPSIS, .SYNOPSIS,
@@ -271,6 +304,11 @@ blockquote.TIP {
border-radius: 8px; border-radius: 8px;
} }
pre.literallayout,
pre.synopsis,
pre.programlisting,
.refsynopsisdiv p,
.screen,
pre.LITERALLAYOUT, pre.LITERALLAYOUT,
pre.SYNOPSIS, pre.SYNOPSIS,
pre.PROGRAMLISTING, pre.PROGRAMLISTING,
@@ -280,6 +318,8 @@ pre.PROGRAMLISTING,
background-color: #F7F7F7; background-color: #F7F7F7;
} }
.note,
.tip,
blockquote.NOTE, blockquote.NOTE,
blockquote.TIP { blockquote.TIP {
border-color: #DBDBCC; border-color: #DBDBCC;
@@ -288,6 +328,10 @@ blockquote.TIP {
width: 572px; width: 572px;
} }
.note,
.tip,
.caution,
.warning,
blockquote.NOTE, blockquote.NOTE,
blockquote.TIP, blockquote.TIP,
table.CAUTION, table.CAUTION,
@@ -295,11 +339,17 @@ table.WARNING {
margin: 4ex auto; margin: 4ex auto;
} }
.note p,
.tip p,
blockquote.NOTE p, blockquote.NOTE p,
blockquote.TIP p { blockquote.TIP p {
margin: 0; margin: 0;
} }
.note pre,
.note code,
.tip pre,
.tip code,
blockquote.NOTE pre, blockquote.NOTE pre,
blockquote.NOTE code, blockquote.NOTE code,
blockquote.TIP pre, blockquote.TIP pre,
@@ -313,11 +363,24 @@ blockquote.TIP code {
box-shadow: none; box-shadow: none;
} }
.caution,
.warning {
max-width: 600px;
}
.tip h3,
.note h3,
.caution h3,
.warning h3 {
text-align: center;
}
.emphasis, .emphasis,
.c2 { .c2 {
font-weight: bold; font-weight: bold;
} }
.replaceable,
.REPLACEABLE { .REPLACEABLE {
font-style: italic; font-style: italic;
} }
@@ -328,6 +391,10 @@ table {
margin-left: 2ex; margin-left: 2ex;
} }
.table table td,
.table table th,
.informaltable table td,
.informaltable table th,
table.CALSTABLE td, table.CALSTABLE td,
table.CALSTABLE th, table.CALSTABLE th,
table.CAUTION td, table.CAUTION td,
@@ -337,6 +404,8 @@ table.WARNING th {
border-style: solid; border-style: solid;
} }
.table table,
.informaltable table,
table.CALSTABLE, table.CALSTABLE,
table.CAUTION, table.CAUTION,
table.WARNING { table.WARNING {
@@ -344,6 +413,8 @@ table.WARNING {
border-collapse: collapse; border-collapse: collapse;
} }
.table table,
.informaltable table,
table.CALSTABLE table.CALSTABLE
{ {
margin: 2ex 0 2ex 2ex; margin: 2ex 0 2ex 2ex;
@@ -351,15 +422,23 @@ table.CALSTABLE
border: 2px solid #A7C6DF; border: 2px solid #A7C6DF;
} }
.table table tr:hover td,
.informaltable table tr:hover td,
table.CALSTABLE tr:hover td table.CALSTABLE tr:hover td
{ {
background-color: #EFEFEF; background-color: #EFEFEF;
} }
.table table td,
.informaltable table td,
table.CALSTABLE td { table.CALSTABLE td {
background-color: #FFF; background-color: #FFF;
} }
.table table td,
.table table th,
.informaltable table td,
.informaltable table th,
table.CALSTABLE td, table.CALSTABLE td,
table.CALSTABLE th { table.CALSTABLE th {
border: 1px solid #A7C6DF; border: 1px solid #A7C6DF;
@@ -374,11 +453,13 @@ table.WARNING {
max-width: 600px; max-width: 600px;
} }
.caution,
table.CAUTION { table.CAUTION {
background-color: #F5F5DC; background-color: #F5F5DC;
border-color: #DEDFA7; border-color: #DEDFA7;
} }
.warning,
table.WARNING { table.WARNING {
background-color: #FFD7D7; background-color: #FFD7D7;
border-color: #DF421E; border-color: #DF421E;
@@ -447,23 +528,7 @@ a:hover {
color:#666; color:#666;
} }
#docContainer code.function tt,
#docContainer code.FUNCTION tt { #docContainer code.FUNCTION tt {
font-size: 1em; 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;
}

2
log.c
View File

@@ -85,7 +85,7 @@ _stderr_log_with_level(const char *level_name, int level, const char *fmt, va_li
time(&t); time(&t);
tm = localtime(&t); tm = localtime(&t);
strftime(buf, 100, "[%Y-%m-%d %H:%M:%S]", tm); strftime(buf, sizeof(buf), "[%Y-%m-%d %H:%M:%S]", tm);
fprintf(stderr, "%s [%s] ", buf, level_name); fprintf(stderr, "%s [%s] ", buf, level_name);
} }
else else

View File

@@ -78,8 +78,6 @@ CREATE VIEW repmgr.show_nodes AS
LEFT JOIN repmgr.nodes un LEFT JOIN repmgr.nodes un
ON un.node_id = n.upstream_node_id; ON un.node_id = n.upstream_node_id;
/* XXX update upgrade scripts! */
CREATE TABLE repmgr.voting_term ( CREATE TABLE repmgr.voting_term (
term INT NOT NULL term INT NOT NULL
); );

View File

@@ -78,8 +78,6 @@ CREATE VIEW repmgr.show_nodes AS
LEFT JOIN repmgr.nodes un LEFT JOIN repmgr.nodes un
ON un.node_id = n.upstream_node_id; ON un.node_id = n.upstream_node_id;
/* XXX update upgrade scripts! */
CREATE TABLE repmgr.voting_term ( CREATE TABLE repmgr.voting_term (
term INT NOT NULL term INT NOT NULL
); );

View File

@@ -1,12 +1,17 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION -- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION repmgr" to load this file. \quit \echo Use "CREATE EXTENSION repmgr" to load this file. \quit
CREATE FUNCTION set_primary_last_seen() CREATE FUNCTION set_upstream_last_seen()
RETURNS VOID RETURNS VOID
AS 'MODULE_PATHNAME', 'set_primary_last_seen' AS 'MODULE_PATHNAME', 'set_upstream_last_seen'
LANGUAGE C STRICT; LANGUAGE C STRICT;
CREATE FUNCTION get_primary_last_seen() CREATE FUNCTION get_upstream_last_seen()
RETURNS INT RETURNS INT
AS 'MODULE_PATHNAME', 'get_primary_last_seen' AS 'MODULE_PATHNAME', 'get_upstream_last_seen'
LANGUAGE C STRICT;
CREATE FUNCTION get_wal_receiver_pid()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_wal_receiver_pid'
LANGUAGE C STRICT; LANGUAGE C STRICT;

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