Skip to content

Commit a08363d

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 fed8dcd commit a08363d

File tree

1 file changed

+17
-18
lines changed

1 file changed

+17
-18
lines changed

src/backend/replication/libpqwalreceiver/libpqwalreceiver.c

Lines changed: 17 additions & 18 deletions
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;
@@ -166,7 +165,6 @@ libpqrcv_connect(char *conninfo, XLogRecPtr startpoint)
166165
}
167166
PQclear(res);
168167

169-
justconnected = true;
170168
ereport(LOG,
171169
(errmsg("streaming replication successfully connected to primary")));
172170

@@ -318,7 +316,6 @@ libpqrcv_disconnect(void)
318316
{
319317
PQfinish(streamConn);
320318
streamConn = NULL;
321-
justconnected = false;
322319
}
323320

324321
/*
@@ -348,28 +345,30 @@ libpqrcv_receive(int timeout, unsigned char *type, char **buffer, int *len)
348345
PQfreemem(recvBuf);
349346
recvBuf = NULL;
350347

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

362362
if (PQconsumeInput(streamConn) == 0)
363363
ereport(ERROR,
364364
(errmsg("could not receive data from WAL stream: %s",
365365
PQerrorMessage(streamConn))));
366-
}
367-
justconnected = false;
368366

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

0 commit comments

Comments
 (0)