aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_basebackup/pg_recvlogical.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/pg_basebackup/pg_recvlogical.c')
-rw-r--r--src/bin/pg_basebackup/pg_recvlogical.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/src/bin/pg_basebackup/pg_recvlogical.c b/src/bin/pg_basebackup/pg_recvlogical.c
index 90a3f41bbbe..679b901964b 100644
--- a/src/bin/pg_basebackup/pg_recvlogical.c
+++ b/src/bin/pg_basebackup/pg_recvlogical.c
@@ -582,14 +582,40 @@ StreamLogicalLog(void)
res = PQgetResult(conn);
if (PQresultStatus(res) == PGRES_COPY_OUT)
{
+ PQclear(res);
+
/*
* We're doing a client-initiated clean exit and have sent CopyDone to
- * the server. We've already sent replay confirmation and fsync'd so
- * we can just clean up the connection now.
+ * the server. Drain any messages, so we don't miss a last-minute
+ * ErrorResponse. The walsender stops generating XLogData records once
+ * it sees CopyDone, so expect this to finish quickly. After CopyDone,
+ * it's too late for sendFeedback(), even if this were to take a long
+ * time. Hence, use synchronous-mode PQgetCopyData().
*/
- goto error;
+ while (1)
+ {
+ int r;
+
+ if (copybuf != NULL)
+ {
+ PQfreemem(copybuf);
+ copybuf = NULL;
+ }
+ r = PQgetCopyData(conn, &copybuf, 0);
+ if (r == -1)
+ break;
+ if (r == -2)
+ {
+ pg_log_error("could not read COPY data: %s",
+ PQerrorMessage(conn));
+ time_to_abort = false; /* unclean exit */
+ goto error;
+ }
+ }
+
+ res = PQgetResult(conn);
}
- else if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
pg_log_error("unexpected termination of replication stream: %s",
PQresultErrorMessage(res));