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

Commit a5a02a7

Browse files
committed
Fix the logic in libpqrcv_receive() to determine if there's any incoming data
that can be read without blocking. It used to conclude that there isn't, even though there was data in the socket receive buffer. That lead walreceiver to flush the WAL after every received chunk, potentially causing big performance issues. Backpatch to 9.0, because the performance impact can be very significant.
1 parent c667cc2 commit a5a02a7

File tree

1 file changed

+17
-18
lines changed

1 file changed

+17
-18
lines changed

src/backend/replication/libpqwalreceiver/libpqwalreceiver.c

+17-18
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ void _PG_init(void);
4141

4242
/* Current connection to the primary, if any */
4343
static PGconn *streamConn = NULL;
44-
static bool justconnected = false;
4544

4645
/* Buffer for currently read records */
4746
static char *recvBuf = NULL;
@@ -168,7 +167,6 @@ libpqrcv_connect(char *conninfo, XLogRecPtr startpoint)
168167
}
169168
PQclear(res);
170169

171-
justconnected = true;
172170
ereport(LOG,
173171
(errmsg("streaming replication successfully connected to primary")));
174172

@@ -321,7 +319,6 @@ libpqrcv_disconnect(void)
321319
{
322320
PQfinish(streamConn);
323321
streamConn = NULL;
324-
justconnected = false;
325322
}
326323

327324
/*
@@ -351,28 +348,30 @@ libpqrcv_receive(int timeout, unsigned char *type, char **buffer, int *len)
351348
PQfreemem(recvBuf);
352349
recvBuf = NULL;
353350

354-
/*
355-
* If the caller requested to block, wait for data to arrive. But if this
356-
* is the first call after connecting, don't wait, because there might
357-
* already be some data in libpq buffer that we haven't returned to
358-
* caller.
359-
*/
360-
if (timeout > 0 && !justconnected)
351+
/* Try to receive a CopyData message */
352+
rawlen = PQgetCopyData(streamConn, &recvBuf, 1);
353+
if (rawlen == 0)
361354
{
362-
if (!libpq_select(timeout))
363-
return false;
355+
/*
356+
* No data available yet. If the caller requested to block, wait for
357+
* more data to arrive.
358+
*/
359+
if (timeout > 0)
360+
{
361+
if (!libpq_select(timeout))
362+
return false;
363+
}
364364

365365
if (PQconsumeInput(streamConn) == 0)
366366
ereport(ERROR,
367367
(errmsg("could not receive data from WAL stream: %s",
368368
PQerrorMessage(streamConn))));
369-
}
370-
justconnected = false;
371369

372-
/* Receive CopyData message */
373-
rawlen = PQgetCopyData(streamConn, &recvBuf, 1);
374-
if (rawlen == 0) /* no data available yet, then return */
375-
return false;
370+
/* Now that we've consumed some input, try again */
371+
rawlen = PQgetCopyData(streamConn, &recvBuf, 1);
372+
if (rawlen == 0)
373+
return false;
374+
}
376375
if (rawlen == -1) /* end-of-streaming or error */
377376
{
378377
PGresult *res;

0 commit comments

Comments
 (0)