2013-01-04 13:43 keltezéssel, Hari Babu írta:
On January 02, 2013 12:41 PM Hari Babu wrote:
On January 01, 2013 10:19 PM Boszormenyi Zoltan wrote:
I am reviewing your patch.
• Is the patch in context diff format?
Yes.
Thanks for reviewing the patch.
• Does it apply cleanly to the current git master?
Not quite cleanly but it doesn't produce rejects or fuzz, only offset
warnings:
Will rebase the patch to head.
• Does it include reasonable tests, necessary doc patches, etc?
The test cases are not applicable. There is no test framework for
testing network outage in "make check".
There are no documentation patches for the new --recvtimeout=INTERVAL
and --conntimeout=INTERVAL options for either pg_basebackup or
pg_receivexlog.
I will add the documentation for the same.
Per the previous comment, no. But those are for the backend
to notice network breakdowns and as such, they need a
separate patch.
I also think it is better to handle it as a separate patch for walsender.
• Are the comments sufficient and accurate?
This chunk below removes a comment which seems obvious enough
so it's not needed:
***************
*** 518,524 **** ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos,
uint32 timeline,
goto error;
}
! /* Check the message type. */
if (copybuf[0] == 'k')
{
int pos;
--- 559,568 ----
goto error;
}
! /* Set the last reply timestamp */
! last_recv_timestamp = localGetCurrentTimestamp();
! ping_sent = false;
!
if (copybuf[0] == 'k')
{
int pos;
***************
Other comments are sufficient and accurate.
I will fix and update the patch.
The attached V2 patch in the mail handles all the review comments identified
above.
Regards,
Hari babu.
Since my other patch against pg_basebackup is now committed,
this patch doesn't apply cleanly, patch rejects 2 hunks.
The fixed up patch is attached.
Best regards,
Zoltán Böszörményi
--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/
diff -dcrpN postgresql.orig/doc/src/sgml/ref/pg_basebackup.sgml postgresql/doc/src/sgml/ref/pg_basebackup.sgml
*** postgresql.orig/doc/src/sgml/ref/pg_basebackup.sgml 2013-01-05 17:34:30.742135371 +0100
--- postgresql/doc/src/sgml/ref/pg_basebackup.sgml 2013-01-07 15:11:40.787007890 +0100
*************** PostgreSQL documentation
*** 400,405 ****
--- 400,425 ----
</varlistentry>
<varlistentry>
+ <term><option>-r <replaceable class="parameter">interval</replaceable></option></term>
+ <term><option>--recvtimeout=<replaceable class="parameter">interval</replaceable></option></term>
+ <listitem>
+ <para>
+ time that receiver waits for communication from server (in seconds).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">interval</replaceable></option></term>
+ <term><option>--conntimeout=<replaceable class="parameter">interval</replaceable></option></term>
+ <listitem>
+ <para>
+ time that client wait for connection to establish with server (in seconds).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-U <replaceable>username</replaceable></option></term>
<term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
<listitem>
diff -dcrpN postgresql.orig/doc/src/sgml/ref/pg_receivexlog.sgml postgresql/doc/src/sgml/ref/pg_receivexlog.sgml
*** postgresql.orig/doc/src/sgml/ref/pg_receivexlog.sgml 2012-11-08 13:13:04.152630639 +0100
--- postgresql/doc/src/sgml/ref/pg_receivexlog.sgml 2013-01-07 15:11:40.788007898 +0100
*************** PostgreSQL documentation
*** 164,169 ****
--- 164,189 ----
</varlistentry>
<varlistentry>
+ <term><option>-r <replaceable class="parameter">interval</replaceable></option></term>
+ <term><option>--recvtimeout=<replaceable class="parameter">interval</replaceable></option></term>
+ <listitem>
+ <para>
+ time that receiver waits for communication from server (in seconds).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">interval</replaceable></option></term>
+ <term><option>--conntimeout=<replaceable class="parameter">interval</replaceable></option></term>
+ <listitem>
+ <para>
+ time that client wait for connection to establish with server (in seconds).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-U <replaceable>username</replaceable></option></term>
<term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
<listitem>
diff -dcrpN postgresql.orig/src/bin/pg_basebackup/pg_basebackup.c postgresql/src/bin/pg_basebackup/pg_basebackup.c
*** postgresql.orig/src/bin/pg_basebackup/pg_basebackup.c 2013-01-05 17:34:30.778135625 +0100
--- postgresql/src/bin/pg_basebackup/pg_basebackup.c 2013-01-07 15:16:24.610037886 +0100
*************** bool streamwal = false;
*** 45,50 ****
--- 45,54 ----
bool fastcheckpoint = false;
bool writerecoveryconf = false;
int standby_message_timeout = 10 * 1000; /* 10 sec = default */
+ int standby_recv_timeout = 60*1000; /* 60 sec = default */
+ char *standby_connect_timeout = NULL;
+
+ #define NAPTIME_PER_CYCLE 100 /* max sleep time between cycles (100ms) */
/* Progress counters */
static uint64 totalsize;
*************** usage(void)
*** 130,135 ****
--- 134,143 ----
printf(_(" -p, --port=PORT database server port number\n"));
printf(_(" -s, --status-interval=INTERVAL\n"
" time between status packets sent to server (in seconds)\n"));
+ printf(_(" -r, --recvtimeout=INTERVAL time that receiver waits for communication from\n"
+ " server (in seconds)\n"));
+ printf(_(" -t, --conntimeout=INTERVAL time that client wait for connection to establish\n"
+ " with server (in seconds)\n"));
printf(_(" -U, --username=NAME connect as specified database user\n"));
printf(_(" -w, --no-password never prompt for password\n"));
printf(_(" -W, --password force password prompt (should happen automatically)\n"));
*************** LogStreamerMain(logstreamer_param *param
*** 242,249 ****
{
if (!ReceiveXlogStream(param->bgconn, param->startptr, param->timeline,
param->sysidentifier, param->xlogdir,
! reached_end_position, standby_message_timeout,
! true))
/*
* Any errors will already have been reported in the function process,
--- 250,257 ----
{
if (!ReceiveXlogStream(param->bgconn, param->startptr, param->timeline,
param->sysidentifier, param->xlogdir,
! reached_end_position, standby_message_timeout,
! standby_recv_timeout, true))
/*
* Any errors will already have been reported in the function process,
*************** StartLogStreamer(char *startpos, uint32
*** 295,302 ****
}
#endif
! /* Get a second connection */
! param->bgconn = GetConnection();
if (!param->bgconn)
/* Error message already written in GetConnection() */
exit(1);
--- 303,311 ----
}
#endif
! /* Get a second connection. Sending connect_timeout
! * as configured, there is no need for rw_timeout.*/
! param->bgconn = GetConnection(standby_connect_timeout);
if (!param->bgconn)
/* Error message already written in GetConnection() */
exit(1);
*************** ReceiveTarFile(PGconn *conn, PGresult *r
*** 511,516 ****
--- 520,526 ----
char filename[MAXPGPATH];
char *copybuf = NULL;
FILE *tarfile = NULL;
+ int64 last_recv_timestamp;
char tarhdr[512];
bool basetablespace = PQgetisnull(res, rownum, 0);
bool in_tarhdr = true;
*************** ReceiveTarFile(PGconn *conn, PGresult *r
*** 634,642 ****
--- 644,655 ----
disconnect_and_exit(1);
}
+ /* Set the last reply timestamp */
+ last_recv_timestamp = localGetCurrentTimestamp();
while (1)
{
int r;
+ int64 now;
if (copybuf != NULL)
{
*************** ReceiveTarFile(PGconn *conn, PGresult *r
*** 644,650 ****
copybuf = NULL;
}
! r = PQgetCopyData(conn, ©buf, 0);
if (r == -1)
{
/*
--- 657,718 ----
copybuf = NULL;
}
! r = PQgetCopyData(conn, ©buf, 1);
! if (r == 0)
! {
! /*
! * In async mode, and no data available. We block on reading but
! * not more than the specified timeout, so that we can send a
! * response back to the client.
! */
! fd_set input_mask;
! struct timeval timeout;
!
! FD_ZERO(&input_mask);
! FD_SET(PQsocket(conn), &input_mask);
! timeout.tv_sec = 0;
! timeout.tv_usec = NAPTIME_PER_CYCLE*1000;
!
! r = select(PQsocket(conn) + 1, &input_mask, NULL, NULL, &timeout);
! if (r == 0 || (r < 0 && errno == EINTR))
! {
! /*
! * Got a timeout or signal. Before Continuing the loop, check for timeout.
! */
! if (standby_recv_timeout > 0)
! {
! now = localGetCurrentTimestamp();
! if (localTimestampDifferenceExceeds(last_recv_timestamp, now, standby_recv_timeout))
! {
! fprintf(stderr, _("%s: terminating DB File receive due to timeout\n"),
! progname);
! disconnect_and_exit(1);
! }
! }
!
! continue;
! }
! else if (r < 0)
! {
! fprintf(stderr, _("%s: select() failed: %s\n"),
! progname, strerror(errno));
! disconnect_and_exit(1);
! }
! /* Else there is actually data on the socket */
! if (PQconsumeInput(conn) == 0)
! {
! fprintf(stderr,
! _("%s: could not receive data from WAL Sender: %s"),
! progname, PQerrorMessage(conn));
! disconnect_and_exit(1);
! }
!
! /* Set the last reply timestamp */
! last_recv_timestamp = localGetCurrentTimestamp();
!
! /* Some data is received, so go back read them in buffer*/
! continue;
! }
if (r == -1)
{
/*
*************** ReceiveTarFile(PGconn *conn, PGresult *r
*** 680,685 ****
--- 748,756 ----
/* 2 * 512 bytes empty data at end of file */
WRITE_TAR_DATA(zerobuf, sizeof(zerobuf));
+ /* Set the last reply timestamp */
+ last_recv_timestamp = localGetCurrentTimestamp();
+
#ifdef HAVE_LIBZ
if (ztarfile != NULL)
{
*************** ReceiveAndUnpackTarFile(PGconn *conn, PG
*** 860,865 ****
--- 931,937 ----
bool basetablespace = PQgetisnull(res, rownum, 0);
char *copybuf = NULL;
FILE *file = NULL;
+ int64 last_recv_timestamp;
if (basetablespace)
strcpy(current_path, basedir);
*************** ReceiveAndUnpackTarFile(PGconn *conn, PG
*** 877,885 ****
--- 949,961 ----
disconnect_and_exit(1);
}
+ /* Set the last reply timestamp */
+ last_recv_timestamp = localGetCurrentTimestamp();
while (1)
{
int r;
+ int64 now;
+
if (copybuf != NULL)
{
*************** ReceiveAndUnpackTarFile(PGconn *conn, PG
*** 887,894 ****
copybuf = NULL;
}
! r = PQgetCopyData(conn, ©buf, 0);
if (r == -1)
{
/*
--- 963,1024 ----
copybuf = NULL;
}
! r = PQgetCopyData(conn, ©buf, 1);
! if (r == 0)
! {
! /*
! * In async mode, and no data available. We block on reading but
! * not more than the specified timeout, so that we can send a
! * response back to the client.
! */
! fd_set input_mask;
! struct timeval timeout;
!
! FD_ZERO(&input_mask);
! FD_SET(PQsocket(conn), &input_mask);
! timeout.tv_sec = 0;
! timeout.tv_usec = NAPTIME_PER_CYCLE*1000;
+ r = select(PQsocket(conn) + 1, &input_mask, NULL, NULL, &timeout);
+ if (r == 0 || (r < 0 && errno == EINTR))
+ {
+ /*
+ * Got a timeout or signal. Before Continuing the loop, check for timeout.
+ */
+ if (standby_recv_timeout > 0)
+ {
+ now = localGetCurrentTimestamp();
+ if (localTimestampDifferenceExceeds(last_recv_timestamp, now, standby_recv_timeout))
+ {
+ fprintf(stderr, _("%s: terminating DB File receive due to timeout\n"),
+ progname);
+ disconnect_and_exit(1);
+ }
+ }
+
+ continue;
+ }
+ else if (r < 0)
+ {
+ fprintf(stderr, _("%s: select() failed: %s\n"),
+ progname, strerror(errno));
+ disconnect_and_exit(1);
+ }
+ /* Else there is actually data on the socket */
+ if (PQconsumeInput(conn) == 0)
+ {
+ fprintf(stderr,
+ _("%s: could not receive data from WAL Sender: %s"),
+ progname, PQerrorMessage(conn));
+ disconnect_and_exit(1);
+ }
+
+ /* Set the last reply timestamp */
+ last_recv_timestamp = localGetCurrentTimestamp();
+
+ /* Some data is received, so go back read them in buffer*/
+ continue;
+ }
if (r == -1)
{
/*
*************** ReceiveAndUnpackTarFile(PGconn *conn, PG
*** 901,911 ****
}
else if (r == -2)
{
fprintf(stderr, _("%s: could not read COPY data: %s"),
progname, PQerrorMessage(conn));
disconnect_and_exit(1);
}
!
if (file == NULL)
{
int filemode;
--- 1031,1044 ----
}
else if (r == -2)
{
+ fprintf(stderr, "\n");
fprintf(stderr, _("%s: could not read COPY data: %s"),
progname, PQerrorMessage(conn));
disconnect_and_exit(1);
}
!
! /* Set the last reply timestamp */
! last_recv_timestamp = localGetCurrentTimestamp();
if (file == NULL)
{
int filemode;
*************** BaseBackup(void)
*** 1213,1221 ****
char xlogend[64];
/*
! * Connect in replication mode to the server
*/
! conn = GetConnection();
if (!conn)
/* Error message already written in GetConnection() */
exit(1);
--- 1346,1354 ----
char xlogend[64];
/*
! * Connect in replication mode to the server. Sending connect_timeout.
*/
! conn = GetConnection(standby_connect_timeout);
if (!conn)
/* Error message already written in GetConnection() */
exit(1);
*************** main(int argc, char **argv)
*** 1524,1529 ****
--- 1657,1664 ----
{"no-password", no_argument, NULL, 'w'},
{"password", no_argument, NULL, 'W'},
{"status-interval", required_argument, NULL, 's'},
+ {"recvtimeout", required_argument, NULL, 'r'},
+ {"conntimeout", required_argument, NULL, 't'},
{"verbose", no_argument, NULL, 'v'},
{"progress", no_argument, NULL, 'P'},
{NULL, 0, NULL, 0}
*************** main(int argc, char **argv)
*** 1550,1556 ****
}
}
! while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:c:h:p:U:s:wWvP",
long_options, &option_index)) != -1)
{
switch (c)
--- 1685,1691 ----
}
}
! while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:c:h:p:U:s:r:t:wWvP",
long_options, &option_index)) != -1)
{
switch (c)
*************** main(int argc, char **argv)
*** 1665,1670 ****
--- 1800,1825 ----
exit(1);
}
break;
+ case 'r':
+ standby_recv_timeout = atoi(optarg)*1000;
+ if (standby_recv_timeout < 0)
+ {
+ fprintf(stderr, _("%s: invalid recv timeout \"%s\"\n"),
+ progname, optarg);
+ exit(1);
+ }
+
+ break;
+ case 't':
+ if (atoi(optarg) < 0)
+ {
+ fprintf(stderr, _("%s: invalid connect timeout \"%s\"\n"),
+ progname, optarg);
+ exit(1);
+ }
+
+ standby_connect_timeout = pg_strdup(optarg);
+ break;
case 'v':
verbose++;
break;
diff -dcrpN postgresql.orig/src/bin/pg_basebackup/pg_receivexlog.c postgresql/src/bin/pg_basebackup/pg_receivexlog.c
*** postgresql.orig/src/bin/pg_basebackup/pg_receivexlog.c 2013-01-02 09:19:03.856521815 +0100
--- postgresql/src/bin/pg_basebackup/pg_receivexlog.c 2013-01-07 15:11:40.792007931 +0100
*************** char *basedir = NULL;
*** 35,40 ****
--- 35,42 ----
int verbose = 0;
int noloop = 0;
int standby_message_timeout = 10 * 1000; /* 10 sec = default */
+ int standby_recv_timeout = 60*1000; /* 60 sec = default */
+ char *standby_connect_timeout = NULL;
volatile bool time_to_abort = false;
*************** usage(void)
*** 63,68 ****
--- 65,74 ----
printf(_(" -p, --port=PORT database server port number\n"));
printf(_(" -s, --status-interval=INTERVAL\n"
" time between status packets sent to server (in seconds)\n"));
+ printf(_(" -r, --recvtimeout=INTERVAL time that receiver waits for communication from\n"
+ " server (in seconds)\n"));
+ printf(_(" -t, --conntimeout=INTERVAL time that client wait for connection to establish\n"
+ " with server (in seconds)\n"));
printf(_(" -U, --username=NAME connect as specified database user\n"));
printf(_(" -w, --no-password never prompt for password\n"));
printf(_(" -W, --password force password prompt (should happen automatically)\n"));
*************** StreamLog(void)
*** 218,226 ****
lo;
/*
! * Connect in replication mode to the server
*/
! conn = GetConnection();
if (!conn)
/* Error message already written in GetConnection() */
return;
--- 224,233 ----
lo;
/*
! * Connect in replication mode to the server, Sending connect_timeout
! * as configured, there is no need for rw_timeout.
*/
! conn = GetConnection(standby_connect_timeout);
if (!conn)
/* Error message already written in GetConnection() */
return;
*************** StreamLog(void)
*** 274,280 ****
timeline);
ReceiveXlogStream(conn, startpos, timeline, NULL, basedir,
! stop_streaming, standby_message_timeout, false);
PQfinish(conn);
}
--- 281,288 ----
timeline);
ReceiveXlogStream(conn, startpos, timeline, NULL, basedir,
! stop_streaming, standby_message_timeout,
! standby_recv_timeout, false);
PQfinish(conn);
}
*************** main(int argc, char **argv)
*** 306,311 ****
--- 314,321 ----
{"no-password", no_argument, NULL, 'w'},
{"password", no_argument, NULL, 'W'},
{"status-interval", required_argument, NULL, 's'},
+ {"recvtimeout", required_argument, NULL, 'r'},
+ {"conntimeout", required_argument, NULL, 't'},
{"verbose", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0}
};
*************** main(int argc, char **argv)
*** 331,337 ****
}
}
! while ((c = getopt_long(argc, argv, "D:h:p:U:s:nwWv",
long_options, &option_index)) != -1)
{
switch (c)
--- 341,347 ----
}
}
! while ((c = getopt_long(argc, argv, "D:h:p:U:s:r:t:nwWv",
long_options, &option_index)) != -1)
{
switch (c)
*************** main(int argc, char **argv)
*** 369,374 ****
--- 379,404 ----
exit(1);
}
break;
+ case 'r':
+ standby_recv_timeout = atoi(optarg)*1000;
+ if (standby_recv_timeout < 0)
+ {
+ fprintf(stderr, _("%s: invalid recv timeout \"%s\"\n"),
+ progname, optarg);
+ exit(1);
+ }
+ break;
+ case 't':
+ if (atoi(optarg) < 0)
+ {
+ fprintf(stderr, _("%s: invalid connect timeout \"%s\"\n"),
+ progname, optarg);
+ exit(1);
+ }
+
+ standby_connect_timeout = pg_strdup(optarg);
+ break;
+
case 'n':
noloop = 1;
break;
diff -dcrpN postgresql.orig/src/bin/pg_basebackup/receivelog.c postgresql/src/bin/pg_basebackup/receivelog.c
*** postgresql.orig/src/bin/pg_basebackup/receivelog.c 2013-01-02 09:19:03.856521815 +0100
--- postgresql/src/bin/pg_basebackup/receivelog.c 2013-01-07 15:11:40.792007931 +0100
*************** close_walfile(char *basedir, char *walna
*** 181,187 ****
* backend code. The protocol always uses integer timestamps, regardless of
* server setting.
*/
! static int64
localGetCurrentTimestamp(void)
{
int64 result;
--- 181,187 ----
* backend code. The protocol always uses integer timestamps, regardless of
* server setting.
*/
! int64
localGetCurrentTimestamp(void)
{
int64 result;
*************** localGetCurrentTimestamp(void)
*** 201,207 ****
* Local version of TimestampDifference(), since we are not linked with
* backend code.
*/
! static void
localTimestampDifference(int64 start_time, int64 stop_time,
long *secs, int *microsecs)
{
--- 201,207 ----
* Local version of TimestampDifference(), since we are not linked with
* backend code.
*/
! void
localTimestampDifference(int64 start_time, int64 stop_time,
long *secs, int *microsecs)
{
*************** localTimestampDifference(int64 start_tim
*** 223,229 ****
* Local version of TimestampDifferenceExceeds(), since we are not
* linked with backend code.
*/
! static bool
localTimestampDifferenceExceeds(int64 start_time,
int64 stop_time,
int msec)
--- 223,229 ----
* Local version of TimestampDifferenceExceeds(), since we are not
* linked with backend code.
*/
! bool
localTimestampDifferenceExceeds(int64 start_time,
int64 stop_time,
int msec)
*************** bool
*** 333,339 ****
ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
char *sysidentifier, char *basedir,
stream_stop_callback stream_stop,
! int standby_message_timeout, bool rename_partial)
{
char query[128];
char current_walfile_name[MAXPGPATH];
--- 333,340 ----
ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
char *sysidentifier, char *basedir,
stream_stop_callback stream_stop,
! int standby_message_timeout,
! int standby_recv_timeout, bool rename_partial)
{
char query[128];
char current_walfile_name[MAXPGPATH];
*************** ReceiveXlogStream(PGconn *conn, XLogRecP
*** 341,346 ****
--- 342,349 ----
char *copybuf = NULL;
int64 last_status = -1;
XLogRecPtr blockpos = InvalidXLogRecPtr;
+ int64 last_recv_timestamp;
+ bool ping_sent = false;
if (sysidentifier != NULL)
{
*************** ReceiveXlogStream(PGconn *conn, XLogRecP
*** 394,399 ****
--- 397,406 ----
}
PQclear(res);
+ /* Set the last reply timestamp */
+ last_recv_timestamp = localGetCurrentTimestamp();
+ ping_sent = false;
+
/*
* Receive the actual xlog data
*/
*************** ReceiveXlogStream(PGconn *conn, XLogRecP
*** 477,486 ****
if (r == 0 || (r < 0 && errno == EINTR))
{
/*
! * Got a timeout or signal. Continue the loop and either
! * deliver a status packet to the server or just go back into
* blocking.
*/
continue;
}
else if (r < 0)
--- 484,522 ----
if (r == 0 || (r < 0 && errno == EINTR))
{
/*
! * Got a timeout or signal. Before Continuing the loop, check for timeout.
! * and then either deliver a status packet to the server or just go back into
* blocking.
*/
+ if (standby_recv_timeout > 0)
+ {
+ now = localGetCurrentTimestamp();
+ if (localTimestampDifferenceExceeds(last_recv_timestamp, now, standby_recv_timeout))
+ {
+ fprintf(stderr, _("%s: terminating XLogStream receiver due to timeout\n"),
+ progname);
+ goto error;
+ }
+
+ /*
+ * We didn't receive anything new, for half of receiver
+ * replication timeout. Ping the server, if not already done.
+ */
+ if (!ping_sent)
+ {
+ if (localTimestampDifferenceExceeds(last_recv_timestamp, now, (standby_recv_timeout/2)))
+ {
+ if (!sendFeedback(conn, blockpos, now, true))
+ {
+ goto error;
+ }
+
+ last_status = now;
+ ping_sent = true;
+ }
+ }
+ }
+
continue;
}
else if (r < 0)
*************** ReceiveXlogStream(PGconn *conn, XLogRecP
*** 497,502 ****
--- 533,543 ----
progname, PQerrorMessage(conn));
goto error;
}
+
+ /* Set the last reply timestamp */
+ last_recv_timestamp = localGetCurrentTimestamp();
+ ping_sent = false;
+
continue;
}
if (r == -1)
*************** ReceiveXlogStream(PGconn *conn, XLogRecP
*** 509,514 ****
--- 550,559 ----
goto error;
}
+ /* Set the last reply timestamp */
+ last_recv_timestamp = localGetCurrentTimestamp();
+ ping_sent = false;
+
/* Check the message type. */
if (copybuf[0] == 'k')
{
diff -dcrpN postgresql.orig/src/bin/pg_basebackup/receivelog.h postgresql/src/bin/pg_basebackup/receivelog.h
*** postgresql.orig/src/bin/pg_basebackup/receivelog.h 2012-06-11 06:22:48.200921787 +0200
--- postgresql/src/bin/pg_basebackup/receivelog.h 2013-01-07 15:11:40.793007938 +0100
***************
*** 7,16 ****
typedef bool (*stream_stop_callback) (XLogRecPtr segendpos, uint32 timeline, bool segment_finished);
extern bool ReceiveXlogStream(PGconn *conn,
! XLogRecPtr startpos,
! uint32 timeline,
! char *sysidentifier,
! char *basedir,
! stream_stop_callback stream_stop,
! int standby_message_timeout,
! bool rename_partial);
--- 7,24 ----
typedef bool (*stream_stop_callback) (XLogRecPtr segendpos, uint32 timeline, bool segment_finished);
extern bool ReceiveXlogStream(PGconn *conn,
! XLogRecPtr startpos,
! uint32 timeline,
! char *sysidentifier,
! char *basedir,
! stream_stop_callback stream_stop,
! int standby_message_timeout,
! int standby_recv_timeout,
! bool rename_partial);
!
! extern int64 localGetCurrentTimestamp(void);
! extern void localTimestampDifference(int64 start_time, int64 stop_time,
! long *secs, int *microsecs);
! extern bool localTimestampDifferenceExceeds(int64 start_time,
! int64 stop_time,
! int msec);
diff -dcrpN postgresql.orig/src/bin/pg_basebackup/streamutil.c postgresql/src/bin/pg_basebackup/streamutil.c
*** postgresql.orig/src/bin/pg_basebackup/streamutil.c 2013-01-02 09:19:03.856521815 +0100
--- postgresql/src/bin/pg_basebackup/streamutil.c 2013-01-07 15:11:40.793007938 +0100
*************** pg_malloc0(size_t size)
*** 66,74 ****
* 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)
{
PGconn *tmpconn;
int argcount = 4; /* dbname, replication, fallback_app_name,
--- 66,76 ----
* 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.
+ * Set conn_timeout to PGconn structure if their value
+ * is not NULL.
*/
PGconn *
! GetConnection(char *conn_timeout)
{
PGconn *tmpconn;
int argcount = 4; /* dbname, replication, fallback_app_name,
*************** GetConnection(void)
*** 85,90 ****
--- 87,94 ----
argcount++;
if (dbport)
argcount++;
+ if (conn_timeout)
+ argcount++;
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
values = pg_malloc0((argcount + 1) * sizeof(*values));
*************** GetConnection(void)
*** 114,119 ****
--- 118,129 ----
values[i] = dbport;
i++;
}
+ if (conn_timeout != NULL)
+ {
+ keywords[i] = "connect_timeout";
+ values[i] = conn_timeout;
+ i++;
+ }
while (true)
{
diff -dcrpN postgresql.orig/src/bin/pg_basebackup/streamutil.h postgresql/src/bin/pg_basebackup/streamutil.h
*** postgresql.orig/src/bin/pg_basebackup/streamutil.h 2012-10-03 10:40:48.299207401 +0200
--- postgresql/src/bin/pg_basebackup/streamutil.h 2013-01-07 15:11:40.794007945 +0100
*************** extern PGconn *conn;
*** 19,22 ****
extern char *pg_strdup(const char *s);
extern void *pg_malloc0(size_t size);
! extern PGconn *GetConnection(void);
--- 19,22 ----
extern char *pg_strdup(const char *s);
extern void *pg_malloc0(size_t size);
! PGconn *GetConnection(char *conn_timeout);
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers