mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-22 22:56:29 +00:00
Merge branch 'docs'
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -40,6 +40,8 @@ lib*.pc
|
||||
# test output
|
||||
/results/
|
||||
|
||||
/doc/Makefile
|
||||
|
||||
# other
|
||||
/.lineno
|
||||
*.dSYM
|
||||
|
||||
@@ -63,6 +63,12 @@ Makefile: Makefile.in config.status configure
|
||||
Makefile.global: Makefile.global.in config.status configure
|
||||
./config.status $@
|
||||
|
||||
doc:
|
||||
$(MAKE) -C doc all
|
||||
|
||||
install-doc:
|
||||
$(MAKE) -C doc install
|
||||
|
||||
clean: additional-clean
|
||||
|
||||
maintainer-clean: additional-maintainer-clean
|
||||
|
||||
@@ -991,10 +991,10 @@ active primary, the previous warning will not be displayed:
|
||||
|
||||
$ 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 port=5501
|
||||
2 | node2 | primary | * running | | default | host=node2 dbname=repmgr user=repmgr port=5502
|
||||
3 | node3 | standby | running | node1 | default | host=node3 dbname=repmgr user=repmgr port=5503
|
||||
----+-------+---------+-----------+----------+----------+--------------------------------------
|
||||
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 | node1 | default | host=node3 dbname=repmgr user=repmgr
|
||||
|
||||
However the sole remaining standby is still trying to replicate from the failed
|
||||
primary; `repmgr standby follow` must now be executed to rectify this situation.
|
||||
|
||||
3
configure
vendored
3
configure
vendored
@@ -1871,6 +1871,8 @@ ac_config_files="$ac_config_files Makefile"
|
||||
|
||||
ac_config_files="$ac_config_files Makefile.global"
|
||||
|
||||
ac_config_files="$ac_config_files doc/Makefile"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
# tests run on this system so they can be shared between configure
|
||||
@@ -2564,6 +2566,7 @@ do
|
||||
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
||||
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
|
||||
"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;;
|
||||
esac
|
||||
|
||||
@@ -65,5 +65,6 @@ AC_SUBST(vpath_build)
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_CONFIG_FILES([Makefile.global])
|
||||
AC_CONFIG_FILES([doc/Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
|
||||
5
doc/.gitignore
vendored
Normal file
5
doc/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
HTML.index
|
||||
bookindex.sgml
|
||||
html-stamp
|
||||
html/
|
||||
version.sgml
|
||||
71
doc/Makefile.in
Normal file
71
doc/Makefile.in
Normal file
@@ -0,0 +1,71 @@
|
||||
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) -d stylesheet.dsl -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) -i include-index $<
|
||||
cp $(srcdir)/stylesheet.css $(srcdir)/website-docs.css html/
|
||||
touch $@
|
||||
|
||||
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) -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
|
||||
5
doc/appendix-signatures.sgml
Normal file
5
doc/appendix-signatures.sgml
Normal file
@@ -0,0 +1,5 @@
|
||||
<appendix id="appendix-signatures" xreflabel="Verifying digital signatures">
|
||||
<title>Verifying digital signatures</title>
|
||||
|
||||
<para>WIP</para>
|
||||
</appendix>
|
||||
403
doc/cloning-standbys.sgml
Normal file
403
doc/cloning-standbys.sgml
Normal file
@@ -0,0 +1,403 @@
|
||||
<chapter id="cloning-standbys" xreflabel="cloning standbys">
|
||||
<title>Cloning standbys</title>
|
||||
<para>
|
||||
</para>
|
||||
|
||||
<sect1 id="cloning-from-barman" xreflabel="Cloning from Barman">
|
||||
<indexterm>
|
||||
<primary>cloning</primary>
|
||||
<secondary>from Barman</secondary>
|
||||
</indexterm>
|
||||
<title>Cloning a standby from Barman</title>
|
||||
<para>
|
||||
<xref linkend="repmgr-standby-clone"> can use
|
||||
<ulink url="https://www.2ndquadrant.com/">2ndQuadrant</ulink>'s
|
||||
<ulink url="https://www.pgbarman.org/">Barman</ulink> application
|
||||
to clone a standby (and also as a fallback source for WAL files).
|
||||
</para>
|
||||
<tip>
|
||||
<simpara>
|
||||
Barman (aka PgBarman) should be considered as an integral part of any
|
||||
PostgreSQL replication cluster. For more details see:
|
||||
<ulink url="https://www.pgbarman.org/">https://www.pgbarman.org/</ulink>.
|
||||
</simpara>
|
||||
</tip>
|
||||
<para>
|
||||
Barman support provides the following advantages:
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
<listitem>
|
||||
<para>
|
||||
the primary node does not need to perform a new backup every time a
|
||||
new standby is cloned
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
a standby node can be disconnected for longer periods without losing
|
||||
the ability to catch up, and without causing accumulation of WAL
|
||||
files on the primary node
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
WAL management on the primary becomes much easier as there's no need
|
||||
to use replication slots, and <varname>wal_keep_segments</varname>
|
||||
does not need to be set.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<sect2 id="cloning-from-barman-prerequisites" xreflabel="Prerequisites for cloning from Barman">
|
||||
<title>Prerequisites for cloning from Barman</title>
|
||||
<para>
|
||||
In order to enable Barman support for <command>repmgr standby clone</command>, following
|
||||
prerequisites must be met:
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
<listitem>
|
||||
<para>
|
||||
the <varname>barman_server</varname> setting in <filename>repmgr.conf</filename> is the same as the
|
||||
server configured in Barman;
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
the <varname>barman_host</varname> setting in <filename>repmgr.conf</filename> is set to the SSH
|
||||
hostname of the Barman server;
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
the <varname>restore_command</varname> setting in <filename>repmgr.conf</filename> is configured to
|
||||
use a copy of the <command>barman-wal-restore</command> script shipped with the
|
||||
<literal>barman-cli</literal> package (see below);
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
the Barman catalogue includes at least one valid backup for this server.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<note>
|
||||
<simpara>
|
||||
Barman support is automatically enabled if <varname>barman_server</varname>
|
||||
is set. Normally it is good practice to use Barman, for instance
|
||||
when fetching a base backup while cloning a standby; in any case,
|
||||
Barman mode can be disabled using the <literal>--without-barman</literal>
|
||||
command line option.
|
||||
</simpara>
|
||||
</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 id="cloning-from-barman-restore-command" xreflabel="Using Barman as a WAL file source">
|
||||
<title>Using Barman as a WAL file source</title>
|
||||
<para>
|
||||
As a fallback in case streaming replication is interrupted, PostgreSQL can optionally
|
||||
retrieve WAL files from an archive, such as that provided by Barman. This is done by
|
||||
setting <varname>restore_command</varname> in <filename>recovery.conf</filename> to
|
||||
a valid shell command which can retrieve a specified WAL file from the archive.
|
||||
</para>
|
||||
<para>
|
||||
<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
|
||||
<command>barman-wal-restore.py</command>) which performs this function for Barman.
|
||||
</para>
|
||||
<para>
|
||||
To use <command>barman-wal-restore</command> with &repmgr;
|
||||
and assuming Barman is located on the <literal>barmansrv</literal> host
|
||||
and that <command>barman-wal-restore</command> is located as an executable at
|
||||
<filename>/usr/bin/barman-wal-restore</filename>,
|
||||
<filename>repmgr.conf</filename> should include the following lines:
|
||||
<programlisting>
|
||||
barman_host=barmansrv
|
||||
barman_server=somedb
|
||||
restore_command=/usr/bin/barman-wal-restore barmansrv somedb %f %p</programlisting>
|
||||
</para>
|
||||
<note>
|
||||
<simpara>
|
||||
<command>barman-wal-restore</command> supports command line switches to
|
||||
control parallelism (<literal>--parallel=N</literal>) and compression (
|
||||
<literal>--bzip2</literal>, <literal>--gzip</literal>).
|
||||
</simpara>
|
||||
</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>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="cloning-replication-slots" xreflabel="Cloning and replication slots">
|
||||
<indexterm>
|
||||
<primary>cloning</primary>
|
||||
<secondary>replication slots</secondary>
|
||||
</indexterm>
|
||||
|
||||
<indexterm>
|
||||
<primary>replication slots</primary>
|
||||
<secondary>cloning</secondary>
|
||||
</indexterm>
|
||||
<title>Cloning and replication slots</title>
|
||||
<para>
|
||||
Replication slots were introduced with PostgreSQL 9.4 and are designed to ensure
|
||||
that any standby connected to the primary using a replication slot will always
|
||||
be able to retrieve the required WAL files. This removes the need to manually
|
||||
manage WAL file retention by estimating the number of WAL files that need to
|
||||
be maintained on the primary using <varname>wal_keep_segments</varname>.
|
||||
Do however be aware that if a standby is disconnected, WAL will continue to
|
||||
accumulate on the primary until either the standby reconnects or the replication
|
||||
slot is dropped.
|
||||
</para>
|
||||
<para>
|
||||
To enable &repmgr; to use replication slots, set the boolean parameter
|
||||
<varname>use_replication_slots</varname> in <filename>repmgr.conf</filename>:
|
||||
<programlisting>
|
||||
use_replication_slots=true
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Replication slots must be enabled in <filename>postgresql.conf</filename>` by
|
||||
setting the parameter <varname>max_replication_slots</varname> to at least the
|
||||
number of expected standbys (changes to this parameter require a server restart).
|
||||
</para>
|
||||
<para>
|
||||
When cloning a standby, &repmgr; will automatically generate an appropriate
|
||||
slot name, which is stored in the <literal>repmgr.nodes</literal> table, and create the slot
|
||||
on the upstream node:
|
||||
<programlisting>
|
||||
repmgr=# SELECT node_id, upstream_node_id, active, node_name, type, priority, slot_name
|
||||
FROM repmgr.nodes ORDER BY node_id;
|
||||
node_id | upstream_node_id | active | node_name | type | priority | slot_name
|
||||
---------+------------------+--------+-----------+---------+----------+---------------
|
||||
1 | | t | node1 | primary | 100 | repmgr_slot_1
|
||||
2 | 1 | t | node2 | standby | 100 | repmgr_slot_2
|
||||
3 | 1 | t | node3 | standby | 100 | repmgr_slot_3
|
||||
(3 rows)</programlisting>
|
||||
|
||||
<programlisting>
|
||||
repmgr=# SELECT slot_name, slot_type, active, active_pid FROM pg_replication_slots ;
|
||||
slot_name | slot_type | active | active_pid
|
||||
---------------+-----------+--------+------------
|
||||
repmgr_slot_2 | physical | t | 23658
|
||||
repmgr_slot_3 | physical | t | 23687
|
||||
(2 rows)</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Note that a slot name will be created by default for the primary but not
|
||||
actually used unless the primary is converted to a standby using e.g.
|
||||
<command>repmgr standby switchover</command>.
|
||||
</para>
|
||||
<para>
|
||||
Further information on replication slots in the PostgreSQL documentation:
|
||||
<ulink url="https://www.postgresql.org/docs/current/interactive/warm-standby.html#STREAMING-REPLICATION-SLOTS">https://www.postgresql.org/docs/current/interactive/warm-standby.html#STREAMING-REPLICATION-SLOTS</ulink>
|
||||
</para>
|
||||
<tip>
|
||||
<simpara>
|
||||
While replication slots can be useful for streaming replication, it's
|
||||
recommended to monitor for inactive slots as these will cause WAL files to
|
||||
build up indefinitely, possibly leading to server failure.
|
||||
</simpara>
|
||||
<simpara>
|
||||
As an alternative we recommend using 2ndQuadrant's <ulink url="https://www.pgbarman.org/">Barman</ulink>,
|
||||
which offloads WAL management to a separate server, negating the need to use replication
|
||||
slots to reserve WAL. See section <xref linkend="cloning-from-barman">
|
||||
for more details on using &repmgr; together with Barman.
|
||||
</simpara>
|
||||
</tip>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="cloning-cascading" xreflabel="Cloning and cascading replication">
|
||||
<indexterm>
|
||||
<primary>cloning</primary>
|
||||
<secondary>cascading replication</secondary>
|
||||
</indexterm>
|
||||
<title>Cloning and cascading replication</title>
|
||||
<para>
|
||||
Cascading replication, introduced with PostgreSQL 9.2, enables a standby server
|
||||
to replicate from another standby server rather than directly from the primary,
|
||||
meaning replication changes "cascade" down through a hierarchy of servers. This
|
||||
can be used to reduce load on the primary and minimize bandwith usage between
|
||||
sites. For more details, see the
|
||||
<ulink url="https://www.postgresql.org/docs/current/static/warm-standby.html#CASCADING-REPLICATION">
|
||||
PostgreSQL cascading replication documentation</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
&repmgr; supports cascading replication. When cloning a standby,
|
||||
set the command-line parameter <literal>--upstream-node-id</literal> to the
|
||||
<varname>node_id</varname> of the server the standby should connect to, and
|
||||
&repmgr; will create <filename>recovery.conf</filename> to point to it. Note
|
||||
that if <literal>--upstream-node-id</literal> is not explicitly provided,
|
||||
&repmgr; will set the standby's <filename>recovery.conf</filename> to
|
||||
point to the primary node.
|
||||
</para>
|
||||
<para>
|
||||
To demonstrate cascading replication, first ensure you have a primary and standby
|
||||
set up as shown in the <xref linkend="quickstart">.
|
||||
Then create an additional standby server with <filename>repmgr.conf</filename> looking
|
||||
like this:
|
||||
<programlisting>
|
||||
node_id=3
|
||||
node_name=node3
|
||||
conninfo='host=node3 user=repmgr dbname=repmgr'
|
||||
data_directory='/var/lib/postgresql/data'</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Clone this standby (using the connection parameters for the existing standby),
|
||||
ensuring <literal>--upstream-node-id</literal> is provide with the <varname>node_id</varname>
|
||||
of the previously created standby (if following the example, this will be <literal>2</literal>):
|
||||
<programlisting>
|
||||
$ repmgr -h node2 -U repmgr -d repmgr -f /etc/repmgr.conf standby clone --upstream-node-id=2
|
||||
NOTICE: using configuration file "/etc/repmgr.conf"
|
||||
NOTICE: destination directory "/var/lib/postgresql/data" provided
|
||||
INFO: connecting to upstream node
|
||||
INFO: connected to source node, checking its state
|
||||
NOTICE: checking for available walsenders on upstream node (2 required)
|
||||
INFO: sufficient walsenders available on upstream node (2 required)
|
||||
INFO: successfully connected to source node
|
||||
DETAIL: current installation size is 29 MB
|
||||
INFO: creating directory "/var/lib/postgresql/data"...
|
||||
NOTICE: starting backup (using pg_basebackup)...
|
||||
HINT: this may take some time; consider using the -c/--fast-checkpoint option
|
||||
INFO: executing: 'pg_basebackup -l "repmgr base backup" -D /var/lib/postgresql/data -h node2 -U repmgr -X stream '
|
||||
NOTICE: standby clone (using pg_basebackup) complete
|
||||
NOTICE: you can now start your PostgreSQL server
|
||||
HINT: for example: pg_ctl -D /var/lib/postgresql/data start</programlisting>
|
||||
|
||||
then register it (note that <literal>--upstream-node-id</literal> must be provided here
|
||||
too):
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf standby register --upstream-node-id=2
|
||||
NOTICE: standby node "node2" (ID: 2) successfully registered
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
After starting the standby, the cluster will look like this, showing that <literal>node3</literal>
|
||||
is attached to <literal>node2</literal>, not the primary (<literal>node1</literal>).
|
||||
<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 | node2 | default | host=node3 dbname=repmgr user=repmgr
|
||||
</programlisting>
|
||||
</para>
|
||||
<tip>
|
||||
<simpara>
|
||||
Under some circumstances when setting up a cascading replication
|
||||
cluster, you may wish to clone a downstream standby whose upstream node
|
||||
does not yet exist. In this case you can clone from the primary (or
|
||||
another upstream node); provide the parameter <literal>--upstream-conninfo</literal>
|
||||
to explictly set the upstream's <varname>primary_conninfo</varname> string
|
||||
in <filename>recovery.conf</filename>.
|
||||
</simpara>
|
||||
</tip>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="cloning-advanced" xreflabel="Advanced cloning options">
|
||||
<indexterm>
|
||||
<primary>cloning</primary>
|
||||
<secondary>advanced options</secondary>
|
||||
</indexterm>
|
||||
<title>Advanced cloning options</title>
|
||||
|
||||
<sect2 id="cloning-advanced-pg-basebackup-options" xreflabel="pg_basebackup options when cloning a standby">
|
||||
<title>pg_basebackup options when cloning a standby</title>
|
||||
<para>
|
||||
By default, <command>pg_basebackup</command> performs a checkpoint before beginning the backup
|
||||
process. However, a normal checkpoint may take some time to complete;
|
||||
a fast checkpoint can be forced with the <literal>-c/--fast-checkpoint</literal> option.
|
||||
However this may impact performance of the server being cloned from
|
||||
so should be used with care.
|
||||
</para>
|
||||
<para>
|
||||
Further options can be passed to the <command>pg_basebackup</command> utility via
|
||||
the setting <varname>pg_basebackup_options</varname> in <filename>repmgr.conf</filename>.
|
||||
See the <ulink url="https://www.postgresql.org/docs/current/static/app-pgbasebackup.html">PostgreSQL pg_basebackup documentation</ulink>
|
||||
for more details of available options.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="cloning-advanced-managing-passwords" xreflabel="Managing passwords">
|
||||
<title>Managing passwords</title>
|
||||
<para>
|
||||
If replication connections to a standby's upstream server are password-protected,
|
||||
the standby must be able to provide the password so it can begin streaming
|
||||
replication.
|
||||
</para>
|
||||
<para>
|
||||
The recommended way to do this is to store the password in the <literal>postgres</literal> system
|
||||
user's <filename>~/.pgpass</filename> file. It's also possible to store the password in the
|
||||
environment variable <varname>PGPASSWORD</varname>, however this is not recommended for
|
||||
security reasons. For more details see the
|
||||
<ulink url="https://www.postgresql.org/docs/current/static/libpq-pgpass.html">PostgreSQL password file documentation</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
If, for whatever reason, you wish to include the password in <filename>recovery.conf</filename>,
|
||||
set <varname>use_primary_conninfo_password</varname> to <literal>true</literal> in
|
||||
<filename>repmgr.conf</filename>. This will read a password set in <varname>PGPASSWORD</varname>
|
||||
(but not <filename>~/.pgpass</filename>) and place it into the <literal>primary_conninfo</literal>
|
||||
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
|
||||
rewritten, e.g. <xref linkend="repmgr-standby-follow">.
|
||||
</para>
|
||||
<para>
|
||||
It is of course also possible to include the password value in the <varname>conninfo</varname>
|
||||
string for each node, but this is obviously a security risk and should be
|
||||
avoided.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="cloning-advanced-replication-user" xreflabel="Separate replication user">
|
||||
<title>Separate replication user</title>
|
||||
<para>
|
||||
In some circumstances it might be desirable to create a dedicated replication-only
|
||||
user (in addition to the user who manages the &repmgr; metadata). In this case,
|
||||
the replication user should be set in <filename>repmgr.conf</filename> via the parameter
|
||||
<varname>replication_user</varname>; &repmgr; will use this value when making
|
||||
replication connections and generating <filename>recovery.conf</filename>. This
|
||||
value will also be stored in the <literal>repmgr.nodes</literal>
|
||||
table for each node; it no longer needs to be explicitly specified when
|
||||
cloning a node or executing <xref linkend="repmgr-standby-follow">.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
|
||||
</chapter>
|
||||
114
doc/configuration-file-settings.sgml
Normal file
114
doc/configuration-file-settings.sgml
Normal file
@@ -0,0 +1,114 @@
|
||||
<sect1 id="configuration-file-settings" xreflabel="configuration file settings">
|
||||
<title>Configuration file settings</title>
|
||||
<para>
|
||||
Each <filename>repmgr.conf</filename> file must contain the following parameters:
|
||||
</para>
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry id="repmgr-conf-node-id" xreflabel="node_id">
|
||||
<term><varname>node_id</varname> (<type>int</type>)
|
||||
<indexterm>
|
||||
<primary><varname>node_id</varname> configuration file parameter</primary>
|
||||
</indexterm>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A unique integer greater than zero which identifies the node.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry id="repmgr-conf-node-name" xreflabel="node_name">
|
||||
<term><varname>node_name</varname> (<type>string</type>)
|
||||
<indexterm>
|
||||
<primary><varname>node_name</varname> configuration file parameter</primary>
|
||||
</indexterm>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
An arbitrary (but unique) string; we recommend using the server's hostname
|
||||
or another identifier unambiguously associated with the server to avoid
|
||||
confusion. Avoid choosing names which reflect the node's current role,
|
||||
e.g. <varname>primary</varname> or <varname>standby1</varname>
|
||||
as roles can change and if you end up in a solution where the current primary is
|
||||
called <varname>standby1</varname> (for example), things will be confusing
|
||||
to say the least.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry id="repmgr-conf-conninfo" xreflabel="conninfo">
|
||||
<term><varname>conninfo</varname> (<type>string</type>)
|
||||
<indexterm>
|
||||
<primary><varname>conninfo</varname> configuration file parameter</primary>
|
||||
</indexterm>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Database connection information as a conninfo string.
|
||||
All servers in the cluster must be able to connect to
|
||||
the local node using this string.
|
||||
</para>
|
||||
<para>
|
||||
For details on conninfo strings, see section <ulink
|
||||
url="https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING">Connection Strings</>
|
||||
in the PosgreSQL documentation.
|
||||
</para>
|
||||
<para>
|
||||
If repmgrd is in use, consider explicitly setting
|
||||
<varname>connect_timeout</varname> in the <varname>conninfo</varname>
|
||||
string to determine the length of time which elapses before a network
|
||||
connection attempt is abandoned; for details see <ulink
|
||||
url="https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT">
|
||||
the PostgreSQL documentation</>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry id="repmgr-conf-data-directory" xreflabel="data_directory">
|
||||
<term><varname>data_directory</varname> (<type>string</type>)
|
||||
<indexterm>
|
||||
<primary><varname>data_directory</varname> configuration file parameter</primary>
|
||||
</indexterm>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The node's data directory. This is needed by repmgr
|
||||
when performing operations when the PostgreSQL instance
|
||||
is not running and there's no other way of determining
|
||||
the data directory.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
</variablelist>
|
||||
</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</>.
|
||||
</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>
|
||||
46
doc/configuration-file.sgml
Normal file
46
doc/configuration-file.sgml
Normal file
@@ -0,0 +1,46 @@
|
||||
<sect1 id="configuration-file" xreflabel="configuration file location">
|
||||
<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 `configuration file parameters`
|
||||
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 `-f/--config-file` 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 <application>-f/--config-file</application>,
|
||||
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 file.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
7
doc/configuration.sgml
Normal file
7
doc/configuration.sgml
Normal file
@@ -0,0 +1,7 @@
|
||||
<chapter id="configuration" xreflabel="Configuration">
|
||||
<title>repmgr configuration</title>
|
||||
|
||||
&configuration-file;
|
||||
&configuration-file-settings;
|
||||
|
||||
</chapter>
|
||||
181
doc/event-notifications.sgml
Normal file
181
doc/event-notifications.sgml
Normal file
@@ -0,0 +1,181 @@
|
||||
<chapter id="event-notifications" xreflabel="event notifications">
|
||||
<title>Event Notifications</title>
|
||||
<para>
|
||||
Each time `repmgr` or `repmgrd` perform a significant event, a record
|
||||
of that event is written into the `repmgr.events` table together with
|
||||
a timestamp, an indication of failure or success, and further details
|
||||
if appropriate. This is useful for gaining an overview of events
|
||||
affecting the replication cluster. However note that this table has
|
||||
advisory character and should be used in combination with the `repmgr`
|
||||
and PostgreSQL logs to obtain details of any events.
|
||||
</para>
|
||||
<para>
|
||||
Example output after a primary was registered and a standby cloned
|
||||
and registered:
|
||||
<programlisting>
|
||||
repmgr=# SELECT * from repmgr.events ;
|
||||
node_id | event | successful | event_timestamp | details
|
||||
---------+------------------+------------+-------------------------------+-------------------------------------------------------------------------------------
|
||||
1 | primary_register | t | 2016-01-08 15:04:39.781733+09 |
|
||||
2 | standby_clone | t | 2016-01-08 15:04:49.530001+09 | Cloned from host 'repmgr_node1', port 5432; backup method: pg_basebackup; --force: N
|
||||
2 | standby_register | t | 2016-01-08 15:04:50.621292+09 |
|
||||
(3 rows)</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Alternatively, use <xref linkend="repmgr-cluster-event"> to output a
|
||||
formatted list of events.
|
||||
</para>
|
||||
<para>
|
||||
Additionally, event notifications can be passed to a user-defined program
|
||||
or script which can take further action, e.g. send email notifications.
|
||||
This is done by setting the `event_notification_command` parameter in
|
||||
`repmgr.conf`.
|
||||
</para>
|
||||
<para>
|
||||
This parameter accepts the following format placeholders:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>%n</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
node ID
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>%e</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
event type
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>%t</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
success (1 or 0)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>%t</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
timestamp
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>%d</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
details
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
The values provided for <literal>%t</literal> and <literal>%d</literal>
|
||||
will probably contain spaces, so should be quoted in the provided command
|
||||
configuration, e.g.:
|
||||
<programlisting>
|
||||
event_notification_command='/path/to/some/script %n %e %s "%t" "%d"'
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Additionally the following format placeholders are available for the event
|
||||
type <varname>bdr_failover</varname> and optionally <varname>bdr_recovery</varname>:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>%c</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
conninfo string of the next available node
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>%a</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
name of the next available node
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
These should always be quoted.
|
||||
</para>
|
||||
<para>
|
||||
By default, all notification types will be passed to the designated script;
|
||||
the notification types can be filtered to explicitly named ones:
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
|
||||
<listitem>
|
||||
<simpara><literal>primary_register</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>standby_register</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>standby_unregister</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>standby_clone</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>standby_promote</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>standby_follow</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>standby_disconnect_manual</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>repmgrd_start</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>repmgrd_shutdown</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>repmgrd_failover_promote</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>repmgrd_failover_follow</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>bdr_failover</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>bdr_reconnect</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>bdr_recovery</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>bdr_register</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>bdr_unregister</literal></simpara>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
Note that under some circumstances (e.g. when no replication cluster primary
|
||||
could be located), it will not be possible to write an entry into the
|
||||
<literal>repmgr.events</literal>
|
||||
table, in which case executing a script via <varname>event_notification_command</varname>
|
||||
can serve as a fallback by generating some form of notification.
|
||||
</para>
|
||||
|
||||
|
||||
</chapter>
|
||||
77
doc/filelist.sgml
Normal file
77
doc/filelist.sgml
Normal file
@@ -0,0 +1,77 @@
|
||||
<!-- 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-settings SYSTEM "configuration-file-settings.sgml">
|
||||
<!ENTITY cloning-standbys SYSTEM "cloning-standbys.sgml">
|
||||
<!ENTITY promoting-standby SYSTEM "promoting-standby.sgml">
|
||||
<!ENTITY follow-new-primary SYSTEM "follow-new-primary.sgml">
|
||||
<!ENTITY switchover SYSTEM "switchover.sgml">
|
||||
<!ENTITY event-notifications SYSTEM "event-notifications.sgml">
|
||||
<!ENTITY upgrading-repmgr SYSTEM "upgrading-repmgr.sgml">
|
||||
|
||||
<!ENTITY repmgrd-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 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-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-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 appendix-signatures SYSTEM "appendix-signatures.sgml">
|
||||
|
||||
<!ENTITY bookindex SYSTEM "bookindex.sgml">
|
||||
|
||||
42
doc/follow-new-primary.sgml
Normal file
42
doc/follow-new-primary.sgml
Normal file
@@ -0,0 +1,42 @@
|
||||
<chapter id="follow-new-primary" xreflabel="Following a new primary">
|
||||
<title>Following a new primary</title>
|
||||
<para>
|
||||
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
|
||||
follow the new primary and catch up to its current state.
|
||||
</para>
|
||||
<para>
|
||||
To demonstrate this, assuming a replication cluster in the same state as the
|
||||
end of the preceding section (<xref linkend="promoting-standby">),
|
||||
execute this:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf repmgr standby follow
|
||||
INFO: changing node 3's primary to node 2
|
||||
NOTICE: restarting server using "pg_ctl -l /var/log/postgresql/startup.log -w -D '/var/lib/postgresql/data' restart"
|
||||
waiting for server to shut down......... done
|
||||
server stopped
|
||||
waiting for server to start.... done
|
||||
server started
|
||||
NOTICE: STANDBY FOLLOW successful
|
||||
DETAIL: node 3 is now attached to node 2
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The standby is now replicating from the new primary and `repmgr cluster show`
|
||||
output reflects this:
|
||||
<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>
|
||||
Note that with cascading replication, <command>repmgr standby follow</command> can also be
|
||||
used to detach a standby from its current upstream server and follow the
|
||||
primary. However it's currently not possible to have it follow another standby;
|
||||
we hope to improve this in a future release.
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
32
doc/install-packages.sgml
Normal file
32
doc/install-packages.sgml
Normal file
@@ -0,0 +1,32 @@
|
||||
<sect1 id="installation-packages" xreflabel="Installing from packages">
|
||||
<title>Installing &repmgr; from packages</title>
|
||||
<para>
|
||||
We recommend installing `repmgr` using the available packages for your
|
||||
system.
|
||||
</para>
|
||||
|
||||
<sect2 id="installation-packages-redhat" xreflabel="Installing from packages on RHEL, Fedora and CentOS">
|
||||
<title>RedHat/Fedora/CentOS</title>
|
||||
<para>
|
||||
RPM packages for `repmgr` are available via Yum through
|
||||
the PostgreSQL Global Development Group RPM repository
|
||||
( <ulink url="https://yum.postgresql.org/">http://yum.postgresql.org/</>).
|
||||
Follow the instructions for your distribution (RedHat, CentOS,
|
||||
Fedora, etc.) and architecture as detailed at yum.postgresql.org.
|
||||
</para>
|
||||
<para>
|
||||
2ndQuadrant also provides its own RPM packages which are made available
|
||||
at the same time as each `repmgr` release, as it can take some days for
|
||||
them to become available via the main PGDG repository. See here for details:
|
||||
<ulink url="http://repmgr.org/yum-repository.html">http://repmgr.org/yum-repository.html</>
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="installation-packages-debian" xreflabel="Installing from packages on Debian or Ubuntu">
|
||||
<title>Debian/Ubuntu</title>
|
||||
<para>.deb packages for `repmgr` are available from the
|
||||
PostgreSQL Community APT repository (<ulink url="http://apt.postgresql.org/">http://apt.postgresql.org/</> ).
|
||||
Instructions can be found in the APT section of the PostgreSQL Wiki
|
||||
(<ulink url="https://wiki.postgresql.org/wiki/Apt">https://wiki.postgresql.org/wiki/Apt</> ).
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
67
doc/install-requirements.sgml
Normal file
67
doc/install-requirements.sgml
Normal file
@@ -0,0 +1,67 @@
|
||||
<sect1 id="install-requirements" xreflabel="installation requirements">
|
||||
<title>Requirements for installing repmgr</title>
|
||||
<para>
|
||||
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
|
||||
Microsoft Windows.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
From version 4.0, repmgr is compatible with all PostgreSQL versions from 9.4, including PostgreSQL 10.
|
||||
</para>
|
||||
<para>
|
||||
PostgreSQL 9.3 is supported by repmgr 3.3.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<simpara>
|
||||
If upgrading from `repmgr 3`, please see the separate upgrade guide
|
||||
`doc/upgrading-from-repmgr3.md`.
|
||||
</simpara>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
All servers in the replication cluster must be running the same major version of
|
||||
PostgreSQL, and we recommend that they also run the same minor version.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
`repmgr` must be installed on each server in the replication cluster.
|
||||
If installing repmgr from packages, the package version must match the PostgreSQL
|
||||
version. If installing from source, repmgr must be compiled against the same
|
||||
major version.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A dedicated system user for `repmgr` is *not* required; as many `repmgr` and
|
||||
`repmgrd` actions require direct access to the PostgreSQL data directory,
|
||||
these commands should be executed by the `postgres` user.
|
||||
</para>
|
||||
|
||||
|
||||
<para>
|
||||
Passwordless `ssh` connectivity between all servers in the replication cluster
|
||||
is not required, but is necessary in the following cases:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>if you need `repmgr` to copy configuration files from outside the PostgreSQL
|
||||
data directory (in which case `rsync` is also required)</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>to perform switchover operations</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>when executing `repmgr cluster matrix` and `repmgr cluster crosscheck`</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<tip>
|
||||
<simpara>
|
||||
We recommend using a session multiplexer utility such as `screen` or
|
||||
`tmux` when performing long-running actions (such as cloning a database)
|
||||
on a remote server - this will ensure the `repmgr` action won't be prematurely
|
||||
terminated if your `ssh` session to the server is interrupted or closed.
|
||||
</simpara>
|
||||
</tip>
|
||||
</sect1>
|
||||
139
doc/install-source.sgml
Normal file
139
doc/install-source.sgml
Normal file
@@ -0,0 +1,139 @@
|
||||
<sect1 id="installation-source" xreflabel="Installing from source code">
|
||||
<title>Installing &repmgr; from source</title>
|
||||
|
||||
<sect2 id="installation-source-prereqs">
|
||||
<title>Prerequisites for installing from source</title>
|
||||
<para>
|
||||
To install &repmgr; the prerequisites for compiling
|
||||
&postgres; must be installed. These are described in &postgres;'s
|
||||
documentation
|
||||
on <ulink url="https://www.postgresql.org/docs/current/install-requirements.html">build requirements</ulink>
|
||||
and <ulink url="https://www.postgresql.org/docs/current/docguide-toolsets.html">build requirements for documentation</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Most mainstream Linux distributions and other UNIX variants provide simple
|
||||
ways to install the prerequisites from packages.
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>Debian</literal> and <literal>Ubuntu</literal>: First
|
||||
add the <ulink
|
||||
url="http://apt.postgresql.org/">apt.postgresql.org</ulink>
|
||||
repository to your <filename>sources.list</filename> if you
|
||||
have not already done so. Then install the pre-requisites for
|
||||
building PostgreSQL with:
|
||||
<programlisting>
|
||||
sudo apt-get update
|
||||
sudo apt-get build-dep postgresql-9.6
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>RHEL or CentOS 6.x or 7.x</literal>: install the appropriate repository RPM
|
||||
for your system from <ulink url="https://yum.postgresql.org/repopackages.php">
|
||||
yum.postgresql.org</ulink>. Then install the prerequisites for building
|
||||
PostgreSQL with:
|
||||
<programlisting>
|
||||
sudo yum check-update
|
||||
sudo yum groupinstall "Development Tools"
|
||||
sudo yum install yum-utils openjade docbook-dtds docbook-style-dsssl docbook-style-xsl
|
||||
sudo yum-builddep postgresql96
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<simpara>
|
||||
Select the appropriate PostgreSQL versions for your target repmgr version.
|
||||
</simpara>
|
||||
</note>
|
||||
</sect2>
|
||||
|
||||
|
||||
<sect2 id="installation-get-source">
|
||||
<title>Getting &repmgr; source code</title>
|
||||
|
||||
<para>
|
||||
There are two ways to get the &repmgr; source code: with git, or by downloading tarballs of released versions.
|
||||
</para>
|
||||
|
||||
<sect3>
|
||||
<title>Using <application>git</application> to get the &repmgr; sources</title>
|
||||
|
||||
<para>
|
||||
Use <application><ulink url="https://git-scm.com">git</ulink></application> if you expect
|
||||
to update often, you want to keep track of development or if you want to contribute
|
||||
changes to &repmgr;. There is no reason <emphasis>not</emphasis> to use <application>git</application>
|
||||
if you're familiar with it.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The source for &repmgr; is maintained at
|
||||
<ulink url="https://github.com/2ndQuadrant/repmgr">https://github.com/2ndQuadrant/repmgr</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There are also tags for each &repmgr; release, e.g. <filename>REL4_0_STABLE</filename>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Clone the source code using <application>git</application>:
|
||||
<programlisting>
|
||||
git clone https://github.com/2ndQuadrant/repmgr
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For more information on using <application>git</application> see
|
||||
<ulink url="https://git-scm.com/">git-scm.com</ulink>.
|
||||
</para>
|
||||
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>Downloading release source tarballs</title>
|
||||
|
||||
<para>
|
||||
Official release source code is uploaded as tarballs to the
|
||||
&repmgr; website along with a tarball checksum and a matching GnuPG
|
||||
signature. See
|
||||
<ulink url="http://repmgr.org/">http://repmgr.org/</ulink>
|
||||
for the download information. See <xref linkend="appendix-signatures">
|
||||
for information on verifying digital signatures.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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
|
||||
<literal>.md5</literal> files and/or verify the GnuPG signatures
|
||||
per <xref linkend="appendix-signatures">.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
After you unpack the source code archives using <literal>tar xf</literal>
|
||||
the installation process is the same as if you were installing from a git
|
||||
clone.
|
||||
</para>
|
||||
|
||||
</sect3>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="installation-repmgr-source">
|
||||
<title>Installation of &repmgr; from source</title>
|
||||
<para>
|
||||
To installing &repmgr; from source, simply execute:
|
||||
|
||||
<programlisting>
|
||||
./configure && make install
|
||||
</programlisting>
|
||||
|
||||
Ensure `pg_config` for the target PostgreSQL version is in `$PATH`.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
24
doc/install.sgml
Normal file
24
doc/install.sgml
Normal file
@@ -0,0 +1,24 @@
|
||||
<chapter id="installation" xreflabel="Installation">
|
||||
<title>Installation</title>
|
||||
|
||||
<para>
|
||||
&repmgr; can be installed from binary packages provided by your operating
|
||||
system's packaging system, or from source.
|
||||
</para>
|
||||
<para>
|
||||
In general we recommend using binary packages, unless unavailable for your operating system.
|
||||
</para>
|
||||
<para>
|
||||
Source installs are mainly useful if you want to keep track of the very
|
||||
latest repmgr development and contribute to development. They're also the
|
||||
only option if there are no packages for your operating system yet.
|
||||
</para>
|
||||
<para>
|
||||
Before installing &repmgr; make sure you satisfy the <xref linkend="install-requirements">.
|
||||
</para>
|
||||
|
||||
&install-requirements;
|
||||
&install-packages;
|
||||
&install-source;
|
||||
|
||||
</chapter>
|
||||
20
doc/legal.sgml
Normal file
20
doc/legal.sgml
Normal file
@@ -0,0 +1,20 @@
|
||||
<!-- doc/src/sgml/legal.sgml -->
|
||||
|
||||
<date>2017</date>
|
||||
|
||||
<copyright>
|
||||
<year>2010-2017</year>
|
||||
<holder>2ndQuadrant, Ltd.</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice id="legalnotice">
|
||||
<title>Legal Notice</title>
|
||||
|
||||
<para>
|
||||
<productname>repmgr</productname> is Copyright © 2010-2017
|
||||
by 2ndQuadrant, Ltd.
|
||||
</para>
|
||||
|
||||
<para>add license</para>
|
||||
|
||||
</legalnotice>
|
||||
209
doc/overview.sgml
Normal file
209
doc/overview.sgml
Normal file
@@ -0,0 +1,209 @@
|
||||
<chapter id="overview" xreflabel="Overview">
|
||||
<title>repmgr overview</title>
|
||||
|
||||
<para>
|
||||
This chapter provides a high-level overview of repmgr's components and functionality.
|
||||
</para>
|
||||
<sect1 id="repmgr-concepts" xreflabel="Concepts">
|
||||
<title>Concepts</title>
|
||||
|
||||
<para>
|
||||
This guide assumes that you are familiar with PostgreSQL administration and
|
||||
streaming replication concepts. For further details on streaming
|
||||
replication, see the PostgreSQL documentation section on <ulink
|
||||
url="https://www.postgresql.org/docs/current/interactive/warm-standby.html#STREAMING-REPLICATION">
|
||||
streaming replication</>.
|
||||
</para>
|
||||
<para>
|
||||
The following terms are used throughout the `repmgr` documentation.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>replication cluster</term>
|
||||
<listitem>
|
||||
<simpara>
|
||||
In the `repmgr` documentation, "replication cluster" refers to the network
|
||||
of PostgreSQL servers connected by streaming replication.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>node</term>
|
||||
<listitem>
|
||||
<simpara>
|
||||
A node is a server within a replication cluster.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>upstream node</term>
|
||||
<listitem>
|
||||
<simpara>
|
||||
The node a standby server connects to, in order to receive streaming replication.
|
||||
This is either the primary server or in the case of cascading replication, another
|
||||
standby.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>failover</term>
|
||||
<listitem>
|
||||
<simpara>
|
||||
This is the action which occurs if a primary server fails and a suitable standby
|
||||
is promoted as the new primary. The `repmgrd` daemon supports automatic failover
|
||||
to minimise downtime.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>switchover</term>
|
||||
<listitem>
|
||||
<simpara>
|
||||
In certain circumstances, such as hardware or operating system maintenance,
|
||||
it's necessary to take a primary server offline; in this case a controlled
|
||||
switchover is necessary, whereby a suitable standby is promoted and the
|
||||
existing primary removed from the replication cluster in a controlled manner.
|
||||
The `repmgr` command line client provides this functionality.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>fencing</term>
|
||||
<listitem>
|
||||
<simpara>
|
||||
In a failover situation, following the promotion of a new standby, it's
|
||||
essential that the previous primary does not unexpectedly come back on
|
||||
line, which would result in a split-brain situation. To prevent this,
|
||||
the failed primary should be isolated from applications, i.e. "fenced off".
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 id="repmgr-components" xreflabel="Components">
|
||||
<title>Components</title>
|
||||
<para>
|
||||
`repmgr` is a suite of open-source tools to manage replication and failover
|
||||
within a cluster of PostgreSQL servers. It supports and enhances PostgreSQL's
|
||||
built-in streaming replication, which provides a single read/write primary server
|
||||
and one or more read-only standbys containing near-real time copies of the primary
|
||||
server's database. It provides two main tools:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>repmgr</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A command-line tool used to perform administrative tasks such as:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>setting up standby servers</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>promoting a standby server to primary</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>switching over primary and standby servers</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>displaying the status of servers in the replication cluster</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>repmgrd</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A daemon which actively monitors servers in a replication cluster
|
||||
and performs the following tasks:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>monitoring and recording replication performance</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>performing failover by detecting failure of the primary and
|
||||
promoting the most suitable standby server
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>provide notifications about events in the cluster to a user-defined
|
||||
script which can perform tasks such as sending alerts by email</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="repmgr-user-metadata" xreflabel="Repmgr user and metadata">
|
||||
<title>Repmgr user and metadata</title>
|
||||
<para>
|
||||
In order to effectively manage a replication cluster, `repmgr` needs to store
|
||||
information about the servers in the cluster in a dedicated database schema.
|
||||
This schema is automatically by the `repmgr` extension, which is installed
|
||||
during the first step in initialising a `repmgr`-administered cluster
|
||||
(`repmgr primary register`) and contains the following objects:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>Tables</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>repmgr.events: records events of interest</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>repmgr.nodes: connection and status information for each server in the
|
||||
replication cluster</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>repmgr.monitoring_history: historical standby monitoring information written by `repmgrd`</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Views</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>repmgr.show_nodes: based on the table `repl_nodes`, additionally showing the
|
||||
name of the server's upstream node</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>repmgr.replication_status: when `repmgrd`'s monitoring is enabled, shows current monitoring
|
||||
status for each standby.</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The `repmgr` metadata schema can be stored in an existing database or in its own
|
||||
dedicated database. Note that the `repmgr` metadata schema cannot reside on a database
|
||||
server which is not part of the replication cluster managed by `repmgr`.
|
||||
</para>
|
||||
<para>
|
||||
A database user must be available for `repmgr` to access this database and perform
|
||||
necessary changes. This user does not need to be a superuser, however some operations
|
||||
such as initial installation of the `repmgr` extension will require a superuser
|
||||
connection (this can be specified where required with the command line option
|
||||
`--superuser`).
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
75
doc/promoting-standby.sgml
Normal file
75
doc/promoting-standby.sgml
Normal file
@@ -0,0 +1,75 @@
|
||||
<chapter id="promoting-standby" xreflabel="Promoting a standby">
|
||||
<title>Promoting a standby server with repmgr</title>
|
||||
<para>
|
||||
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
|
||||
to function correctly. This can be done with <xref linkend="repmgr-standby-promote">,
|
||||
which promotes the standby on the current server to primary.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To demonstrate this, set up a replication cluster with a primary and two attached
|
||||
standby servers so that the cluster looks 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>
|
||||
Stop the current primary with e.g.:
|
||||
<programlisting>
|
||||
$ pg_ctl -D /var/lib/postgresql/data -m fast stop</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
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
|
||||
stopped primary. Note that the &repmgr; metadata table will not yet have been updated;
|
||||
executing <xref linkend="repmgr-cluster-show"> will note the discrepancy:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf cluster show
|
||||
ID | Name | Role | Status | Upstream | Location | Connection string
|
||||
----+-------+---------+---------------+----------+----------+--------------------------------------
|
||||
1 | node1 | primary | ? unreachable | | 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
|
||||
|
||||
WARNING: following issues were detected
|
||||
node "node1" (ID: 1) is registered as an active primary but is unreachable</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Now promote the first standby with:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf standby promote</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
This will produce output similar to the following:
|
||||
<programlisting>
|
||||
INFO: connecting to standby database
|
||||
NOTICE: promoting standby
|
||||
DETAIL: promoting server using "pg_ctl -l /var/log/postgresql/startup.log -w -D '/var/lib/postgresql/data' promote"
|
||||
server promoting
|
||||
INFO: reconnecting to promoted server
|
||||
NOTICE: STANDBY PROMOTE successful
|
||||
DETAIL: node 2 was successfully promoted to primary</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
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:
|
||||
<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 | node1 | default | host=node3 dbname=repmgr user=repmgr</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
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
|
||||
(see <xref linkend="follow-new-primary"> for example).
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
446
doc/quickstart.sgml
Normal file
446
doc/quickstart.sgml
Normal file
@@ -0,0 +1,446 @@
|
||||
<chapter id="quickstart" xreflabel="Quick-start guide">
|
||||
<title>Quick-start guide</title>
|
||||
|
||||
<para>
|
||||
This section gives a quick introduction to &repmgr;, including setting up a
|
||||
sample &repmgr; installation and a basic replication cluster.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
These instructions are not suitable for a production install, as they may not
|
||||
take into account security considerations, proper system administration
|
||||
procedures etc..
|
||||
</para>
|
||||
|
||||
<sect1 id="quickstart-prerequisites">
|
||||
<title>Prerequisites for setting up a basic replication cluster with &repmgr;</title>
|
||||
<para>
|
||||
The following section will describe how to set up a basic replication cluster
|
||||
with a primary and a standby server using the <application>repmgr</application>
|
||||
command line tool.
|
||||
</para>
|
||||
<para>
|
||||
We'll assume the primary is called <literal>node1</literal> with IP address
|
||||
<literal>192.168.1.11</literal>, and the standby is called <literal>node2</literal>
|
||||
with IP address <literal>192.168.1.12</literal>
|
||||
</para>
|
||||
<para>
|
||||
Following software must be installed on both servers:
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
<listitem>
|
||||
<simpara><application>PostgreSQL</application></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>
|
||||
<application>repmgr</application> (matching the installed
|
||||
<application>PostgreSQL</application> major version)
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
At network level, connections between the PostgreSQL port (default: <literal>5432</literal>)
|
||||
must be possible in both directions.
|
||||
</para>
|
||||
<para>
|
||||
If you want <application>repmgr</application> to copy configuration files which are
|
||||
located outside the PostgreSQL data directory, and/or to test <command>switchover</command>
|
||||
functionality, you will also need passwordless SSH connections between both servers, and
|
||||
<application>rsync</application> should be installed.
|
||||
</para>
|
||||
<tip>
|
||||
<simpara>
|
||||
For testing <application>repmgr</application>, it's possible to use multiple PostgreSQL
|
||||
instances running on different ports on the same computer, with
|
||||
passwordless SSH access to <filename>localhost</filename> enabled.
|
||||
</simpara>
|
||||
</tip>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="quickstart-postgresql-configuration">
|
||||
<title>PostgreSQL configuration</title>
|
||||
<para>
|
||||
On the primary server, a PostgreSQL instance must be initialised and running.
|
||||
The following replication settings may need to be adjusted:
|
||||
</para>
|
||||
<programlisting>
|
||||
|
||||
# Enable replication connections; set this figure to at least one more
|
||||
# than the number of standbys which will connect to this server
|
||||
# (note that repmgr will execute `pg_basebackup` in WAL streaming mode,
|
||||
# which requires two free WAL senders)
|
||||
|
||||
max_wal_senders = 10
|
||||
|
||||
# Ensure WAL files contain enough information to enable read-only queries
|
||||
# on the standby.
|
||||
#
|
||||
# PostgreSQL 9.5 and earlier: one of 'hot_standby' or 'logical'
|
||||
# PostgreSQL 9.6 and later: one of 'replica' or 'logical'
|
||||
# ('hot_standby' will still be accepted as an alias for 'replica')
|
||||
#
|
||||
# See: https://www.postgresql.org/docs/current/static/runtime-config-wal.html#GUC-WAL-LEVEL
|
||||
|
||||
wal_level = 'hot_standby'
|
||||
|
||||
# Enable read-only queries on a standby
|
||||
# (Note: this will be ignored on a primary but we recommend including
|
||||
# it anyway)
|
||||
|
||||
hot_standby = on
|
||||
|
||||
# Enable WAL file archiving
|
||||
archive_mode = on
|
||||
|
||||
# Set archive command to a script or application that will safely store
|
||||
# you WALs in a secure place. /bin/true is an example of a command that
|
||||
# ignores archiving. Use something more sensible.
|
||||
archive_command = '/bin/true'
|
||||
|
||||
# If you have configured `pg_basebackup_options`
|
||||
# in `repmgr.conf` to include the setting `--xlog-method=fetch` (from
|
||||
# PostgreSQL 10 `--wal-method=fetch`), *and* you have not set
|
||||
# `restore_command` in `repmgr.conf`to fetch WAL files from another
|
||||
# source such as Barman, you'll need to set `wal_keep_segments` to a
|
||||
# high enough value to ensure that all WAL files generated while
|
||||
# the standby is being cloned are retained until the standby starts up.
|
||||
#
|
||||
# wal_keep_segments = 5000
|
||||
</programlisting>
|
||||
<tip>
|
||||
<simpara>
|
||||
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
|
||||
include it from the end of the main configuration file with:
|
||||
<command>include 'postgresql.replication.conf</command>.
|
||||
</simpara>
|
||||
</tip>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="quickstart-repmgr-user-database">
|
||||
<title>Create the repmgr user and database</title>
|
||||
<para>
|
||||
Create a dedicated PostgreSQL superuser account and a database for
|
||||
the &repmgr; metadata, e.g.
|
||||
</para>
|
||||
<programlisting>
|
||||
createuser -s repmgr
|
||||
createdb repmgr -O repmgr
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
For the examples in this document, the name <literal>repmgr</literal> will be
|
||||
used for both user and database, but any names can be used.
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
For the sake of simplicity, the <literal>repmgr</literal> user is created
|
||||
as a superuser. If desired, it's possible to create the <literal>repmgr</literal>
|
||||
user as a normal user. However for certain operations superuser permissions
|
||||
are requiredl; in this case the command line option <command>--superuser</command>
|
||||
can be provided to specify a superuser.
|
||||
</para>
|
||||
<para>
|
||||
It's also assumed that the <literal>repmgr</literal> user will be used to make the
|
||||
replication connection from the standby to the primary; again this can be
|
||||
overridden by specifying a separate replication user when registering each node.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<tip>
|
||||
<para>
|
||||
&repmgr; will install the <literal>repmgr</literal> extension, which creates a
|
||||
<literal>repmgr</literal> schema containing the &repmgr;'s metadata tables as
|
||||
well as other functions and views. We also recommend that you set the
|
||||
<literal>repmgr</literal> user's search path to include this schema name, e.g.
|
||||
<programlisting>
|
||||
ALTER USER repmgr SET search_path TO repmgr, "$user", public;</programlisting>
|
||||
</para>
|
||||
</tip>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="quickstart-authentication">
|
||||
<title>Configuring authentication in pg_hba.conf</title>
|
||||
<para>
|
||||
Ensure the <literal>repmgr</literal> user has appropriate permissions in <filename>pg_hba.conf</filename> and
|
||||
can connect in replication mode; <filename>pg_hba.conf</filename> should contain entries
|
||||
similar to the following:
|
||||
</para>
|
||||
<programlisting>
|
||||
local replication repmgr trust
|
||||
host replication repmgr 127.0.0.1/32 trust
|
||||
host replication repmgr 192.168.1.0/24 trust
|
||||
|
||||
local repmgr repmgr trust
|
||||
host repmgr repmgr 127.0.0.1/32 trust
|
||||
host repmgr repmgr 192.168.1.0/24 trust
|
||||
</programlisting>
|
||||
<para>
|
||||
Note that these are simple settings for testing purposes.
|
||||
Adjust according to your network environment and authentication requirements.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="quickstart-standby-preparation">
|
||||
<title>Preparing the standby</title>
|
||||
<para>
|
||||
On the standby, do not create a PostgreSQL instance, but do ensure the destination
|
||||
data directory (and any other directories which you want PostgreSQL to use)
|
||||
exist and are owned by the <literal>postgres</literal> system user. Permissions
|
||||
must be set to <literal>0700</literal> (<literal>drwx------</literal>).
|
||||
</para>
|
||||
<para>
|
||||
Check the primary database is reachable from the standby using <application>psql</application>:
|
||||
</para>
|
||||
<programlisting>
|
||||
psql 'host=node1 user=repmgr dbname=repmgr connect_timeout=2'</programlisting>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
&repmgr; stores connection information as <ulink
|
||||
url="https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING">libpq
|
||||
connection strings</ulink> throughout. This documentation refers to them as <literal>conninfo</literal>
|
||||
strings; an alternative name is <literal>DSN</literal> (<literal>data source name</literal>).
|
||||
We'll use these in place of the <command>-h hostname -d databasename -U username</command> syntax.
|
||||
</para>
|
||||
</note>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="quickstart-repmgr-conf">
|
||||
<title>repmgr configuration file</title>
|
||||
<para>
|
||||
Create a <filename>repmgr.conf</filename> file on the primary server. The file must
|
||||
contain at least the following parameters:
|
||||
</para>
|
||||
<programlisting>
|
||||
node_id=1
|
||||
node_name=node1
|
||||
conninfo='host=node1 user=repmgr dbname=repmgr connect_timeout=2'
|
||||
data_directory='/var/lib/postgresql/data'
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
<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
|
||||
server. See sections on <xref linkend="configuration-file"> and <xref linkend="configuration-file-settings">
|
||||
for further details about <filename>repmgr.conf</filename>.
|
||||
</para>
|
||||
<tip>
|
||||
<simpara>
|
||||
For Debian-based distributions we recommend explictly setting
|
||||
<literal>pg_bindir</literal> to the directory where <command>pg_ctl</command> and other binaries
|
||||
not in the standard path are located. For PostgreSQL 9.6 this would be <filename>/usr/lib/postgresql/9.6/bin/</filename>.
|
||||
</simpara>
|
||||
</tip>
|
||||
|
||||
<para>
|
||||
See the file
|
||||
<ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</>
|
||||
for details of all available configuration parameters.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="quickstart-primary-register">
|
||||
<title>Register the primary server</title>
|
||||
<para>
|
||||
To enable &repmgr; to support a replication cluster, the primary node must
|
||||
be registered with &repmgr;. This installs the <literal>repmgr</literal>
|
||||
extension and metadata objects, and adds a metadata record for the primary server:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf primary register
|
||||
INFO: connecting to primary database...
|
||||
NOTICE: attempting to install extension "repmgr"
|
||||
NOTICE: "repmgr" extension successfully installed
|
||||
NOTICE: primary node record (id: 1) registered</programlisting>
|
||||
|
||||
<para>
|
||||
Verify status of the cluster like this:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf cluster show
|
||||
ID | Name | Role | Status | Upstream | Connection string
|
||||
----+-------+---------+-----------+----------+--------------------------------------------------------
|
||||
1 | node1 | primary | * running | | host=node1 dbname=repmgr user=repmgr connect_timeout=2
|
||||
</programlisting>
|
||||
<para>
|
||||
The record in the <literal>repmgr</literal> metadata table will look like this:
|
||||
</para>
|
||||
<programlisting>
|
||||
repmgr=# SELECT * FROM repmgr.nodes;
|
||||
-[ RECORD 1 ]----+-------------------------------------------------------
|
||||
node_id | 1
|
||||
upstream_node_id |
|
||||
active | t
|
||||
node_name | node1
|
||||
type | primary
|
||||
location | default
|
||||
priority | 100
|
||||
conninfo | host=node1 dbname=repmgr user=repmgr connect_timeout=2
|
||||
repluser | repmgr
|
||||
slot_name |
|
||||
config_file | /etc/repmgr.conf</programlisting>
|
||||
<para>
|
||||
Each server in the replication cluster will have its own record. If <command>repmgrd</command>
|
||||
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.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="quickstart-standby-clone">
|
||||
<title>Clone the standby server</title>
|
||||
<para>
|
||||
Create a <filename>repmgr.conf</filename> file on the standby server. It must contain at
|
||||
least the same parameters as the primary's <filename>repmgr.conf</filename>, but with
|
||||
the mandatory values <literal>node</literal>, <literal>node_name</literal>, <literal>conninfo</literal>
|
||||
(and possibly <literal>data_directory</literal>) adjusted accordingly, e.g.:
|
||||
</para>
|
||||
<programlisting>
|
||||
node=2
|
||||
node_name=node2
|
||||
conninfo='host=node2 user=repmgr dbname=repmgr connect_timeout=2'
|
||||
data_directory='/var/lib/postgresql/data'
|
||||
</programlisting>
|
||||
<para>
|
||||
Use the <command>--dry-run</command> option to check the standby can be cloned:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ repmgr -h node1 -U repmgr -d repmgr -f /etc/repmgr.conf standby clone --dry-run
|
||||
NOTICE: using provided configuration file "/etc/repmgr.conf"
|
||||
NOTICE: destination directory "/var/lib/postgresql/data" provided
|
||||
INFO: connecting to source node
|
||||
NOTICE: checking for available walsenders on source node (2 required)
|
||||
INFO: sufficient walsenders available on source node (2 required)
|
||||
NOTICE: standby will attach to upstream node 1
|
||||
HINT: consider using the -c/--fast-checkpoint option
|
||||
INFO: all prerequisites for "standby clone" are met</programlisting>
|
||||
<para>
|
||||
If no problems are reported, the standby can then be cloned with:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ repmgr -h node1 -U repmgr -d repmgr -f /etc/repmgr.conf standby clone
|
||||
|
||||
NOTICE: using configuration file "/etc/repmgr.conf"
|
||||
NOTICE: destination directory "/var/lib/postgresql/data" provided
|
||||
INFO: connecting to source node
|
||||
NOTICE: checking for available walsenders on source node (2 required)
|
||||
INFO: sufficient walsenders available on source node (2 required)
|
||||
INFO: creating directory "/var/lib/postgresql/data"...
|
||||
NOTICE: starting backup (using pg_basebackup)...
|
||||
HINT: this may take some time; consider using the -c/--fast-checkpoint option
|
||||
INFO: executing:
|
||||
pg_basebackup -l "repmgr base backup" -D /var/lib/postgresql/data -h node1 -U repmgr -X stream
|
||||
NOTICE: standby clone (using pg_basebackup) complete
|
||||
NOTICE: you can now start your PostgreSQL server
|
||||
HINT: for example: pg_ctl -D /var/lib/postgresql/data start
|
||||
</programlisting>
|
||||
<para>
|
||||
This has cloned the PostgreSQL data directory files from the primary <literal>node1</literal>
|
||||
using PostgreSQL's <command>pg_basebackup</command> utility. A <filename>recovery.conf</filename>
|
||||
file containing the correct parameters to start streaming from this primary server will be created
|
||||
automatically.
|
||||
</para>
|
||||
<note>
|
||||
<simpara>
|
||||
By default, any configuration files in the primary's data directory will be
|
||||
copied to the standby. Typically these will be <filename>postgresql.conf</filename>,
|
||||
<filename>postgresql.auto.conf</filename>, <filename>pg_hba.conf</filename> and
|
||||
<filename>pg_ident.conf</filename>. These may require modification before the standby
|
||||
is started.
|
||||
</simpara>
|
||||
</note>
|
||||
<para>
|
||||
Make any adjustments to the standby's PostgreSQL configuration files now,
|
||||
then start the server.
|
||||
</para>
|
||||
<para>
|
||||
For more details on <command>repmgr standby clone</command>, see the
|
||||
<link linkend="repmgr-standby-clone">command reference</link>.
|
||||
A more detailed overview of cloning options is available in the
|
||||
<link linkend="cloning-standbys">administration manual</link>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="quickstart-verify-replication">
|
||||
<title>Verify replication is functioning</title>
|
||||
<para>
|
||||
Connect to the primary server and execute:
|
||||
<programlisting>
|
||||
repmgr=# SELECT * FROM pg_stat_replication;
|
||||
-[ RECORD 1 ]----+------------------------------
|
||||
pid | 19111
|
||||
usesysid | 16384
|
||||
usename | repmgr
|
||||
application_name | node2
|
||||
client_addr | 192.168.1.12
|
||||
client_hostname |
|
||||
client_port | 50378
|
||||
backend_start | 2017-08-28 15:14:19.851581+09
|
||||
backend_xmin |
|
||||
state | streaming
|
||||
sent_location | 0/7000318
|
||||
write_location | 0/7000318
|
||||
flush_location | 0/7000318
|
||||
replay_location | 0/7000318
|
||||
sync_priority | 0
|
||||
sync_state | async</programlisting>
|
||||
This shows that the previously cloned standby (<literal>node2</literal> shown in the field
|
||||
<literal>application_name</literal>) has connected to the primary from IP address
|
||||
<literal>192.168.1.12</literal>.
|
||||
</para>
|
||||
<para>
|
||||
From PostgreSQL 9.6 you can also use the view
|
||||
<ulink url="https://www.postgresql.org/docs/current/static/monitoring-stats.html#PG-STAT-WAL-RECEIVER-VIEW">
|
||||
<literal>pg_stat_wal_receiver</literal></ulink> to check the replication status from the standby.
|
||||
|
||||
<programlisting>
|
||||
repmgr=# SELECT * FROM pg_stat_wal_receiver;
|
||||
Expanded display is on.
|
||||
-[ RECORD 1 ]---------+--------------------------------------------------------------------------------
|
||||
pid | 18236
|
||||
status | streaming
|
||||
receive_start_lsn | 0/3000000
|
||||
receive_start_tli | 1
|
||||
received_lsn | 0/7000538
|
||||
received_tli | 1
|
||||
last_msg_send_time | 2017-08-28 15:21:26.465728+09
|
||||
last_msg_receipt_time | 2017-08-28 15:21:26.465774+09
|
||||
latest_end_lsn | 0/7000538
|
||||
latest_end_time | 2017-08-28 15:20:56.418735+09
|
||||
slot_name |
|
||||
conninfo | user=repmgr dbname=replication host=node1 application_name=node2
|
||||
</programlisting>
|
||||
Note that the <varname>conninfo</varname> value is that generated in <filename>recovery.conf</filename>
|
||||
and will differ slightly from the primary's <varname>conninfo</varname> as set in <filename>repmgr.conf</filename> -
|
||||
among others it will contain the connecting node's name as <varname>application_name</varname>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="quickstart-register-standby">
|
||||
<title>Register the standby</title>
|
||||
<para>
|
||||
Register the standby server with:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf standby register
|
||||
NOTICE: standby node "node2" (ID: 2) successfully registered</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Check the node is registered by executing <command>repmgr cluster show</command> on the standby:
|
||||
<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</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Both nodes are now registered with &repmgr; and the records have been copied to the standby server.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
23
doc/repmgr-cluster-cleanup.sgml
Normal file
23
doc/repmgr-cluster-cleanup.sgml
Normal file
@@ -0,0 +1,23 @@
|
||||
<chapter id="repmgr-cluster-cleanup" xreflabel="repmgr cluster cleanup">
|
||||
<indexterm>
|
||||
<primary>repmgr cluster cleanup</primary>
|
||||
</indexterm>
|
||||
<title>repmgr cluster cleanup</title>
|
||||
<para>
|
||||
Purges monitoring history from the <literal>repmgr.monitoring_history</literal> table to
|
||||
prevent excessive table growth. Use the <literal>-k/--keep-history</literal> to specify the
|
||||
number of days of monitoring history to retain. This command can be used
|
||||
manually or as a cronjob.
|
||||
</para>
|
||||
<para>
|
||||
This command requires a valid <filename>repmgr.conf</filename> file for the node on which it is
|
||||
executed; no additional arguments are required.
|
||||
</para>
|
||||
<note>
|
||||
<simpara>
|
||||
Monitoring history will only be written if <command>repmgrd</command> is active, and
|
||||
<varname>monitoring_history</varname> is set to <literal>true</literal> in
|
||||
<filename>repmgr.conf</filename>.
|
||||
</simpara>
|
||||
</note>
|
||||
</chapter>
|
||||
28
doc/repmgr-cluster-crosscheck.sgml
Normal file
28
doc/repmgr-cluster-crosscheck.sgml
Normal file
@@ -0,0 +1,28 @@
|
||||
<chapter id="repmgr-cluster-crosscheck" xreflabel="repmgr cluster crosscheck">
|
||||
<indexterm>
|
||||
<primary>repmgr cluster crosscheck</primary>
|
||||
</indexterm>
|
||||
<title>repmgr cluster crosscheck</title>
|
||||
<para>
|
||||
<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
|
||||
<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
|
||||
overview of the cluster situation:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf cluster crosscheck
|
||||
|
||||
Name | Id | 1 | 2 | 3
|
||||
-------+----+----+----+----
|
||||
node1 | 1 | * | * | x
|
||||
node2 | 2 | * | * | *
|
||||
node3 | 3 | * | * | *</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
What happened is that <command>repmgr cluster crosscheck</command> merged its own
|
||||
<command>repmgr cluster matrix</command> with the <command>repmgr cluster matrix</command>
|
||||
output from <literal>node2</literal>; the latter is able to connect to <literal>node3</literal>
|
||||
and therefore determine the state of outbound connections from that node.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
37
doc/repmgr-cluster-event.sgml
Normal file
37
doc/repmgr-cluster-event.sgml
Normal file
@@ -0,0 +1,37 @@
|
||||
<chapter id="repmgr-cluster-event" xreflabel="repmgr cluster event">
|
||||
<indexterm>
|
||||
<primary>repmgr cluster event</primary>
|
||||
</indexterm>
|
||||
<title>repmgr cluster event</title>
|
||||
<para>
|
||||
This outputs a formatted list of cluster events, as stored in the
|
||||
<literal>repmgr.events</literal> table. Output is in reverse chronological order, and
|
||||
can be filtered with the following options:
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
<listitem>
|
||||
<simpara><literal>--all</literal>: outputs all entries</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>--limit</literal>: set the maximum number of entries to output (default: 20)</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>--node-id</literal>: restrict entries to node with this ID</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>--node-name</literal>: restrict entries to node with this name</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>--event</literal>: filter specific event</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
Example:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf cluster event --event=standby_register
|
||||
Node ID | Name | Event | OK | Timestamp | Details
|
||||
---------+-------+------------------+----+---------------------+--------------------------------
|
||||
3 | node3 | standby_register | t | 2017-08-17 10:28:55 | standby registration succeeded
|
||||
2 | node2 | standby_register | t | 2017-08-17 10:28:53 | standby registration succeeded</programlisting>
|
||||
</para>
|
||||
</chapter>
|
||||
83
doc/repmgr-cluster-matrix.sgml
Normal file
83
doc/repmgr-cluster-matrix.sgml
Normal file
@@ -0,0 +1,83 @@
|
||||
<chapter id="repmgr-cluster-matrix" xreflabel="repmgr cluster matrix">
|
||||
<indexterm>
|
||||
<primary>repmgr cluster matrix</primary>
|
||||
</indexterm>
|
||||
<title>repmgr cluster matrix</title>
|
||||
<para>
|
||||
<command>repmgr cluster matrix</command> runs <command>repmgr cluster show</command> on each
|
||||
node and arranges the results in a matrix, recording success or failure.
|
||||
</para>
|
||||
<para>
|
||||
<command>repmgr cluster matrix</command> requires a valid <filename>repmgr.conf</filename>
|
||||
file on each node. Additionally passwordless `ssh` connections are required between
|
||||
all nodes.
|
||||
</para>
|
||||
<para>
|
||||
Example 1 (all nodes up):
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf cluster matrix
|
||||
|
||||
Name | Id | 1 | 2 | 3
|
||||
-------+----+----+----+----
|
||||
node1 | 1 | * | * | *
|
||||
node2 | 2 | * | * | *
|
||||
node3 | 3 | * | * | *</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Example 2 (<literal>node1</literal> and <literal>node2</literal> up, <literal>node3</literal> down):
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf cluster matrix
|
||||
|
||||
Name | Id | 1 | 2 | 3
|
||||
-------+----+----+----+----
|
||||
node1 | 1 | * | * | x
|
||||
node2 | 2 | * | * | x
|
||||
node3 | 3 | ? | ? | ?
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Each row corresponds to one server, and indicates the result of
|
||||
testing an outbound connection from that server.
|
||||
</para>
|
||||
<para>
|
||||
Since <literal>node3</literal> is down, all the entries in its row are filled with
|
||||
<literal>?</literal>, meaning that there we cannot test outbound connections.
|
||||
</para>
|
||||
<para>
|
||||
The other two nodes are up; the corresponding rows have <literal>x</literal> in the
|
||||
column corresponding to <literal>node3</literal>, meaning that inbound connections to
|
||||
that node have failed, and `*` in the columns corresponding to
|
||||
<literal>node1</literal> and <literal>node2</literal>, meaning that inbound connections
|
||||
to these nodes have succeeded.
|
||||
</para>
|
||||
<para>
|
||||
Example 3 (all nodes up, firewall dropping packets originating
|
||||
from <literal>node1</literal> and directed to port 5432 on <literal>node3</literal>) -
|
||||
running <command>repmgr cluster matrix</command> from <literal>node1</literal> gives the following output:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf cluster matrix
|
||||
|
||||
Name | Id | 1 | 2 | 3
|
||||
-------+----+----+----+----
|
||||
node1 | 1 | * | * | x
|
||||
node2 | 2 | * | * | *
|
||||
node3 | 3 | ? | ? | ?</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Note this may take some time depending on the <varname>connect_timeout</varname>
|
||||
setting in the node <varname>conninfo</varname> strings; default is
|
||||
<literal>1 minute</literal> which means without modification the above
|
||||
command would take around 2 minutes to run; see comment elsewhere about setting
|
||||
<varname>connect_timeout</varname>)
|
||||
</para>
|
||||
<para>
|
||||
The matrix tells us that we cannot connect from <literal>node1</literal> to <literal>node3</literal>,
|
||||
and that (therefore) we don't know the state of any outbound
|
||||
connection from <literal>node3</literal>.
|
||||
</para>
|
||||
<para>
|
||||
In this case, the <xref linkend="repmgr-cluster-crosscheck"> command will produce a more
|
||||
useful result.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
67
doc/repmgr-cluster-show.sgml
Normal file
67
doc/repmgr-cluster-show.sgml
Normal file
@@ -0,0 +1,67 @@
|
||||
<chapter id="repmgr-cluster-show" xreflabel="repmgr cluster show">
|
||||
<indexterm>
|
||||
<primary>repmgr cluster show</primary>
|
||||
</indexterm>
|
||||
<title>repmgr cluster show</title>
|
||||
<para>
|
||||
Displays information about each active node in the replication cluster. This
|
||||
command polls each registered server and shows its role (<literal>primary</literal> /
|
||||
<literal>standby</literal> / <literal>bdr</literal>) and status. It polls each server
|
||||
directly and can be run on any node in the cluster; this is also useful when analyzing
|
||||
connectivity from a particular node.
|
||||
</para>
|
||||
<para>
|
||||
This command requires either a valid <filename>repmgr.conf</filename> file or a database
|
||||
connection string to one of the registered nodes; no additional arguments are needed.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf cluster show
|
||||
|
||||
ID | Name | Role | Status | Upstream | Location | Connection string
|
||||
----+-------+---------+-----------+----------+----------+-----------------------------------------
|
||||
1 | node1 | primary | * running | | default | host=db_node1 dbname=repmgr user=repmgr
|
||||
2 | node2 | standby | running | node1 | default | host=db_node2 dbname=repmgr user=repmgr
|
||||
3 | node3 | standby | running | node1 | default | host=db_node3 dbname=repmgr user=repmgr</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To show database connection errors when polling nodes, run the command in
|
||||
<literal>--verbose</literal> mode.
|
||||
</para>
|
||||
<para>
|
||||
The `cluster show` command accepts an optional parameter <literal>--csv</literal>, which
|
||||
outputs the replication cluster's status in a simple CSV format, suitable for
|
||||
parsing by scripts:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf cluster show --csv
|
||||
1,-1,-1
|
||||
2,0,0
|
||||
3,0,1</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The columns have following meanings:
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
<listitem>
|
||||
<simpara>
|
||||
node ID
|
||||
</simpara>
|
||||
<simpara>
|
||||
availability (0 = available, -1 = unavailable)
|
||||
</simpara>
|
||||
<simpara>
|
||||
recovery state (0 = not in recovery, 1 = in recovery, -1 = unknown)
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Note that the availability is tested by connecting from the node where
|
||||
<command>repmgr cluster show</command> is executed, and does not necessarily imply the node
|
||||
is down. See <xref linkend="repmgr-cluster-matrix"> and <xref linkend="repmgr-cluster-crosscheck"> to get
|
||||
a better overviews of connections between nodes.
|
||||
</para>
|
||||
</chapter>
|
||||
70
doc/repmgr-node-check.sgml
Normal file
70
doc/repmgr-node-check.sgml
Normal file
@@ -0,0 +1,70 @@
|
||||
<chapter id="repmgr-node-check" xreflabel="repmgr node check">
|
||||
<indexterm>
|
||||
<primary>repmgr node check</primary>
|
||||
</indexterm>
|
||||
<title>repmgr node check</title>
|
||||
<para>
|
||||
Performs some health checks on a node from a replication perspective.
|
||||
This command must be run on the local node.
|
||||
</para>
|
||||
<para>
|
||||
Sample output (execute <command>repmgr node check</command>):
|
||||
<programlisting>
|
||||
Node "node1":
|
||||
Server role: OK (node is primary)
|
||||
Replication lag: OK (N/A - node is primary)
|
||||
WAL archiving: OK (0 pending files)
|
||||
Downstream servers: OK (2 of 2 downstream nodes attached)
|
||||
Replication slots: OK (node has no replication slots)
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Additionally each check can be performed individually by supplying
|
||||
an additional command line parameter, e.g.:
|
||||
<programlisting>
|
||||
$ repmgr node check --role
|
||||
OK (node is primary)
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Parameters for individual checks are as follows:
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
<literal>--role</literal>: checks if the node has the expected role
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
<literal>--replication-lag</literal>: checks if the node is lagging by more than
|
||||
<varname>replication_lag_warning</varname> or <varname>replication_lag_critical</varname>
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
<literal>--archive-ready</literal>: checks for WAL files which have not yet been archived
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
<literal>--downstream</literal>: checks that the expected downstream nodes are attached
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
<literal>--slots</literal>: checks there are no inactive replication slots
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
Individual checks can also be output in a Nagios-compatible format by additionally
|
||||
providing the option <literal>--nagios</literal>.
|
||||
</para>
|
||||
</chapter>
|
||||
13
doc/repmgr-node-rejoin.sgml
Normal file
13
doc/repmgr-node-rejoin.sgml
Normal file
@@ -0,0 +1,13 @@
|
||||
<chapter id="repmgr-node-rejoin" xreflabel="repmgr node rejoin">
|
||||
<indexterm>
|
||||
<primary>repmgr node rejoin</primary>
|
||||
</indexterm>
|
||||
<title>repmgr node rejoin</title>
|
||||
<para>
|
||||
Enables a dormant (stopped) node to be rejoined to the replication cluster.
|
||||
</para>
|
||||
<para>
|
||||
This 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.
|
||||
</para>
|
||||
</chapter>
|
||||
29
doc/repmgr-node-status.sgml
Normal file
29
doc/repmgr-node-status.sgml
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
<chapter id="repmgr-node-status" xreflabel="repmgr node status">
|
||||
<indexterm>
|
||||
<primary>repmgr node status</primary>
|
||||
</indexterm>
|
||||
<title>repmgr node status</title>
|
||||
<para>
|
||||
Displays an overview of a node's basic information and replication
|
||||
status. This command must be run on the local node.
|
||||
</para>
|
||||
<para>
|
||||
Sample output (execute <command>repmgr node status</command>):
|
||||
<programlisting>
|
||||
Node "node1":
|
||||
PostgreSQL version: 10beta1
|
||||
Total data size: 30 MB
|
||||
Conninfo: host=node1 dbname=repmgr user=repmgr connect_timeout=2
|
||||
Role: primary
|
||||
WAL archiving: off
|
||||
Archive command: (none)
|
||||
Replication connections: 2 (of maximal 10)
|
||||
Replication slots: 0 (of maximal 10)
|
||||
Replication lag: n/a
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
See <xref linkend="repmgr-node-check"> to diagnose issues.
|
||||
</para>
|
||||
</chapter>
|
||||
18
doc/repmgr-primary-register.sgml
Normal file
18
doc/repmgr-primary-register.sgml
Normal file
@@ -0,0 +1,18 @@
|
||||
<chapter id="repmgr-primary-register" xreflabel="repmgr primary register">
|
||||
<indexterm><primary>repmgr primary register</primary></indexterm>
|
||||
<title>repmgr primary register</title>
|
||||
<para>
|
||||
<command>repmgr primary register</command> registers a primary node in a
|
||||
streaming replication cluster, and configures it for use with repmgr, including
|
||||
installing the &repmgr; extension. This command needs to be executed before any
|
||||
standby nodes are registered.
|
||||
</para>
|
||||
<para>
|
||||
Execute with the <literal>--dry-run</literal> option to check what would happen without
|
||||
actually registering the primary.
|
||||
</para>
|
||||
<para>
|
||||
<command>repmgr master register</command> can be used as an alias for
|
||||
<command>repmgr primary register</command>.
|
||||
</para>
|
||||
</chapter>
|
||||
18
doc/repmgr-primary-unregister.sgml
Normal file
18
doc/repmgr-primary-unregister.sgml
Normal file
@@ -0,0 +1,18 @@
|
||||
<chapter id="repmgr-primary-unregister" xreflabel="repmgr primary unregister">
|
||||
<indexterm><primary>repmgr primary unregister</primary></indexterm>
|
||||
<title>repmgr primary unregister</title>
|
||||
<para>
|
||||
<command>repmgr primary register</command> unregisters an inactive primary node
|
||||
from the &repmgr; metadata. This is typically when the primary has failed and is
|
||||
being removed from the cluster after a new primary has been promoted.
|
||||
</para>
|
||||
<para>
|
||||
Execute with the <literal>--dry-run</literal> option to check what would happen without
|
||||
actually unregistering the node.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<command>repmgr master unregister</command> can be used as an alias for
|
||||
<command>repmgr primary unregister</command>/
|
||||
</para>
|
||||
</chapter>
|
||||
91
doc/repmgr-standby-clone.sgml
Normal file
91
doc/repmgr-standby-clone.sgml
Normal file
@@ -0,0 +1,91 @@
|
||||
<chapter id="repmgr-standby-clone" xreflabel="repmgr standby clone">
|
||||
<indexterm>
|
||||
<primary>repmgr standby clone</primary>
|
||||
<seealso>cloning</seealso>
|
||||
</indexterm>
|
||||
<title>repmgr standby clone</title>
|
||||
<para>
|
||||
<command>repmgr standby clone</command> clones a PostgreSQL node from another
|
||||
PostgreSQL node, typically the primary, but optionally from any other node in
|
||||
the cluster or from Barman. It creates the <filename>recovery.conf</filename> file required
|
||||
to attach the cloned node to the primary node (or another standby, if cascading replication
|
||||
is in use).
|
||||
</para>
|
||||
<note>
|
||||
<simpara>
|
||||
<command>repmgr standby clone</command> does not start the standby, and after cloning
|
||||
<command>repmgr standby register</command> must be executed to notify &repmgr; of its presence.
|
||||
</simpara>
|
||||
</note>
|
||||
|
||||
|
||||
<sect1 id="repmgr-standby-clone-config-file-copying" xreflabel="Copying configuration files">
|
||||
<title>Handling configuration files</title>
|
||||
|
||||
<para>
|
||||
Note that by default, all configuration files in the source node's data
|
||||
directory will be copied to the cloned node. Typically these will be
|
||||
<filename>postgresql.conf</filename>, <filename>postgresql.auto.conf</filename>,
|
||||
<filename>pg_hba.conf</filename> and <filename>pg_ident.conf</filename>.
|
||||
These may require modification before the standby is started.
|
||||
</para>
|
||||
<para>
|
||||
In some cases (e.g. on Debian or Ubuntu Linux installations), PostgreSQL's
|
||||
configuration files are located outside of the data directory and will
|
||||
not be copied by default. &repmgr; can copy these files, either to the same
|
||||
location on the standby server (provided appropriate directory and file permissions
|
||||
are available), or into the standby's data directory. This requires passwordless
|
||||
SSH access to the primary server. Add the option <literal>--copy-external-config-files</literal>
|
||||
to the <command>repmgr standby clone</command> command; by default files will be copied to
|
||||
the same path as on the upstream server. Note that the user executing <command>repmgr</command>
|
||||
must have write access to those directories.
|
||||
</para>
|
||||
<para>
|
||||
To have the configuration files placed in the standby's data directory, specify
|
||||
<literal>--copy-external-config-files=pgdata</literal>, but note that
|
||||
any include directives in the copied files may need to be updated.
|
||||
</para>
|
||||
<tip>
|
||||
<simpara>
|
||||
For reliable configuration file management we recommend using a
|
||||
configuration management tool such as Ansible, Chef, Puppet or Salt.
|
||||
</simpara>
|
||||
</tip>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="repmgr-standby-clone-wal-management" xreflabel="Managing WAL during the cloning process">
|
||||
<title>Managing WAL during the cloning process</title>
|
||||
<para>
|
||||
When initially cloning a standby, you will need to ensure
|
||||
that all required WAL files remain available while the cloning is taking
|
||||
place. To ensure this happens when using the default `pg_basebackup` method,
|
||||
&repmgr; will set <command>pg_basebackup</command>'s <literal>--xlog-method</literal>
|
||||
parameter to <literal>stream</literal>,
|
||||
which will ensure all WAL files generated during the cloning process are
|
||||
streamed in parallel with the main backup. Note that this requires two
|
||||
replication connections to be available (&repmgr; will verify sufficient
|
||||
connections are available before attempting to clone, and this can be checked
|
||||
before performing the clone using the <literal>--dry-run</literal> option).
|
||||
</para>
|
||||
<para>
|
||||
To override this behaviour, in <filename>repmgr.conf</filename> set
|
||||
<command>pg_basebackup</command>'s <literal>--xlog-method</literal>
|
||||
parameter to <literal>fetch</literal>:
|
||||
<programlisting>
|
||||
pg_basebackup_options='--xlog-method=fetch'</programlisting>
|
||||
|
||||
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/static/app-pgbasebackup.html">
|
||||
pg_basebackup</ulink> documentation for details.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<simpara>
|
||||
From PostgreSQL 10, <command>pg_basebackup</command>'s
|
||||
<literal>--xlog-method</literal> parameter has been renamed to
|
||||
<literal>--wal-method</literal>.
|
||||
</simpara>
|
||||
</note>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
21
doc/repmgr-standby-follow.sgml
Normal file
21
doc/repmgr-standby-follow.sgml
Normal file
@@ -0,0 +1,21 @@
|
||||
<chapter id="repmgr-standby-follow" xreflabel="repmgr standby follow">
|
||||
<indexterm>
|
||||
<primary>repmgr standby follow</primary>
|
||||
</indexterm>
|
||||
<title>repmgr standby follow</title>
|
||||
<para>
|
||||
Attaches the standby to a new primary. This command requires a valid
|
||||
<filename>repmgr.conf</filename> file for the standby, either specified
|
||||
explicitly with <literal>-f/--config-file</literal> or located in a
|
||||
default location; no additional arguments are required.
|
||||
</para>
|
||||
<para>
|
||||
This command will force a restart of the standby server, which must be
|
||||
running. It can only be used to attach a standby to a new primary node.
|
||||
</para>
|
||||
<para>
|
||||
To re-add an inactive node to the replication cluster, see
|
||||
<xref linkend="repmgr-node-rejoin">
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
18
doc/repmgr-standby-promote.sgml
Normal file
18
doc/repmgr-standby-promote.sgml
Normal file
@@ -0,0 +1,18 @@
|
||||
<chapter id="repmgr-standby-promote" xreflabel="repmgr standby promote">
|
||||
<indexterm>
|
||||
<primary>repmgr standby promote</primary>
|
||||
</indexterm>
|
||||
<title>repmgr standby promote</title>
|
||||
<para>
|
||||
Promotes a standby to a primary if the current primary has failed. This
|
||||
command requires a valid <filename>repmgr.conf</filename> file for the standby, either
|
||||
specified explicitly with <literal>-f/--config-file</literal> or located in a
|
||||
default location; no additional arguments are required.
|
||||
</para>
|
||||
<para>
|
||||
If the standby promotion succeeds, the server will not need to be
|
||||
restarted. However any other standbys will need to follow the new server,
|
||||
by using <xref linkend="repmgr-standby-follow">; if <command>repmgrd</command>
|
||||
is active, it will handle this automatically.
|
||||
</para>
|
||||
</chapter>
|
||||
50
doc/repmgr-standby-register.sgml
Normal file
50
doc/repmgr-standby-register.sgml
Normal file
@@ -0,0 +1,50 @@
|
||||
<chapter id="repmgr-standby-register" xreflabel="repmgr standby register">
|
||||
<indexterm><primary>repmgr standby register</primary></indexterm>
|
||||
<title>repmgr standby register</title>
|
||||
<para>
|
||||
<command>repmgr standby register</command> adds a standby's information to
|
||||
the &repmgr; metadata. This command needs to be executed to enable
|
||||
promote/follow operations and to allow <command>repmgrd</command> to work with the node.
|
||||
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
|
||||
standby.
|
||||
</para>
|
||||
|
||||
<sect1 id="repmgr-standby-register-wait" xreflabel="repmgr standby register --wait">
|
||||
<title>Waiting for the registration to propagate to the standby</title>
|
||||
<para>
|
||||
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 <command>repmgrd</command>) require that the standby's node record
|
||||
is present and up-to-date to function correctly.
|
||||
</para>
|
||||
<para>
|
||||
By providing the option <literal>--wait-sync</literal> to the
|
||||
<command>repmgr standby register</command> command, &repmgr; will wait
|
||||
until the record is synchronised before exiting. An optional timeout (in
|
||||
seconds) can be added to this option (e.g. <literal>--wait-sync=60</literal>).
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="rempgr-standby-register-inactive-node" xreflabel="Registering an inactive node">
|
||||
<title>Registering an inactive node</title>
|
||||
<para>
|
||||
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
|
||||
a complex replication cluster. In this case, by using the <literal>-F/--force</literal>
|
||||
option and providing the connection parameters to the primary server,
|
||||
the standby can be registered.
|
||||
</para>
|
||||
<para>
|
||||
Similarly, with cascading replication it may be necessary to register
|
||||
a standby whose upstream node has not yet been registered - in this case,
|
||||
using <literal>-F/--force</literal> will result in the creation of an inactive placeholder
|
||||
record for the upstream node, which will however later need to be registered
|
||||
with the <literal>-F/--force</literal> option too.
|
||||
</para>
|
||||
<para>
|
||||
When used with <command>repmgr standby register</command>, care should be taken that use of the
|
||||
<literal>-F/--force</literal> option does not result in an incorrectly configured cluster.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
27
doc/repmgr-standby-switchover.sgml
Normal file
27
doc/repmgr-standby-switchover.sgml
Normal file
@@ -0,0 +1,27 @@
|
||||
<chapter id="repmgr-standby-switchover" xreflabel="repmgr standby switchover">
|
||||
<indexterm>
|
||||
<primary>repmgr standby switchover</primary>
|
||||
</indexterm>
|
||||
<title>repmgr standby switchover</title>
|
||||
<para>
|
||||
Promotes a standby to primary and demotes the existing primary to a standby.
|
||||
This command must be run on the standby to be promoted, and requires a
|
||||
passwordless SSH connection to the current primary.
|
||||
</para>
|
||||
<para>
|
||||
If other standbys are connected to the demotion candidate, &repmgr; can instruct
|
||||
these to follow the new primary if the option <literal>--siblings-follow</literal>
|
||||
is specified.
|
||||
</para>
|
||||
<para>
|
||||
Execute with the <literal>--dry-run</literal> option to test the switchover as far as
|
||||
possible without actually changing the status of either node.
|
||||
</para>
|
||||
<para>
|
||||
<command>repmgrd</command> should not be active on any nodes while a switchover is being
|
||||
executed. This restriction may be lifted in a later version.
|
||||
</para>
|
||||
<para>
|
||||
For more details see the section <xref linkend="performing-switchover">.
|
||||
</para>
|
||||
</chapter>
|
||||
29
doc/repmgr-standby-unregister.sgml
Normal file
29
doc/repmgr-standby-unregister.sgml
Normal file
@@ -0,0 +1,29 @@
|
||||
<chapter id="repmgr-standby-unregister" xreflabel="repmgr standby unregister">
|
||||
<indexterm><primary>repmgr standby unregister</primary></indexterm>
|
||||
<title>repmgr standby unregister</title>
|
||||
<para>
|
||||
Unregisters a standby with `repmgr`. This command does not affect the actual
|
||||
replication, just removes the standby's entry from the &repmgr; metadata.
|
||||
</para>
|
||||
<para>
|
||||
To unregister a running standby, execute:
|
||||
<programlisting>
|
||||
repmgr standby unregister -f /etc/repmgr.conf</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
This will remove the standby record from &repmgr;'s internal metadata
|
||||
table (<literal>repmgr.nodes</literal>). A <literal>standby_unregister</literal>
|
||||
event notification will be recorded in the <literal>repmgr.events</literal> table.
|
||||
</para>
|
||||
<para>
|
||||
If the standby is not running, the command can be executed on another
|
||||
node by providing the id of the node to be unregistered using
|
||||
the command line parameter <literal>--node-id</literal>, e.g. executing the following
|
||||
command on the master server will unregister the standby with
|
||||
id <literal>3</literal>:
|
||||
<programlisting>
|
||||
repmgr standby unregister -f /etc/repmgr.conf --node-id=3
|
||||
</programlisting>
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
117
doc/repmgr.sgml
Normal file
117
doc/repmgr.sgml
Normal file
@@ -0,0 +1,117 @@
|
||||
<!-- doc/src/sgml/postgres.sgml -->
|
||||
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [
|
||||
|
||||
<!ENTITY % version SYSTEM "version.sgml">
|
||||
%version;
|
||||
|
||||
<!ENTITY % filelist SYSTEM "filelist.sgml">
|
||||
%filelist;
|
||||
|
||||
<!ENTITY repmgr "<productname>repmgr</productname>">
|
||||
<!ENTITY postgres "<productname>PostgreSQL</productname>">
|
||||
]>
|
||||
|
||||
<book id="repmgr">
|
||||
<title>repmgr &repmgrversion; Documentation</title>
|
||||
|
||||
<bookinfo>
|
||||
<corpauthor>2ndQuadrant Ltd</corpauthor>
|
||||
<productname>repmgr</productname>
|
||||
<productnumber>&repmgrversion;</productnumber>
|
||||
&legal;
|
||||
|
||||
<abstract>
|
||||
<para>
|
||||
Thisis the official documentation of &repmgr; &repmgrversion; for
|
||||
use with PostgreSQL 9.3 - PostgreSQL 10.
|
||||
It describes the functionality supported by the current version of &repmgr;.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
repmgr was developed by
|
||||
<ulink url="https://2ndquadrant.com">2ndQuadrant</ulink>
|
||||
along with contributions from other individuals and companies.
|
||||
Contributions from the community are appreciated and welcome - get
|
||||
in touch via <ulink url="https://github.com/2ndQuadrant/repmgr">github</>
|
||||
or <ulink url="https://groups.google.com/group/repmgr">the mailing list/forum</>.
|
||||
Multiple 2ndQuadrant customers contribute funding
|
||||
to make repmgr development possible.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
2ndQuadrant, a Platinum sponsor of the PostgreSQL project,
|
||||
continues to develop repmgr to meet internal needs and those of customers.
|
||||
Other companies as well as individual developers
|
||||
are welcome to participate in the efforts.
|
||||
</para>
|
||||
</abstract>
|
||||
|
||||
<keywordset>
|
||||
<keyword>repmgr</keyword>
|
||||
<keyword>PostgreSQL</keyword>
|
||||
<keyword>replication</keyword>
|
||||
<keyword>asynchronous</keyword>
|
||||
<keyword>HA</keyword>
|
||||
<keyword>high-availability</keyword>
|
||||
</keywordset>
|
||||
</bookinfo>
|
||||
|
||||
|
||||
<part id="getting-started">
|
||||
<title>Getting started</title>
|
||||
&overview;
|
||||
&install;
|
||||
&quickstart;
|
||||
</part>
|
||||
|
||||
<part id="repmgr-administration-manual">
|
||||
<title>repmgr administration manual</title>
|
||||
|
||||
&configuration;
|
||||
&cloning-standbys;
|
||||
&promoting-standby;
|
||||
&follow-new-primary;
|
||||
&switchover;
|
||||
&event-notifications;
|
||||
&upgrading-repmgr;
|
||||
</part>
|
||||
|
||||
<part id="using-repmgrd">
|
||||
<title>Using repmgrd</title>
|
||||
&repmgrd-automatic-failover;
|
||||
&repmgrd-configuration;
|
||||
&repmgrd-demonstration;
|
||||
&repmgrd-cascading-replication;
|
||||
&repmgrd-network-split;
|
||||
&repmgrd-degraded-monitoring;
|
||||
&repmgrd-monitoring;
|
||||
</part>
|
||||
|
||||
<part id="repmgr-command-reference">
|
||||
<title>repmgr command reference</title>
|
||||
|
||||
&repmgr-primary-register;
|
||||
&repmgr-primary-unregister;
|
||||
&repmgr-standby-clone;
|
||||
&repmgr-standby-register;
|
||||
&repmgr-standby-unregister;
|
||||
&repmgr-standby-promote;
|
||||
&repmgr-standby-follow;
|
||||
&repmgr-standby-switchover;
|
||||
&repmgr-node-status;
|
||||
&repmgr-node-check;
|
||||
&repmgr-node-rejoin;
|
||||
&repmgr-cluster-show;
|
||||
&repmgr-cluster-matrix;
|
||||
&repmgr-cluster-crosscheck;
|
||||
&repmgr-cluster-event;
|
||||
&repmgr-cluster-cleanup;
|
||||
</part>
|
||||
|
||||
&appendix-signatures;
|
||||
|
||||
<![%include-index;[&bookindex;]]>
|
||||
<![%include-xslt-index;[<index id="bookindex"></index>]]>
|
||||
|
||||
</book>
|
||||
12
doc/repmgrd-automatic-failover.sgml
Normal file
12
doc/repmgrd-automatic-failover.sgml
Normal file
@@ -0,0 +1,12 @@
|
||||
<chapter id="repmgrd-automatic-failover" xreflabel="Automatic failover with repmgrd">
|
||||
<title>Automatic failover with repmgrd</title>
|
||||
|
||||
<para>
|
||||
<command>repmgrd</command> 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>
|
||||
17
doc/repmgrd-cascading-replication.sgml
Normal file
17
doc/repmgrd-cascading-replication.sgml
Normal file
@@ -0,0 +1,17 @@
|
||||
<chapter id="repmgrd-cascading-replication">
|
||||
<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
|
||||
<command>repmgrd</command> support cascading replication by keeping track of the relationship
|
||||
between standby servers - each node record is stored with the node id of its
|
||||
upstream ("parent") server (except of course the primary server).
|
||||
</para>
|
||||
<para>
|
||||
In a failover situation where the primary node fails and a top-level standby
|
||||
is promoted, a standby connected to another standby will not be affected
|
||||
and continue working as normal (even if the upstream standby it's connected
|
||||
to becomes the primary node). If however the node's direct upstream fails,
|
||||
the "cascaded standby" will attempt to reconnect to that node's parent.
|
||||
</para>
|
||||
</chapter>
|
||||
94
doc/repmgrd-configuration.sgml
Normal file
94
doc/repmgrd-configuration.sgml
Normal file
@@ -0,0 +1,94 @@
|
||||
<chapter id="repmgrd-configuration">
|
||||
<title>repmgrd configuration</title>
|
||||
<para>
|
||||
To use <command>repmgrd</command>, its associated function library must be
|
||||
included in <filename>postgresql.conf</filename> with:
|
||||
|
||||
<programlisting>
|
||||
shared_preload_libraries = 'repmgr'</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Changing this setting requires a restart of PostgreSQL; for more details see
|
||||
the <ulink url="https://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">PostgreSQL documentation</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
Additionally the following <command>repmgrd</command> options *must* be set in
|
||||
<filename>repmgr.conf</filename> (adjust configuration file locations as appropriate):
|
||||
<programlisting>
|
||||
failover=automatic
|
||||
promote_command='repmgr standby promote -f /etc/repmgr.conf --log-to-file'
|
||||
follow_command='repmgr standby follow -f /etc/repmgr.conf --log-to-file --upstream-node-id=%n'</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Note that the <literal>--log-to-file</literal> option will cause
|
||||
output generated by the &repmgr; command, when executed by <command>repmgrd</command>,
|
||||
to be logged to the same destination configured to receive log output for <command>repmgrd</command>.
|
||||
See <filename>repmgr.conf.sample</filename> for further <command>repmgrd</command>-specific settings.
|
||||
</para>
|
||||
<para>
|
||||
When <varname>failover</varname> is set to <literal>automatic</literal>, upon detecting failure
|
||||
of the current primary, <command>repmgrd</command> will execute one of
|
||||
<varname>promote_command</varname> or <varname>follow_command</varname>,
|
||||
depending on whether the current server is to become the new primary, or
|
||||
needs to follow another server which has become the new primary. Note that
|
||||
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>
|
||||
<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
|
||||
<command>repmgrd</command> 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>
|
||||
<sect1 id="repmgrd-connection-settings">
|
||||
<title>repmgrd connection settings</title>
|
||||
<para>
|
||||
In addition to the &repmgr; configuration settings, parameters in the
|
||||
<varname>conninfo</varname> string influence how &repmgr; makes a network connection to
|
||||
PostgreSQL. In particular, if another server in the replication cluster
|
||||
is unreachable at network level, system network settings will influence
|
||||
the length of time it takes to determine that the connection is not possible.
|
||||
</para>
|
||||
<para>
|
||||
In particular explicitly setting a parameter for <literal>connect_timeout</literal>
|
||||
should be considered; the effective minimum value of <literal>2</literal>
|
||||
(seconds) will ensure that a connection failure at network level is reported
|
||||
as soon as possible, otherwise depending on the system settings (e.g.
|
||||
<varname>tcp_syn_retries</varname> in Linux) a delay of a minute or more
|
||||
is possible.
|
||||
</para>
|
||||
<para>
|
||||
For further details on <varname>conninfo</varname> network connection
|
||||
parameters, see the
|
||||
<ulink url="https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS">PostgreSQL documentation</ulink>.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 id="repmgrd-log-rotation">
|
||||
<title>repmgrd log rotation</title>
|
||||
<para>
|
||||
To ensure the current <command>repmgrd</command> logfile 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/postgresql/repmgr-9.6.log {
|
||||
missingok
|
||||
compress
|
||||
rotate 52
|
||||
maxsize 100M
|
||||
weekly
|
||||
create 0600 postgres postgres
|
||||
}</programlisting>
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
70
doc/repmgrd-degraded-monitoring.sgml
Normal file
70
doc/repmgrd-degraded-monitoring.sgml
Normal file
@@ -0,0 +1,70 @@
|
||||
<chapter id="repmgrd-degraded-monitoring">
|
||||
<title>"degraded monitoring" mode</title>
|
||||
<para>
|
||||
In certain circumstances, <command>repmgrd</command> is not able to fulfill its primary mission
|
||||
of monitoring the nodes' upstream server. In these cases it enters "degraded
|
||||
monitoring" mode, where <command>repmgrd</command> 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</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 <command>repmgrd</command> will terminate.
|
||||
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
96
doc/repmgrd-demonstration.sgml
Normal file
96
doc/repmgrd-demonstration.sgml
Normal file
@@ -0,0 +1,96 @@
|
||||
<chapter id="repmgrd-demonstration">
|
||||
<title>repmgrd demonstration</title>
|
||||
<para>
|
||||
To demonstrate automatic failover, set up a 3-node replication cluster (one primary
|
||||
and two standbys streaming directly from the primary) so that the cluster looks
|
||||
something like this:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf cluster show
|
||||
ID | Name | Role | Status | Upstream | Location | Connection string
|
||||
----+-------+---------+-----------+----------+----------+--------------------------------------
|
||||
1 | node1 | primary | * running | | default | host=node1 dbname=repmgr user=repmgr
|
||||
2 | node2 | standby | running | node1 | default | host=node2 dbname=repmgr user=repmgr
|
||||
3 | node3 | standby | running | node1 | default | host=node3 dbname=repmgr user=repmgr </programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Start <command>repmgrd</command> 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 <command>repmgrd</command> 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 <command>repmgrd</command> log
|
||||
files as each <command>repmgrd</command> 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 '/home/barwick/devel/builds/HEAD/bin/pg_ctl -l /tmp/postgres.5602.log -w -D '/tmp/repmgr-test/node_2/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>
|
||||
71
doc/repmgrd-monitoring.sgml
Normal file
71
doc/repmgrd-monitoring.sgml
Normal file
@@ -0,0 +1,71 @@
|
||||
<chapter id="repmgrd-monitoring">
|
||||
<title>Monitoring with repmgrd</title>
|
||||
<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 <command>repmgrd</command> 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>
|
||||
43
doc/repmgrd-network-split.sgml
Normal file
43
doc/repmgrd-network-split.sgml
Normal file
@@ -0,0 +1,43 @@
|
||||
<chapter id="repmgrd-network-split">
|
||||
<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>
|
||||
Previous &repmgr; versions used the concept of a "witness server" 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, <command>repmgrd</command> will check if any servers in the
|
||||
same location as the current primary node are visible. If not, <command>repmgrd</command>
|
||||
will assume a network interruption and not promote any node in any
|
||||
other location (it will however enter <xref linkend="repmgrd-degraded-monitoring"> mode until
|
||||
a primary becomes visible).
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
96
doc/stylesheet.css
Normal file
96
doc/stylesheet.css
Normal file
@@ -0,0 +1,96 @@
|
||||
/* doc/src/sgml/stylesheet.css */
|
||||
|
||||
/* color scheme similar to www.postgresql.org */
|
||||
|
||||
BODY {
|
||||
color: #000000;
|
||||
background: #FFFFFF;
|
||||
font-family: verdana, sans-serif;
|
||||
}
|
||||
|
||||
A:link { color:#0066A2; }
|
||||
A:visited { color:#004E66; }
|
||||
A:active { color:#0066A2; }
|
||||
A:hover { color:#000000; }
|
||||
|
||||
H1 {
|
||||
font-size: 1.4em;
|
||||
font-weight: bold;
|
||||
margin-top: 0em;
|
||||
margin-bottom: 0em;
|
||||
color: #EC5800;
|
||||
}
|
||||
|
||||
H2 {
|
||||
font-size: 1.2em;
|
||||
margin: 1.2em 0em 1.2em 0em;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
H3 {
|
||||
font-size: 1.1em;
|
||||
margin: 1.2em 0em 1.2em 0em;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
H4 {
|
||||
font-size: 0.95em;
|
||||
margin: 1.2em 0em 1.2em 0em;
|
||||
font-weight: normal;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
H5 {
|
||||
font-size: 0.9em;
|
||||
margin: 1.2em 0em 1.2em 0em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
H6 {
|
||||
font-size: 0.85em;
|
||||
margin: 1.2em 0em 1.2em 0em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* center some titles */
|
||||
|
||||
.BOOK .TITLE, .BOOK .CORPAUTHOR, .BOOK .COPYRIGHT {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* decoration for formal examples */
|
||||
|
||||
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 */
|
||||
|
||||
.BOOK .TOC DL DT {
|
||||
padding-top: 1.5ex;
|
||||
padding-bottom: 1.5ex;
|
||||
}
|
||||
|
||||
.BOOK .TOC DL DL DT {
|
||||
padding-top: 0ex;
|
||||
padding-bottom: 0ex;
|
||||
}
|
||||
|
||||
/* miscellaneous */
|
||||
|
||||
PRE.LITERALLAYOUT, .SCREEN, .SYNOPSIS, .PROGRAMLISTING {
|
||||
margin-left: 4ex;
|
||||
}
|
||||
|
||||
.COMMENT { color: red; }
|
||||
|
||||
VAR { font-family: monospace; font-style: italic; }
|
||||
/* Konqueror's standard style for ACRONYM is italic. */
|
||||
ACRONYM { font-style: inherit; }
|
||||
851
doc/stylesheet.dsl
Normal file
851
doc/stylesheet.dsl
Normal file
@@ -0,0 +1,851 @@
|
||||
<!-- doc/src/sgml/stylesheet.dsl -->
|
||||
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
|
||||
|
||||
<!-- must turn on one of these with -i on the jade command line -->
|
||||
<!ENTITY % output-html "IGNORE">
|
||||
<!ENTITY % output-print "IGNORE">
|
||||
<!ENTITY % output-text "IGNORE">
|
||||
|
||||
<![ %output-html; [
|
||||
<!ENTITY dbstyle PUBLIC "-//Norman Walsh//DOCUMENT DocBook HTML Stylesheet//EN" CDATA DSSSL>
|
||||
]]>
|
||||
|
||||
<![ %output-print; [
|
||||
<!ENTITY dbstyle PUBLIC "-//Norman Walsh//DOCUMENT DocBook Print Stylesheet//EN" CDATA DSSSL>
|
||||
]]>
|
||||
|
||||
<![ %output-text; [
|
||||
<!ENTITY dbstyle PUBLIC "-//Norman Walsh//DOCUMENT DocBook HTML Stylesheet//EN" CDATA DSSSL>
|
||||
]]>
|
||||
|
||||
]>
|
||||
|
||||
<style-sheet>
|
||||
<style-specification use="docbook">
|
||||
<style-specification-body>
|
||||
|
||||
<!-- general customization ......................................... -->
|
||||
|
||||
<!-- (applicable to all output formats) -->
|
||||
|
||||
(define draft-mode #f)
|
||||
|
||||
;; Don't show manpage volume numbers
|
||||
(define %refentry-xref-manvolnum% #f)
|
||||
|
||||
;; Don't use graphics for callouts. (We could probably do that, but
|
||||
;; it needs extra work.)
|
||||
(define %callout-graphics% #f)
|
||||
|
||||
;; Show comments during the development stage.
|
||||
(define %show-comments% draft-mode)
|
||||
|
||||
;; Force a chapter TOC even if it includes only a single entry
|
||||
(define %force-chapter-toc% #t)
|
||||
|
||||
;; Don't append period if run-in title ends with any of these
|
||||
;; characters. We had to add the colon here. This is fixed in
|
||||
;; stylesheets version 1.71, so it can be removed sometime.
|
||||
(define %content-title-end-punct%
|
||||
'(#\. #\! #\? #\:))
|
||||
|
||||
;; No automatic punctuation after honorific name parts
|
||||
(define %honorific-punctuation% "")
|
||||
|
||||
;; Change display of some elements
|
||||
(element command ($mono-seq$))
|
||||
(element envar ($mono-seq$))
|
||||
(element lineannotation ($italic-seq$))
|
||||
(element literal ($mono-seq$))
|
||||
(element option ($mono-seq$))
|
||||
(element parameter ($mono-seq$))
|
||||
(element structfield ($mono-seq$))
|
||||
(element structname ($mono-seq$))
|
||||
(element symbol ($mono-seq$))
|
||||
(element token ($mono-seq$))
|
||||
(element type ($mono-seq$))
|
||||
(element varname ($mono-seq$))
|
||||
(element (programlisting emphasis) ($bold-seq$)) ;; to highlight sections of code
|
||||
|
||||
;; Special support for Tcl synopses
|
||||
(element optional
|
||||
(if (equal? (attribute-string (normalize "role")) "tcl")
|
||||
(make sequence
|
||||
(literal "?")
|
||||
($charseq$)
|
||||
(literal "?"))
|
||||
(make sequence
|
||||
(literal %arg-choice-opt-open-str%)
|
||||
($charseq$)
|
||||
(literal %arg-choice-opt-close-str%))))
|
||||
|
||||
;; Avoid excessive cross-reference labels
|
||||
(define (auto-xref-indirect? target ancestor)
|
||||
(cond
|
||||
; ;; Always add indirect references to another book
|
||||
; ((member (gi ancestor) (book-element-list))
|
||||
; #t)
|
||||
;; Add indirect references to the section or component a block
|
||||
;; is in iff chapters aren't autolabelled. (Otherwise "Figure 1-3"
|
||||
;; is sufficient)
|
||||
((and (member (gi target) (block-element-list))
|
||||
(not %chapter-autolabel%))
|
||||
#t)
|
||||
;; Add indirect references to the component a section is in if
|
||||
;; the sections are not autolabelled
|
||||
((and (member (gi target) (section-element-list))
|
||||
(member (gi ancestor) (component-element-list))
|
||||
(not %section-autolabel%))
|
||||
#t)
|
||||
(else #f)))
|
||||
|
||||
|
||||
;; Bibliography things
|
||||
|
||||
;; Use the titles of bibliography entries in cross-references
|
||||
(define biblio-xref-title #t)
|
||||
|
||||
;; Process bibliography entry components in the order shown below, not
|
||||
;; in the order they appear in the document. (I suppose this should
|
||||
;; be made to fit some publishing standard.)
|
||||
(define %biblioentry-in-entry-order% #f)
|
||||
|
||||
(define (biblioentry-inline-elements)
|
||||
(list
|
||||
(normalize "author")
|
||||
(normalize "authorgroup")
|
||||
(normalize "title")
|
||||
(normalize "subtitle")
|
||||
(normalize "volumenum")
|
||||
(normalize "edition")
|
||||
(normalize "othercredit")
|
||||
(normalize "contrib")
|
||||
(normalize "editor")
|
||||
(normalize "publishername")
|
||||
(normalize "confgroup")
|
||||
(normalize "publisher")
|
||||
(normalize "isbn")
|
||||
(normalize "issn")
|
||||
(normalize "pubsnumber")
|
||||
(normalize "date")
|
||||
(normalize "pubdate")
|
||||
(normalize "pagenums")
|
||||
(normalize "bibliomisc")))
|
||||
|
||||
(mode biblioentry-inline-mode
|
||||
|
||||
(element confgroup
|
||||
(make sequence
|
||||
(literal "Proc. ")
|
||||
(next-match)))
|
||||
|
||||
(element isbn
|
||||
(make sequence
|
||||
(literal "ISBN ")
|
||||
(process-children)))
|
||||
|
||||
(element issn
|
||||
(make sequence
|
||||
(literal "ISSN ")
|
||||
(process-children))))
|
||||
|
||||
|
||||
;; The rules in the default stylesheet for productname format it as a
|
||||
;; paragraph. This may be suitable for productname directly within
|
||||
;; *info, but it's nonsense when productname is used inline, as we do.
|
||||
(mode book-titlepage-recto-mode
|
||||
(element (para productname) ($charseq$)))
|
||||
(mode book-titlepage-verso-mode
|
||||
(element (para productname) ($charseq$)))
|
||||
;; Add more here if needed...
|
||||
|
||||
|
||||
;; Replace a sequence of whitespace in a string by a single space
|
||||
(define (normalize-whitespace str #!optional (whitespace '(#\space #\U-000D)))
|
||||
(let loop ((characters (string->list str))
|
||||
(result '())
|
||||
(prev-was-space #f))
|
||||
(if (null? characters)
|
||||
(list->string (reverse result))
|
||||
(let ((c (car characters))
|
||||
(rest (cdr characters)))
|
||||
(if (member c whitespace)
|
||||
(if prev-was-space
|
||||
(loop rest result #t)
|
||||
(loop rest (cons #\space result) #t))
|
||||
(loop rest (cons c result) #f))))))
|
||||
|
||||
|
||||
<!-- HTML output customization ..................................... -->
|
||||
|
||||
<![ %output-html; [
|
||||
|
||||
(define %section-autolabel% #t)
|
||||
(define %label-preface-sections% #f)
|
||||
(define %generate-legalnotice-link% #t)
|
||||
(define %html-ext% ".html")
|
||||
(define %root-filename% "index")
|
||||
(define %link-mailto-url% (string-append "mailto: repmgr-list@2ndquadrant.com"))
|
||||
(define %use-id-as-filename% #t)
|
||||
(define website-build #f)
|
||||
(define %stylesheet% (if website-build "/resources/docs.css" "website-docs.css"))
|
||||
(define %graphic-default-extension% "gif")
|
||||
(define %body-attr% '())
|
||||
(define ($generate-book-lot-list$) '())
|
||||
(define use-output-dir #t)
|
||||
(define %output-dir% "html")
|
||||
(define html-index-filename "../HTML.index")
|
||||
|
||||
|
||||
;; Only build HTML.index or the actual HTML output, not both. Saves a
|
||||
;; *lot* of time. (overrides docbook.dsl)
|
||||
(root
|
||||
(if (not html-index)
|
||||
(make sequence
|
||||
(process-children)
|
||||
(with-mode manifest
|
||||
(process-children)))
|
||||
(with-mode htmlindex
|
||||
(process-children))))
|
||||
|
||||
|
||||
;; Do not combine first section into chapter chunk.
|
||||
(define (chunk-skip-first-element-list) '())
|
||||
|
||||
;; Returns the depth of auto TOC that should be made at the nd-level
|
||||
(define (toc-depth nd)
|
||||
(cond ((string=? (gi nd) (normalize "book")) 2)
|
||||
((string=? (gi nd) (normalize "part")) 2)
|
||||
((string=? (gi nd) (normalize "chapter")) 2)
|
||||
(else 1)))
|
||||
|
||||
;; Add character encoding and time of creation into HTML header
|
||||
(define %html-header-tags%
|
||||
(list (list "META" '("HTTP-EQUIV" "Content-Type") '("CONTENT" "text/html; charset=ISO-8859-1"))
|
||||
(list "META" '("NAME" "creation") (list "CONTENT" (time->string (time) #t)))))
|
||||
|
||||
|
||||
;; Block elements are allowed in PARA in DocBook, but not in P in
|
||||
;; HTML. With %fix-para-wrappers% turned on, the stylesheets attempt
|
||||
;; to avoid putting block elements in HTML P tags by outputting
|
||||
;; additional end/begin P pairs around them.
|
||||
(define %fix-para-wrappers% #t)
|
||||
|
||||
;; ...but we need to do some extra work to make the above apply to PRE
|
||||
;; as well. (mostly pasted from dbverb.dsl)
|
||||
(define ($verbatim-display$ indent line-numbers?)
|
||||
(let ((content (make element gi: "PRE"
|
||||
attributes: (list
|
||||
(list "CLASS" (gi)))
|
||||
(if (or indent line-numbers?)
|
||||
($verbatim-line-by-line$ indent line-numbers?)
|
||||
(process-children)))))
|
||||
(if %shade-verbatim%
|
||||
(make element gi: "TABLE"
|
||||
attributes: ($shade-verbatim-attr$)
|
||||
(make element gi: "TR"
|
||||
(make element gi: "TD"
|
||||
content)))
|
||||
(make sequence
|
||||
(para-check)
|
||||
content
|
||||
(para-check 'restart)))))
|
||||
|
||||
;; ...and for notes.
|
||||
(element note
|
||||
(make sequence
|
||||
(para-check)
|
||||
($admonition$)
|
||||
(para-check 'restart)))
|
||||
|
||||
;;; XXX The above is very ugly. It might be better to run 'tidy' on
|
||||
;;; the resulting *.html files.
|
||||
|
||||
|
||||
;; Format multiple terms in varlistentry vertically, instead
|
||||
;; of comma-separated.
|
||||
(element (varlistentry term)
|
||||
(make sequence
|
||||
(process-children-trim)
|
||||
(if (not (last-sibling?))
|
||||
(make empty-element gi: "BR")
|
||||
(empty-sosofo))))
|
||||
|
||||
|
||||
;; Customization of header
|
||||
;; - make title a link to the home page
|
||||
;; - add tool tips to Prev/Next links
|
||||
;; - add Up link
|
||||
;; (overrides dbnavig.dsl)
|
||||
(define (default-header-nav-tbl-noff elemnode prev next prevsib nextsib)
|
||||
(let* ((r1? (nav-banner? elemnode))
|
||||
(r1-sosofo (make element gi: "TR"
|
||||
(make element gi: "TH"
|
||||
attributes: (list
|
||||
(list "COLSPAN" "4")
|
||||
(list "ALIGN" "center")
|
||||
(list "VALIGN" "bottom"))
|
||||
(make element gi: "A"
|
||||
attributes: (list
|
||||
(list "HREF" (href-to (nav-home elemnode))))
|
||||
(nav-banner elemnode)))))
|
||||
(r2? (or (not (node-list-empty? prev))
|
||||
(not (node-list-empty? next))
|
||||
(nav-context? elemnode)))
|
||||
(r2-sosofo (make element gi: "TR"
|
||||
(make element gi: "TD"
|
||||
attributes: (list
|
||||
(list "WIDTH" "10%")
|
||||
(list "ALIGN" "left")
|
||||
(list "VALIGN" "top"))
|
||||
(if (node-list-empty? prev)
|
||||
(make entity-ref name: "nbsp")
|
||||
(make element gi: "A"
|
||||
attributes: (list
|
||||
(list "TITLE" (element-title-string prev))
|
||||
(list "HREF"
|
||||
(href-to
|
||||
prev))
|
||||
(list "ACCESSKEY"
|
||||
"P"))
|
||||
(gentext-nav-prev prev))))
|
||||
(make element gi: "TD"
|
||||
attributes: (list
|
||||
(list "WIDTH" "10%")
|
||||
(list "ALIGN" "left")
|
||||
(list "VALIGN" "top"))
|
||||
(if (nav-up? elemnode)
|
||||
(nav-up elemnode)
|
||||
(nav-home-link elemnode)))
|
||||
(make element gi: "TD"
|
||||
attributes: (list
|
||||
(list "WIDTH" "60%")
|
||||
(list "ALIGN" "center")
|
||||
(list "VALIGN" "bottom"))
|
||||
(nav-context elemnode))
|
||||
(make element gi: "TD"
|
||||
attributes: (list
|
||||
(list "WIDTH" "20%")
|
||||
(list "ALIGN" "right")
|
||||
(list "VALIGN" "top"))
|
||||
(if (node-list-empty? next)
|
||||
(make entity-ref name: "nbsp")
|
||||
(make element gi: "A"
|
||||
attributes: (list
|
||||
(list "TITLE" (element-title-string next))
|
||||
(list "HREF"
|
||||
(href-to
|
||||
next))
|
||||
(list "ACCESSKEY"
|
||||
"N"))
|
||||
(gentext-nav-next next)))))))
|
||||
(if (or r1? r2?)
|
||||
(make element gi: "DIV"
|
||||
attributes: '(("CLASS" "NAVHEADER"))
|
||||
(make element gi: "TABLE"
|
||||
attributes: (list
|
||||
(list "SUMMARY" "Header navigation table")
|
||||
(list "WIDTH" %gentext-nav-tblwidth%)
|
||||
(list "BORDER" "0")
|
||||
(list "CELLPADDING" "0")
|
||||
(list "CELLSPACING" "0"))
|
||||
(if r1? r1-sosofo (empty-sosofo))
|
||||
(if r2? r2-sosofo (empty-sosofo)))
|
||||
(make empty-element gi: "HR"
|
||||
attributes: (list
|
||||
(list "ALIGN" "LEFT")
|
||||
(list "WIDTH" %gentext-nav-tblwidth%))))
|
||||
(empty-sosofo))))
|
||||
|
||||
|
||||
;; Put index "quicklinks" (A | B | C | ...) at the top of the bookindex page.
|
||||
|
||||
(element index
|
||||
(let ((preamble (node-list-filter-by-not-gi
|
||||
(children (current-node))
|
||||
(list (normalize "indexentry"))))
|
||||
(indexdivs (node-list-filter-by-gi
|
||||
(children (current-node))
|
||||
(list (normalize "indexdiv"))))
|
||||
(entries (node-list-filter-by-gi
|
||||
(children (current-node))
|
||||
(list (normalize "indexentry")))))
|
||||
(html-document
|
||||
(with-mode head-title-mode
|
||||
(literal (element-title-string (current-node))))
|
||||
(make element gi: "DIV"
|
||||
attributes: (list (list "CLASS" (gi)))
|
||||
($component-separator$)
|
||||
($component-title$)
|
||||
(if (node-list-empty? indexdivs)
|
||||
(empty-sosofo)
|
||||
(make element gi: "P"
|
||||
attributes: (list (list "CLASS" "INDEXDIV-QUICKLINKS"))
|
||||
(with-mode indexdiv-quicklinks-mode
|
||||
(process-node-list indexdivs))))
|
||||
(process-node-list preamble)
|
||||
(if (node-list-empty? entries)
|
||||
(empty-sosofo)
|
||||
(make element gi: "DL"
|
||||
(process-node-list entries)))))))
|
||||
|
||||
|
||||
(mode indexdiv-quicklinks-mode
|
||||
(element indexdiv
|
||||
(make sequence
|
||||
(make element gi: "A"
|
||||
attributes: (list (list "HREF" (href-to (current-node))))
|
||||
(element-title-sosofo))
|
||||
(if (not (last-sibling?))
|
||||
(literal " | ")
|
||||
(literal "")))))
|
||||
|
||||
|
||||
;; Changed to strip and normalize index term content (overrides
|
||||
;; dbindex.dsl)
|
||||
(define (htmlindexterm)
|
||||
(let* ((attr (gi (current-node)))
|
||||
(content (data (current-node)))
|
||||
(string (strip (normalize-whitespace content))) ;; changed
|
||||
(sortas (attribute-string (normalize "sortas"))))
|
||||
(make sequence
|
||||
(make formatting-instruction data: attr)
|
||||
(if sortas
|
||||
(make sequence
|
||||
(make formatting-instruction data: "[")
|
||||
(make formatting-instruction data: sortas)
|
||||
(make formatting-instruction data: "]"))
|
||||
(empty-sosofo))
|
||||
(make formatting-instruction data: " ")
|
||||
(make formatting-instruction data: string)
|
||||
(htmlnewline))))
|
||||
|
||||
(define ($html-body-start$)
|
||||
(if website-build
|
||||
(make empty-element gi: "!--#include virtual=\"/resources/docs-header.html\"--")
|
||||
(empty-sosofo)))
|
||||
|
||||
(define ($html-body-end$)
|
||||
(if website-build
|
||||
(make empty-element gi: "!--#include virtual=\"/resources/docs-footer.html\"--")
|
||||
(empty-sosofo)))
|
||||
|
||||
]]> <!-- %output-html -->
|
||||
|
||||
|
||||
<!-- Print output customization .................................... -->
|
||||
|
||||
<![ %output-print; [
|
||||
|
||||
(define %section-autolabel% #t)
|
||||
(define %default-quadding% 'justify)
|
||||
|
||||
;; Don't know how well hyphenation works with other backends. Might
|
||||
;; turn this on if desired.
|
||||
(define %hyphenation%
|
||||
(if tex-backend #t #f))
|
||||
|
||||
;; Put footnotes at the bottom of the page (rather than end of
|
||||
;; section), and put the URLs of links into footnotes.
|
||||
;;
|
||||
;; bop-footnotes only works with TeX, otherwise it's ignored. But
|
||||
;; when both of these are #t and TeX is used, you need at least
|
||||
;; stylesheets 1.73 because otherwise you don't get any footnotes at
|
||||
;; all for the links.
|
||||
(define bop-footnotes #t)
|
||||
(define %footnote-ulinks% #t)
|
||||
|
||||
(define %refentry-new-page% #t)
|
||||
(define %refentry-keep% #f)
|
||||
|
||||
;; Disabled because of TeX problems
|
||||
;; (http://archives.postgresql.org/pgsql-docs/2007-12/msg00056.php)
|
||||
(define ($generate-book-lot-list$) '())
|
||||
|
||||
;; Indentation of verbatim environments. (This should really be done
|
||||
;; with start-indent in DSSSL.)
|
||||
;; Use of indentation in this area exposes a bug in openjade,
|
||||
;; http://archives.postgresql.org/pgsql-docs/2006-12/msg00064.php
|
||||
;; (define %indent-programlisting-lines% " ")
|
||||
;; (define %indent-screen-lines% " ")
|
||||
;; (define %indent-synopsis-lines% " ")
|
||||
|
||||
|
||||
;; Default graphic format: Jadetex wants eps, pdfjadetex wants pdf.
|
||||
;; (Note that pdfjadetex will not accept eps, that's why we need to
|
||||
;; create a different .tex file for each.) What works with RTF?
|
||||
|
||||
(define texpdf-output #f) ;; override from command line
|
||||
|
||||
(define %graphic-default-extension%
|
||||
(cond (tex-backend (if texpdf-output "pdf" "eps"))
|
||||
(rtf-backend "gif")
|
||||
(else "XXX")))
|
||||
|
||||
;; Need to add pdf here so that the above works. Default setup
|
||||
;; doesn't know about PDF.
|
||||
(define preferred-mediaobject-extensions
|
||||
(list "eps" "ps" "jpg" "jpeg" "pdf" "png"))
|
||||
|
||||
|
||||
;; Don't show links when citing a bibliography entry. This fouls up
|
||||
;; the footnumber counting. To get the link, one can still look into
|
||||
;; the bibliography itself.
|
||||
(mode xref-title-mode
|
||||
(element ulink
|
||||
(process-children)))
|
||||
|
||||
|
||||
;; Format legalnotice justified and with space between paragraphs.
|
||||
(mode book-titlepage-verso-mode
|
||||
(element (legalnotice para)
|
||||
(make paragraph
|
||||
use: book-titlepage-verso-style ;; alter this if ever it needs to appear elsewhere
|
||||
quadding: %default-quadding%
|
||||
line-spacing: (* 0.8 (inherited-line-spacing))
|
||||
font-size: (* 0.8 (inherited-font-size))
|
||||
space-before: (* 0.8 %para-sep%)
|
||||
space-after: (* 0.8 %para-sep%)
|
||||
first-line-start-indent: (if (is-first-para)
|
||||
(* 0.8 %para-indent-firstpara%)
|
||||
(* 0.8 %para-indent%))
|
||||
(process-children))))
|
||||
|
||||
|
||||
;; Fix spacing problems in variablelists
|
||||
|
||||
(element (varlistentry term)
|
||||
(make paragraph
|
||||
space-before: (if (first-sibling?)
|
||||
%para-sep%
|
||||
0pt)
|
||||
keep-with-next?: #t
|
||||
(process-children)))
|
||||
|
||||
(define %varlistentry-indent% 2em)
|
||||
|
||||
(element (varlistentry listitem)
|
||||
(make sequence
|
||||
start-indent: (+ (inherited-start-indent) %varlistentry-indent%)
|
||||
(process-children)))
|
||||
|
||||
|
||||
;; Whitespace fixes for itemizedlists and orderedlists
|
||||
|
||||
(define (process-listitem-content)
|
||||
(if (absolute-first-sibling?)
|
||||
(make sequence
|
||||
(process-children-trim))
|
||||
(next-match)))
|
||||
|
||||
|
||||
;; Default stylesheets format simplelists as tables. This spells
|
||||
;; trouble for Jade. So we just format them as plain lines.
|
||||
|
||||
(define %simplelist-indent% 1em)
|
||||
|
||||
(define (my-simplelist-vert members)
|
||||
(make display-group
|
||||
space-before: %para-sep%
|
||||
space-after: %para-sep%
|
||||
start-indent: (+ %simplelist-indent% (inherited-start-indent))
|
||||
(process-children)))
|
||||
|
||||
(element simplelist
|
||||
(let ((type (attribute-string (normalize "type")))
|
||||
(cols (if (attribute-string (normalize "columns"))
|
||||
(if (> (string->number (attribute-string (normalize "columns"))) 0)
|
||||
(string->number (attribute-string (normalize "columns")))
|
||||
1)
|
||||
1))
|
||||
(members (select-elements (children (current-node)) (normalize "member"))))
|
||||
(cond
|
||||
((equal? type (normalize "inline"))
|
||||
(if (equal? (gi (parent (current-node)))
|
||||
(normalize "para"))
|
||||
(process-children)
|
||||
(make paragraph
|
||||
space-before: %para-sep%
|
||||
space-after: %para-sep%
|
||||
start-indent: (inherited-start-indent))))
|
||||
((equal? type (normalize "vert"))
|
||||
(my-simplelist-vert members))
|
||||
((equal? type (normalize "horiz"))
|
||||
(simplelist-table 'row cols members)))))
|
||||
|
||||
(element member
|
||||
(let ((type (inherited-attribute-string (normalize "type"))))
|
||||
(cond
|
||||
((equal? type (normalize "inline"))
|
||||
(make sequence
|
||||
(process-children)
|
||||
(if (not (last-sibling?))
|
||||
(literal ", ")
|
||||
(literal ""))))
|
||||
((equal? type (normalize "vert"))
|
||||
(make paragraph
|
||||
space-before: 0pt
|
||||
space-after: 0pt))
|
||||
((equal? type (normalize "horiz"))
|
||||
(make paragraph
|
||||
quadding: 'start
|
||||
(process-children))))))
|
||||
|
||||
|
||||
;; Jadetex doesn't handle links to the content of tables, so
|
||||
;; indexterms that point to table entries will go nowhere. We fix
|
||||
;; this by pointing the index entry to the table itself instead, which
|
||||
;; should be equally useful in practice.
|
||||
|
||||
(define (find-parent-table nd)
|
||||
(let ((table (ancestor-member nd ($table-element-list$))))
|
||||
(if (node-list-empty? table)
|
||||
nd
|
||||
table)))
|
||||
|
||||
;; (The function below overrides the one in print/dbindex.dsl.)
|
||||
|
||||
(define (indexentry-link nd)
|
||||
(let* ((id (attribute-string (normalize "role") nd))
|
||||
(prelim-target (find-indexterm id))
|
||||
(target (find-parent-table prelim-target))
|
||||
(preferred (not (node-list-empty?
|
||||
(select-elements (children (current-node))
|
||||
(normalize "emphasis")))))
|
||||
(sosofo (if (node-list-empty? target)
|
||||
(literal "?")
|
||||
(make link
|
||||
destination: (node-list-address target)
|
||||
(with-mode toc-page-number-mode
|
||||
(process-node-list target))))))
|
||||
(if preferred
|
||||
(make sequence
|
||||
font-weight: 'bold
|
||||
sosofo)
|
||||
sosofo)))
|
||||
|
||||
|
||||
;; By default, the part and reference title pages get wrong page
|
||||
;; numbers: The first title page gets roman numerals carried over from
|
||||
;; preface/toc -- we want Arabic numerals. We also need to make sure
|
||||
;; that page-number-restart is set of #f explicitly, because otherwise
|
||||
;; it will carry over from the previous component, which is not good.
|
||||
;;
|
||||
;; (This looks worse than it is. It's copied from print/dbttlpg.dsl
|
||||
;; and common/dbcommon.dsl and modified in minor detail.)
|
||||
|
||||
(define (first-part?)
|
||||
(let* ((book (ancestor (normalize "book")))
|
||||
(nd (ancestor-member (current-node)
|
||||
(append
|
||||
(component-element-list)
|
||||
(division-element-list))))
|
||||
(bookch (children book)))
|
||||
(let loop ((nl bookch))
|
||||
(if (node-list-empty? nl)
|
||||
#f
|
||||
(if (equal? (gi (node-list-first nl)) (normalize "part"))
|
||||
(if (node-list=? (node-list-first nl) nd)
|
||||
#t
|
||||
#f)
|
||||
(loop (node-list-rest nl)))))))
|
||||
|
||||
(define (first-reference?)
|
||||
(let* ((book (ancestor (normalize "book")))
|
||||
(nd (ancestor-member (current-node)
|
||||
(append
|
||||
(component-element-list)
|
||||
(division-element-list))))
|
||||
(bookch (children book)))
|
||||
(let loop ((nl bookch))
|
||||
(if (node-list-empty? nl)
|
||||
#f
|
||||
(if (equal? (gi (node-list-first nl)) (normalize "reference"))
|
||||
(if (node-list=? (node-list-first nl) nd)
|
||||
#t
|
||||
#f)
|
||||
(loop (node-list-rest nl)))))))
|
||||
|
||||
|
||||
(define (part-titlepage elements #!optional (side 'recto))
|
||||
(let ((nodelist (titlepage-nodelist
|
||||
(if (equal? side 'recto)
|
||||
(reference-titlepage-recto-elements)
|
||||
(reference-titlepage-verso-elements))
|
||||
elements))
|
||||
;; partintro is a special case...
|
||||
(partintro (node-list-first
|
||||
(node-list-filter-by-gi elements (list (normalize "partintro"))))))
|
||||
(if (part-titlepage-content? elements side)
|
||||
(make simple-page-sequence
|
||||
page-n-columns: %titlepage-n-columns%
|
||||
;; Make sure that page number format is correct.
|
||||
page-number-format: ($page-number-format$)
|
||||
;; Make sure that the page number is set to 1 if this is the
|
||||
;; first part in the book
|
||||
page-number-restart?: (first-part?)
|
||||
input-whitespace-treatment: 'collapse
|
||||
use: default-text-style
|
||||
|
||||
;; This hack is required for the RTF backend. If an external-graphic
|
||||
;; is the first thing on the page, RTF doesn't seem to do the right
|
||||
;; thing (the graphic winds up on the baseline of the first line
|
||||
;; of the page, left justified). This "one point rule" fixes
|
||||
;; that problem.
|
||||
(make paragraph
|
||||
line-spacing: 1pt
|
||||
(literal ""))
|
||||
|
||||
(let loop ((nl nodelist) (lastnode (empty-node-list)))
|
||||
(if (node-list-empty? nl)
|
||||
(empty-sosofo)
|
||||
(make sequence
|
||||
(if (or (node-list-empty? lastnode)
|
||||
(not (equal? (gi (node-list-first nl))
|
||||
(gi lastnode))))
|
||||
(part-titlepage-before (node-list-first nl) side)
|
||||
(empty-sosofo))
|
||||
(cond
|
||||
((equal? (gi (node-list-first nl)) (normalize "subtitle"))
|
||||
(part-titlepage-subtitle (node-list-first nl) side))
|
||||
((equal? (gi (node-list-first nl)) (normalize "title"))
|
||||
(part-titlepage-title (node-list-first nl) side))
|
||||
(else
|
||||
(part-titlepage-default (node-list-first nl) side)))
|
||||
(loop (node-list-rest nl) (node-list-first nl)))))
|
||||
|
||||
(if (and %generate-part-toc%
|
||||
%generate-part-toc-on-titlepage%
|
||||
(equal? side 'recto))
|
||||
(make display-group
|
||||
(build-toc (current-node)
|
||||
(toc-depth (current-node))))
|
||||
(empty-sosofo))
|
||||
|
||||
;; PartIntro is a special case
|
||||
(if (and (equal? side 'recto)
|
||||
(not (node-list-empty? partintro))
|
||||
%generate-partintro-on-titlepage%)
|
||||
($process-partintro$ partintro #f)
|
||||
(empty-sosofo)))
|
||||
|
||||
(empty-sosofo))))
|
||||
|
||||
|
||||
(define (reference-titlepage elements #!optional (side 'recto))
|
||||
(let ((nodelist (titlepage-nodelist
|
||||
(if (equal? side 'recto)
|
||||
(reference-titlepage-recto-elements)
|
||||
(reference-titlepage-verso-elements))
|
||||
elements))
|
||||
;; partintro is a special case...
|
||||
(partintro (node-list-first
|
||||
(node-list-filter-by-gi elements (list (normalize "partintro"))))))
|
||||
(if (reference-titlepage-content? elements side)
|
||||
(make simple-page-sequence
|
||||
page-n-columns: %titlepage-n-columns%
|
||||
;; Make sure that page number format is correct.
|
||||
page-number-format: ($page-number-format$)
|
||||
;; Make sure that the page number is set to 1 if this is the
|
||||
;; first part in the book
|
||||
page-number-restart?: (first-reference?)
|
||||
input-whitespace-treatment: 'collapse
|
||||
use: default-text-style
|
||||
|
||||
;; This hack is required for the RTF backend. If an external-graphic
|
||||
;; is the first thing on the page, RTF doesn't seem to do the right
|
||||
;; thing (the graphic winds up on the baseline of the first line
|
||||
;; of the page, left justified). This "one point rule" fixes
|
||||
;; that problem.
|
||||
(make paragraph
|
||||
line-spacing: 1pt
|
||||
(literal ""))
|
||||
|
||||
(let loop ((nl nodelist) (lastnode (empty-node-list)))
|
||||
(if (node-list-empty? nl)
|
||||
(empty-sosofo)
|
||||
(make sequence
|
||||
(if (or (node-list-empty? lastnode)
|
||||
(not (equal? (gi (node-list-first nl))
|
||||
(gi lastnode))))
|
||||
(reference-titlepage-before (node-list-first nl) side)
|
||||
(empty-sosofo))
|
||||
(cond
|
||||
((equal? (gi (node-list-first nl)) (normalize "author"))
|
||||
(reference-titlepage-author (node-list-first nl) side))
|
||||
((equal? (gi (node-list-first nl)) (normalize "authorgroup"))
|
||||
(reference-titlepage-authorgroup (node-list-first nl) side))
|
||||
((equal? (gi (node-list-first nl)) (normalize "corpauthor"))
|
||||
(reference-titlepage-corpauthor (node-list-first nl) side))
|
||||
((equal? (gi (node-list-first nl)) (normalize "editor"))
|
||||
(reference-titlepage-editor (node-list-first nl) side))
|
||||
((equal? (gi (node-list-first nl)) (normalize "subtitle"))
|
||||
(reference-titlepage-subtitle (node-list-first nl) side))
|
||||
((equal? (gi (node-list-first nl)) (normalize "title"))
|
||||
(reference-titlepage-title (node-list-first nl) side))
|
||||
(else
|
||||
(reference-titlepage-default (node-list-first nl) side)))
|
||||
(loop (node-list-rest nl) (node-list-first nl)))))
|
||||
|
||||
(if (and %generate-reference-toc%
|
||||
%generate-reference-toc-on-titlepage%
|
||||
(equal? side 'recto))
|
||||
(make display-group
|
||||
(build-toc (current-node)
|
||||
(toc-depth (current-node))))
|
||||
(empty-sosofo))
|
||||
|
||||
;; PartIntro is a special case
|
||||
(if (and (equal? side 'recto)
|
||||
(not (node-list-empty? partintro))
|
||||
%generate-partintro-on-titlepage%)
|
||||
($process-partintro$ partintro #f)
|
||||
(empty-sosofo)))
|
||||
|
||||
(empty-sosofo))))
|
||||
|
||||
]]> <!-- %output-print -->
|
||||
|
||||
|
||||
<!-- Plain text output customization ............................... -->
|
||||
|
||||
<!--
|
||||
This is used for making the INSTALL file and others. We customize the
|
||||
HTML stylesheets to be suitable for dumping plain text (via Netscape,
|
||||
Lynx, or similar).
|
||||
-->
|
||||
|
||||
<![ %output-text; [
|
||||
|
||||
(define %section-autolabel% #f)
|
||||
(define %chapter-autolabel% #f)
|
||||
(define $generate-chapter-toc$ (lambda () #f))
|
||||
|
||||
;; For text output, produce "ASCII markup" for emphasis and such.
|
||||
|
||||
(define ($asterix-seq$ #!optional (sosofo (process-children)))
|
||||
(make sequence
|
||||
(literal "*")
|
||||
sosofo
|
||||
(literal "*")))
|
||||
|
||||
(define ($dquote-seq$ #!optional (sosofo (process-children)))
|
||||
(make sequence
|
||||
(literal (gentext-start-quote))
|
||||
sosofo
|
||||
(literal (gentext-end-quote))))
|
||||
|
||||
(element (para command) ($dquote-seq$))
|
||||
(element (para emphasis) ($asterix-seq$))
|
||||
(element (para filename) ($dquote-seq$))
|
||||
(element (para option) ($dquote-seq$))
|
||||
(element (para replaceable) ($dquote-seq$))
|
||||
(element (para userinput) ($dquote-seq$))
|
||||
|
||||
]]> <!-- %output-text -->
|
||||
|
||||
</style-specification-body>
|
||||
</style-specification>
|
||||
|
||||
<external-specification id="docbook" document="dbstyle">
|
||||
</style-sheet>
|
||||
204
doc/switchover.sgml
Normal file
204
doc/switchover.sgml
Normal file
@@ -0,0 +1,204 @@
|
||||
<chapter id="performing-switchover" xreflabel="Performing a switchover with repmgr">
|
||||
<title>Performing a switchover with repmgr</title>
|
||||
<para>
|
||||
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
|
||||
in case of a problem with the primary. Such an unplanned failover would
|
||||
normally be handled by promoting the standby, after which an appropriate
|
||||
action must be taken to restore the old primary.
|
||||
</para>
|
||||
<para>
|
||||
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
|
||||
is supported by the <xref linkend="repmgr-standby-switchover"> command.
|
||||
</para>
|
||||
<para>
|
||||
<command>repmgr standby switchover</command> differs from other &repmgr;
|
||||
actions in that it lso performs actions on another server (the demotion
|
||||
candidate), which means passwordless SSH access is required to that server
|
||||
from the one where <command>repmgr standby switchover</command> is executed.
|
||||
</para>
|
||||
<note>
|
||||
<simpara>
|
||||
<command>repmgr standby switchover</command> performs a relatively complex
|
||||
series of operations on two servers, and should therefore be performed after
|
||||
careful preparation and with adequate attention. In particular you should
|
||||
be confident that your network environment is stable and reliable.
|
||||
</simpara>
|
||||
<simpara>
|
||||
Additionally you should be sure that the current primary can be shut down
|
||||
quickly and cleanly. In particular, access from applications should be
|
||||
minimalized or preferably blocked completely. Also be aware that if there
|
||||
is a backlog of files waiting to be archived, PostgreSQL will not shut
|
||||
down until archiving completes.
|
||||
</simpara>
|
||||
<simpara>
|
||||
We recommend running <command>repmgr standby switchover</command> at the
|
||||
most verbose logging level (<literal>--log-level=DEBUG --verbose</literal>)
|
||||
and capturing all output to assist troubleshooting any problems.
|
||||
</simpara>
|
||||
<simpara>
|
||||
Please also read carefully the sections <xref linkend="preparing-for-switchover"> and
|
||||
`Caveats` below.
|
||||
</simpara>
|
||||
</note>
|
||||
|
||||
<sect1 id="preparing-for-switchover" xreflabel="Preparing for switchover">
|
||||
<indexterm>
|
||||
<primary>switchover</primary>
|
||||
<secondary>preparation</secondary>
|
||||
</indexterm>
|
||||
<title>Preparing for switchover</title>
|
||||
<para>
|
||||
As mentioned above, success of the switchover operation depends on &repmgr;
|
||||
being able to shut down the current primary server quickly and cleanly.
|
||||
</para>
|
||||
<para>
|
||||
Double-check which commands will be used to stop/start/restart the current
|
||||
primary; on the primary execute:
|
||||
<programlisting>
|
||||
repmgr -f /etc./repmgr.conf node service --list --action=stop
|
||||
repmgr -f /etc./repmgr.conf node service --list --action=start
|
||||
repmgr -f /etc./repmgr.conf node service --list --action=restart
|
||||
</programlisting>
|
||||
</para>
|
||||
<note>
|
||||
<simpara>
|
||||
On <literal>systemd</literal> systems we strongly recommend using the appropriate
|
||||
<command>systemctl</command> commands (typically run via <command>sudo</command>) to ensure
|
||||
<literal>systemd</literal> informed about the status of the PostgreSQL service.
|
||||
</simpara>
|
||||
</note>
|
||||
<para>
|
||||
Check that access from applications is minimalized or preferably blocked
|
||||
completely, so applications are not unexpectedly interrupted.
|
||||
</para>
|
||||
<para>
|
||||
Check there is no significant replication lag on standbys attached to the
|
||||
current primary.
|
||||
</para>
|
||||
<para>
|
||||
If WAL file archiving is set up, check that there is no backlog of files waiting
|
||||
to be archived, as PostgreSQL will not finally shut down until all these have been
|
||||
archived. If there is a backlog exceeding <varname>archive_ready_warning</varname> WAL files,
|
||||
`repmgr` will emit a warning before attempting to perform a switchover; you can also check
|
||||
manually with <command>repmgr node check --archive-ready</command>.
|
||||
</para>
|
||||
<para>
|
||||
Ensure that <command>repmgrd</command> is *not* running anywhere to prevent it unintentionally
|
||||
promoting a node.
|
||||
</para>
|
||||
<para>
|
||||
Finally, consider executing <command>repmgr standby switchover</command> with the
|
||||
<literal>--dry-run</literal> option; this will perform any necessary checks and inform you about
|
||||
success/failure, and stop before the first actual command is run (which would be the shutdown of the
|
||||
current primary). Example output:
|
||||
<programlisting>
|
||||
$ repmgr standby switchover -f /etc/repmgr.conf --siblings-follow --dry-run
|
||||
NOTICE: checking switchover on node "node2" (ID: 2) in --dry-run mode
|
||||
INFO: SSH connection to host "localhost" succeeded
|
||||
INFO: archive mode is "off"
|
||||
INFO: replication lag on this standby is 0 seconds
|
||||
INFO: all sibling nodes are reachable via SSH
|
||||
NOTICE: local node "node2" (ID: 2) will be promoted to primary; current primary "node1" (ID: 1) will be demoted to standby
|
||||
INFO: following shutdown command would be run on node "node1":
|
||||
"pg_ctl -l /var/log/postgresql/startup.log -D '/var/lib/postgresql/data' -m fast -W stop"
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="switchover-execution" xreflabel="Executing the switchover command">
|
||||
<indexterm>
|
||||
<primary>switchover</primary>
|
||||
<secondary>execution</secondary>
|
||||
</indexterm>
|
||||
<title>Executing the switchover command</title>
|
||||
<para>
|
||||
To demonstrate switchover, we will assume a replication cluster with a
|
||||
primary (<literal>node1</literal>) and one standby (<literal>node2</literal>);
|
||||
after the switchover <literal>node2</literal> should become the primary with
|
||||
<literal>node1</literal> following it.
|
||||
</para>
|
||||
<para>
|
||||
The switchover command must be run from the standby which is to be promoted,
|
||||
and in its simplest form looks like this:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf standby switchover
|
||||
NOTICE: executing switchover on node "node2" (ID: 2)
|
||||
INFO: searching for primary node
|
||||
INFO: checking if node 1 is primary
|
||||
INFO: current primary node is 1
|
||||
INFO: SSH connection to host "localhost" succeeded
|
||||
INFO: archive mode is "off"
|
||||
INFO: replication lag on this standby is 0 seconds
|
||||
NOTICE: local node "node2" (ID: 2) will be promoted to primary; current primary "node1" (ID: 1) will be demoted to standby
|
||||
NOTICE: stopping current primary node "node1" (ID: 1)
|
||||
NOTICE: issuing CHECKPOINT
|
||||
DETAIL: executing server command "pg_ctl -l /var/log/postgres/startup.log -D '/var/lib/pgsql/data' -m fast -W stop"
|
||||
INFO: checking primary status; 1 of 6 attempts
|
||||
NOTICE: current primary has been cleanly shut down at location 0/3001460
|
||||
NOTICE: promoting standby to primary
|
||||
DETAIL: promoting server "node2" (ID: 2) using "pg_ctl -l /var/log/postgres/startup.log -w -D '/var/lib/pgsql/data' promote"
|
||||
server promoting
|
||||
NOTICE: STANDBY PROMOTE successful
|
||||
DETAIL: server "node2" (ID: 2) was successfully promoted to primary
|
||||
INFO: setting node 1's primary to node 2
|
||||
NOTICE: starting server using "pg_ctl -l /var/log/postgres/startup.log -w -D '/var/lib/pgsql/data' restart"
|
||||
NOTICE: NODE REJOIN successful
|
||||
DETAIL: node 1 is now attached to node 2
|
||||
NOTICE: switchover was successful
|
||||
DETAIL: node "node2" is now primary
|
||||
NOTICE: STANDBY SWITCHOVER is complete
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The old primary is now replicating as a standby from the new primary, and the
|
||||
cluster status will now look like this:
|
||||
<programlisting>
|
||||
$ repmgr -f /etc/repmgr.conf cluster show
|
||||
ID | Name | Role | Status | Upstream | Location | Connection string
|
||||
----+-------+---------+-----------+----------+----------+--------------------------------------
|
||||
1 | node1 | standby | running | node2 | default | host=node1 dbname=repmgr user=repmgr
|
||||
2 | node2 | primary | * running | | default | host=node2 dbname=repmgr user=repmgr
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 id="switchover-caveats" xreflabel="Caveats">
|
||||
<indexterm>
|
||||
<primary>switchover</primary>
|
||||
<secondary>caveats</secondary>
|
||||
</indexterm>
|
||||
<title>Caveats</title>
|
||||
<para>
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
<listitem>
|
||||
<simpara>
|
||||
If using PostgreSQL 9.3 or 9.4, you should ensure that the shutdown command
|
||||
is configured to use PostgreSQL's <varname>fast</varname> shutdown mode (the default in 9.5
|
||||
and later). If relying on <command>pg_ctl</command> to perform database server operations,
|
||||
you should include <literal>-m fast</literal> in <varname>pg_ctl_options</varname>
|
||||
in <filename>repmgr.conf</filename>.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>
|
||||
<command>pg_rewind</command> *requires* that either <varname>wal_log_hints</varname> is enabled, or that
|
||||
data checksums were enabled when the cluster was initialized. See the
|
||||
<ulink url="https://www.postgresql.org/docs/current/static/app-pgrewind.html">pg_rewind documentation</ulink>
|
||||
for details.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>
|
||||
<command>repmgrd</command> should not be running with setting <varname>failover=automatic</varname>
|
||||
in <filename>repmgr.conf</filename> when a switchover is carried out, otherwise the
|
||||
<command>repmgrd</command> daemon may try and promote a standby by itself.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
We hope to remove some of these restrictions in future versions of `repmgr`.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
245
doc/upgrading-repmgr.sgml
Normal file
245
doc/upgrading-repmgr.sgml
Normal file
@@ -0,0 +1,245 @@
|
||||
<chapter id="upgrading-repmgr" xreflabel="Upgrading repmgr">
|
||||
<title>Upgrading repmgr</title>
|
||||
<para>
|
||||
&repmgr; is updated regularly with point releases (e.g. 4.0.1 to 4.0.2)
|
||||
containing bugfixes and other minor improvements. Any substantial new
|
||||
functionality will be included in a feature release (e.g. 4.0.x to 4.1.x).
|
||||
</para>
|
||||
<para>
|
||||
&repmgr; is implemented as a PostgreSQL extension; to upgrade it, first
|
||||
install the updated package (or compile the updated source), then in the
|
||||
database where the &repmgr; extension is installed, execute
|
||||
<command>ALTER EXTENSION repmgr UPDATE</command>.
|
||||
</para>
|
||||
<para>
|
||||
If <command>repmgrd</command> is running, it may be necessary to restart
|
||||
the PostgreSQL server if the upgrade contains changes to the shared object
|
||||
file used by <command>repmgrd</command>; check the release notes for details.
|
||||
</para>
|
||||
|
||||
<sect1 id="upgrading-from-repmgr-3">
|
||||
<title>Upgrading from repmgr 3</title>
|
||||
<para>
|
||||
The upgrade process consists of two steps:
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
converting the repmgr.conf configuration files
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>
|
||||
upgrading the repmgr schema
|
||||
</simpara>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
<para>
|
||||
A script is provided to assist with converting <filename>repmgr.conf</filename>.
|
||||
</para>
|
||||
<para>
|
||||
The schema upgrade (which converts the &repmgr; metadata into
|
||||
a packaged PostgreSQL extension) is normally carried out
|
||||
automatically when the &repmgr; extension is created.
|
||||
</para>
|
||||
<sect2 id="converting-repmgr-conf">
|
||||
<title>Converting repmgr.conf configuration files</title>
|
||||
<para>
|
||||
With a completely new repmgr version, we've taken the opportunity
|
||||
to rename some configuration items have had their names changed for
|
||||
clarity and consistency, both between the configuration file and
|
||||
the column names in <structname>repmgr.nodes</structname>
|
||||
(e.g. <varname>node</varname> to <varname>node_id</varname>), and
|
||||
also for consistency with PostgreSQL naming conventions
|
||||
(e.g. <varname>loglevel</varname> to <varname>log_level</varname>).
|
||||
</para>
|
||||
<para>
|
||||
Other configuration items have been changed to command line options,
|
||||
and vice-versa, e.g. to avoid hard-coding items such as a a node's
|
||||
upstream ID, which might change over time.
|
||||
</para>
|
||||
<para>
|
||||
&repmgr; will issue a warning about deprecated/altered options.
|
||||
</para>
|
||||
<sect3>
|
||||
<title>Changed parameters in "repmgr.conf"</title>
|
||||
<para>
|
||||
Following parameters have been added:
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
<listitem>
|
||||
<simpara><varname>data_directory</varname>: this is mandatory and must
|
||||
contain the path to the node's data directory</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><varname>monitoring_history</varname>: this replaces the
|
||||
<command>repmgrd</command> command line option
|
||||
<literal>--monitoring-history</literal></simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
Following parameters have been renamed:
|
||||
</para>
|
||||
<table tocentry="1" id="repmgr3-repmgr4-renamed-parameters">
|
||||
<title>Parameters renamed in repmgr4</title>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>repmgr3</entry>
|
||||
<entry>repmgr4</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><varname>node</varname></entry>
|
||||
<entry><varname>node_id</varname></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><varname>loglevel</varname></entry>
|
||||
<entry><varname>log_level</varname></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><varname>logfacility</varname></entry>
|
||||
<entry><varname>log_facility</varname></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><varname>logfile</varname></entry>
|
||||
<entry><varname>log_file</varname></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><varname>master_reponse_timeout</varname></entry>
|
||||
<entry><varname>async_query_timeout</varname></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<para>
|
||||
Following parameters have been removed:
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
<listitem>
|
||||
<simpara><varname>cluster</varname>: is no longer required and will
|
||||
be ignored.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><varname>upstream_node_id</varname>: is replaced by the
|
||||
command-line parameter <literal>--upstream-node-id</literal></simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect3>
|
||||
<sect3>
|
||||
<title>Conversion script</title>
|
||||
<para>
|
||||
To assist with conversion of <filename>repmgr.conf</filename> files, a Perl script
|
||||
is provided in <filename>contrib/convert-config.pl</filename>.
|
||||
Use like this:
|
||||
<programlisting>
|
||||
$ ./convert-config.pl /etc/repmgr.conf
|
||||
node_id=2
|
||||
node_name=node2
|
||||
conninfo=host=localhost dbname=repmgr user=repmgr connect_timeout=2
|
||||
pg_ctl_options='-l /var/log/postgres/startup.log'
|
||||
rsync_options=--exclude=postgresql.local.conf --archive
|
||||
log_level=INFO
|
||||
pg_basebackup_options=--no-slot
|
||||
data_directory=</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The converted file is printed to <literal>STDOUT</literal> and the original file is not
|
||||
changed.
|
||||
</para>
|
||||
<para>
|
||||
Please note that the parameter <varname>data_directory</varname> <emphasis>must</emphasis>
|
||||
be provided; if not already present, the conversion script will add an empty
|
||||
placeholder parameter.
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Upgrading the repmgr schema</title>
|
||||
<para>
|
||||
Ensure <command>repmgrd</command> is not running, or any cron jobs which execute the
|
||||
<command>repmgr</command> binary.
|
||||
</para>
|
||||
<para>
|
||||
Install <literal>repmgr4</literal>; any <literal>repmgr3</literal> packages should be uninstalled
|
||||
(if not automatically uninstalled already).
|
||||
</para>
|
||||
<sect3>
|
||||
<title>Upgrading from repmgr 3.1.1 or earlier</title>
|
||||
<para>
|
||||
If your repmgr version is 3.1.1 or earlier, you will need to update
|
||||
the schema to the latest version in the 3.x series (3.3.2) before
|
||||
converting the installation to repmgr 4.
|
||||
</para>
|
||||
<para>
|
||||
To do this, apply the following upgrade scripts as appropriate for
|
||||
your current version:
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
<listitem>
|
||||
<simpara>
|
||||
<ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/REL3_3_STABLE/sql/repmgr3.0_repmgr3.1.sql">repmgr3.0_repmgr3.1.sql</ulink></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/REL3_3_STABLE/sql/repmgr3.1.1_repmgr3.1.2.sql">repmgr3.1.1_repmgr3.1.2.sql</ulink></simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
For more details see the
|
||||
<ulink url="https://repmgr.org/release-notes-3.3.2.html#upgrading">repmgr 3 upgrade notes</ulink>.
|
||||
</para>
|
||||
</sect3>
|
||||
<sect3>
|
||||
<title>Manually create the repmgr extension</title>
|
||||
<para>
|
||||
In the database used by the existing &repmgr; installation, execute:
|
||||
<programlisting>
|
||||
CREATE EXTENSION repmgr FROM unpackaged;</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
This will move and convert all objects from the existing schema
|
||||
into the new, standard <literal>repmgr</literal> schema.
|
||||
</para>
|
||||
<note>
|
||||
<simpara>there must be only one schema matching <literal>repmgr_%</literal> in the
|
||||
database, otherwise this step may not work.</simpara>
|
||||
</note>
|
||||
</sect3>
|
||||
<sect3>
|
||||
<title>Re-register each node</title>
|
||||
<para>
|
||||
This is necessary to update the <literal>repmgr</literal> metadata with some additional items.
|
||||
</para>
|
||||
<para>
|
||||
On the primary node, execute e.g.
|
||||
<programlisting>
|
||||
repmgr primary register -f /etc/repmgr.conf --force</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
On each standby node, execute e.g.
|
||||
<programlisting>
|
||||
repmgr standby register -f /etc/repmgr.conf --force</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Check the data is updated as expected by examining the <structname>repmgr.nodes</structname>
|
||||
table; restart <command>repmgrd</command> if required.
|
||||
</para>
|
||||
<para>
|
||||
The original <literal>repmgr_$cluster</literal> schema can be dropped at any time.
|
||||
</para>
|
||||
<tip>
|
||||
<simpara>
|
||||
If you don't care about any data from the existing &repmgr; installation,
|
||||
(e.g. the contents of the <structname>events</structname> and <structname>monitoring</structname>
|
||||
tables), the manual <command>CREATE EXTENSION</command> step can be skipped; just re-register
|
||||
each node, starting with the primary node, and the <literal>repmgr</literal> extension will be
|
||||
automatically created.
|
||||
</simpara>
|
||||
</tip>
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
1
doc/version.sgml
Normal file
1
doc/version.sgml
Normal file
@@ -0,0 +1 @@
|
||||
<!ENTITY repmgrversion "4.0dev">
|
||||
469
doc/website-docs.css
Normal file
469
doc/website-docs.css
Normal file
@@ -0,0 +1,469 @@
|
||||
/* PostgreSQL.org Documentation Style */
|
||||
|
||||
/* requires global.css, table.css and text.css to be loaded before this file! */
|
||||
body {
|
||||
font-family: verdana, sans-serif;
|
||||
font-size: 76%;
|
||||
background: url("/resources/background.png") repeat-x scroll left top transparent;
|
||||
padding: 15px 4%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* monospace font size fix */
|
||||
pre, code, kbd, samp, tt {
|
||||
font-family: monospace,monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.NAVHEADER table {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
/* Container Definitions */
|
||||
|
||||
#docContainerWrap {
|
||||
text-align: center; /* Win IE5 */
|
||||
}
|
||||
|
||||
#docContainer {
|
||||
margin: 0 auto;
|
||||
width: 90%;
|
||||
padding-bottom: 2em;
|
||||
display: block;
|
||||
text-align: left; /* Win IE5 */
|
||||
}
|
||||
|
||||
#docHeader {
|
||||
background-image: url("/media/img/docs/bg_hdr.png");
|
||||
height: 83px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#docHeaderLogo {
|
||||
position: relative;
|
||||
width: 206px;
|
||||
height: 83px;
|
||||
border: 0px;
|
||||
padding: 0px;
|
||||
margin: 0 0 0 20px;
|
||||
}
|
||||
|
||||
#docHeaderLogo img {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
#docNavSearchContainer {
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
#docNav, #docVersions {
|
||||
position: relative;
|
||||
text-align: left;
|
||||
margin-left: 10px;
|
||||
margin-top: 5px;
|
||||
color: #666;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
#docSearch {
|
||||
position: relative;
|
||||
text-align: right;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#docTextSize {
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
margin-top: 7px;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
#docSearch form {
|
||||
position: relative;
|
||||
top: 5px;
|
||||
right: 0;
|
||||
margin: 0; /* need for IE 5.5 OSX */
|
||||
text-align: right; /* need for IE 5.5 OSX */
|
||||
white-space: nowrap; /* for Opera */
|
||||
}
|
||||
|
||||
#docSearch form label {
|
||||
color: #666;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
#docSearch form input {
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
#docSearch form #submit {
|
||||
font-size: 0.95em;
|
||||
background: #7A7A7A;
|
||||
color: #fff;
|
||||
border: 1px solid #7A7A7A;
|
||||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
#docSearch form #q {
|
||||
width: 170px;
|
||||
font-size: 0.95em;
|
||||
border: 1px solid #7A7A7A;
|
||||
background: #E1E1E1;
|
||||
color: #000000;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.frmDocSearch {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.inpDocSearch {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#docContent {
|
||||
position: relative;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
#docFooter {
|
||||
position: relative;
|
||||
font-size: 0.9em;
|
||||
color: #666;
|
||||
line-height: 1.3em;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#docComments {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#docClear {
|
||||
clear: both;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Heading Definitions */
|
||||
|
||||
h1, h2, h3 {
|
||||
font-weight: bold;
|
||||
margin-top: 2ex;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.2em !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
h1 a:hover,
|
||||
h2 a:hover,
|
||||
h3 a:hover,
|
||||
h4 a:hover {
|
||||
color: #444;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Text Styles */
|
||||
|
||||
div.SECT2 {
|
||||
margin-top: 4ex;
|
||||
}
|
||||
|
||||
div.SECT3 {
|
||||
margin-top: 3ex;
|
||||
margin-left: 3ex;
|
||||
}
|
||||
|
||||
.txtCurrentLocation {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p, ol, ul, li {
|
||||
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;
|
||||
}
|
||||
@@ -1,25 +1,2 @@
|
||||
/*
|
||||
* repmgr_version.h
|
||||
* Copyright (c) 2ndQuadrant, 2010-2017
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _VERSION_H_
|
||||
#define _VERSION_H_
|
||||
|
||||
#define REPMGR_VERSION_DATE ""
|
||||
#define REPMGR_VERSION "4.0dev"
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user