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

Commit 470687b

Browse files
committed
walsnd: Don't set waiting_for_ping_response spuriously
Ashutosh Bapat noticed that when logical walsender needs to wait for WAL, and it realizes that it must send a keepalive message to walreceiver to update the sent-LSN, which *does not* request a reply from walreceiver, it wrongly sets the flag that it's going to wait for that reply. That means that any future would-be sender of feedback messages ends up not sending a feedback message, because they all believe that a reply is expected. With built-in logical replication there's not much harm in this, because WalReceiverMain will send a ping-back every wal_receiver_timeout/2 anyway; but with other logical replication systems (e.g. pglogical) it can cause significant pain. This problem was introduced in commit 41d5f8a, where the request-reply flag was changed from true to false to WalSndKeepalive, without at the same time removing the line that sets waiting_for_ping_response. Just removing that line would be a sufficient fix, but it seems better to shift the responsibility of setting the flag to WalSndKeepalive itself instead of requiring caller to do it; this is clearly less error-prone. Author: Álvaro Herrera <alvherre@alvh.no-ip.org> Reported-by: Ashutosh Bapat <ashutosh.bapat@2ndquadrant.com> Backpatch: 9.5 and up Discussion: https://postgr.es/m/20200806225558.GA22401@alvherre.pgsql
1 parent 82a0ba7 commit 470687b

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

src/backend/replication/walsender.c

+12-12
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ static XLogRecPtr sendTimeLineValidUpto = InvalidXLogRecPtr;
151151
* How far have we sent WAL already? This is also advertised in
152152
* MyWalSnd->sentPtr. (Actually, this is the next WAL location to send.)
153153
*/
154-
static XLogRecPtr sentPtr = 0;
154+
static XLogRecPtr sentPtr = InvalidXLogRecPtr;
155155

156156
/* Buffers for constructing outgoing messages and processing reply messages. */
157157
static StringInfoData output_message;
@@ -1451,10 +1451,7 @@ WalSndWaitForWal(XLogRecPtr loc)
14511451
if (MyWalSnd->flush < sentPtr &&
14521452
MyWalSnd->write < sentPtr &&
14531453
!waiting_for_ping_response)
1454-
{
14551454
WalSndKeepalive(false);
1456-
waiting_for_ping_response = true;
1457-
}
14581455

14591456
/* check whether we're done */
14601457
if (loc <= RecentFlushPtr)
@@ -2932,10 +2929,7 @@ WalSndDone(WalSndSendDataCallback send_data)
29322929
proc_exit(0);
29332930
}
29342931
if (!waiting_for_ping_response)
2935-
{
29362932
WalSndKeepalive(true);
2937-
waiting_for_ping_response = true;
2938-
}
29392933
}
29402934

29412935
/*
@@ -3432,10 +3426,13 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
34323426
}
34333427

34343428
/*
3435-
* This function is used to send a keepalive message to standby.
3436-
* If requestReply is set, sets a flag in the message requesting the standby
3437-
* to send a message back to us, for heartbeat purposes.
3438-
*/
3429+
* Send a keepalive message to standby.
3430+
*
3431+
* If requestReply is set, the message requests the other party to send
3432+
* a message back to us, for heartbeat purposes. We also set a flag to
3433+
* let nearby code that we're waiting for that response, to avoid
3434+
* repeated requests.
3435+
*/
34393436
static void
34403437
WalSndKeepalive(bool requestReply)
34413438
{
@@ -3450,6 +3447,10 @@ WalSndKeepalive(bool requestReply)
34503447

34513448
/* ... and send it wrapped in CopyData */
34523449
pq_putmessage_noblock('d', output_message.data, output_message.len);
3450+
3451+
/* Set local flag */
3452+
if (requestReply)
3453+
waiting_for_ping_response = true;
34533454
}
34543455

34553456
/*
@@ -3480,7 +3481,6 @@ WalSndKeepaliveIfNecessary(void)
34803481
if (last_processing >= ping_time)
34813482
{
34823483
WalSndKeepalive(true);
3483-
waiting_for_ping_response = true;
34843484

34853485
/* Try to flush pending output to the client */
34863486
if (pq_flush_if_writable() != 0)

0 commit comments

Comments
 (0)