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:
Ian Barwick
2019-08-28 14:14:20 +09:00
parent 3e812f6e91
commit 931da14df1
28 changed files with 1557 additions and 646 deletions

View File

@@ -1,6 +1,7 @@
5.0 2019-??-??
general: add PostgreSQL 12 support (Ian)
general: add PostgreSQL 12 support (Ian)
general: parse configuration file using flex (Ian)
repmgr: rename "repmgr daemon ..." commands to "repmgr service ..." (Ian)
4.4.1 2019-??-??
repmgr: improve data directory check (Ian)

View File

@@ -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-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
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")

768
daemon-start-stop.patch Normal file
View 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 &quot;repmgr service start&quot;</secondary>
+ <secondary>with &quot;repmgr daemon start&quot;</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

View File

@@ -23,6 +23,45 @@
<sect2>
<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>
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)
@@ -209,7 +248,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem>
<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
<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
@@ -227,7 +266,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem>
<para>
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>
and <link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>:
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
situations where the cluster is in an unexpected state, and provide a better idea of the
actual cluster state.
@@ -245,7 +284,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem>
<para>
<link linkend="repmgr-cluster-show"><command>repmgr cluster show</command></link>
and <link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>:
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
warning if the node is not attached.
</para>
@@ -462,7 +501,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
<listitem>
<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
&repmgrd; instance last verified its upstream node was available.
</para>

View File

@@ -54,11 +54,11 @@
<!ENTITY repmgr-cluster-crosscheck SYSTEM "repmgr-cluster-crosscheck.xml">
<!ENTITY repmgr-cluster-event SYSTEM "repmgr-cluster-event.xml">
<!ENTITY repmgr-cluster-cleanup SYSTEM "repmgr-cluster-cleanup.xml">
<!ENTITY repmgr-daemon-status SYSTEM "repmgr-daemon-status.xml">
<!ENTITY repmgr-service-status SYSTEM "repmgr-service-status.xml">
<!ENTITY repmgr-service-pause SYSTEM "repmgr-service-pause.xml">
<!ENTITY repmgr-service-unpause SYSTEM "repmgr-service-unpause.xml">
<!ENTITY repmgr-daemon-start SYSTEM "repmgr-daemon-start.xml">
<!ENTITY repmgr-daemon-stop SYSTEM "repmgr-daemon-stop.xml">
<!ENTITY repmgr-daemon-pause SYSTEM "repmgr-daemon-pause.xml">
<!ENTITY repmgr-daemon-unpause SYSTEM "repmgr-daemon-unpause.xml">
<!ENTITY appendix-release-notes SYSTEM "appendix-release-notes.xml">
<!ENTITY appendix-faq SYSTEM "appendix-faq.xml">

View File

@@ -233,7 +233,7 @@
<refsect1>
<title>See also</title>
<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>
</refsect1>

View File

@@ -14,13 +14,13 @@
<refnamediv>
<refname>repmgr daemon start</refname>
<refpurpose>Start the &repmgrd; daemon</refpurpose>
<refpurpose>Start the &repmgrd; service</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
This command starts the &repmgrd; daemon on the
This command starts the &repmgrd; service on the
local node.
</para>
<para>
@@ -197,7 +197,7 @@
<refsect1>
<title>See also</title>
<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>
</refsect1>

View File

@@ -194,7 +194,7 @@
<refsect1>
<title>See also</title>
<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>
</refsect1>

View File

