Make pg_recievexlog by default loop on connection failures

Avoids the need for an external script in the most common
scenario. Behavior can be overridden using the -n/--noloop
commandline parameter.
This commit is contained in:
Magnus Hagander 2012-05-27 11:05:24 +02:00
parent 2b97db61dd
commit 16282ae688
4 changed files with 67 additions and 4 deletions

View 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>

View 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

View File

@ -33,9 +33,13 @@
#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);
}

View 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! */