]> granicus.if.org Git - postgresql/commitdiff
Make pg_recievexlog by default loop on connection failures
authorMagnus Hagander <magnus@hagander.net>
Sun, 27 May 2012 09:05:24 +0000 (11:05 +0200)
committerMagnus Hagander <magnus@hagander.net>
Sun, 27 May 2012 09:05:24 +0000 (11:05 +0200)
Avoids the need for an external script in the most common
scenario. Behavior can be overridden using the -n/--noloop
commandline parameter.

doc/src/sgml/ref/pg_receivexlog.sgml
src/bin/pg_basebackup/pg_basebackup.c
src/bin/pg_basebackup/pg_receivexlog.c
src/bin/pg_basebackup/streamutil.c

index 8e5fca402281e91551ea217e6378b4a87fffd74e..f0a7763bdfc488024c11b2edf031d9f1effd5ff6 100644 (file)
@@ -58,6 +58,14 @@ PostgreSQL documentation
    configured with <xref linkend="guc-max-wal-senders"> set high enough to
    leave at least one session available for the stream.
   </para>
+
+  <para>
+   If the connection is lost, or if it cannot be initially established,
+   with a non-fatal error, <application>pg_receivexlog</application> will
+   retry the connection indefinitely, and reestablish streaming as soon
+   as possible. To avoid this behavior, use the <literal>-n</literal>
+   parameter.
+  </para>
  </refsect1>
 
  <refsect1>
@@ -86,6 +94,17 @@ PostgreSQL documentation
     The following command-line options control the running of the program.
 
     <variablelist>
+     <varlistentry>
+      <term><option>-n</option></term>
+      <term><option>--noloop</option></term>
+      <listitem>
+       <para>
+        Don't loop on connection errors. Instead, exit right away with
+        an error.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>-v</option></term>
       <term><option>--verbose</option></term>
index 6a2e557809a49161f091b16d8a83386849b5630d..d7466168d7856afd336de818416c7186830368ed 100644 (file)
@@ -279,6 +279,9 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
 
        /* Get a second connection */
        param->bgconn = GetConnection();
+       if (!param->bgconn)
+               /* Error message already written in GetConnection() */
+               exit(1);
 
        /*
         * Always in plain format, so we can write to basedir/pg_xlog. But the
@@ -915,6 +918,9 @@ BaseBackup(void)
         * Connect in replication mode to the server
         */
        conn = GetConnection();
+       if (!conn)
+               /* Error message already written in GetConnection() */
+               exit(1);
 
        /*
         * Run IDENTIFY_SYSTEM so we can get the timeline
index 01f20f372a4de32d9329ebaa249012f559581fd6..084ddc4a8cb001b8ab328443fbcc40746cc55922 100644 (file)
 
 #include "getopt_long.h"
 
+/* Time to sleep between reconnection attempts */
+#define RECONNECT_SLEEP_TIME 5
+
 /* Global options */
 char      *basedir = NULL;
 int                    verbose = 0;
+int                    noloop = 0;
 int                    standby_message_timeout = 10;           /* 10 sec = default */
 volatile bool time_to_abort = false;
 
@@ -55,6 +59,7 @@ usage(void)
        printf(_("\nOptions controlling the output:\n"));
        printf(_("  -D, --dir=directory       receive xlog files into this directory\n"));
        printf(_("\nGeneral options:\n"));
+       printf(_("  -n, --noloop              do not loop on connection lost\n"));
        printf(_("  -v, --verbose             output verbose messages\n"));
        printf(_("  -?, --help                show this help, then exit\n"));
        printf(_("  -V, --version             output version information, then exit\n"));
@@ -214,6 +219,9 @@ StreamLog(void)
         * Connect in replication mode to the server
         */
        conn = GetConnection();
+       if (!conn)
+               /* Error message already written in GetConnection() */
+               return;
 
        /*
         * Run IDENTIFY_SYSTEM so we can get the timeline and current xlog
@@ -289,6 +297,7 @@ main(int argc, char **argv)
                {"host", required_argument, NULL, 'h'},
                {"port", required_argument, NULL, 'p'},
                {"username", required_argument, NULL, 'U'},
+               {"noloop", no_argument, NULL, 'n'},
                {"no-password", no_argument, NULL, 'w'},
                {"password", no_argument, NULL, 'W'},
                {"statusint", required_argument, NULL, 's'},
@@ -317,7 +326,7 @@ main(int argc, char **argv)
                }
        }
 
-       while ((c = getopt_long(argc, argv, "D:h:p:U:s:wWv",
+       while ((c = getopt_long(argc, argv, "D:h:p:U:s:nwWv",
                                                        long_options, &option_index)) != -1)
        {
                switch (c)
@@ -355,6 +364,9 @@ main(int argc, char **argv)
                                        exit(1);
                                }
                                break;
+                       case 'n':
+                               noloop = 1;
+                               break;
                        case 'v':
                                verbose++;
                                break;
@@ -397,7 +409,28 @@ main(int argc, char **argv)
        pqsignal(SIGINT, sigint_handler);
 #endif
 
-       StreamLog();
+       while (true)
+       {
+               StreamLog();
+               if (time_to_abort)
+                       /*
+                        * We've been Ctrl-C'ed. That's not an error, so exit without
+                        * an errorcode.
+                        */
+                       exit(0);
+               else if (noloop)
+               {
+                       fprintf(stderr, _("%s: disconnected.\n"), progname);
+                       exit(1);
+               }
+               else
+               {
+                       fprintf(stderr, _("%s: disconnected. Waiting %d seconds to try again\n"),
+                                       progname, RECONNECT_SLEEP_TIME);
+                       pg_usleep(RECONNECT_SLEEP_TIME * 1000000);
+               }
+       }
 
-       exit(0);
+       /* Never get here */
+       exit(2);
 }
index cc015370ff6607d47f2bc9da5e981c5603ec1bea..1416faa2e3c11437e27b59de1f4df3e6ee2b036b 100644 (file)
@@ -65,6 +65,11 @@ xmalloc0(int size)
 }
 
 
+/*
+ * Connect to the server. Returns a valid PGconn pointer if connected,
+ * or NULL on non-permanent error. On permanent error, the function will
+ * call exit(1) directly.
+ */
 PGconn *
 GetConnection(void)
 {
@@ -151,7 +156,7 @@ GetConnection(void)
                {
                        fprintf(stderr, _("%s: could not connect to server: %s\n"),
                                        progname, PQerrorMessage(tmpconn));
-                       exit(1);
+                       return NULL;
                }
 
                /* Connection ok! */