From: Tom Lane <tgl@sss.pgh.pa.us>
To: Alvaro Herrera <alvherre@alvh.no-ip.org>
Cc: Andres Freund <andres@anarazel.de>
Cc: Andreas Seltenreich <seltenreich@gmx.de>
Cc: pgsql-hackers@postgresql.org, Michael Paquier <michael.paquier@gmail.com>
Subject: Re: [sqlsmith] stuck spinlock in pg_stat_get_wal_receiver after OOM
Date: Tue, 03 Oct 2017 12:30:02 -0400
Message-ID: <22735.1507048202@sss.pgh.pa.us> (raw)
In-Reply-To: <20171003145023.nc2ffduj3qvy4b5b@alvherre.pgsql>
References: <20171003145023.nc2ffduj3qvy4b5b@alvherre.pgsql>
List-Unsubscribe: <mailto:majordomo@postgresql.org?body=unsub%20pgsql-hackers>
Alvaro Herrera <alvherre@alvh.no-ip.org> writes:
> Tom Lane wrote:
>> Alvaro Herrera <alvherre@alvh.no-ip.org> writes:
>>> I think the latch is only used locally. Seems that it was only put in
>>> shmem to avoid a separate variable ...
>> Hm, I'm strongly tempted to move it to a separate static variable then.
Oh, wait, look at
/*
* Wake up the walreceiver main loop.
*
* This is called by the startup process whenever interesting xlog records
* are applied, so that walreceiver can check if it needs to send an apply
* notification back to the master which may be waiting in a COMMIT with
* synchronous_commit = remote_apply.
*/
void
WalRcvForceReply(void)
{
WalRcv->force_reply = true;
if (WalRcv->latch)
SetLatch(WalRcv->latch);
}
So that's trouble waiting to happen, for sure. At the very least we
need to do a single fetch of WalRcv->latch, not two. I wonder whether
even that is sufficient, though: this coding requires an atomic fetch of
a pointer, which is something we generally don't assume to be safe.
I'm inclined to think that it'd be a good idea to move the set and
clear of the latch field into the nearby spinlock critical sections,
and then change WalRcvForceReply to look like
void
WalRcvForceReply(void)
{
Latch *latch;
WalRcv->force_reply = true;
/* fetching the latch pointer might not be atomic, so use spinlock */
SpinLockAcquire(&WalRcv->mutex);
latch = WalRcv->latch;
SpinLockRelease(&WalRcv->mutex);
if (latch)
SetLatch(latch);
}
This still leaves us with a hazard of applying SetLatch to the latch
of a PGPROC that is no longer the walreceiver's, but I think that's
okay (and we have the same problem elsewhere). At worst it leads to
an extra wakeup of the next process using that PGPROC.
I'm also thinking that the force_reply flag needs to be sig_atomic_t,
not bool, because bool store/fetch isn't necessarily atomic on all
platforms.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: tgl@sss.pgh.pa.us, alvherre@alvh.no-ip.org, andres@anarazel.de, seltenreich@gmx.de, michael.paquier@gmail.com
Subject: Re: [sqlsmith] stuck spinlock in pg_stat_get_wal_receiver after OOM
In-Reply-To: <22735.1507048202@sss.pgh.pa.us>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox