Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a0b4c5a

Browse files
committed
Fix pg_basebackup/pg_receivexlog for floating point timestamps
Since the replication protocol deals with TimestampTz, we need to care for the floating point case as well in the frontend tools. Fujii Masao, with changes from Magnus Hagander
1 parent 7c1abc0 commit a0b4c5a

File tree

5 files changed

+64
-11
lines changed

5 files changed

+64
-11
lines changed

doc/src/sgml/ref/pg_basebackup.sgml

+2-2
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,8 @@ PostgreSQL documentation
338338
Specifies the number of seconds between status packets sent back to the
339339
server. This is required when streaming the transaction log (using
340340
<literal>--xlog=stream</literal>) if replication timeout is configured
341-
on the server, and allows for easier monitoring. The default value is
342-
10 seconds.
341+
on the server, and allows for easier monitoring. A value of zero disables
342+
the status updates completely. The default value is 10 seconds.
343343
</para>
344344
</listitem>
345345
</varlistentry>

doc/src/sgml/ref/pg_receivexlog.sgml

+2-2
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ PostgreSQL documentation
129129
<para>
130130
Specifies the number of seconds between status packets sent back to the
131131
server. This is required if replication timeout is configured on the
132-
server, and allows for easier monitoring. The default value is
133-
10 seconds.
132+
server, and allows for easier monitoring. A value of zero disables the
133+
status updates completely. The default value is 10 seconds.
134134
</para>
135135
</listitem>
136136
</varlistentry>

src/bin/pg_basebackup/pg_basebackup.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ int compresslevel = 0;
4646
bool includewal = false;
4747
bool streamwal = false;
4848
bool fastcheckpoint = false;
49-
int standby_message_timeout = 10; /* 10 sec = default */
49+
int standby_message_timeout = 10 * 1000; /* 10 sec = default */
5050

5151
/* Progress counters */
5252
static uint64 totalsize;
@@ -1311,7 +1311,7 @@ main(int argc, char **argv)
13111311
dbgetpassword = 1;
13121312
break;
13131313
case 's':
1314-
standby_message_timeout = atoi(optarg);
1314+
standby_message_timeout = atoi(optarg) * 1000;
13151315
if (standby_message_timeout < 0)
13161316
{
13171317
fprintf(stderr, _("%s: invalid status interval \"%s\"\n"),

src/bin/pg_basebackup/pg_receivexlog.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
char *basedir = NULL;
4141
int verbose = 0;
4242
int noloop = 0;
43-
int standby_message_timeout = 10; /* 10 sec = default */
43+
int standby_message_timeout = 10 * 1000; /* 10 sec = default */
4444
volatile bool time_to_abort = false;
4545

4646

@@ -356,7 +356,7 @@ main(int argc, char **argv)
356356
dbgetpassword = 1;
357357
break;
358358
case 's':
359-
standby_message_timeout = atoi(optarg);
359+
standby_message_timeout = atoi(optarg) * 1000;
360360
if (standby_message_timeout < 0)
361361
{
362362
fprintf(stderr, _("%s: invalid status interval \"%s\"\n"),

src/bin/pg_basebackup/receivelog.c

+56-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "access/xlog_internal.h"
2424
#include "replication/walprotocol.h"
2525
#include "utils/datetime.h"
26+
#include "utils/timestamp.h"
2627

2728
#include "receivelog.h"
2829
#include "streamutil.h"
@@ -195,6 +196,51 @@ localGetCurrentTimestamp(void)
195196
return result;
196197
}
197198

199+
/*
200+
* Local version of TimestampDifference(), since we are not
201+
* linked with backend code.
202+
*/
203+
static void
204+
localTimestampDifference(TimestampTz start_time, TimestampTz stop_time,
205+
long *secs, int *microsecs)
206+
{
207+
TimestampTz diff = stop_time - start_time;
208+
209+
if (diff <= 0)
210+
{
211+
*secs = 0;
212+
*microsecs = 0;
213+
}
214+
else
215+
{
216+
#ifdef HAVE_INT64_TIMESTAMP
217+
*secs = (long) (diff / USECS_PER_SEC);
218+
*microsecs = (int) (diff % USECS_PER_SEC);
219+
#else
220+
*secs = (long) diff;
221+
*microsecs = (int) ((diff - *secs) * 1000000.0);
222+
#endif
223+
}
224+
}
225+
226+
/*
227+
* Local version of TimestampDifferenceExceeds(), since we are not
228+
* linked with backend code.
229+
*/
230+
static bool
231+
localTimestampDifferenceExceeds(TimestampTz start_time,
232+
TimestampTz stop_time,
233+
int msec)
234+
{
235+
TimestampTz diff = stop_time - start_time;
236+
237+
#ifdef HAVE_INT64_TIMESTAMP
238+
return (diff >= msec * INT64CONST(1000));
239+
#else
240+
return (diff * 1000.0 >= msec);
241+
#endif
242+
}
243+
198244
/*
199245
* Receive a log stream starting at the specified position.
200246
*
@@ -306,7 +352,8 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
306352
*/
307353
now = localGetCurrentTimestamp();
308354
if (standby_message_timeout > 0 &&
309-
last_status < now - standby_message_timeout * 1000000)
355+
localTimestampDifferenceExceeds(last_status, now,
356+
standby_message_timeout))
310357
{
311358
/* Time to send feedback! */
312359
char replybuf[sizeof(StandbyReplyMessage) + 1];
@@ -345,10 +392,16 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
345392
FD_SET(PQsocket(conn), &input_mask);
346393
if (standby_message_timeout)
347394
{
348-
timeout.tv_sec = last_status + standby_message_timeout - now - 1;
395+
TimestampTz targettime;
396+
397+
targettime = TimestampTzPlusMilliseconds(last_status,
398+
standby_message_timeout - 1);
399+
localTimestampDifference(now,
400+
targettime,
401+
&timeout.tv_sec,
402+
(int *)&timeout.tv_usec);
349403
if (timeout.tv_sec <= 0)
350404
timeout.tv_sec = 1; /* Always sleep at least 1 sec */
351-
timeout.tv_usec = 0;
352405
timeoutptr = &timeout;
353406
}
354407
else

0 commit comments

Comments
 (0)