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:
parent
2b97db61dd
commit
16282ae688
|
@ -58,6 +58,14 @@ PostgreSQL documentation
|
||||||
configured with <xref linkend="guc-max-wal-senders"> set high enough to
|
configured with <xref linkend="guc-max-wal-senders"> set high enough to
|
||||||
leave at least one session available for the stream.
|
leave at least one session available for the stream.
|
||||||
</para>
|
</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>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
@ -86,6 +94,17 @@ PostgreSQL documentation
|
||||||
The following command-line options control the running of the program.
|
The following command-line options control the running of the program.
|
||||||
|
|
||||||
<variablelist>
|
<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>
|
<varlistentry>
|
||||||
<term><option>-v</option></term>
|
<term><option>-v</option></term>
|
||||||
<term><option>--verbose</option></term>
|
<term><option>--verbose</option></term>
|
||||||
|
|
|
@ -279,6 +279,9 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
|
||||||
|
|
||||||
/* Get a second connection */
|
/* Get a second connection */
|
||||||
param->bgconn = GetConnection();
|
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
|
* 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
|
* Connect in replication mode to the server
|
||||||
*/
|
*/
|
||||||
conn = GetConnection();
|
conn = GetConnection();
|
||||||
|
if (!conn)
|
||||||
|
/* Error message already written in GetConnection() */
|
||||||
|
exit(1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run IDENTIFY_SYSTEM so we can get the timeline
|
* Run IDENTIFY_SYSTEM so we can get the timeline
|
||||||
|
|
|
@ -33,9 +33,13 @@
|
||||||
|
|
||||||
#include "getopt_long.h"
|
#include "getopt_long.h"
|
||||||
|
|
||||||
|
/* Time to sleep between reconnection attempts */
|
||||||
|
#define RECONNECT_SLEEP_TIME 5
|
||||||
|
|
||||||
/* Global options */
|
/* Global options */
|
||||||
char *basedir = NULL;
|
char *basedir = NULL;
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
int noloop = 0;
|
||||||
int standby_message_timeout = 10; /* 10 sec = default */
|
int standby_message_timeout = 10; /* 10 sec = default */
|
||||||
volatile bool time_to_abort = false;
|
volatile bool time_to_abort = false;
|
||||||
|
|
||||||
|
@ -55,6 +59,7 @@ usage(void)
|
||||||
printf(_("\nOptions controlling the output:\n"));
|
printf(_("\nOptions controlling the output:\n"));
|
||||||
printf(_(" -D, --dir=directory receive xlog files into this directory\n"));
|
printf(_(" -D, --dir=directory receive xlog files into this directory\n"));
|
||||||
printf(_("\nGeneral options:\n"));
|
printf(_("\nGeneral options:\n"));
|
||||||
|
printf(_(" -n, --noloop do not loop on connection lost\n"));
|
||||||
printf(_(" -v, --verbose output verbose messages\n"));
|
printf(_(" -v, --verbose output verbose messages\n"));
|
||||||
printf(_(" -?, --help show this help, then exit\n"));
|
printf(_(" -?, --help show this help, then exit\n"));
|
||||||
printf(_(" -V, --version output version information, 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
|
* Connect in replication mode to the server
|
||||||
*/
|
*/
|
||||||
conn = GetConnection();
|
conn = GetConnection();
|
||||||
|
if (!conn)
|
||||||
|
/* Error message already written in GetConnection() */
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run IDENTIFY_SYSTEM so we can get the timeline and current xlog
|
* 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'},
|
{"host", required_argument, NULL, 'h'},
|
||||||
{"port", required_argument, NULL, 'p'},
|
{"port", required_argument, NULL, 'p'},
|
||||||
{"username", required_argument, NULL, 'U'},
|
{"username", required_argument, NULL, 'U'},
|
||||||
|
{"noloop", no_argument, NULL, 'n'},
|
||||||
{"no-password", no_argument, NULL, 'w'},
|
{"no-password", no_argument, NULL, 'w'},
|
||||||
{"password", no_argument, NULL, 'W'},
|
{"password", no_argument, NULL, 'W'},
|
||||||
{"statusint", required_argument, NULL, 's'},
|
{"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)
|
long_options, &option_index)) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
|
@ -355,6 +364,9 @@ main(int argc, char **argv)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'n':
|
||||||
|
noloop = 1;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose++;
|
verbose++;
|
||||||
break;
|
break;
|
||||||
|
@ -397,7 +409,28 @@ main(int argc, char **argv)
|
||||||
pqsignal(SIGINT, sigint_handler);
|
pqsignal(SIGINT, sigint_handler);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
StreamLog();
|
StreamLog();
|
||||||
|
if (time_to_abort)
|
||||||
|
/*
|
||||||
|
* We've been Ctrl-C'ed. That's not an error, so exit without
|
||||||
|
* an errorcode.
|
||||||
|
*/
|
||||||
exit(0);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Never get here */
|
||||||
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 *
|
PGconn *
|
||||||
GetConnection(void)
|
GetConnection(void)
|
||||||
{
|
{
|
||||||
|
@ -151,7 +156,7 @@ GetConnection(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, _("%s: could not connect to server: %s\n"),
|
fprintf(stderr, _("%s: could not connect to server: %s\n"),
|
||||||
progname, PQerrorMessage(tmpconn));
|
progname, PQerrorMessage(tmpconn));
|
||||||
exit(1);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connection ok! */
|
/* Connection ok! */
|
||||||
|
|
Loading…
Reference in New Issue