mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-22 22:56:29 +00:00
Rename some "repmgr daemon ..." commands to "repmgr service ..."
"repmgr daemon" can be interpreted to mean the commands affect the local daemon process only. Rename the commands which affect the entire cluster to "repmgr service ...". The "repmgr daemon ..." form of the affected commands is retained for backwards compatibility.
This commit is contained in:
3
HISTORY
3
HISTORY
@@ -1,6 +1,7 @@
|
|||||||
5.0 2019-??-??
|
5.0 2019-??-??
|
||||||
general: add PostgreSQL 12 support (Ian)
|
general: add PostgreSQL 12 support (Ian)
|
||||||
general: parse configuration file using flex (Ian)
|
general: parse configuration file using flex (Ian)
|
||||||
|
repmgr: rename "repmgr daemon ..." commands to "repmgr service ..." (Ian)
|
||||||
|
|
||||||
4.4.1 2019-??-??
|
4.4.1 2019-??-??
|
||||||
repmgr: improve data directory check (Ian)
|
repmgr: improve data directory check (Ian)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ $(info Building against PostgreSQL $(MAJORVERSION))
|
|||||||
|
|
||||||
REPMGR_CLIENT_OBJS = repmgr-client.o \
|
REPMGR_CLIENT_OBJS = repmgr-client.o \
|
||||||
repmgr-action-primary.o repmgr-action-standby.o repmgr-action-witness.o \
|
repmgr-action-primary.o repmgr-action-standby.o repmgr-action-witness.o \
|
||||||
repmgr-action-bdr.o repmgr-action-cluster.o repmgr-action-node.o repmgr-action-daemon.o \
|
repmgr-action-bdr.o repmgr-action-cluster.o repmgr-action-node.o repmgr-action-service.o repmgr-action-daemon.o \
|
||||||
configfile.o configfile-scan.o log.o strutil.o controldata.o dirutil.o compat.o dbutils.o sysutils.o
|
configfile.o configfile-scan.o log.o strutil.o controldata.o dirutil.o compat.o dbutils.o sysutils.o
|
||||||
REPMGRD_OBJS = repmgrd.o repmgrd-physical.o repmgrd-bdr.o configfile.o configfile-scan.o log.o dbutils.o strutil.o controldata.o compat.o sysutils.o
|
REPMGRD_OBJS = repmgrd.o repmgrd-physical.o repmgrd-bdr.o configfile.o configfile-scan.o log.o dbutils.o strutil.o controldata.o compat.o sysutils.o
|
||||||
DATE=$(shell date "+%Y-%m-%d")
|
DATE=$(shell date "+%Y-%m-%d")
|
||||||
|
|||||||
768
daemon-start-stop.patch
Normal file
768
daemon-start-stop.patch
Normal file
@@ -0,0 +1,768 @@
|
|||||||
|
diff --git a/Makefile.in b/Makefile.in
|
||||||
|
index 2700a78..108bfe8 100644
|
||||||
|
--- a/Makefile.in
|
||||||
|
+++ b/Makefile.in
|
||||||
|
@@ -53,7 +53,7 @@ $(info Building against PostgreSQL $(MAJORVERSION))
|
||||||
|
|
||||||
|
REPMGR_CLIENT_OBJS = repmgr-client.o \
|
||||||
|
repmgr-action-primary.o repmgr-action-standby.o repmgr-action-witness.o \
|
||||||
|
- repmgr-action-bdr.o repmgr-action-cluster.o repmgr-action-node.o repmgr-action-service.o \
|
||||||
|
+ repmgr-action-bdr.o repmgr-action-cluster.o repmgr-action-node.o repmgr-action-service.o repmgr-action-daemon.o \
|
||||||
|
configfile.o configfile-scan.o log.o strutil.o controldata.o dirutil.o compat.o dbutils.o sysutils.o
|
||||||
|
REPMGRD_OBJS = repmgrd.o repmgrd-physical.o repmgrd-bdr.o configfile.o configfile-scan.o log.o dbutils.o strutil.o controldata.o compat.o sysutils.o
|
||||||
|
DATE=$(shell date "+%Y-%m-%d")
|
||||||
|
diff --git a/doc/appendix-release-notes.xml b/doc/appendix-release-notes.xml
|
||||||
|
index 93e5a8c..e5fe4e0 100644
|
||||||
|
--- a/doc/appendix-release-notes.xml
|
||||||
|
+++ b/doc/appendix-release-notes.xml
|
||||||
|
@@ -24,12 +24,9 @@
|
||||||
|
<sect2>
|
||||||
|
<title>Compatibility changes</title>
|
||||||
|
<para>
|
||||||
|
- The <command>repmgr daemon ...</command> commands have been renamed to
|
||||||
|
- <command>repmgr service ...</command>.
|
||||||
|
- </para>
|
||||||
|
- <para>
|
||||||
|
- The <command>repmgr daemon ...</command> form will still be accepted
|
||||||
|
- for backwards compatibility.
|
||||||
|
+ Some <command>repmgr daemon ...</command> commands have been renamed to
|
||||||
|
+ <command>repmgr service ...</command> as they have a cluster-wide effect
|
||||||
|
+ and to avoid giving the impression they affect only the local &repmgr; daemon.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Following commands are affected:
|
||||||
|
@@ -57,22 +54,13 @@
|
||||||
|
</simpara>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
- <listitem>
|
||||||
|
- <simpara>
|
||||||
|
- <command>repmgr daemon start</command>
|
||||||
|
- (now <link linkend="repmgr-service-start"><command>repmgr service start</command></link>)
|
||||||
|
- </simpara>
|
||||||
|
- </listitem>
|
||||||
|
-
|
||||||
|
- <listitem>
|
||||||
|
- <simpara>
|
||||||
|
- <command>repmgr daemon stop</command>
|
||||||
|
- (now <link linkend="repmgr-service-stop"><command>repmgr service stop</command></link>)
|
||||||
|
- </simpara>
|
||||||
|
- </listitem>
|
||||||
|
-
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
+ <para>
|
||||||
|
+ The <command>repmgr daemon ...</command> form will still be accepted
|
||||||
|
+ for backwards compatibility.
|
||||||
|
+ </para>
|
||||||
|
+
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The following command line options, which have been deprecated since &repmgr; 3.3
|
||||||
|
@@ -497,8 +485,8 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
- New commands <link linkend="repmgr-service-start"><command>repmgr daemon start</command></link> and
|
||||||
|
- <link linkend="repmgr-service-stop"><command>repmgr daemon stop</command></link>:
|
||||||
|
+ New commands <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> and
|
||||||
|
+ <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link>:
|
||||||
|
these provide a standardized way of starting and stopping &repmgrd;.
|
||||||
|
GitHub #528.
|
||||||
|
</para>
|
||||||
|
diff --git a/doc/filelist.xml b/doc/filelist.xml
|
||||||
|
index e59e35d..b2bb157 100644
|
||||||
|
--- a/doc/filelist.xml
|
||||||
|
+++ b/doc/filelist.xml
|
||||||
|
@@ -55,10 +55,10 @@
|
||||||
|
<!ENTITY repmgr-cluster-event SYSTEM "repmgr-cluster-event.xml">
|
||||||
|
<!ENTITY repmgr-cluster-cleanup SYSTEM "repmgr-cluster-cleanup.xml">
|
||||||
|
<!ENTITY repmgr-service-status SYSTEM "repmgr-service-status.xml">
|
||||||
|
-<!ENTITY repmgr-service-start SYSTEM "repmgr-service-start.xml">
|
||||||
|
-<!ENTITY repmgr-service-stop SYSTEM "repmgr-service-stop.xml">
|
||||||
|
<!ENTITY repmgr-service-pause SYSTEM "repmgr-service-pause.xml">
|
||||||
|
<!ENTITY repmgr-service-unpause SYSTEM "repmgr-service-unpause.xml">
|
||||||
|
+<!ENTITY repmgr-daemon-start SYSTEM "repmgr-daemon-start.xml">
|
||||||
|
+<!ENTITY repmgr-daemon-stop SYSTEM "repmgr-daemon-stop.xml">
|
||||||
|
|
||||||
|
<!ENTITY appendix-release-notes SYSTEM "appendix-release-notes.xml">
|
||||||
|
<!ENTITY appendix-faq SYSTEM "appendix-faq.xml">
|
||||||
|
diff --git a/doc/repmgr-daemon-start.xml b/doc/repmgr-daemon-start.xml
|
||||||
|
index ae5e21f..fb0eb6d 100644
|
||||||
|
--- a/doc/repmgr-daemon-start.xml
|
||||||
|
+++ b/doc/repmgr-daemon-start.xml
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
-<refentry id="repmgr-service-start">
|
||||||
|
+<refentry id="repmgr-daemon-start">
|
||||||
|
<indexterm>
|
||||||
|
- <primary>repmgr service start</primary>
|
||||||
|
+ <primary>repmgr daemon start</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<indexterm>
|
||||||
|
@@ -9,11 +9,11 @@
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
- <refentrytitle>repmgr service start</refentrytitle>
|
||||||
|
+ <refentrytitle>repmgr daemon start</refentrytitle>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
- <refname>repmgr service start</refname>
|
||||||
|
+ <refname>repmgr daemon start</refname>
|
||||||
|
<refpurpose>Start the &repmgrd; service</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
@@ -32,8 +32,8 @@
|
||||||
|
<important>
|
||||||
|
<para>
|
||||||
|
The <filename>repmgr.conf</filename> parameter <varname>repmgrd_service_start_command</varname>
|
||||||
|
- must be set for <command>repmgr service start</command> to work; see section
|
||||||
|
- <xref linkend="repmgr-service-start-configuration"/> for details.
|
||||||
|
+ must be set for <command>repmgr daemon start</command> to work; see section
|
||||||
|
+ <xref linkend="repmgr-daemon-start-configuration"/> for details.
|
||||||
|
</para>
|
||||||
|
</important>
|
||||||
|
</refsect1>
|
||||||
|
@@ -89,11 +89,11 @@
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
- <refsect1 id="repmgr-service-start-configuration" xreflabel="repmgr service start configuration">
|
||||||
|
+ <refsect1 id="repmgr-daemon-start-configuration" xreflabel="repmgr daemon start configuration">
|
||||||
|
<title>Configuration file settings</title>
|
||||||
|
<para>
|
||||||
|
The following parameter in <filename>repmgr.conf</filename> is relevant
|
||||||
|
- to <command>repmgr service start</command>:
|
||||||
|
+ to <command>repmgr daemon start</command>:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
@@ -104,11 +104,11 @@
|
||||||
|
<listitem>
|
||||||
|
<indexterm>
|
||||||
|
<primary>repmgrd_service_start_command</primary>
|
||||||
|
- <secondary>with "repmgr service start"</secondary>
|
||||||
|
+ <secondary>with "repmgr daemon start"</secondary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
- <command>repmgr service start</command> will execute the command defined by the
|
||||||
|
+ <command>repmgr daemon start</command> will execute the command defined by the
|
||||||
|
<varname>repmgrd_service_start_command</varname> parameter in <filename>repmgr.conf</filename>.
|
||||||
|
This must be set to a shell command which will start &repmgrd;;
|
||||||
|
if &repmgr; was installed from a package, this will be the service command defined by the
|
||||||
|
@@ -132,7 +132,7 @@
|
||||||
|
<refsect1>
|
||||||
|
<title>Exit codes</title>
|
||||||
|
<para>
|
||||||
|
- One of the following exit codes will be emitted by <command>repmgr service start</command>:
|
||||||
|
+ One of the following exit codes will be emitted by <command>repmgr daemon start</command>:
|
||||||
|
</para>
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
@@ -197,7 +197,7 @@
|
||||||
|
<refsect1>
|
||||||
|
<title>See also</title>
|
||||||
|
<para>
|
||||||
|
- <xref linkend="repmgr-service-stop"/>, <xref linkend="repmgr-service-status"/>, <xref linkend="repmgrd-daemon"/>
|
||||||
|
+ <xref linkend="repmgr-daemon-stop"/>, <xref linkend="repmgrd-daemon"/>, <xref linkend="repmgr-service-status"/>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
diff --git a/doc/repmgr-daemon-stop.xml b/doc/repmgr-daemon-stop.xml
|
||||||
|
index dc93856..2304201 100644
|
||||||
|
--- a/doc/repmgr-daemon-stop.xml
|
||||||
|
+++ b/doc/repmgr-daemon-stop.xml
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-<refentry id="repmgr-service-stop">
|
||||||
|
+<refentry id="repmgr-daemon-stop">
|
||||||
|
<indexterm>
|
||||||
|
<primary>repmgr daemon stop</primary>
|
||||||
|
</indexterm>
|
||||||
|
@@ -40,7 +40,7 @@
|
||||||
|
<para>
|
||||||
|
The <filename>repmgr.conf</filename> parameter <varname>repmgrd_service_stop_command</varname>
|
||||||
|
must be set for <command>repmgr daemon stop</command> to work; see section
|
||||||
|
- <xref linkend="repmgr-service-stop-configuration"/> for details.
|
||||||
|
+ <xref linkend="repmgr-daemon-stop-configuration"/> for details.
|
||||||
|
</para>
|
||||||
|
</important>
|
||||||
|
</refsect1>
|
||||||
|
@@ -114,7 +114,7 @@
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
- <refsect1 id="repmgr-service-stop-configuration" xreflabel="repmgr daemon stop configuration">
|
||||||
|
+ <refsect1 id="repmgr-daemon-stop-configuration" xreflabel="repmgr daemon stop configuration">
|
||||||
|
<title>Configuration file settings</title>
|
||||||
|
<para>
|
||||||
|
The following parameter in <filename>repmgr.conf</filename> is relevant
|
||||||
|
@@ -194,7 +194,7 @@
|
||||||
|
<refsect1>
|
||||||
|
<title>See also</title>
|
||||||
|
<para>
|
||||||
|
- <xref linkend="repmgr-service-start"/>, <xref linkend="repmgr-service-status"/>, <xref linkend="repmgrd-daemon"/>
|
||||||
|
+ <xref linkend="repmgr-daemon-start"/>, <xref linkend="repmgrd-daemon"/>, <xref linkend="repmgr-service-status"/>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
diff --git a/doc/repmgr.xml b/doc/repmgr.xml
|
||||||
|
index d3dc3b7..5de1178 100644
|
||||||
|
--- a/doc/repmgr.xml
|
||||||
|
+++ b/doc/repmgr.xml
|
||||||
|
@@ -117,10 +117,10 @@
|
||||||
|
&repmgr-cluster-event;
|
||||||
|
&repmgr-cluster-cleanup;
|
||||||
|
&repmgr-service-status;
|
||||||
|
- &repmgr-service-start;
|
||||||
|
- &repmgr-service-stop;
|
||||||
|
&repmgr-service-pause;
|
||||||
|
&repmgr-service-unpause;
|
||||||
|
+ &repmgr-daemon-start;
|
||||||
|
+ &repmgr-daemon-stop;
|
||||||
|
</part>
|
||||||
|
|
||||||
|
&appendix-release-notes;
|
||||||
|
diff --git a/doc/repmgrd-configuration.xml b/doc/repmgrd-configuration.xml
|
||||||
|
index d674e4e..dd28650 100644
|
||||||
|
--- a/doc/repmgrd-configuration.xml
|
||||||
|
+++ b/doc/repmgrd-configuration.xml
|
||||||
|
@@ -518,10 +518,8 @@
|
||||||
|
<secondary>repmgrd service configuration</secondary>
|
||||||
|
</indexterm>
|
||||||
|
<para>
|
||||||
|
- If you are intending to use the <link linkend="repmgr-service-start"><command>repmgr service start</command></link>
|
||||||
|
- and <link linkend="repmgr-service-stop"><command>repmgr service stop</command></link>
|
||||||
|
- (&repmgr; 4.2 - 4.4: <link linkend="repmgr-service-start"><command>repmgr daemon start</command></link>
|
||||||
|
- and <link linkend="repmgr-service-stop"><command>repmgr daemon stop</command></link>)
|
||||||
|
+ If you are intending to use the <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link>
|
||||||
|
+ and <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link>
|
||||||
|
commands, the following
|
||||||
|
parameters <emphasis>must</emphasis> be set in <filename>repmgr.conf</filename>:
|
||||||
|
<itemizedlist spacing="compact" mark="bullet">
|
||||||
|
@@ -861,14 +859,14 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
|
||||||
|
for different distributions.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
- The commands <link linkend="repmgr-service-start"><command>repmgr service start</command></link> and
|
||||||
|
- <link linkend="repmgr-service-stop"><command>repmgr service stop</command></link> can be used
|
||||||
|
+ The commands <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> and
|
||||||
|
+ <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> can be used
|
||||||
|
as convenience wrappers to start and stop &repmgrd; on the local node.
|
||||||
|
</para>
|
||||||
|
<important>
|
||||||
|
<para>
|
||||||
|
- <link linkend="repmgr-service-start"><command>repmgr daemon start</command></link> and
|
||||||
|
- <link linkend="repmgr-service-stop"><command>repmgr daemon stop</command></link> require
|
||||||
|
+ <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> and
|
||||||
|
+ <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> require
|
||||||
|
that the appropriate start/stop commands are configured as
|
||||||
|
<varname>repmgrd_service_start_command</varname> and <varname>repmgrd_service_stop_command</varname>
|
||||||
|
in <filename>repmgr.conf</filename>.
|
||||||
|
diff --git a/repmgr-action-service.c b/repmgr-action-service.c
|
||||||
|
index 74941be..2e29e30 100644
|
||||||
|
--- a/repmgr-action-service.c
|
||||||
|
+++ b/repmgr-action-service.c
|
||||||
|
@@ -26,9 +26,6 @@
|
||||||
|
#include "repmgr-client-global.h"
|
||||||
|
#include "repmgr-action-service.h"
|
||||||
|
|
||||||
|
-#define REPMGR_SERVICE_STOP_START_WAIT 15
|
||||||
|
-#define REPMGR_SERVICE_STATUS_START_HINT _("use \"repmgr service status\" to confirm that repmgrd was successfully started")
|
||||||
|
-#define REPMGR_SERVICE_STATUS_STOP_HINT _("use \"repmgr service status\" to confirm that repmgrd was successfully stopped")
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Possibly also show:
|
||||||
|
@@ -499,284 +496,6 @@ fetch_node_records(PGconn *conn, NodeInfoList *node_list)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-void
|
||||||
|
-do_service_start(void)
|
||||||
|
-{
|
||||||
|
- PGconn *conn = NULL;
|
||||||
|
- PQExpBufferData repmgrd_command;
|
||||||
|
- PQExpBufferData output_buf;
|
||||||
|
- bool success;
|
||||||
|
-
|
||||||
|
- if (config_file_options.repmgrd_service_start_command[0] == '\0')
|
||||||
|
- {
|
||||||
|
- log_error(_("\"repmgrd_service_start_command\" is not set"));
|
||||||
|
- log_hint(_("set \"repmgrd_service_start_command\" in \"repmgr.conf\""));
|
||||||
|
- exit(ERR_BAD_CONFIG);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- log_verbose(LOG_INFO, _("connecting to local node"));
|
||||||
|
-
|
||||||
|
- conn = establish_db_connection(config_file_options.conninfo, false);
|
||||||
|
-
|
||||||
|
- if (PQstatus(conn) != CONNECTION_OK)
|
||||||
|
- {
|
||||||
|
- /* TODO: if PostgreSQL is not available, have repmgrd loop and retry connection */
|
||||||
|
- log_error(_("unable to connect to local node"));
|
||||||
|
- log_detail(_("PostgreSQL must be running before \"repmgrd\" can be started"));
|
||||||
|
- exit(ERR_DB_CONN);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * if local connection available, check if repmgr.so is installed, and
|
||||||
|
- * whether repmgrd is running
|
||||||
|
- */
|
||||||
|
- check_shared_library(conn);
|
||||||
|
-
|
||||||
|
- if (is_repmgrd_running(conn) == true)
|
||||||
|
- {
|
||||||
|
- pid_t pid = UNKNOWN_PID;
|
||||||
|
-
|
||||||
|
- log_error(_("repmgrd appears to be running already"));
|
||||||
|
-
|
||||||
|
- pid = repmgrd_get_pid(conn);
|
||||||
|
-
|
||||||
|
- if (pid != UNKNOWN_PID)
|
||||||
|
- log_detail(_("repmgrd PID is %i"), pid);
|
||||||
|
- else
|
||||||
|
- log_warning(_("unable to determine repmgrd PID"));
|
||||||
|
-
|
||||||
|
- PQfinish(conn);
|
||||||
|
- exit(ERR_REPMGRD_SERVICE);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- PQfinish(conn);
|
||||||
|
-
|
||||||
|
-
|
||||||
|
- initPQExpBuffer(&repmgrd_command);
|
||||||
|
- appendPQExpBufferStr(&repmgrd_command,
|
||||||
|
- config_file_options.repmgrd_service_start_command);
|
||||||
|
-
|
||||||
|
- if (runtime_options.dry_run == true)
|
||||||
|
- {
|
||||||
|
- log_info(_("prerequisites for starting repmgrd met"));
|
||||||
|
- log_detail("following command would be executed:\n %s", repmgrd_command.data);
|
||||||
|
- exit(SUCCESS);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- log_notice(_("executing: \"%s\""), repmgrd_command.data);
|
||||||
|
-
|
||||||
|
- initPQExpBuffer(&output_buf);
|
||||||
|
-
|
||||||
|
- success = local_command(repmgrd_command.data, &output_buf);
|
||||||
|
- termPQExpBuffer(&repmgrd_command);
|
||||||
|
-
|
||||||
|
- if (success == false)
|
||||||
|
- {
|
||||||
|
- log_error(_("unable to start repmgrd"));
|
||||||
|
- if (output_buf.data[0] != '\0')
|
||||||
|
- log_detail("%s", output_buf.data);
|
||||||
|
- termPQExpBuffer(&output_buf);
|
||||||
|
- exit(ERR_REPMGRD_SERVICE);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- termPQExpBuffer(&output_buf);
|
||||||
|
-
|
||||||
|
- if (runtime_options.no_wait == true || runtime_options.wait == 0)
|
||||||
|
- {
|
||||||
|
- log_hint(REPMGR_SERVICE_STATUS_START_HINT);
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- int i = 0;
|
||||||
|
- int timeout = REPMGR_SERVICE_STOP_START_WAIT;
|
||||||
|
-
|
||||||
|
- if (runtime_options.wait_provided)
|
||||||
|
- timeout = runtime_options.wait;
|
||||||
|
-
|
||||||
|
- conn = establish_db_connection(config_file_options.conninfo, false);
|
||||||
|
-
|
||||||
|
- if (PQstatus(conn) != CONNECTION_OK)
|
||||||
|
- {
|
||||||
|
- log_notice(_("unable to connect to local node"));
|
||||||
|
- log_hint(REPMGR_SERVICE_STATUS_START_HINT);
|
||||||
|
- exit(ERR_DB_CONN);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- for (;;)
|
||||||
|
- {
|
||||||
|
- if (is_repmgrd_running(conn) == true)
|
||||||
|
- {
|
||||||
|
- log_notice(_("repmgrd was successfully started"));
|
||||||
|
- PQfinish(conn);
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (i == timeout)
|
||||||
|
- {
|
||||||
|
- PQfinish(conn);
|
||||||
|
- log_error(_("repmgrd does not appear to have started after %i seconds"),
|
||||||
|
- timeout);
|
||||||
|
- log_hint(REPMGR_SERVICE_STATUS_START_HINT);
|
||||||
|
- exit(ERR_REPMGRD_SERVICE);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- log_debug("sleeping 1 second; %i of %i attempts to determine if repmgrd is running",
|
||||||
|
- i, runtime_options.wait);
|
||||||
|
- sleep(1);
|
||||||
|
- i++;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-void do_service_stop(void)
|
||||||
|
-{
|
||||||
|
- PGconn *conn = NULL;
|
||||||
|
- PQExpBufferData repmgrd_command;
|
||||||
|
- PQExpBufferData output_buf;
|
||||||
|
- bool success;
|
||||||
|
- bool have_db_connection = true;
|
||||||
|
- pid_t pid = UNKNOWN_PID;
|
||||||
|
-
|
||||||
|
- if (config_file_options.repmgrd_service_stop_command[0] == '\0')
|
||||||
|
- {
|
||||||
|
- log_error(_("\"repmgrd_service_stop_command\" is not set"));
|
||||||
|
- log_hint(_("set \"repmgrd_service_stop_command\" in \"repmgr.conf\""));
|
||||||
|
- exit(ERR_BAD_CONFIG);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * if local connection available, check if repmgr.so is installed, and
|
||||||
|
- * whether repmgrd is running
|
||||||
|
- */
|
||||||
|
- log_verbose(LOG_INFO, _("connecting to local node"));
|
||||||
|
-
|
||||||
|
- conn = establish_db_connection(config_file_options.conninfo, false);
|
||||||
|
-
|
||||||
|
- if (PQstatus(conn) != CONNECTION_OK)
|
||||||
|
- {
|
||||||
|
- /*
|
||||||
|
- * a PostgreSQL connection is not required to stop repmgrd,
|
||||||
|
- */
|
||||||
|
- log_warning(_("unable to connect to local node"));
|
||||||
|
- have_db_connection = false;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- check_shared_library(conn);
|
||||||
|
-
|
||||||
|
- if (is_repmgrd_running(conn) == false)
|
||||||
|
- {
|
||||||
|
- log_error(_("repmgrd appears to be stopped already"));
|
||||||
|
- PQfinish(conn);
|
||||||
|
- exit(ERR_REPMGRD_SERVICE);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Attempt to fetch the PID, in case we need it later */
|
||||||
|
- pid = repmgrd_get_pid(conn);
|
||||||
|
- log_debug("retrieved pid is %i", pid);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- PQfinish(conn);
|
||||||
|
-
|
||||||
|
- initPQExpBuffer(&repmgrd_command);
|
||||||
|
-
|
||||||
|
- appendPQExpBufferStr(&repmgrd_command,
|
||||||
|
- config_file_options.repmgrd_service_stop_command);
|
||||||
|
-
|
||||||
|
- if (runtime_options.dry_run == true)
|
||||||
|
- {
|
||||||
|
- log_info(_("prerequisites for stopping repmgrd met"));
|
||||||
|
- log_detail("following command would be executed:\n %s", repmgrd_command.data);
|
||||||
|
- exit(SUCCESS);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- log_notice(_("executing: \"%s\""), repmgrd_command.data);
|
||||||
|
-
|
||||||
|
- initPQExpBuffer(&output_buf);
|
||||||
|
-
|
||||||
|
- success = local_command(repmgrd_command.data, &output_buf);
|
||||||
|
- termPQExpBuffer(&repmgrd_command);
|
||||||
|
-
|
||||||
|
- if (success == false)
|
||||||
|
- {
|
||||||
|
- log_error(_("unable to stop repmgrd"));
|
||||||
|
- if (output_buf.data[0] != '\0')
|
||||||
|
- log_detail("%s", output_buf.data);
|
||||||
|
- termPQExpBuffer(&output_buf);
|
||||||
|
- exit(ERR_REPMGRD_SERVICE);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- termPQExpBuffer(&output_buf);
|
||||||
|
-
|
||||||
|
- if (runtime_options.no_wait == true || runtime_options.wait == 0)
|
||||||
|
- {
|
||||||
|
- if (have_db_connection == true)
|
||||||
|
- log_hint(REPMGR_SERVICE_STATUS_STOP_HINT);
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- int i = 0;
|
||||||
|
- int timeout = REPMGR_SERVICE_STOP_START_WAIT;
|
||||||
|
- /*
|
||||||
|
- *
|
||||||
|
- */
|
||||||
|
- if (pid == UNKNOWN_PID)
|
||||||
|
- {
|
||||||
|
- /*
|
||||||
|
- * XXX attempt to get pidfile from config
|
||||||
|
- * and get contents
|
||||||
|
- * ( see check_and_create_pid_file() )
|
||||||
|
- * if PID still unknown, exit here
|
||||||
|
- */
|
||||||
|
- log_warning(_("unable to determine repmgrd PID"));
|
||||||
|
-
|
||||||
|
- if (have_db_connection == true)
|
||||||
|
- log_hint(REPMGR_SERVICE_STATUS_STOP_HINT);
|
||||||
|
-
|
||||||
|
- exit(ERR_REPMGRD_SERVICE);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (runtime_options.wait_provided)
|
||||||
|
- timeout = runtime_options.wait;
|
||||||
|
-
|
||||||
|
- for (;;)
|
||||||
|
- {
|
||||||
|
- if (kill(pid, 0) == -1)
|
||||||
|
- {
|
||||||
|
- if (errno == ESRCH)
|
||||||
|
- {
|
||||||
|
- log_notice(_("repmgrd was successfully stopped"));
|
||||||
|
- exit(SUCCESS);
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- log_error(_("unable to determine status of process with PID %i"), pid);
|
||||||
|
- log_detail("%s", strerror(errno));
|
||||||
|
- exit(ERR_REPMGRD_SERVICE);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-
|
||||||
|
- if (i == timeout)
|
||||||
|
- {
|
||||||
|
- log_error(_("repmgrd does not appear to have stopped after %i seconds"),
|
||||||
|
- timeout);
|
||||||
|
-
|
||||||
|
- if (have_db_connection == true)
|
||||||
|
- log_hint(REPMGR_SERVICE_STATUS_START_HINT);
|
||||||
|
-
|
||||||
|
- exit(ERR_REPMGRD_SERVICE);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- log_debug("sleeping 1 second; %i of %i attempts to determine if repmgrd with PID %i is running",
|
||||||
|
- i, timeout, pid);
|
||||||
|
- sleep(1);
|
||||||
|
- i++;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
|
||||||
|
void do_service_help(void)
|
||||||
|
{
|
||||||
|
@@ -786,8 +505,7 @@ void do_service_help(void)
|
||||||
|
printf(_(" %s [OPTIONS] service status\n"), progname());
|
||||||
|
printf(_(" %s [OPTIONS] service pause\n"), progname());
|
||||||
|
printf(_(" %s [OPTIONS] service unpause\n"), progname());
|
||||||
|
- printf(_(" %s [OPTIONS] service start\n"), progname());
|
||||||
|
- printf(_(" %s [OPTIONS] service stop\n"), progname());
|
||||||
|
+
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
printf(_("SERVICE STATUS\n"));
|
||||||
|
@@ -799,24 +517,6 @@ void do_service_help(void)
|
||||||
|
printf(_(" --verbose show text of database connection error messages\n"));
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
- printf(_("SERVICE START\n"));
|
||||||
|
- puts("");
|
||||||
|
- printf(_(" \"service start\" attempts to start repmgrd\n"));
|
||||||
|
- puts("");
|
||||||
|
- printf(_(" --dry-run check prerequisites but don't start repmgrd\n"));
|
||||||
|
- printf(_(" -w/--wait wait for repmgrd to start (default: %i seconds)\n"), REPMGR_SERVICE_STOP_START_WAIT);
|
||||||
|
- printf(_(" --no-wait don't wait for repmgrd to start\n"));
|
||||||
|
- puts("");
|
||||||
|
-
|
||||||
|
- printf(_("SERVICE STOP\n"));
|
||||||
|
- puts("");
|
||||||
|
- printf(_(" \"service stop\" attempts to stop repmgrd\n"));
|
||||||
|
- puts("");
|
||||||
|
- printf(_(" --dry-run check prerequisites but don't stop repmgrd\n"));
|
||||||
|
- printf(_(" -w/--wait wait for repmgrd to stop (default: %i seconds)\n"), REPMGR_SERVICE_STOP_START_WAIT);
|
||||||
|
- printf(_(" --no-wait don't wait for repmgrd to stop\n"));
|
||||||
|
- puts("");
|
||||||
|
-
|
||||||
|
printf(_("SERVICE PAUSE\n"));
|
||||||
|
puts("");
|
||||||
|
printf(_(" \"service pause\" instructs repmgrd on each node to pause failover detection\n"));
|
||||||
|
diff --git a/repmgr-action-service.h b/repmgr-action-service.h
|
||||||
|
index a62ce75..e22c059 100644
|
||||||
|
--- a/repmgr-action-service.h
|
||||||
|
+++ b/repmgr-action-service.h
|
||||||
|
@@ -23,8 +23,6 @@
|
||||||
|
extern void do_service_status(void);
|
||||||
|
extern void do_service_pause(void);
|
||||||
|
extern void do_service_unpause(void);
|
||||||
|
-extern void do_service_start(void);
|
||||||
|
-extern void do_service_stop(void);
|
||||||
|
|
||||||
|
extern void do_service_help(void);
|
||||||
|
#endif
|
||||||
|
diff --git a/repmgr-client.c b/repmgr-client.c
|
||||||
|
index ee7315c..c0e6263 100644
|
||||||
|
--- a/repmgr-client.c
|
||||||
|
+++ b/repmgr-client.c
|
||||||
|
@@ -36,8 +36,9 @@
|
||||||
|
* SERVICE STATUS
|
||||||
|
* SERVICE PAUSE
|
||||||
|
* SERVICE UNPAUSE
|
||||||
|
- * SERVICE START
|
||||||
|
- * SERVICE STOP
|
||||||
|
+ *
|
||||||
|
+ * DAEMON START
|
||||||
|
+ * DAEMON STOP
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
@@ -70,6 +71,7 @@
|
||||||
|
#include "repmgr-action-node.h"
|
||||||
|
#include "repmgr-action-cluster.h"
|
||||||
|
#include "repmgr-action-service.h"
|
||||||
|
+#include "repmgr-action-daemon.h"
|
||||||
|
|
||||||
|
#include <storage/fd.h> /* for PG_TEMP_FILE_PREFIX */
|
||||||
|
|
||||||
|
@@ -952,8 +954,7 @@ main(int argc, char **argv)
|
||||||
|
else if (strcasecmp(repmgr_action, "CLEANUP") == 0)
|
||||||
|
action = CLUSTER_CLEANUP;
|
||||||
|
}
|
||||||
|
- /* allow "daemon" as an alias for "service" for repmgr 4.x compatibility */
|
||||||
|
- else if (strcasecmp(repmgr_command, "SERVICE") == 0 || strcasecmp(repmgr_command, "DAEMON") == 0)
|
||||||
|
+ else if (strcasecmp(repmgr_command, "SERVICE") == 0)
|
||||||
|
{
|
||||||
|
if (help_option == true)
|
||||||
|
{
|
||||||
|
@@ -967,10 +968,28 @@ main(int argc, char **argv)
|
||||||
|
action = SERVICE_PAUSE;
|
||||||
|
else if (strcasecmp(repmgr_action, "UNPAUSE") == 0)
|
||||||
|
action = SERVICE_UNPAUSE;
|
||||||
|
- else if (strcasecmp(repmgr_action, "START") == 0)
|
||||||
|
- action = SERVICE_START;
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+ else if (strcasecmp(repmgr_command, "DAEMON") == 0)
|
||||||
|
+ {
|
||||||
|
+ if (help_option == true)
|
||||||
|
+ {
|
||||||
|
+ do_daemon_help();
|
||||||
|
+ exit(SUCCESS);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (strcasecmp(repmgr_action, "START") == 0)
|
||||||
|
+ action = DAEMON_START;
|
||||||
|
else if (strcasecmp(repmgr_action, "STOP") == 0)
|
||||||
|
- action = SERVICE_STOP;
|
||||||
|
+ action = DAEMON_STOP;
|
||||||
|
+
|
||||||
|
+ /* allow "daemon" as an alias for "service" for repmgr 4.x compatibility */
|
||||||
|
+ if (strcasecmp(repmgr_action, "STATUS") == 0)
|
||||||
|
+ action = SERVICE_STATUS;
|
||||||
|
+ else if (strcasecmp(repmgr_action, "PAUSE") == 0)
|
||||||
|
+ action = SERVICE_PAUSE;
|
||||||
|
+ else if (strcasecmp(repmgr_action, "UNPAUSE") == 0)
|
||||||
|
+ action = SERVICE_UNPAUSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@@ -1383,11 +1402,13 @@ main(int argc, char **argv)
|
||||||
|
case SERVICE_UNPAUSE:
|
||||||
|
do_service_unpause();
|
||||||
|
break;
|
||||||
|
- case SERVICE_START:
|
||||||
|
- do_service_start();
|
||||||
|
+
|
||||||
|
+ /* DAEMON */
|
||||||
|
+ case DAEMON_START:
|
||||||
|
+ do_daemon_start();
|
||||||
|
break;
|
||||||
|
- case SERVICE_STOP:
|
||||||
|
- do_service_stop();
|
||||||
|
+ case DAEMON_STOP:
|
||||||
|
+ do_daemon_stop();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
@@ -1755,8 +1776,8 @@ check_cli_parameters(const int action)
|
||||||
|
{
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
- case SERVICE_START:
|
||||||
|
- case SERVICE_STOP:
|
||||||
|
+ case DAEMON_START:
|
||||||
|
+ case DAEMON_STOP:
|
||||||
|
case STANDBY_FOLLOW:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
@@ -1769,8 +1790,8 @@ check_cli_parameters(const int action)
|
||||||
|
{
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
- case SERVICE_START:
|
||||||
|
- case SERVICE_STOP:
|
||||||
|
+ case DAEMON_START:
|
||||||
|
+ case DAEMON_STOP:
|
||||||
|
case NODE_REJOIN:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
@@ -1895,8 +1916,8 @@ check_cli_parameters(const int action)
|
||||||
|
case NODE_SERVICE:
|
||||||
|
case SERVICE_PAUSE:
|
||||||
|
case SERVICE_UNPAUSE:
|
||||||
|
- case SERVICE_START:
|
||||||
|
- case SERVICE_STOP:
|
||||||
|
+ case DAEMON_START:
|
||||||
|
+ case DAEMON_STOP:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
item_list_append_format(&cli_warnings,
|
||||||
|
@@ -2469,10 +2490,11 @@ action_name(const int action)
|
||||||
|
return "SERVICE PAUSE";
|
||||||
|
case SERVICE_UNPAUSE:
|
||||||
|
return "SERVICE UNPAUSE";
|
||||||
|
- case SERVICE_START:
|
||||||
|
- return "SERVICE START";
|
||||||
|
- case SERVICE_STOP:
|
||||||
|
- return "SERVICE STOP";
|
||||||
|
+
|
||||||
|
+ case DAEMON_START:
|
||||||
|
+ return "DAEMON START";
|
||||||
|
+ case DAEMON_STOP:
|
||||||
|
+ return "DAEMON STOP";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "UNKNOWN ACTION";
|
||||||
|
@@ -2583,7 +2605,8 @@ do_help(void)
|
||||||
|
printf(_(" %s [OPTIONS] node {status|check|rejoin|service}\n"), progname());
|
||||||
|
printf(_(" %s [OPTIONS] cluster {show|event|matrix|crosscheck|cleanup}\n"), progname());
|
||||||
|
printf(_(" %s [OPTIONS] witness {register|unregister}\n"), progname());
|
||||||
|
- printf(_(" %s [OPTIONS] service {status|pause|unpause|start|stop}\n"), progname());
|
||||||
|
+ printf(_(" %s [OPTIONS] service {status|pause|unpause}\n"), progname());
|
||||||
|
+ printf(_(" %s [OPTIONS] daemon {start|stop}\n"), progname());
|
||||||
|
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
diff --git a/repmgr-client.h b/repmgr-client.h
|
||||||
|
index 679aa38..9620849 100644
|
||||||
|
--- a/repmgr-client.h
|
||||||
|
+++ b/repmgr-client.h
|
||||||
|
@@ -49,8 +49,8 @@
|
||||||
|
#define SERVICE_STATUS 23
|
||||||
|
#define SERVICE_PAUSE 24
|
||||||
|
#define SERVICE_UNPAUSE 25
|
||||||
|
-#define SERVICE_START 26
|
||||||
|
-#define SERVICE_STOP 27
|
||||||
|
+#define DAEMON_START 26
|
||||||
|
+#define DAEMON_STOP 27
|
||||||
|
|
||||||
|
/* command line options without short versions */
|
||||||
|
#define OPT_HELP 1001
|
||||||
@@ -23,6 +23,45 @@
|
|||||||
|
|
||||||
<sect2>
|
<sect2>
|
||||||
<title>Compatibility changes</title>
|
<title>Compatibility changes</title>
|
||||||
|
<para>
|
||||||
|
Some <command>repmgr daemon ...</command> commands have been renamed to
|
||||||
|
<command>repmgr service ...</command> as they have a cluster-wide effect
|
||||||
|
and to avoid giving the impression they affect only the local &repmgr; daemon.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Following commands are affected:
|
||||||
|
|
||||||
|
<itemizedlist spacing="compact" mark="bullet">
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<simpara>
|
||||||
|
<command>repmgr daemon pause</command>
|
||||||
|
(now <link linkend="repmgr-service-pause"><command>repmgr service pause</command></link>)
|
||||||
|
</simpara>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<simpara>
|
||||||
|
<command>repmgr daemon unpause</command>
|
||||||
|
(now <link linkend="repmgr-service-unpause"><command>repmgr service unpause</command></link>)
|
||||||
|
</simpara>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<simpara>
|
||||||
|
<command>repmgr daemon status</command>
|
||||||
|
(now <link linkend="repmgr-service-status"><command>repmgr service status</command></link>)
|
||||||
|
</simpara>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The <command>repmgr daemon ...</command> form will still be accepted
|
||||||
|
for backwards compatibility.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The following command line options, which have been deprecated since &repmgr; 3.3
|
The following command line options, which have been deprecated since &repmgr; 3.3
|
||||||
(and which no longer had any effect other than to generate a warning about their use)
|
(and which no longer had any effect other than to generate a warning about their use)
|
||||||
@@ -209,7 +248,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>:
|
<link linkend="repmgr-service-status"><command>repmgr daemon status</command></link>:
|
||||||
make output similar to that of
|
make output similar to that of
|
||||||
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>
|
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>
|
||||||
for consistency and to make it easier to identify nodes not in the expected
|
for consistency and to make it easier to identify nodes not in the expected
|
||||||
@@ -227,7 +266,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>
|
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>
|
||||||
and <link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>:
|
and <link linkend="repmgr-service-status"><command>repmgr daemon status</command></link>:
|
||||||
show the upstream node name as reported by each individual node - this helps visualise
|
show the upstream node name as reported by each individual node - this helps visualise
|
||||||
situations where the cluster is in an unexpected state, and provide a better idea of the
|
situations where the cluster is in an unexpected state, and provide a better idea of the
|
||||||
actual cluster state.
|
actual cluster state.
|
||||||
@@ -245,7 +284,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>
|
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>
|
||||||
and <link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>:
|
and <link linkend="repmgr-service-status"><command>repmgr daemon status</command></link>:
|
||||||
check if a node is attached to its advertised upstream node, and issue a
|
check if a node is attached to its advertised upstream node, and issue a
|
||||||
warning if the node is not attached.
|
warning if the node is not attached.
|
||||||
</para>
|
</para>
|
||||||
@@ -462,7 +501,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>
|
<link linkend="repmgr-service-status"><command>repmgr daemon status</command></link>
|
||||||
additionally displays the node priority and the interval (in seconds) since the
|
additionally displays the node priority and the interval (in seconds) since the
|
||||||
&repmgrd; instance last verified its upstream node was available.
|
&repmgrd; instance last verified its upstream node was available.
|
||||||
</para>
|
</para>
|
||||||
|
|||||||
@@ -54,11 +54,11 @@
|
|||||||
<!ENTITY repmgr-cluster-crosscheck SYSTEM "repmgr-cluster-crosscheck.xml">
|
<!ENTITY repmgr-cluster-crosscheck SYSTEM "repmgr-cluster-crosscheck.xml">
|
||||||
<!ENTITY repmgr-cluster-event SYSTEM "repmgr-cluster-event.xml">
|
<!ENTITY repmgr-cluster-event SYSTEM "repmgr-cluster-event.xml">
|
||||||
<!ENTITY repmgr-cluster-cleanup SYSTEM "repmgr-cluster-cleanup.xml">
|
<!ENTITY repmgr-cluster-cleanup SYSTEM "repmgr-cluster-cleanup.xml">
|
||||||
<!ENTITY repmgr-daemon-status SYSTEM "repmgr-daemon-status.xml">
|
<!ENTITY repmgr-service-status SYSTEM "repmgr-service-status.xml">
|
||||||
|
<!ENTITY repmgr-service-pause SYSTEM "repmgr-service-pause.xml">
|
||||||
|
<!ENTITY repmgr-service-unpause SYSTEM "repmgr-service-unpause.xml">
|
||||||
<!ENTITY repmgr-daemon-start SYSTEM "repmgr-daemon-start.xml">
|
<!ENTITY repmgr-daemon-start SYSTEM "repmgr-daemon-start.xml">
|
||||||
<!ENTITY repmgr-daemon-stop SYSTEM "repmgr-daemon-stop.xml">
|
<!ENTITY repmgr-daemon-stop SYSTEM "repmgr-daemon-stop.xml">
|
||||||
<!ENTITY repmgr-daemon-pause SYSTEM "repmgr-daemon-pause.xml">
|
|
||||||
<!ENTITY repmgr-daemon-unpause SYSTEM "repmgr-daemon-unpause.xml">
|
|
||||||
|
|
||||||
<!ENTITY appendix-release-notes SYSTEM "appendix-release-notes.xml">
|
<!ENTITY appendix-release-notes SYSTEM "appendix-release-notes.xml">
|
||||||
<!ENTITY appendix-faq SYSTEM "appendix-faq.xml">
|
<!ENTITY appendix-faq SYSTEM "appendix-faq.xml">
|
||||||
|
|||||||
@@ -233,7 +233,7 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>See also</title>
|
<title>See also</title>
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="repmgr-node-status"/>, <xref linkend="repmgr-node-check"/>, <xref linkend="repmgr-daemon-status"/>
|
<xref linkend="repmgr-node-status"/>, <xref linkend="repmgr-node-check"/>, <xref linkend="repmgr-service-status"/>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|||||||
@@ -14,13 +14,13 @@
|
|||||||
|
|
||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>repmgr daemon start</refname>
|
<refname>repmgr daemon start</refname>
|
||||||
<refpurpose>Start the &repmgrd; daemon</refpurpose>
|
<refpurpose>Start the &repmgrd; service</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Description</title>
|
<title>Description</title>
|
||||||
<para>
|
<para>
|
||||||
This command starts the &repmgrd; daemon on the
|
This command starts the &repmgrd; service on the
|
||||||
local node.
|
local node.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>See also</title>
|
<title>See also</title>
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="repmgr-daemon-stop"/>, <xref linkend="repmgr-daemon-status"/>, <xref linkend="repmgrd-daemon"/>
|
<xref linkend="repmgr-daemon-stop"/>, <xref linkend="repmgrd-daemon"/>, <xref linkend="repmgr-service-status"/>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|||||||
@@ -194,7 +194,7 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>See also</title>
|
<title>See also</title>
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="repmgr-daemon-start"/>, <xref linkend="repmgr-daemon-status"/>, <xref linkend="repmgrd-daemon"/>
|
<xref linkend="repmgr-daemon-start"/>, <xref linkend="repmgrd-daemon"/>, <xref linkend="repmgr-service-status"/>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<refentry id="repmgr-daemon-pause">
|
<refentry id="repmgr-service-pause">
|
||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>repmgr daemon pause</primary>
|
<primary>repmgr service pause</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<indexterm>
|
<indexterm>
|
||||||
@@ -9,11 +9,11 @@
|
|||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<refmeta>
|
<refmeta>
|
||||||
<refentrytitle>repmgr daemon pause</refentrytitle>
|
<refentrytitle>repmgr service pause</refentrytitle>
|
||||||
</refmeta>
|
</refmeta>
|
||||||
|
|
||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>repmgr daemon pause</refname>
|
<refname>repmgr service pause</refname>
|
||||||
<refpurpose>Instruct all &repmgrd; instances in the replication cluster to pause failover operations</refpurpose>
|
<refpurpose>Instruct all &repmgrd; instances in the replication cluster to pause failover operations</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
@@ -32,12 +32,12 @@
|
|||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
It's important to wait a few seconds after restarting PostgreSQL on any node before running
|
It's important to wait a few seconds after restarting PostgreSQL on any node before running
|
||||||
<command>repmgr daemon pause</command>, as the &repmgrd; instance
|
<command>repmgr service pause</command>, as the &repmgrd; instance
|
||||||
on the restarted node will take a second or two before it has updated its status.
|
on the restarted node will take a second or two before it has updated its status.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="repmgr-daemon-unpause"/> will instruct all previously paused &repmgrd;
|
<xref linkend="repmgr-service-unpause"/> will instruct all previously paused &repmgrd;
|
||||||
instances to resume normal failover operation.
|
instances to resume normal failover operation.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Execution</title>
|
<title>Execution</title>
|
||||||
<para>
|
<para>
|
||||||
<command>repmgr daemon pause</command> can be executed on any active node in the
|
<command>repmgr service pause</command> can be executed on any active node in the
|
||||||
replication cluster. A valid <filename>repmgr.conf</filename> file is required.
|
replication cluster. A valid <filename>repmgr.conf</filename> file is required.
|
||||||
It will have no effect on previously paused nodes.
|
It will have no effect on previously paused nodes.
|
||||||
</para>
|
</para>
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
<title>Example</title>
|
<title>Example</title>
|
||||||
<para>
|
<para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
$ repmgr -f /etc/repmgr.conf daemon pause
|
$ repmgr -f /etc/repmgr.conf service pause
|
||||||
NOTICE: node 1 (node1) paused
|
NOTICE: node 1 (node1) paused
|
||||||
NOTICE: node 2 (node2) paused
|
NOTICE: node 2 (node2) paused
|
||||||
NOTICE: node 3 (node3) paused</programlisting>
|
NOTICE: node 3 (node3) paused</programlisting>
|
||||||
@@ -79,7 +79,7 @@ NOTICE: node 3 (node3) paused</programlisting>
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Exit codes</title>
|
<title>Exit codes</title>
|
||||||
<para>
|
<para>
|
||||||
One of the following exit codes will be emitted by <command>repmgr daemon unpause</command>:
|
One of the following exit codes will be emitted by <command>repmgr service unpause</command>:
|
||||||
</para>
|
</para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ NOTICE: node 3 (node3) paused</programlisting>
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>See also</title>
|
<title>See also</title>
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="repmgr-daemon-unpause"/>, <xref linkend="repmgr-daemon-status"/>
|
<xref linkend="repmgr-service-unpause"/>, <xref linkend="repmgr-service-status"/>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
</refentry>
|
</refentry>
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
<refentry id="repmgr-daemon-status">
|
<refentry id="repmgr-service-status">
|
||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>repmgr daemon status</primary>
|
<primary>repmgr service status</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>repmgrd</primary>
|
<primary>repmgrd</primary>
|
||||||
<secondary>displaying daemon status</secondary>
|
<secondary>displaying service status</secondary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<refmeta>
|
<refmeta>
|
||||||
<refentrytitle>repmgr daemon status</refentrytitle>
|
<refentrytitle>repmgr service status</refentrytitle>
|
||||||
</refmeta>
|
</refmeta>
|
||||||
|
|
||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>repmgr daemon status</refname>
|
<refname>repmgr service status</refname>
|
||||||
<refpurpose>display information about the status of &repmgrd; on each node in the cluster</refpurpose>
|
<refpurpose>display information about the status of &repmgrd; on each node in the cluster</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<para>
|
<para>
|
||||||
This command provides an overview over all active nodes in the cluster and the state
|
This command provides an overview over all active nodes in the cluster and the state
|
||||||
of each node's &repmgrd; instance. It can be used to check
|
of each node's &repmgrd; instance. It can be used to check
|
||||||
the result of <xref linkend="repmgr-daemon-pause"/> and <xref linkend="repmgr-daemon-unpause"/>
|
the result of <xref linkend="repmgr-service-pause"/> and <xref linkend="repmgr-service-unpause"/>
|
||||||
operations.
|
operations.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Execution</title>
|
<title>Execution</title>
|
||||||
<para>
|
<para>
|
||||||
<command>repmgr daemon status</command> can be executed on any active node in the
|
<command>repmgr service status</command> can be executed on any active node in the
|
||||||
replication cluster. A valid <filename>repmgr.conf</filename> file is required.
|
replication cluster. A valid <filename>repmgr.conf</filename> file is required.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
<para>
|
<para>
|
||||||
&repmgrd; running normally on all nodes:
|
&repmgrd; running normally on all nodes:
|
||||||
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
|
<programlisting>$ repmgr -f /etc/repmgr.conf service status
|
||||||
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
|
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
|
||||||
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
|
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
|
||||||
1 | node1 | primary | * running | | running | 96563 | no | n/a
|
1 | node1 | primary | * running | | running | 96563 | no | n/a
|
||||||
@@ -60,8 +60,8 @@
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
&repmgrd; paused on all nodes (using <xref linkend="repmgr-daemon-pause"/>):
|
&repmgrd; paused on all nodes (using <xref linkend="repmgr-service-pause"/>):
|
||||||
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
|
<programlisting>$ repmgr -f /etc/repmgr.conf service status
|
||||||
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
|
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
|
||||||
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
|
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
|
||||||
1 | node1 | primary | * running | | running | 96563 | yes | n/a
|
1 | node1 | primary | * running | | running | 96563 | yes | n/a
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
&repmgrd; not running on one node:
|
&repmgrd; not running on one node:
|
||||||
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
|
<programlisting>$ repmgr -f /etc/repmgr.conf service status
|
||||||
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
|
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
|
||||||
----+-------+---------+-----------+----------+-------------+-------+---------+--------------------
|
----+-------+---------+-----------+----------+-------------+-------+---------+--------------------
|
||||||
1 | node1 | primary | * running | | running | 96563 | yes | n/a
|
1 | node1 | primary | * running | | running | 96563 | yes | n/a
|
||||||
@@ -89,11 +89,11 @@
|
|||||||
<term><option>--csv</option></term>
|
<term><option>--csv</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<command>repmgr daemon status</command> accepts an optional parameter <literal>--csv</literal>, which
|
<command>repmgr service status</command> accepts an optional parameter <literal>--csv</literal>, which
|
||||||
outputs the replication cluster's status in a simple CSV format, suitable for
|
outputs the replication cluster's status in a simple CSV format, suitable for
|
||||||
parsing by scripts, e.g.:
|
parsing by scripts, e.g.:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
$ repmgr -f /etc/repmgr.conf daemon status --csv
|
$ repmgr -f /etc/repmgr.conf service status --csv
|
||||||
1,node1,primary,1,1,5722,1,100,-1,default
|
1,node1,primary,1,1,5722,1,100,-1,default
|
||||||
2,node2,standby,1,0,-1,1,100,1,default
|
2,node2,standby,1,0,-1,1,100,1,default
|
||||||
3,node3,standby,1,1,5779,1,100,1,default</programlisting>
|
3,node3,standby,1,1,5779,1,100,1,default</programlisting>
|
||||||
@@ -171,7 +171,7 @@
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Display additional information (<literal>location</literal>, <literal>priority</literal>)
|
Display additional information (<literal>location</literal>, <literal>priority</literal>)
|
||||||
about the &repmgr; configuration.
|
about the &repmgr; configuration.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@@ -180,7 +180,7 @@
|
|||||||
<term><option>--verbose</option></term>
|
<term><option>--verbose</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Display the full text of any database connection error messages
|
Display the full text of any database connection error messages.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@@ -192,7 +192,7 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>See also</title>
|
<title>See also</title>
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="repmgr-daemon-pause"/>, <xref linkend="repmgr-daemon-unpause"/>, <xref linkend="repmgr-cluster-show"/>
|
<xref linkend="repmgr-service-pause"/>, <xref linkend="repmgr-service-unpause"/>, <xref linkend="repmgr-cluster-show"/>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
</refentry>
|
</refentry>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<refentry id="repmgr-daemon-unpause">
|
<refentry id="repmgr-service-unpause">
|
||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>repmgr daemon unpause</primary>
|
<primary>repmgr service unpause</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<indexterm>
|
<indexterm>
|
||||||
@@ -8,13 +8,12 @@
|
|||||||
<secondary>unpausing</secondary>
|
<secondary>unpausing</secondary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
|
|
||||||
<refmeta>
|
<refmeta>
|
||||||
<refentrytitle>repmgr daemon unpause</refentrytitle>
|
<refentrytitle>repmgr service unpause</refentrytitle>
|
||||||
</refmeta>
|
</refmeta>
|
||||||
|
|
||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>repmgr daemon unpause</refname>
|
<refname>repmgr service unpause</refname>
|
||||||
<refpurpose>Instruct all &repmgrd; instances in the replication cluster to resume failover operations</refpurpose>
|
<refpurpose>Instruct all &repmgrd; instances in the replication cluster to resume failover operations</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
@@ -23,14 +22,14 @@
|
|||||||
<para>
|
<para>
|
||||||
This command can be run on any active node in the replication cluster to instruct all
|
This command can be run on any active node in the replication cluster to instruct all
|
||||||
running &repmgrd; instances to "unpause"
|
running &repmgrd; instances to "unpause"
|
||||||
(following a previous execution of <xref linkend="repmgr-daemon-pause"/>)
|
(following a previous execution of <xref linkend="repmgr-service-pause"/>)
|
||||||
and resume normal failover/monitoring operation.
|
and resume normal failover/monitoring operation.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
It's important to wait a few seconds after restarting PostgreSQL on any node before running
|
It's important to wait a few seconds after restarting PostgreSQL on any node before running
|
||||||
<command>repmgr daemon pause</command>, as the &repmgrd; instance
|
<command>repmgr service pause</command>, as the &repmgrd; instance
|
||||||
on the restarted node will take a second or two before it has updated its status.
|
on the restarted node will take a second or two before it has updated its status.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
@@ -40,7 +39,7 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Execution</title>
|
<title>Execution</title>
|
||||||
<para>
|
<para>
|
||||||
<command>repmgr daemon unpause</command> can be executed on any active node in the
|
<command>repmgr service unpause</command> can be executed on any active node in the
|
||||||
replication cluster. A valid <filename>repmgr.conf</filename> file is required.
|
replication cluster. A valid <filename>repmgr.conf</filename> file is required.
|
||||||
It will have no effect on nodes which are not already paused.
|
It will have no effect on nodes which are not already paused.
|
||||||
</para>
|
</para>
|
||||||
@@ -50,7 +49,7 @@
|
|||||||
<title>Example</title>
|
<title>Example</title>
|
||||||
<para>
|
<para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
$ repmgr -f /etc/repmgr.conf daemon unpause
|
$ repmgr -f /etc/repmgr.conf service unpause
|
||||||
NOTICE: node 1 (node1) unpaused
|
NOTICE: node 1 (node1) unpaused
|
||||||
NOTICE: node 2 (node2) unpaused
|
NOTICE: node 2 (node2) unpaused
|
||||||
NOTICE: node 3 (node3) unpaused</programlisting>
|
NOTICE: node 3 (node3) unpaused</programlisting>
|
||||||
@@ -74,7 +73,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Exit codes</title>
|
<title>Exit codes</title>
|
||||||
<para>
|
<para>
|
||||||
One of the following exit codes will be emitted by <command>repmgr daemon unpause</command>:
|
One of the following exit codes will be emitted by <command>repmgr service unpause</command>:
|
||||||
</para>
|
</para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
@@ -102,7 +101,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>See also</title>
|
<title>See also</title>
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="repmgr-daemon-pause"/>, <xref linkend="repmgr-daemon-status"/>
|
<xref linkend="repmgr-service-pause"/>, <xref linkend="repmgr-service-status"/>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
</refentry>
|
</refentry>
|
||||||
@@ -23,7 +23,8 @@
|
|||||||
<important>
|
<important>
|
||||||
<para>
|
<para>
|
||||||
If &repmgrd; is active, you must execute
|
If &repmgrd; is active, you must execute
|
||||||
<command><link linkend="repmgr-daemon-pause">repmgr daemon pause</link></command>
|
<command><link linkend="repmgr-service-pause">repmgr service pause</link></command>
|
||||||
|
(&repmgr; 4.2 - 4.4: <command><link linkend="repmgr-service-pause">repmgr service pause</link></command>)
|
||||||
to temporarily disable &repmgrd; while making any changes
|
to temporarily disable &repmgrd; while making any changes
|
||||||
to the replication cluster.
|
to the replication cluster.
|
||||||
</para>
|
</para>
|
||||||
|
|||||||
@@ -116,11 +116,11 @@
|
|||||||
&repmgr-cluster-crosscheck;
|
&repmgr-cluster-crosscheck;
|
||||||
&repmgr-cluster-event;
|
&repmgr-cluster-event;
|
||||||
&repmgr-cluster-cleanup;
|
&repmgr-cluster-cleanup;
|
||||||
&repmgr-daemon-status;
|
&repmgr-service-status;
|
||||||
|
&repmgr-service-pause;
|
||||||
|
&repmgr-service-unpause;
|
||||||
&repmgr-daemon-start;
|
&repmgr-daemon-start;
|
||||||
&repmgr-daemon-stop;
|
&repmgr-daemon-stop;
|
||||||
&repmgr-daemon-pause;
|
|
||||||
&repmgr-daemon-unpause;
|
|
||||||
</part>
|
</part>
|
||||||
|
|
||||||
&appendix-release-notes;
|
&appendix-release-notes;
|
||||||
|
|||||||
@@ -199,9 +199,10 @@
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
The time the primary was last seen by each node can be checked by executing
|
The time the primary was last seen by each node can be checked by executing
|
||||||
<link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>,
|
<link linkend="repmgr-service-status"><command>repmgr service status</command></link>
|
||||||
|
(&repmgr; 4.2 - 4.4: <link linkend="repmgr-service-status"><command>repmgr daemon status</command></link>)
|
||||||
which includes this in its output, e.g.:
|
which includes this in its output, e.g.:
|
||||||
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
|
<programlisting>$ repmgr -f /etc/repmgr.conf service status
|
||||||
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
|
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
|
||||||
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
|
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
|
||||||
1 | node1 | primary | * running | | running | 96563 | no | n/a
|
1 | node1 | primary | * running | | running | 96563 | no | n/a
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
&repmgrd; is a daemon which runs on each PostgreSQL node,
|
&repmgrd; is a daemon process which runs on each PostgreSQL node,
|
||||||
monitoring the local node, and (unless it's the primary node) the upstream server
|
monitoring the local node, and (unless it's the primary node) the upstream server
|
||||||
(the primary server or with cascading replication, another standby) which it's
|
(the primary server or with cascading replication, another standby) which it's
|
||||||
connected to.
|
connected to.
|
||||||
@@ -519,7 +519,8 @@
|
|||||||
</indexterm>
|
</indexterm>
|
||||||
<para>
|
<para>
|
||||||
If you are intending to use the <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link>
|
If you are intending to use the <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link>
|
||||||
and <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> commands, the following
|
and <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link>
|
||||||
|
commands, the following
|
||||||
parameters <emphasis>must</emphasis> be set in <filename>repmgr.conf</filename>:
|
parameters <emphasis>must</emphasis> be set in <filename>repmgr.conf</filename>:
|
||||||
<itemizedlist spacing="compact" mark="bullet">
|
<itemizedlist spacing="compact" mark="bullet">
|
||||||
|
|
||||||
@@ -860,7 +861,7 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
|
|||||||
<para>
|
<para>
|
||||||
The commands <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> and
|
The commands <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> and
|
||||||
<link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> can be used
|
<link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> can be used
|
||||||
as convenience wrappers to start and stop &repmgrd;.
|
as convenience wrappers to start and stop &repmgrd; on the local node.
|
||||||
</para>
|
</para>
|
||||||
<important>
|
<important>
|
||||||
<para>
|
<para>
|
||||||
|
|||||||
@@ -88,17 +88,21 @@
|
|||||||
<sect2 id="repmgrd-pausing-execution">
|
<sect2 id="repmgrd-pausing-execution">
|
||||||
<title>Pausing/unpausing &repmgrd;</title>
|
<title>Pausing/unpausing &repmgrd;</title>
|
||||||
<para>
|
<para>
|
||||||
To pause &repmgrd;, execute <link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link>, e.g.:
|
To pause &repmgrd;, execute <link linkend="repmgr-service-pause"><command>repmgr service pause</command></link>
|
||||||
|
(&repmgr; 4.2 - 4.4: <link linkend="repmgr-service-pause"><command>repmgr daemon pause</command></link>),
|
||||||
|
e.g.:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
$ repmgr -f /etc/repmgr.conf daemon pause
|
$ repmgr -f /etc/repmgr.conf service pause
|
||||||
NOTICE: node 1 (node1) paused
|
NOTICE: node 1 (node1) paused
|
||||||
NOTICE: node 2 (node2) paused
|
NOTICE: node 2 (node2) paused
|
||||||
NOTICE: node 3 (node3) paused</programlisting>
|
NOTICE: node 3 (node3) paused</programlisting>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The state of &repmgrd; on each node can be checked with
|
The state of &repmgrd; on each node can be checked with
|
||||||
<link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>, e.g.:
|
<link linkend="repmgr-service-status"><command>repmgr service status</command></link>
|
||||||
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
|
(&repmgr; 4.2 - 4.4: <link linkend="repmgr-service-status"><command>repmgr daemon status</command></link>),
|
||||||
|
e.g.:
|
||||||
|
<programlisting>$ repmgr -f /etc/repmgr.conf service status
|
||||||
ID | Name | Role | Status | repmgrd | PID | Paused?
|
ID | Name | Role | Status | repmgrd | PID | Paused?
|
||||||
----+-------+---------+---------+---------+------+---------
|
----+-------+---------+---------+---------+------+---------
|
||||||
1 | node1 | primary | running | running | 7851 | yes
|
1 | node1 | primary | running | running | 7851 | yes
|
||||||
@@ -108,8 +112,8 @@ NOTICE: node 3 (node3) paused</programlisting>
|
|||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
If executing a switchover with <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>,
|
If executing a switchover with <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>,
|
||||||
&repmgr; will automatically pause/unpause &repmgrd; as part of the switchover process.
|
&repmgr; will automatically pause/unpause the &repmgrd; service as part of the switchover process.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
@@ -117,29 +121,32 @@ NOTICE: node 3 (node3) paused</programlisting>
|
|||||||
If the primary (in this example, <literal>node1</literal>) is stopped, &repmgrd;
|
If the primary (in this example, <literal>node1</literal>) is stopped, &repmgrd;
|
||||||
running on one of the standbys (here: <literal>node2</literal>) will react like this:
|
running on one of the standbys (here: <literal>node2</literal>) will react like this:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
[2018-09-20 12:22:21] [WARNING] unable to connect to upstream node "node1" (ID: 1)
|
[2019-08-28 12:22:21] [WARNING] unable to connect to upstream node "node1" (node ID: 1)
|
||||||
[2018-09-20 12:22:21] [INFO] checking state of node 1, 1 of 5 attempts
|
[2019-08-28 12:22:21] [INFO] checking state of node 1, 1 of 5 attempts
|
||||||
[2018-09-20 12:22:21] [INFO] sleeping 1 seconds until next reconnection attempt
|
[2019-08-28 12:22:21] [INFO] sleeping 1 seconds until next reconnection attempt
|
||||||
...
|
...
|
||||||
[2018-09-20 12:22:24] [INFO] sleeping 1 seconds until next reconnection attempt
|
[2019-08-28 12:22:24] [INFO] sleeping 1 seconds until next reconnection attempt
|
||||||
[2018-09-20 12:22:25] [INFO] checking state of node 1, 5 of 5 attempts
|
[2019-08-28 12:22:25] [INFO] checking state of node 1, 5 of 5 attempts
|
||||||
[2018-09-20 12:22:25] [WARNING] unable to reconnect to node 1 after 5 attempts
|
[2019-08-28 12:22:25] [WARNING] unable to reconnect to node 1 after 5 attempts
|
||||||
[2018-09-20 12:22:25] [NOTICE] node is paused
|
[2019-08-28 12:22:25] [NOTICE] node is paused
|
||||||
[2018-09-20 12:22:33] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (ID: 1) in degraded state
|
[2019-08-28 12:22:33] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (node ID: 1) in degraded state
|
||||||
[2018-09-20 12:22:33] [DETAIL] repmgrd paused by administrator
|
[2019-08-28 12:22:33] [DETAIL] repmgrd paused by administrator
|
||||||
[2018-09-20 12:22:33] [HINT] execute "repmgr daemon unpause" to resume normal failover mode</programlisting>
|
[2019-08-28 12:22:33] [HINT] execute "repmgr service unpause" to resume normal failover mode</programlisting>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
If the primary becomes available again (e.g. following a software upgrade), &repmgrd;
|
If the primary becomes available again (e.g. following a software upgrade), &repmgrd;
|
||||||
will automatically reconnect, e.g.:
|
will automatically reconnect, e.g.:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
[2018-09-20 13:12:41] [NOTICE] reconnected to upstream node 1 after 8 seconds, resuming monitoring</programlisting>
|
[2019-08-28 12:25:41] [NOTICE] reconnected to upstream node 1 after 8 seconds, resuming monitoring</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To unpause &repmgrd;, execute <link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>, e.g.:
|
To unpause the &repmgrd; service, execute
|
||||||
|
<link linkend="repmgr-service-unpause"><command>repmgr service unpause</command></link>
|
||||||
|
((&repmgr; 4.2 - 4.4: <link linkend="repmgr-service-unpause"><command>repmgr daemon unpause</command></link>),
|
||||||
|
e.g.:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
$ repmgr -f /etc/repmgr.conf daemon unpause
|
$ repmgr -f /etc/repmgr.conf service unpause
|
||||||
NOTICE: node 1 (node1) unpaused
|
NOTICE: node 1 (node1) unpaused
|
||||||
NOTICE: node 2 (node2) unpaused
|
NOTICE: node 2 (node2) unpaused
|
||||||
NOTICE: node 3 (node3) unpaused</programlisting>
|
NOTICE: node 3 (node3) unpaused</programlisting>
|
||||||
@@ -150,11 +157,11 @@ NOTICE: node 3 (node3) unpaused</programlisting>
|
|||||||
If the previous primary is no longer accessible when &repmgrd;
|
If the previous primary is no longer accessible when &repmgrd;
|
||||||
is unpaused, no failover action will be taken. Instead, a new primary must be manually promoted using
|
is unpaused, no failover action will be taken. Instead, a new primary must be manually promoted using
|
||||||
<link linkend="repmgr-standby-promote"><command>repmgr standby promote</command></link>,
|
<link linkend="repmgr-standby-promote"><command>repmgr standby promote</command></link>,
|
||||||
and any standbys attached to the new primary with
|
and any standbys attached to the new primary with
|
||||||
<link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>.
|
<link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
This is to prevent <link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>
|
This is to prevent execution of <link linkend="repmgr-service-unpause"><command>repmgr service unpause</command></link>
|
||||||
resulting in the automatic promotion of a new primary, which may be a problem particularly
|
resulting in the automatic promotion of a new primary, which may be a problem particularly
|
||||||
in larger clusters, where &repmgrd; could select a different promotion
|
in larger clusters, where &repmgrd; could select a different promotion
|
||||||
candidate to the one intended by the administrator.
|
candidate to the one intended by the administrator.
|
||||||
@@ -168,17 +175,17 @@ NOTICE: node 3 (node3) unpaused</programlisting>
|
|||||||
The pause state of each node will be stored over a PostgreSQL restart.
|
The pause state of each node will be stored over a PostgreSQL restart.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link> and
|
<link linkend="repmgr-service-pause"><command>repmgr service pause</command></link> and
|
||||||
<link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link> can be
|
<link linkend="repmgr-service-unpause"><command>repmgr service unpause</command></link> can be
|
||||||
executed even if &repmgrd; is not running; in this case,
|
executed even if &repmgrd; is not running; in this case,
|
||||||
&repmgrd; will start up in whichever pause state has been set.
|
&repmgrd; will start up in whichever pause state has been set.
|
||||||
</para>
|
</para>
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
<link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link> and
|
<link linkend="repmgr-service-pause"><command>repmgr service pause</command></link> and
|
||||||
<link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>
|
<link linkend="repmgr-service-unpause"><command>repmgr service unpause</command></link>
|
||||||
<emphasis>do not</emphasis> stop/start &repmgrd;.
|
<emphasis>do not</emphasis> stop/start &repmgrd;.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
<simpara>
|
<simpara>
|
||||||
ability to <link linkend="repmgrd-pausing">pause repmgrd</link>
|
ability to <link linkend="repmgrd-pausing">pause repmgrd</link>
|
||||||
operation on all nodes with a
|
operation on all nodes with a
|
||||||
<link linkend="repmgr-daemon-pause"><command>single command</command></link>
|
<link linkend="repmgr-service-pause"><command>single command</command></link>
|
||||||
</simpara>
|
</simpara>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
|||||||
@@ -317,7 +317,9 @@
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
If &repmgrd; is in use, it's worth double-checking that
|
If &repmgrd; is in use, it's worth double-checking that
|
||||||
all nodes are unpaused by executing <command><link linkend="repmgr-daemon-status">repmgr-daemon-status</link></command>.
|
all nodes are unpaused by executing
|
||||||
|
<command><link linkend="repmgr-service-status">repmgr service status</link></command>
|
||||||
|
(&repmgr; 4.2 - 4.4: <command><link linkend="repmgr-service-status">repmgr daemon status</link></command>).
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
|
|||||||
@@ -216,7 +216,9 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
|
|||||||
<secondary>checking repmgrd status</secondary>
|
<secondary>checking repmgrd status</secondary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
<para>
|
<para>
|
||||||
From <link linkend="release-4.2">repmgr 4.2</link>, once the upgrade is complete, execute the <command><link linkend="repmgr-daemon-status">repmgr daemon status</link></command>
|
From <link linkend="release-4.2">repmgr 4.2</link>, once the upgrade is complete, execute the
|
||||||
|
<command><link linkend="repmgr-service-status">repmgr service status</link></command>
|
||||||
|
(&repmgr; 4.2 - 4.4: <command><link linkend="repmgr-service-status">repmgr daemon status</link></command>)
|
||||||
command (on any node) to show an overview of the status of &repmgrd; on all nodes.
|
command (on any node) to show an overview of the status of &repmgrd; on all nodes.
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|||||||
@@ -26,478 +26,9 @@
|
|||||||
#include "repmgr-client-global.h"
|
#include "repmgr-client-global.h"
|
||||||
#include "repmgr-action-daemon.h"
|
#include "repmgr-action-daemon.h"
|
||||||
|
|
||||||
#define REPMGR_DAEMON_STOP_START_WAIT 15
|
#define REPMGR_SERVICE_STOP_START_WAIT 15
|
||||||
#define REPMGR_DAEMON_STATUS_START_HINT _("use \"repmgr daemon status\" to confirm that repmgrd was successfully started")
|
#define REPMGR_SERVICE_STATUS_START_HINT _("use \"repmgr service status\" to confirm that repmgrd was successfully started")
|
||||||
#define REPMGR_DAEMON_STATUS_STOP_HINT _("use \"repmgr daemon status\" to confirm that repmgrd was successfully stopped")
|
#define REPMGR_SERVICE_STATUS_STOP_HINT _("use \"repmgr service status\" to confirm that repmgrd was successfully stopped")
|
||||||
|
|
||||||
/*
|
|
||||||
* Possibly also show:
|
|
||||||
* - repmgrd start time?
|
|
||||||
* - repmgrd mode
|
|
||||||
* - priority
|
|
||||||
* - whether promotion candidate (due to zero priority/different location)
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
STATUS_ID = 0,
|
|
||||||
STATUS_NAME,
|
|
||||||
STATUS_ROLE,
|
|
||||||
STATUS_PG,
|
|
||||||
STATUS_UPSTREAM_NAME,
|
|
||||||
STATUS_LOCATION,
|
|
||||||
STATUS_PRIORITY,
|
|
||||||
STATUS_REPMGRD,
|
|
||||||
STATUS_PID,
|
|
||||||
STATUS_PAUSED,
|
|
||||||
STATUS_UPSTREAM_LAST_SEEN
|
|
||||||
} StatusHeader;
|
|
||||||
|
|
||||||
#define STATUS_HEADER_COUNT 11
|
|
||||||
|
|
||||||
struct ColHeader headers_status[STATUS_HEADER_COUNT];
|
|
||||||
|
|
||||||
static void fetch_node_records(PGconn *conn, NodeInfoList *node_list);
|
|
||||||
static void _do_repmgr_pause(bool pause);
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
do_daemon_status(void)
|
|
||||||
{
|
|
||||||
PGconn *conn = NULL;
|
|
||||||
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
|
|
||||||
NodeInfoListCell *cell = NULL;
|
|
||||||
int i;
|
|
||||||
RepmgrdInfo **repmgrd_info;
|
|
||||||
ItemList warnings = {NULL, NULL};
|
|
||||||
bool connection_error_found = false;
|
|
||||||
|
|
||||||
/* Connect to local database to obtain cluster connection data */
|
|
||||||
log_verbose(LOG_INFO, _("connecting to database"));
|
|
||||||
|
|
||||||
if (strlen(config_file_options.conninfo))
|
|
||||||
conn = establish_db_connection(config_file_options.conninfo, true);
|
|
||||||
else
|
|
||||||
conn = establish_db_connection_by_params(&source_conninfo, true);
|
|
||||||
|
|
||||||
fetch_node_records(conn, &nodes);
|
|
||||||
|
|
||||||
repmgrd_info = (RepmgrdInfo **) pg_malloc0(sizeof(RepmgrdInfo *) * nodes.node_count);
|
|
||||||
|
|
||||||
if (repmgrd_info == NULL)
|
|
||||||
{
|
|
||||||
log_error(_("unable to allocate memory"));
|
|
||||||
exit(ERR_OUT_OF_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(headers_status[STATUS_ID].title, _("ID"), MAXLEN);
|
|
||||||
strncpy(headers_status[STATUS_NAME].title, _("Name"), MAXLEN);
|
|
||||||
strncpy(headers_status[STATUS_ROLE].title, _("Role"), MAXLEN);
|
|
||||||
strncpy(headers_status[STATUS_PG].title, _("Status"), MAXLEN);
|
|
||||||
strncpy(headers_status[STATUS_UPSTREAM_NAME].title, _("Upstream"), MAXLEN);
|
|
||||||
|
|
||||||
/* following only displayed with the --detail option */
|
|
||||||
strncpy(headers_status[STATUS_LOCATION].title, _("Location"), MAXLEN);
|
|
||||||
if (runtime_options.compact == true)
|
|
||||||
strncpy(headers_status[STATUS_PRIORITY].title, _("Prio."), MAXLEN);
|
|
||||||
else
|
|
||||||
strncpy(headers_status[STATUS_PRIORITY].title, _("Priority"), MAXLEN);
|
|
||||||
|
|
||||||
strncpy(headers_status[STATUS_REPMGRD].title, _("repmgrd"), MAXLEN);
|
|
||||||
strncpy(headers_status[STATUS_PID].title, _("PID"), MAXLEN);
|
|
||||||
strncpy(headers_status[STATUS_PAUSED].title, _("Paused?"), MAXLEN);
|
|
||||||
|
|
||||||
if (runtime_options.compact == true)
|
|
||||||
strncpy(headers_status[STATUS_UPSTREAM_LAST_SEEN].title, _("Upstr. last"), MAXLEN);
|
|
||||||
else
|
|
||||||
strncpy(headers_status[STATUS_UPSTREAM_LAST_SEEN].title, _("Upstream last seen"), MAXLEN);
|
|
||||||
|
|
||||||
for (i = 0; i < STATUS_HEADER_COUNT; i++)
|
|
||||||
{
|
|
||||||
headers_status[i].max_length = strlen(headers_status[i].title);
|
|
||||||
headers_status[i].display = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (runtime_options.detail == false)
|
|
||||||
{
|
|
||||||
headers_status[STATUS_LOCATION].display = false;
|
|
||||||
headers_status[STATUS_PRIORITY].display = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for (cell = nodes.head; cell; cell = cell->next)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
PQExpBufferData node_status;
|
|
||||||
PQExpBufferData upstream;
|
|
||||||
|
|
||||||
repmgrd_info[i] = pg_malloc0(sizeof(RepmgrdInfo));
|
|
||||||
repmgrd_info[i]->node_id = cell->node_info->node_id;
|
|
||||||
repmgrd_info[i]->pid = UNKNOWN_PID;
|
|
||||||
repmgrd_info[i]->recovery_type = RECTYPE_UNKNOWN;
|
|
||||||
repmgrd_info[i]->paused = false;
|
|
||||||
repmgrd_info[i]->running = false;
|
|
||||||
repmgrd_info[i]->pg_running = true;
|
|
||||||
repmgrd_info[i]->wal_paused_pending_wal = false;
|
|
||||||
repmgrd_info[i]->upstream_last_seen = -1;
|
|
||||||
|
|
||||||
cell->node_info->conn = establish_db_connection_quiet(cell->node_info->conninfo);
|
|
||||||
|
|
||||||
if (PQstatus(cell->node_info->conn) != CONNECTION_OK)
|
|
||||||
{
|
|
||||||
|
|
||||||
connection_error_found = true;
|
|
||||||
|
|
||||||
if (runtime_options.verbose)
|
|
||||||
{
|
|
||||||
char error[MAXLEN];
|
|
||||||
|
|
||||||
strncpy(error, PQerrorMessage(cell->node_info->conn), MAXLEN);
|
|
||||||
|
|
||||||
item_list_append_format(&warnings,
|
|
||||||
"when attempting to connect to node \"%s\" (ID: %i), following error encountered :\n\"%s\"",
|
|
||||||
cell->node_info->node_name, cell->node_info->node_id, trim(error));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item_list_append_format(&warnings,
|
|
||||||
"unable to connect to node \"%s\" (ID: %i)",
|
|
||||||
cell->node_info->node_name, cell->node_info->node_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
repmgrd_info[i]->pg_running = false;
|
|
||||||
maxlen_snprintf(repmgrd_info[i]->repmgrd_running, "%s", _("n/a"));
|
|
||||||
maxlen_snprintf(repmgrd_info[i]->pid_text, "%s", _("n/a"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cell->node_info->node_status = NODE_STATUS_UP;
|
|
||||||
cell->node_info->recovery_type = get_recovery_type(cell->node_info->conn);
|
|
||||||
|
|
||||||
repmgrd_info[i]->pid = repmgrd_get_pid(cell->node_info->conn);
|
|
||||||
|
|
||||||
repmgrd_info[i]->running = repmgrd_is_running(cell->node_info->conn);
|
|
||||||
|
|
||||||
if (repmgrd_info[i]->running == true)
|
|
||||||
{
|
|
||||||
maxlen_snprintf(repmgrd_info[i]->repmgrd_running, "%s", _("running"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
maxlen_snprintf(repmgrd_info[i]->repmgrd_running, "%s", _("not running"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (repmgrd_info[i]->pid == UNKNOWN_PID)
|
|
||||||
{
|
|
||||||
maxlen_snprintf(repmgrd_info[i]->pid_text, "%s", _("n/a"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
maxlen_snprintf(repmgrd_info[i]->pid_text, "%i", repmgrd_info[i]->pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
repmgrd_info[i]->paused = repmgrd_is_paused(cell->node_info->conn);
|
|
||||||
|
|
||||||
repmgrd_info[i]->recovery_type = get_recovery_type(cell->node_info->conn);
|
|
||||||
|
|
||||||
if (repmgrd_info[i]->recovery_type == RECTYPE_STANDBY)
|
|
||||||
{
|
|
||||||
repmgrd_info[i]->wal_paused_pending_wal = is_wal_replay_paused(cell->node_info->conn, true);
|
|
||||||
|
|
||||||
if (repmgrd_info[i]->wal_paused_pending_wal == true)
|
|
||||||
{
|
|
||||||
item_list_append_format(&warnings,
|
|
||||||
_("WAL replay is paused on node \"%s\" (ID: %i) with WAL replay pending; this node cannot be manually promoted until WAL replay is resumed"),
|
|
||||||
cell->node_info->node_name, cell->node_info->node_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
repmgrd_info[i]->upstream_last_seen = get_upstream_last_seen(cell->node_info->conn, cell->node_info->type);
|
|
||||||
if (repmgrd_info[i]->upstream_last_seen < 0)
|
|
||||||
{
|
|
||||||
maxlen_snprintf(repmgrd_info[i]->upstream_last_seen_text, "%s", _("n/a"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (runtime_options.compact == true)
|
|
||||||
{
|
|
||||||
maxlen_snprintf(repmgrd_info[i]->upstream_last_seen_text, _("%i sec(s) ago"), repmgrd_info[i]->upstream_last_seen);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
maxlen_snprintf(repmgrd_info[i]->upstream_last_seen_text, _("%i second(s) ago"), repmgrd_info[i]->upstream_last_seen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initPQExpBuffer(&node_status);
|
|
||||||
initPQExpBuffer(&upstream);
|
|
||||||
|
|
||||||
(void)format_node_status(cell->node_info, &node_status, &upstream, &warnings);
|
|
||||||
snprintf(repmgrd_info[i]->pg_running_text, sizeof(cell->node_info->details),
|
|
||||||
"%s", node_status.data);
|
|
||||||
|
|
||||||
snprintf(cell->node_info->upstream_node_name, sizeof(cell->node_info->upstream_node_name),
|
|
||||||
"%s", upstream.data);
|
|
||||||
|
|
||||||
termPQExpBuffer(&node_status);
|
|
||||||
termPQExpBuffer(&upstream);
|
|
||||||
|
|
||||||
PQfinish(cell->node_info->conn);
|
|
||||||
|
|
||||||
headers_status[STATUS_NAME].cur_length = strlen(cell->node_info->node_name);
|
|
||||||
headers_status[STATUS_ROLE].cur_length = strlen(get_node_type_string(cell->node_info->type));
|
|
||||||
headers_status[STATUS_PG].cur_length = strlen(repmgrd_info[i]->pg_running_text);
|
|
||||||
headers_status[STATUS_UPSTREAM_NAME].cur_length = strlen(cell->node_info->upstream_node_name);
|
|
||||||
|
|
||||||
if (runtime_options.detail == true)
|
|
||||||
{
|
|
||||||
PQExpBufferData buf;
|
|
||||||
|
|
||||||
headers_status[STATUS_LOCATION].cur_length = strlen(cell->node_info->location);
|
|
||||||
|
|
||||||
initPQExpBuffer(&buf);
|
|
||||||
appendPQExpBuffer(&buf, "%i", cell->node_info->priority);
|
|
||||||
headers_status[STATUS_PRIORITY].cur_length = strlen(buf.data);
|
|
||||||
termPQExpBuffer(&buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
headers_status[STATUS_PID].cur_length = strlen(repmgrd_info[i]->pid_text);
|
|
||||||
headers_status[STATUS_REPMGRD].cur_length = strlen(repmgrd_info[i]->repmgrd_running);
|
|
||||||
|
|
||||||
headers_status[STATUS_UPSTREAM_LAST_SEEN].cur_length = strlen(repmgrd_info[i]->upstream_last_seen_text);
|
|
||||||
|
|
||||||
for (j = 0; j < STATUS_HEADER_COUNT; j++)
|
|
||||||
{
|
|
||||||
if (headers_status[j].cur_length > headers_status[j].max_length)
|
|
||||||
{
|
|
||||||
headers_status[j].max_length = headers_status[j].cur_length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print column header row (text mode only) */
|
|
||||||
if (runtime_options.output_mode == OM_TEXT)
|
|
||||||
{
|
|
||||||
print_status_header(STATUS_HEADER_COUNT, headers_status);
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for (cell = nodes.head; cell; cell = cell->next)
|
|
||||||
{
|
|
||||||
if (runtime_options.output_mode == OM_CSV)
|
|
||||||
{
|
|
||||||
int running = repmgrd_info[i]->running ? 1 : 0;
|
|
||||||
int paused = repmgrd_info[i]->paused ? 1 : 0;
|
|
||||||
|
|
||||||
/* If PostgreSQL is not running, repmgrd status is unknown */
|
|
||||||
if (repmgrd_info[i]->pg_running == false)
|
|
||||||
{
|
|
||||||
running = -1;
|
|
||||||
paused = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%i,%s,%s,%i,%i,%i,%i,%i,%i,%s\n",
|
|
||||||
cell->node_info->node_id,
|
|
||||||
cell->node_info->node_name,
|
|
||||||
get_node_type_string(cell->node_info->type),
|
|
||||||
repmgrd_info[i]->pg_running ? 1 : 0,
|
|
||||||
running,
|
|
||||||
repmgrd_info[i]->pid,
|
|
||||||
paused,
|
|
||||||
cell->node_info->priority,
|
|
||||||
repmgrd_info[i]->pid == UNKNOWN_PID
|
|
||||||
? -1
|
|
||||||
: repmgrd_info[i]->upstream_last_seen,
|
|
||||||
cell->node_info->location);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(" %-*i ", headers_status[STATUS_ID].max_length, cell->node_info->node_id);
|
|
||||||
printf("| %-*s ", headers_status[STATUS_NAME].max_length, cell->node_info->node_name);
|
|
||||||
printf("| %-*s ", headers_status[STATUS_ROLE].max_length, get_node_type_string(cell->node_info->type));
|
|
||||||
printf("| %-*s ", headers_status[STATUS_PG].max_length, repmgrd_info[i]->pg_running_text);
|
|
||||||
printf("| %-*s ", headers_status[STATUS_UPSTREAM_NAME].max_length, cell->node_info->upstream_node_name);
|
|
||||||
|
|
||||||
if (runtime_options.detail == true)
|
|
||||||
{
|
|
||||||
printf("| %-*s ", headers_status[STATUS_LOCATION].max_length, cell->node_info->location);
|
|
||||||
printf("| %-*i ", headers_status[STATUS_PRIORITY].max_length, cell->node_info->priority);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("| %-*s ", headers_status[STATUS_REPMGRD].max_length, repmgrd_info[i]->repmgrd_running);
|
|
||||||
printf("| %-*s ", headers_status[STATUS_PID].max_length, repmgrd_info[i]->pid_text);
|
|
||||||
|
|
||||||
if (repmgrd_info[i]->pid == UNKNOWN_PID)
|
|
||||||
{
|
|
||||||
printf("| %-*s ", headers_status[STATUS_PAUSED].max_length, _("n/a"));
|
|
||||||
printf("| %-*s ", headers_status[STATUS_UPSTREAM_LAST_SEEN].max_length, _("n/a"));
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("| %-*s ", headers_status[STATUS_PAUSED].max_length, repmgrd_info[i]->paused ? _("yes") : _("no"));
|
|
||||||
|
|
||||||
printf("| %-*s ", headers_status[STATUS_UPSTREAM_LAST_SEEN].max_length, repmgrd_info[i]->upstream_last_seen_text);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
pfree(repmgrd_info[i]);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
pfree(repmgrd_info);
|
|
||||||
|
|
||||||
/* emit any warnings */
|
|
||||||
|
|
||||||
if (warnings.head != NULL && runtime_options.terse == false && runtime_options.output_mode != OM_CSV)
|
|
||||||
{
|
|
||||||
ItemListCell *cell = NULL;
|
|
||||||
|
|
||||||
printf(_("\nWARNING: following issues were detected\n"));
|
|
||||||
for (cell = warnings.head; cell; cell = cell->next)
|
|
||||||
{
|
|
||||||
printf(_(" - %s\n"), cell->string);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (runtime_options.verbose == false && connection_error_found == true)
|
|
||||||
{
|
|
||||||
log_hint(_("execute with --verbose option to see connection error messages"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
do_daemon_pause(void)
|
|
||||||
{
|
|
||||||
_do_repmgr_pause(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
do_daemon_unpause(void)
|
|
||||||
{
|
|
||||||
_do_repmgr_pause(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
_do_repmgr_pause(bool pause)
|
|
||||||
{
|
|
||||||
PGconn *conn = NULL;
|
|
||||||
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
|
|
||||||
NodeInfoListCell *cell = NULL;
|
|
||||||
int i;
|
|
||||||
int error_nodes = 0;
|
|
||||||
|
|
||||||
/* Connect to local database to obtain cluster connection data */
|
|
||||||
log_verbose(LOG_INFO, _("connecting to database"));
|
|
||||||
|
|
||||||
if (strlen(config_file_options.conninfo))
|
|
||||||
conn = establish_db_connection(config_file_options.conninfo, true);
|
|
||||||
else
|
|
||||||
conn = establish_db_connection_by_params(&source_conninfo, true);
|
|
||||||
|
|
||||||
fetch_node_records(conn, &nodes);
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for (cell = nodes.head; cell; cell = cell->next)
|
|
||||||
{
|
|
||||||
log_verbose(LOG_DEBUG, "pausing node %i (%s)",
|
|
||||||
cell->node_info->node_id,
|
|
||||||
cell->node_info->node_name);
|
|
||||||
cell->node_info->conn = establish_db_connection_quiet(cell->node_info->conninfo);
|
|
||||||
|
|
||||||
if (PQstatus(cell->node_info->conn) != CONNECTION_OK)
|
|
||||||
{
|
|
||||||
log_warning(_("unable to connect to node %i"),
|
|
||||||
cell->node_info->node_id);
|
|
||||||
error_nodes++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (runtime_options.dry_run == true)
|
|
||||||
{
|
|
||||||
if (pause == true)
|
|
||||||
{
|
|
||||||
log_info(_("would pause node %i (%s) "),
|
|
||||||
cell->node_info->node_id,
|
|
||||||
cell->node_info->node_name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log_info(_("would unpause node %i (%s) "),
|
|
||||||
cell->node_info->node_id,
|
|
||||||
cell->node_info->node_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool success = repmgrd_pause(cell->node_info->conn, pause);
|
|
||||||
|
|
||||||
if (success == false)
|
|
||||||
error_nodes++;
|
|
||||||
|
|
||||||
log_notice(_("node %i (%s) %s"),
|
|
||||||
cell->node_info->node_id,
|
|
||||||
cell->node_info->node_name,
|
|
||||||
success == true
|
|
||||||
? pause == true ? "paused" : "unpaused"
|
|
||||||
: pause == true ? "not paused" : "not unpaused");
|
|
||||||
}
|
|
||||||
PQfinish(cell->node_info->conn);
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error_nodes > 0)
|
|
||||||
{
|
|
||||||
if (pause == true)
|
|
||||||
{
|
|
||||||
log_error(_("unable to pause %i node(s)"), error_nodes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log_error(_("unable to unpause %i node(s)"), error_nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
log_hint(_("execute \"repmgr daemon status\" to view current status"));
|
|
||||||
|
|
||||||
exit(ERR_REPMGRD_PAUSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
fetch_node_records(PGconn *conn, NodeInfoList *node_list)
|
|
||||||
{
|
|
||||||
bool success = get_all_node_records_with_upstream(conn, node_list);
|
|
||||||
|
|
||||||
if (success == false)
|
|
||||||
{
|
|
||||||
/* get_all_node_records() will display any error message */
|
|
||||||
PQfinish(conn);
|
|
||||||
exit(ERR_BAD_CONFIG);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node_list->node_count == 0)
|
|
||||||
{
|
|
||||||
log_error(_("no node records were found"));
|
|
||||||
log_hint(_("ensure at least one node is registered"));
|
|
||||||
PQfinish(conn);
|
|
||||||
exit(ERR_BAD_CONFIG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
do_daemon_start(void)
|
do_daemon_start(void)
|
||||||
@@ -583,12 +114,12 @@ do_daemon_start(void)
|
|||||||
|
|
||||||
if (runtime_options.no_wait == true || runtime_options.wait == 0)
|
if (runtime_options.no_wait == true || runtime_options.wait == 0)
|
||||||
{
|
{
|
||||||
log_hint(REPMGR_DAEMON_STATUS_START_HINT);
|
log_hint(REPMGR_SERVICE_STATUS_START_HINT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int timeout = REPMGR_DAEMON_STOP_START_WAIT;
|
int timeout = REPMGR_SERVICE_STOP_START_WAIT;
|
||||||
|
|
||||||
if (runtime_options.wait_provided)
|
if (runtime_options.wait_provided)
|
||||||
timeout = runtime_options.wait;
|
timeout = runtime_options.wait;
|
||||||
@@ -598,7 +129,7 @@ do_daemon_start(void)
|
|||||||
if (PQstatus(conn) != CONNECTION_OK)
|
if (PQstatus(conn) != CONNECTION_OK)
|
||||||
{
|
{
|
||||||
log_notice(_("unable to connect to local node"));
|
log_notice(_("unable to connect to local node"));
|
||||||
log_hint(REPMGR_DAEMON_STATUS_START_HINT);
|
log_hint(REPMGR_SERVICE_STATUS_START_HINT);
|
||||||
exit(ERR_DB_CONN);
|
exit(ERR_DB_CONN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,7 +147,7 @@ do_daemon_start(void)
|
|||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
log_error(_("repmgrd does not appear to have started after %i seconds"),
|
log_error(_("repmgrd does not appear to have started after %i seconds"),
|
||||||
timeout);
|
timeout);
|
||||||
log_hint(REPMGR_DAEMON_STATUS_START_HINT);
|
log_hint(REPMGR_SERVICE_STATUS_START_HINT);
|
||||||
exit(ERR_REPMGRD_SERVICE);
|
exit(ERR_REPMGRD_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,12 +243,12 @@ void do_daemon_stop(void)
|
|||||||
if (runtime_options.no_wait == true || runtime_options.wait == 0)
|
if (runtime_options.no_wait == true || runtime_options.wait == 0)
|
||||||
{
|
{
|
||||||
if (have_db_connection == true)
|
if (have_db_connection == true)
|
||||||
log_hint(REPMGR_DAEMON_STATUS_STOP_HINT);
|
log_hint(REPMGR_SERVICE_STATUS_STOP_HINT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int timeout = REPMGR_DAEMON_STOP_START_WAIT;
|
int timeout = REPMGR_SERVICE_STOP_START_WAIT;
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -732,7 +263,7 @@ void do_daemon_stop(void)
|
|||||||
log_warning(_("unable to determine repmgrd PID"));
|
log_warning(_("unable to determine repmgrd PID"));
|
||||||
|
|
||||||
if (have_db_connection == true)
|
if (have_db_connection == true)
|
||||||
log_hint(REPMGR_DAEMON_STATUS_STOP_HINT);
|
log_hint(REPMGR_SERVICE_STATUS_STOP_HINT);
|
||||||
|
|
||||||
exit(ERR_REPMGRD_SERVICE);
|
exit(ERR_REPMGRD_SERVICE);
|
||||||
}
|
}
|
||||||
@@ -764,7 +295,7 @@ void do_daemon_stop(void)
|
|||||||
timeout);
|
timeout);
|
||||||
|
|
||||||
if (have_db_connection == true)
|
if (have_db_connection == true)
|
||||||
log_hint(REPMGR_DAEMON_STATUS_START_HINT);
|
log_hint(REPMGR_SERVICE_STATUS_START_HINT);
|
||||||
|
|
||||||
exit(ERR_REPMGRD_SERVICE);
|
exit(ERR_REPMGRD_SERVICE);
|
||||||
}
|
}
|
||||||
@@ -783,53 +314,29 @@ void do_daemon_help(void)
|
|||||||
print_help_header();
|
print_help_header();
|
||||||
|
|
||||||
printf(_("Usage:\n"));
|
printf(_("Usage:\n"));
|
||||||
printf(_(" %s [OPTIONS] daemon status\n"), progname());
|
|
||||||
printf(_(" %s [OPTIONS] daemon pause\n"), progname());
|
|
||||||
printf(_(" %s [OPTIONS] daemon unpause\n"), progname());
|
|
||||||
printf(_(" %s [OPTIONS] daemon start\n"), progname());
|
printf(_(" %s [OPTIONS] daemon start\n"), progname());
|
||||||
printf(_(" %s [OPTIONS] daemon stop\n"), progname());
|
printf(_(" %s [OPTIONS] daemon stop\n"), progname());
|
||||||
puts("");
|
|
||||||
|
|
||||||
printf(_("DAEMON STATUS\n"));
|
|
||||||
puts("");
|
|
||||||
printf(_(" \"daemon status\" shows the status of repmgrd on each node in the cluster\n"));
|
|
||||||
puts("");
|
|
||||||
printf(_(" --csv emit output as CSV\n"));
|
|
||||||
printf(_(" --detail show additional detail\n"));
|
|
||||||
printf(_(" --verbose show text of database connection error messages\n"));
|
|
||||||
puts("");
|
puts("");
|
||||||
|
|
||||||
printf(_("DAEMON START\n"));
|
printf(_("DAEMON START\n"));
|
||||||
puts("");
|
puts("");
|
||||||
printf(_(" \"daemon start\" attempts to start repmgrd\n"));
|
printf(_(" \"daemon start\" attempts to start repmgrd on the local node\n"));
|
||||||
puts("");
|
puts("");
|
||||||
printf(_(" --dry-run check prerequisites but don't start repmgrd\n"));
|
printf(_(" --dry-run check prerequisites but don't start repmgrd\n"));
|
||||||
printf(_(" -w/--wait wait for repmgrd to start (default: %i seconds)\n"), REPMGR_DAEMON_STOP_START_WAIT);
|
printf(_(" -w/--wait wait for repmgrd to start (default: %i seconds)\n"), REPMGR_SERVICE_STOP_START_WAIT);
|
||||||
printf(_(" --no-wait don't wait for repmgrd to start\n"));
|
printf(_(" --no-wait don't wait for repmgrd to start\n"));
|
||||||
puts("");
|
puts("");
|
||||||
|
|
||||||
printf(_("DAEMON STOP\n"));
|
printf(_("DAEMON STOP\n"));
|
||||||
puts("");
|
puts("");
|
||||||
printf(_(" \"daemon stop\" attempts to stop repmgrd\n"));
|
printf(_(" \"daemon stop\" attempts to stop repmgrd on the local node\n"));
|
||||||
puts("");
|
puts("");
|
||||||
printf(_(" --dry-run check prerequisites but don't stop repmgrd\n"));
|
printf(_(" --dry-run check prerequisites but don't stop repmgrd\n"));
|
||||||
printf(_(" -w/--wait wait for repmgrd to stop (default: %i seconds)\n"), REPMGR_DAEMON_STOP_START_WAIT);
|
printf(_(" -w/--wait wait for repmgrd to stop (default: %i seconds)\n"), REPMGR_SERVICE_STOP_START_WAIT);
|
||||||
printf(_(" --no-wait don't wait for repmgrd to stop\n"));
|
printf(_(" --no-wait don't wait for repmgrd to stop\n"));
|
||||||
puts("");
|
puts("");
|
||||||
|
|
||||||
printf(_("DAEMON PAUSE\n"));
|
|
||||||
puts("");
|
|
||||||
printf(_(" \"daemon pause\" instructs repmgrd on each node to pause failover detection\n"));
|
|
||||||
puts("");
|
|
||||||
printf(_(" --dry-run check if nodes are reachable but don't pause repmgrd\n"));
|
|
||||||
puts("");
|
puts("");
|
||||||
|
|
||||||
printf(_("DAEMON UNPAUSE\n"));
|
|
||||||
puts("");
|
|
||||||
printf(_(" \"daemon unpause\" instructs repmgrd on each node to resume failover detection\n"));
|
|
||||||
puts("");
|
|
||||||
printf(_(" --dry-run check if nodes are reachable but don't unpause repmgrd\n"));
|
|
||||||
puts("");
|
|
||||||
|
|
||||||
puts("");
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,6 @@
|
|||||||
#ifndef _REPMGR_ACTION_DAEMON_H_
|
#ifndef _REPMGR_ACTION_DAEMON_H_
|
||||||
#define _REPMGR_ACTION_DAEMON_H_
|
#define _REPMGR_ACTION_DAEMON_H_
|
||||||
|
|
||||||
|
|
||||||
extern void do_daemon_status(void);
|
|
||||||
extern void do_daemon_pause(void);
|
|
||||||
extern void do_daemon_unpause(void);
|
|
||||||
extern void do_daemon_start(void);
|
extern void do_daemon_start(void);
|
||||||
extern void do_daemon_stop(void);
|
extern void do_daemon_stop(void);
|
||||||
|
|
||||||
|
|||||||
535
repmgr-action-service.c
Normal file
535
repmgr-action-service.c
Normal file
@@ -0,0 +1,535 @@
|
|||||||
|
/*
|
||||||
|
* repmgr-action-service.c
|
||||||
|
*
|
||||||
|
* Implements repmgrd actions for the repmgr command line utility
|
||||||
|
* Copyright (c) 2ndQuadrant, 2010-2019
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/stat.h> /* for stat() */
|
||||||
|
|
||||||
|
#include "repmgr.h"
|
||||||
|
|
||||||
|
#include "repmgr-client-global.h"
|
||||||
|
#include "repmgr-action-service.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Possibly also show:
|
||||||
|
* - repmgrd start time?
|
||||||
|
* - repmgrd mode
|
||||||
|
* - priority
|
||||||
|
* - whether promotion candidate (due to zero priority/different location)
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
STATUS_ID = 0,
|
||||||
|
STATUS_NAME,
|
||||||
|
STATUS_ROLE,
|
||||||
|
STATUS_PG,
|
||||||
|
STATUS_UPSTREAM_NAME,
|
||||||
|
STATUS_LOCATION,
|
||||||
|
STATUS_PRIORITY,
|
||||||
|
STATUS_REPMGRD,
|
||||||
|
STATUS_PID,
|
||||||
|
STATUS_PAUSED,
|
||||||
|
STATUS_UPSTREAM_LAST_SEEN
|
||||||
|
} StatusHeader;
|
||||||
|
|
||||||
|
#define STATUS_HEADER_COUNT 11
|
||||||
|
|
||||||
|
struct ColHeader headers_status[STATUS_HEADER_COUNT];
|
||||||
|
|
||||||
|
static void fetch_node_records(PGconn *conn, NodeInfoList *node_list);
|
||||||
|
static void _do_repmgr_pause(bool pause);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
do_service_status(void)
|
||||||
|
{
|
||||||
|
PGconn *conn = NULL;
|
||||||
|
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
|
||||||
|
NodeInfoListCell *cell = NULL;
|
||||||
|
int i;
|
||||||
|
RepmgrdInfo **repmgrd_info;
|
||||||
|
ItemList warnings = {NULL, NULL};
|
||||||
|
bool connection_error_found = false;
|
||||||
|
|
||||||
|
/* Connect to local database to obtain cluster connection data */
|
||||||
|
log_verbose(LOG_INFO, _("connecting to database"));
|
||||||
|
|
||||||
|
if (strlen(config_file_options.conninfo))
|
||||||
|
conn = establish_db_connection(config_file_options.conninfo, true);
|
||||||
|
else
|
||||||
|
conn = establish_db_connection_by_params(&source_conninfo, true);
|
||||||
|
|
||||||
|
fetch_node_records(conn, &nodes);
|
||||||
|
|
||||||
|
repmgrd_info = (RepmgrdInfo **) pg_malloc0(sizeof(RepmgrdInfo *) * nodes.node_count);
|
||||||
|
|
||||||
|
if (repmgrd_info == NULL)
|
||||||
|
{
|
||||||
|
log_error(_("unable to allocate memory"));
|
||||||
|
exit(ERR_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(headers_status[STATUS_ID].title, _("ID"), MAXLEN);
|
||||||
|
strncpy(headers_status[STATUS_NAME].title, _("Name"), MAXLEN);
|
||||||
|
strncpy(headers_status[STATUS_ROLE].title, _("Role"), MAXLEN);
|
||||||
|
strncpy(headers_status[STATUS_PG].title, _("Status"), MAXLEN);
|
||||||
|
strncpy(headers_status[STATUS_UPSTREAM_NAME].title, _("Upstream"), MAXLEN);
|
||||||
|
|
||||||
|
/* following only displayed with the --detail option */
|
||||||
|
strncpy(headers_status[STATUS_LOCATION].title, _("Location"), MAXLEN);
|
||||||
|
if (runtime_options.compact == true)
|
||||||
|
strncpy(headers_status[STATUS_PRIORITY].title, _("Prio."), MAXLEN);
|
||||||
|
else
|
||||||
|
strncpy(headers_status[STATUS_PRIORITY].title, _("Priority"), MAXLEN);
|
||||||
|
|
||||||
|
strncpy(headers_status[STATUS_REPMGRD].title, _("repmgrd"), MAXLEN);
|
||||||
|
strncpy(headers_status[STATUS_PID].title, _("PID"), MAXLEN);
|
||||||
|
strncpy(headers_status[STATUS_PAUSED].title, _("Paused?"), MAXLEN);
|
||||||
|
|
||||||
|
if (runtime_options.compact == true)
|
||||||
|
strncpy(headers_status[STATUS_UPSTREAM_LAST_SEEN].title, _("Upstr. last"), MAXLEN);
|
||||||
|
else
|
||||||
|
strncpy(headers_status[STATUS_UPSTREAM_LAST_SEEN].title, _("Upstream last seen"), MAXLEN);
|
||||||
|
|
||||||
|
for (i = 0; i < STATUS_HEADER_COUNT; i++)
|
||||||
|
{
|
||||||
|
headers_status[i].max_length = strlen(headers_status[i].title);
|
||||||
|
headers_status[i].display = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runtime_options.detail == false)
|
||||||
|
{
|
||||||
|
headers_status[STATUS_LOCATION].display = false;
|
||||||
|
headers_status[STATUS_PRIORITY].display = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
for (cell = nodes.head; cell; cell = cell->next)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
PQExpBufferData node_status;
|
||||||
|
PQExpBufferData upstream;
|
||||||
|
|
||||||
|
repmgrd_info[i] = pg_malloc0(sizeof(RepmgrdInfo));
|
||||||
|
repmgrd_info[i]->node_id = cell->node_info->node_id;
|
||||||
|
repmgrd_info[i]->pid = UNKNOWN_PID;
|
||||||
|
repmgrd_info[i]->recovery_type = RECTYPE_UNKNOWN;
|
||||||
|
repmgrd_info[i]->paused = false;
|
||||||
|
repmgrd_info[i]->running = false;
|
||||||
|
repmgrd_info[i]->pg_running = true;
|
||||||
|
repmgrd_info[i]->wal_paused_pending_wal = false;
|
||||||
|
repmgrd_info[i]->upstream_last_seen = -1;
|
||||||
|
|
||||||
|
cell->node_info->conn = establish_db_connection_quiet(cell->node_info->conninfo);
|
||||||
|
|
||||||
|
if (PQstatus(cell->node_info->conn) != CONNECTION_OK)
|
||||||
|
{
|
||||||
|
|
||||||
|
connection_error_found = true;
|
||||||
|
|
||||||
|
if (runtime_options.verbose)
|
||||||
|
{
|
||||||
|
char error[MAXLEN];
|
||||||
|
|
||||||
|
strncpy(error, PQerrorMessage(cell->node_info->conn), MAXLEN);
|
||||||
|
|
||||||
|
item_list_append_format(&warnings,
|
||||||
|
"when attempting to connect to node \"%s\" (ID: %i), following error encountered :\n\"%s\"",
|
||||||
|
cell->node_info->node_name, cell->node_info->node_id, trim(error));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item_list_append_format(&warnings,
|
||||||
|
"unable to connect to node \"%s\" (ID: %i)",
|
||||||
|
cell->node_info->node_name, cell->node_info->node_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
repmgrd_info[i]->pg_running = false;
|
||||||
|
maxlen_snprintf(repmgrd_info[i]->repmgrd_running, "%s", _("n/a"));
|
||||||
|
maxlen_snprintf(repmgrd_info[i]->pid_text, "%s", _("n/a"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cell->node_info->node_status = NODE_STATUS_UP;
|
||||||
|
cell->node_info->recovery_type = get_recovery_type(cell->node_info->conn);
|
||||||
|
|
||||||
|
repmgrd_info[i]->pid = repmgrd_get_pid(cell->node_info->conn);
|
||||||
|
|
||||||
|
repmgrd_info[i]->running = repmgrd_is_running(cell->node_info->conn);
|
||||||
|
|
||||||
|
if (repmgrd_info[i]->running == true)
|
||||||
|
{
|
||||||
|
maxlen_snprintf(repmgrd_info[i]->repmgrd_running, "%s", _("running"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxlen_snprintf(repmgrd_info[i]->repmgrd_running, "%s", _("not running"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (repmgrd_info[i]->pid == UNKNOWN_PID)
|
||||||
|
{
|
||||||
|
maxlen_snprintf(repmgrd_info[i]->pid_text, "%s", _("n/a"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxlen_snprintf(repmgrd_info[i]->pid_text, "%i", repmgrd_info[i]->pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
repmgrd_info[i]->paused = repmgrd_is_paused(cell->node_info->conn);
|
||||||
|
|
||||||
|
repmgrd_info[i]->recovery_type = get_recovery_type(cell->node_info->conn);
|
||||||
|
|
||||||
|
if (repmgrd_info[i]->recovery_type == RECTYPE_STANDBY)
|
||||||
|
{
|
||||||
|
repmgrd_info[i]->wal_paused_pending_wal = is_wal_replay_paused(cell->node_info->conn, true);
|
||||||
|
|
||||||
|
if (repmgrd_info[i]->wal_paused_pending_wal == true)
|
||||||
|
{
|
||||||
|
item_list_append_format(&warnings,
|
||||||
|
_("WAL replay is paused on node \"%s\" (ID: %i) with WAL replay pending; this node cannot be manually promoted until WAL replay is resumed"),
|
||||||
|
cell->node_info->node_name, cell->node_info->node_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repmgrd_info[i]->upstream_last_seen = get_upstream_last_seen(cell->node_info->conn, cell->node_info->type);
|
||||||
|
if (repmgrd_info[i]->upstream_last_seen < 0)
|
||||||
|
{
|
||||||
|
maxlen_snprintf(repmgrd_info[i]->upstream_last_seen_text, "%s", _("n/a"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (runtime_options.compact == true)
|
||||||
|
{
|
||||||
|
maxlen_snprintf(repmgrd_info[i]->upstream_last_seen_text, _("%i sec(s) ago"), repmgrd_info[i]->upstream_last_seen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxlen_snprintf(repmgrd_info[i]->upstream_last_seen_text, _("%i second(s) ago"), repmgrd_info[i]->upstream_last_seen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initPQExpBuffer(&node_status);
|
||||||
|
initPQExpBuffer(&upstream);
|
||||||
|
|
||||||
|
(void)format_node_status(cell->node_info, &node_status, &upstream, &warnings);
|
||||||
|
snprintf(repmgrd_info[i]->pg_running_text, sizeof(cell->node_info->details),
|
||||||
|
"%s", node_status.data);
|
||||||
|
|
||||||
|
snprintf(cell->node_info->upstream_node_name, sizeof(cell->node_info->upstream_node_name),
|
||||||
|
"%s", upstream.data);
|
||||||
|
|
||||||
|
termPQExpBuffer(&node_status);
|
||||||
|
termPQExpBuffer(&upstream);
|
||||||
|
|
||||||
|
PQfinish(cell->node_info->conn);
|
||||||
|
|
||||||
|
headers_status[STATUS_NAME].cur_length = strlen(cell->node_info->node_name);
|
||||||
|
headers_status[STATUS_ROLE].cur_length = strlen(get_node_type_string(cell->node_info->type));
|
||||||
|
headers_status[STATUS_PG].cur_length = strlen(repmgrd_info[i]->pg_running_text);
|
||||||
|
headers_status[STATUS_UPSTREAM_NAME].cur_length = strlen(cell->node_info->upstream_node_name);
|
||||||
|
|
||||||
|
if (runtime_options.detail == true)
|
||||||
|
{
|
||||||
|
PQExpBufferData buf;
|
||||||
|
|
||||||
|
headers_status[STATUS_LOCATION].cur_length = strlen(cell->node_info->location);
|
||||||
|
|
||||||
|
initPQExpBuffer(&buf);
|
||||||
|
appendPQExpBuffer(&buf, "%i", cell->node_info->priority);
|
||||||
|
headers_status[STATUS_PRIORITY].cur_length = strlen(buf.data);
|
||||||
|
termPQExpBuffer(&buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
headers_status[STATUS_PID].cur_length = strlen(repmgrd_info[i]->pid_text);
|
||||||
|
headers_status[STATUS_REPMGRD].cur_length = strlen(repmgrd_info[i]->repmgrd_running);
|
||||||
|
|
||||||
|
headers_status[STATUS_UPSTREAM_LAST_SEEN].cur_length = strlen(repmgrd_info[i]->upstream_last_seen_text);
|
||||||
|
|
||||||
|
for (j = 0; j < STATUS_HEADER_COUNT; j++)
|
||||||
|
{
|
||||||
|
if (headers_status[j].cur_length > headers_status[j].max_length)
|
||||||
|
{
|
||||||
|
headers_status[j].max_length = headers_status[j].cur_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print column header row (text mode only) */
|
||||||
|
if (runtime_options.output_mode == OM_TEXT)
|
||||||
|
{
|
||||||
|
print_status_header(STATUS_HEADER_COUNT, headers_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
for (cell = nodes.head; cell; cell = cell->next)
|
||||||
|
{
|
||||||
|
if (runtime_options.output_mode == OM_CSV)
|
||||||
|
{
|
||||||
|
int running = repmgrd_info[i]->running ? 1 : 0;
|
||||||
|
int paused = repmgrd_info[i]->paused ? 1 : 0;
|
||||||
|
|
||||||
|
/* If PostgreSQL is not running, repmgrd status is unknown */
|
||||||
|
if (repmgrd_info[i]->pg_running == false)
|
||||||
|
{
|
||||||
|
running = -1;
|
||||||
|
paused = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%i,%s,%s,%i,%i,%i,%i,%i,%i,%s\n",
|
||||||
|
cell->node_info->node_id,
|
||||||
|
cell->node_info->node_name,
|
||||||
|
get_node_type_string(cell->node_info->type),
|
||||||
|
repmgrd_info[i]->pg_running ? 1 : 0,
|
||||||
|
running,
|
||||||
|
repmgrd_info[i]->pid,
|
||||||
|
paused,
|
||||||
|
cell->node_info->priority,
|
||||||
|
repmgrd_info[i]->pid == UNKNOWN_PID
|
||||||
|
? -1
|
||||||
|
: repmgrd_info[i]->upstream_last_seen,
|
||||||
|
cell->node_info->location);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(" %-*i ", headers_status[STATUS_ID].max_length, cell->node_info->node_id);
|
||||||
|
printf("| %-*s ", headers_status[STATUS_NAME].max_length, cell->node_info->node_name);
|
||||||
|
printf("| %-*s ", headers_status[STATUS_ROLE].max_length, get_node_type_string(cell->node_info->type));
|
||||||
|
printf("| %-*s ", headers_status[STATUS_PG].max_length, repmgrd_info[i]->pg_running_text);
|
||||||
|
printf("| %-*s ", headers_status[STATUS_UPSTREAM_NAME].max_length, cell->node_info->upstream_node_name);
|
||||||
|
|
||||||
|
if (runtime_options.detail == true)
|
||||||
|
{
|
||||||
|
printf("| %-*s ", headers_status[STATUS_LOCATION].max_length, cell->node_info->location);
|
||||||
|
printf("| %-*i ", headers_status[STATUS_PRIORITY].max_length, cell->node_info->priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("| %-*s ", headers_status[STATUS_REPMGRD].max_length, repmgrd_info[i]->repmgrd_running);
|
||||||
|
printf("| %-*s ", headers_status[STATUS_PID].max_length, repmgrd_info[i]->pid_text);
|
||||||
|
|
||||||
|
if (repmgrd_info[i]->pid == UNKNOWN_PID)
|
||||||
|
{
|
||||||
|
printf("| %-*s ", headers_status[STATUS_PAUSED].max_length, _("n/a"));
|
||||||
|
printf("| %-*s ", headers_status[STATUS_UPSTREAM_LAST_SEEN].max_length, _("n/a"));
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("| %-*s ", headers_status[STATUS_PAUSED].max_length, repmgrd_info[i]->paused ? _("yes") : _("no"));
|
||||||
|
|
||||||
|
printf("| %-*s ", headers_status[STATUS_UPSTREAM_LAST_SEEN].max_length, repmgrd_info[i]->upstream_last_seen_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
pfree(repmgrd_info[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pfree(repmgrd_info);
|
||||||
|
|
||||||
|
/* emit any warnings */
|
||||||
|
|
||||||
|
if (warnings.head != NULL && runtime_options.terse == false && runtime_options.output_mode != OM_CSV)
|
||||||
|
{
|
||||||
|
ItemListCell *cell = NULL;
|
||||||
|
|
||||||
|
printf(_("\nWARNING: following issues were detected\n"));
|
||||||
|
for (cell = warnings.head; cell; cell = cell->next)
|
||||||
|
{
|
||||||
|
printf(_(" - %s\n"), cell->string);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runtime_options.verbose == false && connection_error_found == true)
|
||||||
|
{
|
||||||
|
log_hint(_("execute with --verbose option to see connection error messages"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
do_service_pause(void)
|
||||||
|
{
|
||||||
|
_do_repmgr_pause(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
do_service_unpause(void)
|
||||||
|
{
|
||||||
|
_do_repmgr_pause(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_do_repmgr_pause(bool pause)
|
||||||
|
{
|
||||||
|
PGconn *conn = NULL;
|
||||||
|
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
|
||||||
|
NodeInfoListCell *cell = NULL;
|
||||||
|
int i;
|
||||||
|
int error_nodes = 0;
|
||||||
|
|
||||||
|
/* Connect to local database to obtain cluster connection data */
|
||||||
|
log_verbose(LOG_INFO, _("connecting to database"));
|
||||||
|
|
||||||
|
if (strlen(config_file_options.conninfo))
|
||||||
|
conn = establish_db_connection(config_file_options.conninfo, true);
|
||||||
|
else
|
||||||
|
conn = establish_db_connection_by_params(&source_conninfo, true);
|
||||||
|
|
||||||
|
fetch_node_records(conn, &nodes);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
for (cell = nodes.head; cell; cell = cell->next)
|
||||||
|
{
|
||||||
|
log_verbose(LOG_DEBUG, "pausing node %i (%s)",
|
||||||
|
cell->node_info->node_id,
|
||||||
|
cell->node_info->node_name);
|
||||||
|
cell->node_info->conn = establish_db_connection_quiet(cell->node_info->conninfo);
|
||||||
|
|
||||||
|
if (PQstatus(cell->node_info->conn) != CONNECTION_OK)
|
||||||
|
{
|
||||||
|
log_warning(_("unable to connect to node %i"),
|
||||||
|
cell->node_info->node_id);
|
||||||
|
error_nodes++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (runtime_options.dry_run == true)
|
||||||
|
{
|
||||||
|
if (pause == true)
|
||||||
|
{
|
||||||
|
log_info(_("would pause node %i (%s) "),
|
||||||
|
cell->node_info->node_id,
|
||||||
|
cell->node_info->node_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_info(_("would unpause node %i (%s) "),
|
||||||
|
cell->node_info->node_id,
|
||||||
|
cell->node_info->node_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool success = repmgrd_pause(cell->node_info->conn, pause);
|
||||||
|
|
||||||
|
if (success == false)
|
||||||
|
error_nodes++;
|
||||||
|
|
||||||
|
log_notice(_("node %i (%s) %s"),
|
||||||
|
cell->node_info->node_id,
|
||||||
|
cell->node_info->node_name,
|
||||||
|
success == true
|
||||||
|
? pause == true ? "paused" : "unpaused"
|
||||||
|
: pause == true ? "not paused" : "not unpaused");
|
||||||
|
}
|
||||||
|
PQfinish(cell->node_info->conn);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_nodes > 0)
|
||||||
|
{
|
||||||
|
if (pause == true)
|
||||||
|
{
|
||||||
|
log_error(_("unable to pause %i node(s)"), error_nodes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_error(_("unable to unpause %i node(s)"), error_nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
log_hint(_("execute \"repmgr service status\" to view current status"));
|
||||||
|
|
||||||
|
exit(ERR_REPMGRD_PAUSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
fetch_node_records(PGconn *conn, NodeInfoList *node_list)
|
||||||
|
{
|
||||||
|
bool success = get_all_node_records_with_upstream(conn, node_list);
|
||||||
|
|
||||||
|
if (success == false)
|
||||||
|
{
|
||||||
|
/* get_all_node_records() will display any error message */
|
||||||
|
PQfinish(conn);
|
||||||
|
exit(ERR_BAD_CONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node_list->node_count == 0)
|
||||||
|
{
|
||||||
|
log_error(_("no node records were found"));
|
||||||
|
log_hint(_("ensure at least one node is registered"));
|
||||||
|
PQfinish(conn);
|
||||||
|
exit(ERR_BAD_CONFIG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void do_service_help(void)
|
||||||
|
{
|
||||||
|
print_help_header();
|
||||||
|
|
||||||
|
printf(_("Usage:\n"));
|
||||||
|
printf(_(" %s [OPTIONS] service status\n"), progname());
|
||||||
|
printf(_(" %s [OPTIONS] service pause\n"), progname());
|
||||||
|
printf(_(" %s [OPTIONS] service unpause\n"), progname());
|
||||||
|
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
printf(_("SERVICE STATUS\n"));
|
||||||
|
puts("");
|
||||||
|
printf(_(" \"service status\" shows the status of repmgrd on each node in the cluster\n"));
|
||||||
|
puts("");
|
||||||
|
printf(_(" --csv emit output as CSV\n"));
|
||||||
|
printf(_(" --detail show additional detail\n"));
|
||||||
|
printf(_(" --verbose show text of database connection error messages\n"));
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
printf(_("SERVICE PAUSE\n"));
|
||||||
|
puts("");
|
||||||
|
printf(_(" \"service pause\" instructs repmgrd on each node to pause failover detection\n"));
|
||||||
|
puts("");
|
||||||
|
printf(_(" --dry-run check if nodes are reachable but don't pause repmgrd\n"));
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
printf(_("SERVICE UNPAUSE\n"));
|
||||||
|
puts("");
|
||||||
|
printf(_(" \"service unpause\" instructs repmgrd on each node to resume failover detection\n"));
|
||||||
|
puts("");
|
||||||
|
printf(_(" --dry-run check if nodes are reachable but don't unpause repmgrd\n"));
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
28
repmgr-action-service.h
Normal file
28
repmgr-action-service.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* repmgr-action-service.h
|
||||||
|
* Copyright (c) 2ndQuadrant, 2010-2019
|
||||||
|
*
|
||||||
|
* 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 _REPMGR_ACTION_SERVICE_H_
|
||||||
|
#define _REPMGR_ACTION_SERVICE_H_
|
||||||
|
|
||||||
|
|
||||||
|
extern void do_service_status(void);
|
||||||
|
extern void do_service_pause(void);
|
||||||
|
extern void do_service_unpause(void);
|
||||||
|
|
||||||
|
extern void do_service_help(void);
|
||||||
|
#endif
|
||||||
@@ -4782,7 +4782,7 @@ do_standby_switchover(void)
|
|||||||
log_warning(_("unable to unpause repmgrd on %i node(s)"),
|
log_warning(_("unable to unpause repmgrd on %i node(s)"),
|
||||||
error_node_count);
|
error_node_count);
|
||||||
log_detail(_("errors encountered for following node(s):\n%s"), detail.data);
|
log_detail(_("errors encountered for following node(s):\n%s"), detail.data);
|
||||||
log_hint(_("check node connection and status; unpause manually with \"repmgr daemon unpause\""));
|
log_hint(_("check node connection and status; unpause manually with \"repmgr service unpause\""));
|
||||||
|
|
||||||
termPQExpBuffer(&detail);
|
termPQExpBuffer(&detail);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,9 +33,10 @@
|
|||||||
* NODE SERVICE
|
* NODE SERVICE
|
||||||
* NODE CONTROL
|
* NODE CONTROL
|
||||||
*
|
*
|
||||||
* DAEMON STATUS
|
* SERVICE STATUS
|
||||||
* DAEMON PAUSE
|
* SERVICE PAUSE
|
||||||
* DAEMON UNPAUSE
|
* SERVICE UNPAUSE
|
||||||
|
*
|
||||||
* DAEMON START
|
* DAEMON START
|
||||||
* DAEMON STOP
|
* DAEMON STOP
|
||||||
*
|
*
|
||||||
@@ -69,6 +70,7 @@
|
|||||||
#include "repmgr-action-bdr.h"
|
#include "repmgr-action-bdr.h"
|
||||||
#include "repmgr-action-node.h"
|
#include "repmgr-action-node.h"
|
||||||
#include "repmgr-action-cluster.h"
|
#include "repmgr-action-cluster.h"
|
||||||
|
#include "repmgr-action-service.h"
|
||||||
#include "repmgr-action-daemon.h"
|
#include "repmgr-action-daemon.h"
|
||||||
|
|
||||||
#include <storage/fd.h> /* for PG_TEMP_FILE_PREFIX */
|
#include <storage/fd.h> /* for PG_TEMP_FILE_PREFIX */
|
||||||
@@ -813,7 +815,7 @@ main(int argc, char **argv)
|
|||||||
* BDR { REGISTER | UNREGISTER } |
|
* BDR { REGISTER | UNREGISTER } |
|
||||||
* NODE { STATUS | CHECK | REJOIN | SERVICE } |
|
* NODE { STATUS | CHECK | REJOIN | SERVICE } |
|
||||||
* CLUSTER { CROSSCHECK | MATRIX | SHOW | EVENT | CLEANUP }
|
* CLUSTER { CROSSCHECK | MATRIX | SHOW | EVENT | CLEANUP }
|
||||||
* DAEMON { STATUS | PAUSE | UNPAUSE | START | STOP }
|
* SERVICE { STATUS | PAUSE | UNPAUSE | START | STOP }
|
||||||
*
|
*
|
||||||
* [node] is an optional hostname, provided instead of the -h/--host
|
* [node] is an optional hostname, provided instead of the -h/--host
|
||||||
* option
|
* option
|
||||||
@@ -952,6 +954,22 @@ main(int argc, char **argv)
|
|||||||
else if (strcasecmp(repmgr_action, "CLEANUP") == 0)
|
else if (strcasecmp(repmgr_action, "CLEANUP") == 0)
|
||||||
action = CLUSTER_CLEANUP;
|
action = CLUSTER_CLEANUP;
|
||||||
}
|
}
|
||||||
|
else if (strcasecmp(repmgr_command, "SERVICE") == 0)
|
||||||
|
{
|
||||||
|
if (help_option == true)
|
||||||
|
{
|
||||||
|
do_service_help();
|
||||||
|
exit(SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcasecmp(repmgr_action, "STATUS") == 0)
|
||||||
|
action = SERVICE_STATUS;
|
||||||
|
else if (strcasecmp(repmgr_action, "PAUSE") == 0)
|
||||||
|
action = SERVICE_PAUSE;
|
||||||
|
else if (strcasecmp(repmgr_action, "UNPAUSE") == 0)
|
||||||
|
action = SERVICE_UNPAUSE;
|
||||||
|
|
||||||
|
}
|
||||||
else if (strcasecmp(repmgr_command, "DAEMON") == 0)
|
else if (strcasecmp(repmgr_command, "DAEMON") == 0)
|
||||||
{
|
{
|
||||||
if (help_option == true)
|
if (help_option == true)
|
||||||
@@ -960,16 +978,18 @@ main(int argc, char **argv)
|
|||||||
exit(SUCCESS);
|
exit(SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(repmgr_action, "STATUS") == 0)
|
if (strcasecmp(repmgr_action, "START") == 0)
|
||||||
action = DAEMON_STATUS;
|
|
||||||
else if (strcasecmp(repmgr_action, "PAUSE") == 0)
|
|
||||||
action = DAEMON_PAUSE;
|
|
||||||
else if (strcasecmp(repmgr_action, "UNPAUSE") == 0)
|
|
||||||
action = DAEMON_UNPAUSE;
|
|
||||||
else if (strcasecmp(repmgr_action, "START") == 0)
|
|
||||||
action = DAEMON_START;
|
action = DAEMON_START;
|
||||||
else if (strcasecmp(repmgr_action, "STOP") == 0)
|
else if (strcasecmp(repmgr_action, "STOP") == 0)
|
||||||
action = DAEMON_STOP;
|
action = DAEMON_STOP;
|
||||||
|
|
||||||
|
/* allow "daemon" as an alias for "service" for repmgr 4.x compatibility */
|
||||||
|
if (strcasecmp(repmgr_action, "STATUS") == 0)
|
||||||
|
action = SERVICE_STATUS;
|
||||||
|
else if (strcasecmp(repmgr_action, "PAUSE") == 0)
|
||||||
|
action = SERVICE_PAUSE;
|
||||||
|
else if (strcasecmp(repmgr_action, "UNPAUSE") == 0)
|
||||||
|
action = SERVICE_UNPAUSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1372,16 +1392,18 @@ main(int argc, char **argv)
|
|||||||
do_cluster_cleanup();
|
do_cluster_cleanup();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* SERVICE */
|
||||||
|
case SERVICE_STATUS:
|
||||||
|
do_service_status();
|
||||||
|
break;
|
||||||
|
case SERVICE_PAUSE:
|
||||||
|
do_service_pause();
|
||||||
|
break;
|
||||||
|
case SERVICE_UNPAUSE:
|
||||||
|
do_service_unpause();
|
||||||
|
break;
|
||||||
|
|
||||||
/* DAEMON */
|
/* DAEMON */
|
||||||
case DAEMON_STATUS:
|
|
||||||
do_daemon_status();
|
|
||||||
break;
|
|
||||||
case DAEMON_PAUSE:
|
|
||||||
do_daemon_pause();
|
|
||||||
break;
|
|
||||||
case DAEMON_UNPAUSE:
|
|
||||||
do_daemon_unpause();
|
|
||||||
break;
|
|
||||||
case DAEMON_START:
|
case DAEMON_START:
|
||||||
do_daemon_start();
|
do_daemon_start();
|
||||||
break;
|
break;
|
||||||
@@ -1892,8 +1914,8 @@ check_cli_parameters(const int action)
|
|||||||
case WITNESS_UNREGISTER:
|
case WITNESS_UNREGISTER:
|
||||||
case NODE_REJOIN:
|
case NODE_REJOIN:
|
||||||
case NODE_SERVICE:
|
case NODE_SERVICE:
|
||||||
case DAEMON_PAUSE:
|
case SERVICE_PAUSE:
|
||||||
case DAEMON_UNPAUSE:
|
case SERVICE_UNPAUSE:
|
||||||
case DAEMON_START:
|
case DAEMON_START:
|
||||||
case DAEMON_STOP:
|
case DAEMON_STOP:
|
||||||
break;
|
break;
|
||||||
@@ -1932,7 +1954,7 @@ check_cli_parameters(const int action)
|
|||||||
{
|
{
|
||||||
case CLUSTER_SHOW:
|
case CLUSTER_SHOW:
|
||||||
case CLUSTER_EVENT:
|
case CLUSTER_EVENT:
|
||||||
case DAEMON_STATUS:
|
case SERVICE_STATUS:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
item_list_append_format(&cli_warnings,
|
item_list_append_format(&cli_warnings,
|
||||||
@@ -1946,7 +1968,7 @@ check_cli_parameters(const int action)
|
|||||||
{
|
{
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case DAEMON_STATUS:
|
case SERVICE_STATUS:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
item_list_append_format(&cli_warnings,
|
item_list_append_format(&cli_warnings,
|
||||||
@@ -1996,7 +2018,7 @@ check_cli_parameters(const int action)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate formatted node status output for display by "cluster show" and
|
* Generate formatted node status output for display by "cluster show" and
|
||||||
* "daemon status".
|
* "service status".
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
format_node_status(t_node_info *node_info, PQExpBufferData *node_status, PQExpBufferData *upstream, ItemList *warnings)
|
format_node_status(t_node_info *node_info, PQExpBufferData *node_status, PQExpBufferData *upstream, ItemList *warnings)
|
||||||
@@ -2462,12 +2484,13 @@ action_name(const int action)
|
|||||||
case CLUSTER_CROSSCHECK:
|
case CLUSTER_CROSSCHECK:
|
||||||
return "CLUSTER CROSSCHECK";
|
return "CLUSTER CROSSCHECK";
|
||||||
|
|
||||||
case DAEMON_STATUS:
|
case SERVICE_STATUS:
|
||||||
return "DAEMON STATUS";
|
return "SERVICE STATUS";
|
||||||
case DAEMON_PAUSE:
|
case SERVICE_PAUSE:
|
||||||
return "DAEMON PAUSE";
|
return "SERVICE PAUSE";
|
||||||
case DAEMON_UNPAUSE:
|
case SERVICE_UNPAUSE:
|
||||||
return "DAEMON UNPAUSE";
|
return "SERVICE UNPAUSE";
|
||||||
|
|
||||||
case DAEMON_START:
|
case DAEMON_START:
|
||||||
return "DAEMON START";
|
return "DAEMON START";
|
||||||
case DAEMON_STOP:
|
case DAEMON_STOP:
|
||||||
@@ -2582,11 +2605,12 @@ do_help(void)
|
|||||||
printf(_(" %s [OPTIONS] node {status|check|rejoin|service}\n"), progname());
|
printf(_(" %s [OPTIONS] node {status|check|rejoin|service}\n"), progname());
|
||||||
printf(_(" %s [OPTIONS] cluster {show|event|matrix|crosscheck|cleanup}\n"), progname());
|
printf(_(" %s [OPTIONS] cluster {show|event|matrix|crosscheck|cleanup}\n"), progname());
|
||||||
printf(_(" %s [OPTIONS] witness {register|unregister}\n"), progname());
|
printf(_(" %s [OPTIONS] witness {register|unregister}\n"), progname());
|
||||||
printf(_(" %s [OPTIONS] daemon {status|pause|unpause|start|stop}\n"), progname());
|
printf(_(" %s [OPTIONS] service {status|pause|unpause}\n"), progname());
|
||||||
|
printf(_(" %s [OPTIONS] daemon {start|stop}\n"), progname());
|
||||||
|
|
||||||
puts("");
|
puts("");
|
||||||
|
|
||||||
printf(_(" Execute \"%s {primary|standby|bdr|node|cluster|witness|daemon} --help\" to see command-specific options\n"), progname());
|
printf(_(" Execute \"%s {primary|standby|bdr|node|cluster|witness|service} --help\" to see command-specific options\n"), progname());
|
||||||
|
|
||||||
puts("");
|
puts("");
|
||||||
|
|
||||||
|
|||||||
@@ -46,9 +46,9 @@
|
|||||||
#define CLUSTER_MATRIX 20
|
#define CLUSTER_MATRIX 20
|
||||||
#define CLUSTER_CROSSCHECK 21
|
#define CLUSTER_CROSSCHECK 21
|
||||||
#define CLUSTER_EVENT 22
|
#define CLUSTER_EVENT 22
|
||||||
#define DAEMON_STATUS 23
|
#define SERVICE_STATUS 23
|
||||||
#define DAEMON_PAUSE 24
|
#define SERVICE_PAUSE 24
|
||||||
#define DAEMON_UNPAUSE 25
|
#define SERVICE_UNPAUSE 25
|
||||||
#define DAEMON_START 26
|
#define DAEMON_START 26
|
||||||
#define DAEMON_STOP 27
|
#define DAEMON_STOP 27
|
||||||
|
|
||||||
|
|||||||
@@ -402,7 +402,7 @@ ssh_options='-q -o ConnectTimeout=10' # Options to append to "ssh"
|
|||||||
# for "promote_command"; do not use "repmgr standby promote"
|
# for "promote_command"; do not use "repmgr standby promote"
|
||||||
# (or a script which executes "repmgr standby promote") here.
|
# (or a script which executes "repmgr standby promote") here.
|
||||||
|
|
||||||
# Used by "repmgr daemon (start|stop)" to control repmgrd
|
# Used by "repmgr service (start|stop)" to control repmgrd
|
||||||
#
|
#
|
||||||
#repmgrd_service_start_command = ''
|
#repmgrd_service_start_command = ''
|
||||||
#repmgrd_service_stop_command = ''
|
#repmgrd_service_stop_command = ''
|
||||||
|
|||||||
@@ -1580,7 +1580,7 @@ monitor_streaming_standby(void)
|
|||||||
{
|
{
|
||||||
log_notice(_("repmgrd on this node is paused"));
|
log_notice(_("repmgrd on this node is paused"));
|
||||||
log_detail(_("no failover will be carried out"));
|
log_detail(_("no failover will be carried out"));
|
||||||
log_hint(_("execute \"repmgr daemon unpause\" to resume normal failover mode"));
|
log_hint(_("execute \"repmgr service unpause\" to resume normal failover mode"));
|
||||||
monitoring_state = MS_DEGRADED;
|
monitoring_state = MS_DEGRADED;
|
||||||
INSTR_TIME_SET_CURRENT(degraded_monitoring_start);
|
INSTR_TIME_SET_CURRENT(degraded_monitoring_start);
|
||||||
}
|
}
|
||||||
@@ -1884,7 +1884,7 @@ loop:
|
|||||||
if (PQstatus(local_conn) == CONNECTION_OK && repmgrd_is_paused(local_conn))
|
if (PQstatus(local_conn) == CONNECTION_OK && repmgrd_is_paused(local_conn))
|
||||||
{
|
{
|
||||||
log_detail(_("repmgrd paused by administrator"));
|
log_detail(_("repmgrd paused by administrator"));
|
||||||
log_hint(_("execute \"repmgr daemon unpause\" to resume normal failover mode"));
|
log_hint(_("execute \"repmgr service unpause\" to resume normal failover mode"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user