@@ -1,6 +1,6 @@
<refentry id="repmgr-daemon-pause">
<refentry id="repmgr-service-pause">
<indexterm>
<primary>repmgr daemon pause</primary>
<primary>repmgr service pause</primary>
</indexterm>
<indexterm>
@@ -9,11 +9,11 @@
</indexterm>
<refmeta>
<refentrytitle>repmgr daemon pause</refentrytitle>
<refentrytitle>repmgr service pause</refentrytitle>
</refmeta>
<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>
</refnamediv>
@@ -32,12 +32,12 @@
<note>
<para>
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.
</para>
</note>
<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.
</para>
</refsect1>
@@ -45,7 +45,7 @@
<refsect1>
<title>Execution</title>
<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.
It will have no effect on previously paused nodes.
</para>
@@ -55,7 +55,7 @@
<title>Example</title>
<para>
<programlisting>
$ repmgr -f /etc/repmgr.conf daemon pause
$ repmgr -f /etc/repmgr.conf service pause
NOTICE: node 1 (node1) paused
NOTICE: node 2 (node2) paused
NOTICE: node 3 (node3) paused</programlisting>
@@ -79,7 +79,7 @@ NOTICE: node 3 (node3) paused</programlisting>
<refsect1>
<title>Exit codes</title>
<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>
<variablelist>
@@ -107,7 +107,7 @@ NOTICE: node 3 (node3) paused</programlisting>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-daemon-unpause"/>, <xref linkend="repmgr-daemon-status"/>
<xref linkend="repmgr-service-unpause"/>, <xref linkend="repmgr-service-status"/>
</para>
</refsect1>
</refentry>

View File

@@ -1,19 +1,19 @@
<refentry id="repmgr-daemon-status">
<refentry id="repmgr-service-status">
<indexterm>
<primary>repmgr daemon status</primary>
<primary>repmgr service status</primary>
</indexterm>
<indexterm>
<primary>repmgrd</primary>
<secondary>displaying daemon status</secondary>
<secondary>displaying service status</secondary>
</indexterm>
<refmeta>
<refentrytitle>repmgr daemon status</refentrytitle>
<refentrytitle>repmgr service status</refentrytitle>
</refmeta>
<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>
</refnamediv>
@@ -22,7 +22,7 @@
<para>
This command provides an overview over all active nodes in the cluster and the state
of each node's &repmgrd; instance. It can be used to check
the result of <xref linkend="repmgr-daemon-pause"/> and <xref linkend="repmgr-daemon-unpause"/>
the result of <xref linkend="repmgr-service-pause"/> and <xref linkend="repmgr-service-unpause"/>
operations.
</para>
</refsect1>
@@ -30,7 +30,7 @@
<refsect1>
<title>Execution</title>
<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.
</para>
<para>
@@ -51,7 +51,7 @@
<title>Examples</title>
<para>
&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
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
1 | node1 | primary | * running | | running | 96563 | no | n/a
@@ -60,8 +60,8 @@
</para>
<para>
&repmgrd; paused on all nodes (using <xref linkend="repmgr-daemon-pause"/>):
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
&repmgrd; paused on all nodes (using <xref linkend="repmgr-service-pause"/>):
<programlisting>$ repmgr -f /etc/repmgr.conf service status
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
1 | node1 | primary | * running | | running | 96563 | yes | n/a
@@ -71,7 +71,7 @@
<para>
&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
----+-------+---------+-----------+----------+-------------+-------+---------+--------------------
1 | node1 | primary | * running | | running | 96563 | yes | n/a
@@ -89,11 +89,11 @@
<term><option>--csv</option></term>
<listitem>
<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
parsing by scripts, e.g.:
<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
2,node2,standby,1,0,-1,1,100,1,default
3,node3,standby,1,1,5779,1,100,1,default</programlisting>
@@ -171,7 +171,7 @@
<listitem>
<para>
Display additional information (<literal>location</literal>, <literal>priority</literal>)
about the &repmgr; configuration.
about the &repmgr; configuration.
</para>
</listitem>
</varlistentry>
@@ -180,7 +180,7 @@
<term><option>--verbose</option></term>
<listitem>
<para>
Display the full text of any database connection error messages
Display the full text of any database connection error messages.
</para>
</listitem>
</varlistentry>
@@ -192,7 +192,7 @@
<refsect1>
<title>See also</title>
<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>
</refsect1>
</refentry>

View File

