Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i5HYX-00066q-SB for pgsql-hackers@arkaria.postgresql.org; Tue, 03 Sep 2019 22:45:45 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1i5HYW-0001BL-Mw for pgsql-hackers@arkaria.postgresql.org; Tue, 03 Sep 2019 22:45:44 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i5HYW-0001BD-Ee for pgsql-hackers@lists.postgresql.org; Tue, 03 Sep 2019 22:45:44 +0000 Received: from mail-qk1-x744.google.com ([2607:f8b0:4864:20::744]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i5HY7-0004Gx-NG for pgsql-hackers@postgresql.org; Tue, 03 Sep 2019 22:45:44 +0000 Received: by mail-qk1-x744.google.com with SMTP id m2so17723978qkd.10 for ; Tue, 03 Sep 2019 15:45:19 -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:in-reply-to:user-agent; bh=1Ehz2znc/aqg44EbmzE+s9XK9Me6QGJJUDUPYWP0xIc=; b=Dah6C2JqpYHf1bluGqcPSk6tCDiph9Fe+J/HYxOjZ16DNtc0WDdZG0lZcvnZb6yCAX BFN40tFEEXKEZXFX9574HG4rgFTmQznUXvyFvWV6/zWS9J+9RSCSgRcd0G25wFHQSRbx sOJ8V09a3rCQ9NNGlYTNIy/RomkV5u6PDxG3Q3dwtNIivrJBymMNJA+BvdVp4oHgMn91 FJ7jh4kr7JsD7Tr7LDKUx02vqqY7NUdX2N4gjfLVBj0Uxom+ZRi0sxaSYJCGa6NyKOM+ dPWEArvv7liVclYQU78HnODjL46Nllo/Ir6b4G61HZLVjQ2Mt9yGQ6yotwIMBjeyf8fn Sf2w== 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:in-reply-to :user-agent; bh=1Ehz2znc/aqg44EbmzE+s9XK9Me6QGJJUDUPYWP0xIc=; b=XE36rUyOAwRn7oOVx7pGY200QkGsTUAOmjUmNhHlrzCryTIquGSvnmA3Abe5fq4E6R iK7IosEOlOkgh56x2cWbZNS9cuAiL6PR1CXgKDd7AxvGSynHyYgiSuNTTJTPSKFHZWQc fvOxDVmDSkuHCTxsNwFF7Qc0j6Xs6cjsVCLIMfGy1qzkslFQjUlni+U93i0gDiiUN3PJ k7PtTFk9alwQ8gvlsec8tfJ40UHc1lgKfApgI1HCY4AOAZUSY2DZOZ5e7oMIjdkhpqWp vZLeORDBxUsLmcn4HwYLw+sU++4pb8NumBtGArEDU760fUPX6/1hHTGf8rbe7aOxTu6p n3zw== X-Gm-Message-State: APjAAAVMwgo8yZaVarXwaQneQcunEWaENuIEXlVAyX6slLbVlnq8BALd IZNhe58t3LNHcl3ltT581mz23tcAl6Cj5Q== X-Google-Smtp-Source: APXvYqzKgO4PIHQDub0X0LefsGmcdnFdMJz9V1KcBj07xRgPAoAkrzsR/jB8ZeVlyLyzmRJXCovgaQ== X-Received: by 2002:a37:7f41:: with SMTP id a62mr9636286qkd.21.1567549141075; Tue, 03 Sep 2019 15:19:01 -0700 (PDT) Received: from nimloth.alvh.no-ip.org ([190.121.29.3]) by smtp.gmail.com with ESMTPSA id a23sm8679137qtj.5.2019.09.03.15.19.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Sep 2019 15:19:00 -0700 (PDT) Received: by nimloth.alvh.no-ip.org (Postfix, from userid 1000) id 89D52120E47; Tue, 3 Sep 2019 18:18:58 -0400 (-04) Date: Tue, 3 Sep 2019 18:18:58 -0400 From: Alvaro Herrera To: Craig Ringer Cc: PostgreSQL Hackers Subject: Re: [PATCH] Race condition in logical walsender causes long postgresql shutdown delay Message-ID: <20190903221858.GA13440@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="BXVAT5kNtrzKuDFl" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --BXVAT5kNtrzKuDFl Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2019-Jul-25, Craig Ringer wrote: > Patch attached. Here's a non-broken version of this patch. I have not done anything other than reflowing the new comment. -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services --BXVAT5kNtrzKuDFl Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v2-0001-Fix-a-delay-in-PostgreSQL-shutdown-caused-by-logi.patch" From 98eac4afa6995c57c5b8288c126f88b434268dbc Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Tue, 3 Sep 2019 18:17:11 -0400 Subject: [PATCH v2] Fix a delay in PostgreSQL shutdown caused by logical replication Due to a race with WAL writing during shutdown, if logical walsenders were running then PostgreSQL's shutdown could be delayed by up to wal_sender_timeout/2 while it waits for the walsenders to shut down. The walsenders wait for new WAL or end-of-wal which won't come until shutdown so there's a deadlock. The walsender timeout eventually breaks the deadlock. The issue was introduced by PostgreSQL 10 commit c6c3334364 "Prevent possibility of panics during shutdown checkpoint". A logical walsender never enters WALSNDSTATE_STOPPING and allows the checkpointer to continue shutdown. Instead it exits when it reads end-of-WAL. But if it reads the last WAL record written before shutdown and that record doesn't generate a client network write, it can mark itself caught up and go to sleep without checking to see if it's been asked to shut down. Fix by making sure the logical walsender always checks if it's been asked to shut down before it allows the walsender main loop to go to sleep. When this issue happens the walsender(s) can be seen to be sleeping in WaitLatchOrSocket in WalSndLoop until woken by the keepalive timeout. The checkpointer will be waiting in WalSndWaitStopping() for the walsenders to enter WALSNDSTATE_STOPPING or exit, whichever happens first. The postmaster will be waiting in ServerLoop for the checkpointer to finish the shutdown checkpoint. --- src/backend/replication/walsender.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 23870a25a5..88fad46376 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -2858,18 +2858,25 @@ XLogSendLogical(void) * point, then we're caught up. */ if (logical_decoding_ctx->reader->EndRecPtr >= GetFlushRecPtr()) - { WalSndCaughtUp = true; - - /* - * Have WalSndLoop() terminate the connection in an orderly - * manner, after writing out all the pending data. - */ - if (got_STOPPING) - got_SIGUSR2 = true; - } } + /* + * If we've recently sent up to the currently flushed WAL and are shutting + * down, we can safely wrap up by flushing buffers and exchanging CopyDone + * messages. It doesn't matter if more WAL may be written before shutdown + * because no WAL written after replication slots are checkpointed can + * result in invocation of logical decoding hooks and output to the + * client. + * + * We could instead WalSndSetState(WALSNDSTATE_STOPPING) to allow shutdown + * to continue and put the walsender in a state where any unexpected WAL + * records Assert. But the net effect is the same and this is safer to + * backpatch on customer systems. + */ + if (got_STOPPING && WalSndCaughtUp) + got_SIGUSR2 = true; + /* Update shared memory status */ { WalSnd *walsnd = MyWalSnd; -- 2.17.1 --BXVAT5kNtrzKuDFl--