Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1k3oo1-0005PM-W3 for pgsql-hackers@arkaria.postgresql.org; Thu, 06 Aug 2020 22:56:14 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1k3oo0-00081s-59 for pgsql-hackers@arkaria.postgresql.org; Thu, 06 Aug 2020 22:56:12 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1k3onz-00081l-RA for pgsql-hackers@lists.postgresql.org; Thu, 06 Aug 2020 22:56:11 +0000 Received: from mail-qk1-x730.google.com ([2607:f8b0:4864:20::730]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1k3ons-0006pm-G9 for pgsql-hackers@lists.postgresql.org; Thu, 06 Aug 2020 22:56:11 +0000 Received: by mail-qk1-x730.google.com with SMTP id h7so120320qkk.7 for ; Thu, 06 Aug 2020 15:56:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :content-transfer-encoding:user-agent; bh=2YnopquUPES1+orAf4hyE15AjDmFQiblL6xh3y2tmvA=; b=cC3j9gKOa9UGS6jd1rTnDJHcGFlEo/sAetuLvaDicrd3dFeOdBn/RLr9x9rPVzuEji TrZaqStj4qCy/J8e1Bta1Dbb2TDax3RiDKIZQRouH635lqVyrb8jbhXPhvzsr0td4Gej qrwxYln6hmlC40OoNJatIvQxHtk/G0b2t+RxwTmNM/PoX6EcF+gyggbDnuhLK2YKqkLB VeUOa5zMvpxtakWWthNulMBxnjIZbvJqaqy7y60DYuRXr/mynTQf3ZG1oAsuZ7odYOR3 1AAyCOqMeZJwHEU7by3QRpuf/ln4XILWwooHA58jj06ZtFK0a0SkvBgV5EsoHdlozUlY x1wQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:content-transfer-encoding:user-agent; bh=2YnopquUPES1+orAf4hyE15AjDmFQiblL6xh3y2tmvA=; b=hAwZttOu84NbYv2lvsGbJOBmuXTD0j+u47sVDc2HxNEQeokaKiLLBacbmUnnG4PhF4 ej0OrvJTL8cqubhbKUGHaUgze9P9yJJWPjc2LJ9YXLAvEJQ41aSqZo3CKMrOwkkq/By/ kW7zx0h+oIXKx605p8f99IruOnarUoO9tqWO6F/1W7SUWEBjgPUlU2FRMVORD0Q0n9Ob F01UE0DwoM2aG2dXJPV0uAc5KgLmurJMo59hhIAyVZsHIsyQZulH2xOs+hfiNtUQEBmM eia0tu1KuelVoqTiJR9pqGnRLmSCcgGiS55JSZT80DuPH0fDIYKG9I8WvQfO2zbAElaD Lnsg== X-Gm-Message-State: AOAM532XLj2AEjah/tjqbZad5JOsSFrZ+xThdFr9Xn1v604iSY1HdCsb Qai+jMCVeij10H2dMEHDw43H5g== X-Google-Smtp-Source: ABdhPJzD8NOJ5njHJQ+1Rwt87MuiGrLi4HiEmakiwQQ3IAaZXRScDxmKdPSH45S1zjWo4rtGmgLsRg== X-Received: by 2002:ae9:efcd:: with SMTP id d196mr10968397qkg.251.1596754561891; Thu, 06 Aug 2020 15:56:01 -0700 (PDT) Received: from perhan.alvh.no-ip.org ([190.95.19.47]) by smtp.gmail.com with ESMTPSA id k48sm6708177qtk.44.2020.08.06.15.56.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2020 15:56:00 -0700 (PDT) Received: by perhan.alvh.no-ip.org (Postfix, from userid 1000) id DA4022A0FA5; Thu, 6 Aug 2020 18:55:58 -0400 (-04) Date: Thu, 6 Aug 2020 18:55:58 -0400 From: Alvaro Herrera To: Pg Hackers Cc: ashutosh.bapat@2ndquadrant.com Subject: walsender waiting_for_ping spuriously set Message-ID: <20200806225558.GA22401@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="r5Pyd7+fXNt84Ff3" Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.10.1 (2018-07-13) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --r5Pyd7+fXNt84Ff3 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit Ashutosh Bapat noticed that WalSndWaitForWal() is setting waiting_for_ping_response after sending a keepalive that does *not* request a reply. The bad consequence is that other callers that do require a reply end up in not sending a keepalive, because they think it was already sent previously. So the whole thing gets stuck. He found that commit 41d5f8ad734 failed to remove the setting of waiting_for_ping_response after changing the "request" parameter WalSndKeepalive from true to false; that seems to have been an omission and it breaks the algorithm. Thread at [1]. The simplest fix is just to remove the line that sets waiting_for_ping_response, but I think it is less error-prone to have WalSndKeepalive set the flag itself, instead of expecting its callers to do it (and know when to). Patch attached. Also rewords some related commentary. [1] https://postgr.es/m/flat/BLU436-SMTP25712B7EF9FC2ADEB87C522DC040@phx.gbl -- Álvaro Herrera Valdivia, Chile --r5Pyd7+fXNt84Ff3 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0001-Fix-waiting_for_ping-in-walsender.patch" From bf5ca106817744c1ba300ecb8c86d230789988e0 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Thu, 6 Aug 2020 14:57:09 -0400 Subject: [PATCH] Fix waiting_for_ping in walsender --- src/backend/replication/walsender.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 5e2210dd7b..c239902e0e 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -151,7 +151,7 @@ static XLogRecPtr sendTimeLineValidUpto = InvalidXLogRecPtr; * How far have we sent WAL already? This is also advertised in * MyWalSnd->sentPtr. (Actually, this is the next WAL location to send.) */ -static XLogRecPtr sentPtr = 0; +static XLogRecPtr sentPtr = InvalidXLogRecPtr; /* Buffers for constructing outgoing messages and processing reply messages. */ static StringInfoData output_message; @@ -1444,17 +1444,13 @@ WalSndWaitForWal(XLogRecPtr loc) * We only send regular messages to the client for full decoded * transactions, but a synchronous replication and walsender shutdown * possibly are waiting for a later location. So, before sleeping, we - * send a ping containing the flush location. If the receiver is - * otherwise idle, this keepalive will trigger a reply. Processing the - * reply will update these MyWalSnd locations. + * send a ping containing the flush location. A reply from standby is + * not needed and would be wasteful. */ if (MyWalSnd->flush < sentPtr && MyWalSnd->write < sentPtr && !waiting_for_ping_response) - { WalSndKeepalive(false); - waiting_for_ping_response = true; - } /* check whether we're done */ if (loc <= RecentFlushPtr) @@ -2932,10 +2928,7 @@ WalSndDone(WalSndSendDataCallback send_data) proc_exit(0); } if (!waiting_for_ping_response) - { WalSndKeepalive(true); - waiting_for_ping_response = true; - } } /* @@ -3432,10 +3425,13 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS) } /* - * This function is used to send a keepalive message to standby. - * If requestReply is set, sets a flag in the message requesting the standby - * to send a message back to us, for heartbeat purposes. - */ + * Send a keepalive message to standby. + * + * If requestReply is set, the message requests the other party to send + * a message back to us, for heartbeat purposes. We also set a flag to + * let nearby code that we're waiting for that response, to avoid + * repeated requests. + */ static void WalSndKeepalive(bool requestReply) { @@ -3450,6 +3446,10 @@ WalSndKeepalive(bool requestReply) /* ... and send it wrapped in CopyData */ pq_putmessage_noblock('d', output_message.data, output_message.len); + + /* Set local flag */ + if (requestReply) + waiting_for_ping_response = true; } /* @@ -3480,7 +3480,6 @@ WalSndKeepaliveIfNecessary(void) if (last_processing >= ping_time) { WalSndKeepalive(true); - waiting_for_ping_response = true; /* Try to flush pending output to the client */ if (pq_flush_if_writable() != 0) -- 2.20.1 --r5Pyd7+fXNt84Ff3--