@@ -1,6 +1,6 @@
<refentry id="repmgr-daemon-unpause">
<refentry id="repmgr-service-unpause">
<indexterm>
<primary>repmgr daemon unpause</primary>
<primary>repmgr service unpause</primary>
</indexterm>
<indexterm>
@@ -8,13 +8,12 @@
<secondary>unpausing</secondary>
</indexterm>
<refmeta>
<refentrytitle>repmgr daemon unpause</refentrytitle>
<refentrytitle>repmgr service unpause</refentrytitle>
</refmeta>
<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>
</refnamediv>
@@ -23,14 +22,14 @@
<para>
This command can be run on any active node in the replication cluster to instruct all
running &repmgrd; instances to &quot;unpause&quot;
(following a previous execution of <xref linkend="repmgr-daemon-pause"/>)
(following a previous execution of <xref linkend="repmgr-service-pause"/>)
and resume normal failover/monitoring operation.
</para>
<note>
<para>
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.
</para>
</note>
@@ -40,7 +39,7 @@
<refsect1>
<title>Execution</title>
<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.
It will have no effect on nodes which are not already paused.
</para>
@@ -50,7 +49,7 @@
<title>Example</title>
<para>
<programlisting>
$ repmgr -f /etc/repmgr.conf daemon unpause
$ repmgr -f /etc/repmgr.conf service unpause
NOTICE: node 1 (node1) unpaused
NOTICE: node 2 (node2) unpaused
NOTICE: node 3 (node3) unpaused</programlisting>
@@ -74,7 +73,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<refsect1>
<title>Exit codes</title>
<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>
<variablelist>
@@ -102,7 +101,7 @@ NOTICE: node 3 (node3) unpaused</programlisting>
<refsect1>
<title>See also</title>
<para>
<xref linkend="repmgr-daemon-pause"/>, <xref linkend="repmgr-daemon-status"/>
<xref linkend="repmgr-service-pause"/>, <xref linkend="repmgr-service-status"/>
</para>
</refsect1>
</refentry>

View File

@@ -23,7 +23,8 @@
<important>
<para>
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 the replication cluster.
</para>

View File

@@ -116,11 +116,11 @@
&repmgr-cluster-crosscheck;
&repmgr-cluster-event;
&repmgr-cluster-cleanup;
&repmgr-daemon-status;
&repmgr-service-status;
&repmgr-service-pause;
&repmgr-service-unpause;
&repmgr-daemon-start;
&repmgr-daemon-stop;
&repmgr-daemon-pause;
&repmgr-daemon-unpause;
</part>
&appendix-release-notes;

View File

@@ -199,9 +199,10 @@
<para>
The time the primary was last seen by each node can be checked by executing
<link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>,
<link linkend="repmgr-service-status"><command>repmgr service status</command></link>
(&repmgr; 4.2 - 4.4: <link linkend="repmgr-service-status"><command>repmgr daemon status</command></link>)
which includes this in its output, e.g.:
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
<programlisting>$ repmgr -f /etc/repmgr.conf service status
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
1 | node1 | primary | * running | | running | 96563 | no | n/a

View File

@@ -8,7 +8,7 @@
</indexterm>
<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
(the primary server or with cascading replication, another standby) which it's
connected to.
@@ -519,7 +519,8 @@
</indexterm>
<para>
If you are intending to use the <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link>
and <link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> commands, the following
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">
@@ -860,7 +861,7 @@ repmgrd_service_stop_command='sudo systemctl repmgr11 stop'
<para>
The commands <link linkend="repmgr-daemon-start"><command>repmgr daemon start</command></link> and
<link linkend="repmgr-daemon-stop"><command>repmgr daemon stop</command></link> can be used
as convenience wrappers to start and stop &repmgrd;.
as convenience wrappers to start and stop &repmgrd; on the local node.
</para>
<important>
<para>

View File

@@ -88,17 +88,21 @@
<sect2 id="repmgrd-pausing-execution">
<title>Pausing/unpausing &repmgrd;</title>
<para>
To pause &repmgrd;, execute <link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link>, e.g.:
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>
$ repmgr -f /etc/repmgr.conf daemon pause
$ repmgr -f /etc/repmgr.conf service pause
NOTICE: node 1 (node1) paused
NOTICE: node 2 (node2) paused
NOTICE: node 3 (node3) paused</programlisting>
</para>
<para>
The state of &repmgrd; on each node can be checked with
<link linkend="repmgr-daemon-status"><command>repmgr daemon status</command></link>, e.g.:
<programlisting>$ repmgr -f /etc/repmgr.conf daemon status
<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>),
e.g.:
<programlisting>$ repmgr -f /etc/repmgr.conf service status
ID | Name | Role | Status | repmgrd | PID | Paused?
----+-------+---------+---------+---------+------+---------
1 | node1 | primary | running | running | 7851 | yes
@@ -108,8 +112,8 @@ NOTICE: node 3 (node3) paused</programlisting>
<note>
<para>
If executing a switchover with <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>,
&repmgr; will automatically pause/unpause &repmgrd; as part of the switchover process.
If executing a switchover with <link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>,
&repmgr; will automatically pause/unpause the &repmgrd; service as part of the switchover process.
</para>
</note>
@@ -117,29 +121,32 @@ NOTICE: node 3 (node3) paused</programlisting>
If the primary (in this example, <literal>node1</literal>) is stopped, &repmgrd;
running on one of the standbys (here: <literal>node2</literal>) will react like this:
<programlisting>
[2018-09-20 12:22:21] [WARNING] unable to connect to upstream node "node1" (ID: 1)
[2018-09-20 12:22:21] [INFO] checking state of node 1, 1 of 5 attempts
[2018-09-20 12:22:21] [INFO] sleeping 1 seconds until next reconnection attempt
[2019-08-28 12:22:21] [WARNING] unable to connect to upstream node "node1" (node ID: 1)
[2019-08-28 12:22:21] [INFO] checking state of node 1, 1 of 5 attempts
[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
[2018-09-20 12:22:25] [INFO] checking state of node 1, 5 of 5 attempts
[2018-09-20 12:22:25] [WARNING] unable to reconnect to node 1 after 5 attempts
[2018-09-20 12:22:25] [NOTICE] node is paused
[2018-09-20 12:22:33] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (ID: 1) in degraded state
[2018-09-20 12:22:33] [DETAIL] repmgrd paused by administrator
[2018-09-20 12:22:33] [HINT] execute "repmgr daemon unpause" to resume normal failover mode</programlisting>
[2019-08-28 12:22:24] [INFO] sleeping 1 seconds until next reconnection attempt
[2019-08-28 12:22:25] [INFO] checking state of node 1, 5 of 5 attempts
[2019-08-28 12:22:25] [WARNING] unable to reconnect to node 1 after 5 attempts
[2019-08-28 12:22:25] [NOTICE] node is paused
[2019-08-28 12:22:33] [INFO] node "node2" (ID: 2) monitoring upstream node "node1" (node ID: 1) in degraded state
[2019-08-28 12:22:33] [DETAIL] repmgrd paused by administrator
[2019-08-28 12:22:33] [HINT] execute "repmgr service unpause" to resume normal failover mode</programlisting>
</para>
<para>
If the primary becomes available again (e.g. following a software upgrade), &repmgrd;
will automatically reconnect, e.g.:
<programlisting>
[2018-09-20 13:12:41] [NOTICE] reconnected to upstream node 1 after 8 seconds, resuming monitoring</programlisting>
[2019-08-28 12:25:41] [NOTICE] reconnected to upstream node 1 after 8 seconds, resuming monitoring</programlisting>
</para>
<para>
To unpause &repmgrd;, execute <link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>, e.g.:
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>
$ repmgr -f /etc/repmgr.conf daemon unpause
$ repmgr -f /etc/repmgr.conf service unpause
NOTICE: node 1 (node1) unpaused
NOTICE: node 2 (node2) unpaused
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;
is unpaused, no failover action will be taken. Instead, a new primary must be manually promoted using
<link linkend="repmgr-standby-promote"><command>repmgr standby promote</command></link>,
and any standbys attached to the new primary with
<link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>.
and any standbys attached to the new primary with
<link linkend="repmgr-standby-follow"><command>repmgr standby follow</command></link>.
</para>
<para>
This is to prevent <link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>
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
in larger clusters, where &repmgrd; could select a different promotion
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.
</para>
<para>
<link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link> and
<link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link> can be
executed even if &repmgrd; is not running; in this case,
&repmgrd; will start up in whichever pause state has been set.
</para>
<para>
<link linkend="repmgr-service-pause"><command>repmgr service pause</command></link> and
<link linkend="repmgr-service-unpause"><command>repmgr service unpause</command></link> can be
executed even if &repmgrd; is not running; in this case,
&repmgrd; will start up in whichever pause state has been set.
</para>
<note>
<para>
<link linkend="repmgr-daemon-pause"><command>repmgr daemon pause</command></link> and
<link linkend="repmgr-daemon-unpause"><command>repmgr daemon unpause</command></link>
<emphasis>do not</emphasis> stop/start &repmgrd;.
<link linkend="repmgr-service-pause"><command>repmgr service pause</command></link> and
<link linkend="repmgr-service-unpause"><command>repmgr service unpause</command></link>
<emphasis>do not</emphasis> stop/start &repmgrd;.
</para>
</note>
</sect2>

View File

@@ -38,7 +38,7 @@
<simpara>
ability to <link linkend="repmgrd-pausing">pause repmgrd</link>
operation on all nodes with a
<link linkend="repmgr-daemon-pause"><command>single command</command></link>
<link linkend="repmgr-service-pause"><command>single command</command></link>
</simpara>
</listitem>

View File

@@ -317,7 +317,9 @@
</para>
<para>
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>
<note>

View File

@@ -216,7 +216,9 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
<secondary>checking repmgrd status</secondary>
</indexterm>
<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.
</para>
</sect2>

View File

@@ -26,478 +26,9 @@
#include "repmgr-client-global.h"
#include "repmgr-action-daemon.h"
#define REPMGR_DAEMON_STOP_START_WAIT 15
#define REPMGR_DAEMON_STATUS_START_HINT _("use \"repmgr daemon 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")
/*
* 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);
}
}
#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")
void
do_daemon_start(void)
@@ -583,12 +114,12 @@ do_daemon_start(void)
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
{
int i = 0;
int timeout = REPMGR_DAEMON_STOP_START_WAIT;
int timeout = REPMGR_SERVICE_STOP_START_WAIT;
if (runtime_options.wait_provided)
timeout = runtime_options.wait;
@@ -598,7 +129,7 @@ do_daemon_start(void)
if (PQstatus(conn) != CONNECTION_OK)
{
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);
}
@@ -616,7 +147,7 @@ do_daemon_start(void)
PQfinish(conn);
log_error(_("repmgrd does not appear to have started after %i seconds"),
timeout);
log_hint(REPMGR_DAEMON_STATUS_START_HINT);
log_hint(REPMGR_SERVICE_STATUS_START_HINT);
exit(ERR_REPMGRD_SERVICE);
}
@@ -712,12 +243,12 @@ void do_daemon_stop(void)
if (runtime_options.no_wait == true || runtime_options.wait == 0)
{
if (have_db_connection == true)
log_hint(REPMGR_DAEMON_STATUS_STOP_HINT);
log_hint(REPMGR_SERVICE_STATUS_STOP_HINT);
}
else
{
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"));
if (have_db_connection == true)
log_hint(REPMGR_DAEMON_STATUS_STOP_HINT);
log_hint(REPMGR_SERVICE_STATUS_STOP_HINT);
exit(ERR_REPMGRD_SERVICE);
}
@@ -764,7 +295,7 @@ void do_daemon_stop(void)
timeout);
if (have_db_connection == true)
log_hint(REPMGR_DAEMON_STATUS_START_HINT);
log_hint(REPMGR_SERVICE_STATUS_START_HINT);
exit(ERR_REPMGRD_SERVICE);
}
@@ -783,53 +314,29 @@ void do_daemon_help(void)
print_help_header();
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 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("");
printf(_("DAEMON START\n"));
puts("");
printf(_(" \"daemon start\" attempts to start repmgrd\n"));
printf(_(" \"daemon start\" attempts to start repmgrd on the local node\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_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"));
puts("");
printf(_("DAEMON STOP\n"));
puts("");
printf(_(" \"daemon stop\" attempts to stop repmgrd\n"));
printf(_(" \"daemon stop\" attempts to stop repmgrd on the local node\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_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"));
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("");
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("");
}

View File

@@ -19,10 +19,6 @@
#ifndef _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_stop(void);

535
repmgr-action-service.c Normal file
View 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
View 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

View File

@@ -4782,7 +4782,7 @@ do_standby_switchover(void)
log_warning(_("unable to unpause repmgrd on %i node(s)"),
error_node_count);
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);
}

View File

@@ -33,9 +33,10 @@
* NODE SERVICE
* NODE CONTROL
*
* DAEMON STATUS
* DAEMON PAUSE
* DAEMON UNPAUSE
* SERVICE STATUS
* SERVICE PAUSE
* SERVICE UNPAUSE
*
* DAEMON START
* DAEMON STOP
*
@@ -69,6 +70,7 @@
#include "repmgr-action-bdr.h"
#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 */
@@ -813,7 +815,7 @@ main(int argc, char **argv)
* BDR { REGISTER | UNREGISTER } |
* NODE { STATUS | CHECK | REJOIN | SERVICE } |
* 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
* option
@@ -952,6 +954,22 @@ main(int argc, char **argv)
else if (strcasecmp(repmgr_action, "CLEANUP") == 0)
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)
{
if (help_option == true)
@@ -960,16 +978,18 @@ main(int argc, char **argv)
exit(SUCCESS);
}
if (strcasecmp(repmgr_action, "STATUS") == 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)
if (strcasecmp(repmgr_action, "START") == 0)
action = DAEMON_START;
else if (strcasecmp(repmgr_action, "STOP") == 0)
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
{
@@ -1372,16 +1392,18 @@ main(int argc, char **argv)
do_cluster_cleanup();
break;
/* SERVICE */
case SERVICE_STATUS:
do_service_status();
break;
case SERVICE_PAUSE:
do_service_pause();
break;
case SERVICE_UNPAUSE:
do_service_unpause();
break;
/* 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:
do_daemon_start();
break;
@@ -1892,8 +1914,8 @@ check_cli_parameters(const int action)
case WITNESS_UNREGISTER:
case NODE_REJOIN:
case NODE_SERVICE:
case DAEMON_PAUSE:
case DAEMON_UNPAUSE:
case SERVICE_PAUSE:
case SERVICE_UNPAUSE:
case DAEMON_START:
case DAEMON_STOP:
break;
@@ -1932,7 +1954,7 @@ check_cli_parameters(const int action)
{
case CLUSTER_SHOW:
case CLUSTER_EVENT:
case DAEMON_STATUS:
case SERVICE_STATUS:
break;
default:
item_list_append_format(&cli_warnings,
@@ -1946,7 +1968,7 @@ check_cli_parameters(const int action)
{
switch (action)
{
case DAEMON_STATUS:
case SERVICE_STATUS:
break;
default:
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
* "daemon status".
* "service status".
*/
bool
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:
return "CLUSTER CROSSCHECK";
case DAEMON_STATUS:
return "DAEMON STATUS";
case DAEMON_PAUSE:
return "DAEMON PAUSE";
case DAEMON_UNPAUSE:
return "DAEMON UNPAUSE";
case SERVICE_STATUS:
return "SERVICE STATUS";
case SERVICE_PAUSE:
return "SERVICE PAUSE";
case SERVICE_UNPAUSE:
return "SERVICE UNPAUSE";
case DAEMON_START:
return "DAEMON START";
case DAEMON_STOP:
@@ -2582,11 +2605,12 @@ 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] 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("");
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("");

View File

@@ -46,9 +46,9 @@
#define CLUSTER_MATRIX 20
#define CLUSTER_CROSSCHECK 21
#define CLUSTER_EVENT 22
#define DAEMON_STATUS 23
#define DAEMON_PAUSE 24
#define DAEMON_UNPAUSE 25
#define SERVICE_STATUS 23
#define SERVICE_PAUSE 24
#define SERVICE_UNPAUSE 25
#define DAEMON_START 26
#define DAEMON_STOP 27

View File

@@ -402,7 +402,7 @@ ssh_options='-q -o ConnectTimeout=10' # Options to append to "ssh"
# for "promote_command"; do not use "repmgr standby promote"
# (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_stop_command = ''

View File

@@ -1580,7 +1580,7 @@ monitor_streaming_standby(void)
{
log_notice(_("repmgrd on this node is paused"));
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;
INSTR_TIME_SET_CURRENT(degraded_monitoring_start);
}
@@ -1884,7 +1884,7 @@ loop:
if (PQstatus(local_conn) == CONNECTION_OK && repmgrd_is_paused(local_conn))
{
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
{