From: Andres Freund on
Hi Tom, Hi Simon,

On Wednesday 20 January 2010 17:59:36 Tom Lane wrote:
> Andres Freund <andres(a)anarazel.de> writes:
> > I realize its way too late in the cycle for that, but why dont we start
> > using some library for easy cross platform atomic ops?
>
> (1) there probably isn't one that does exactly what we want, works
> everywhere, and has the right license;
> (2) what actual gain would we get? We've already done the work.
That there might be some other instructions were interested in?
Like really atomic increment?

> >> [ grows visibly pale ] *Please* tell me we are not trying to take
> >> locks in a signal handler. What happens if it interrupts code that
> >> is already holding that lock?
> >
> > Yes the patch does that at two places.
>
> That's a must-fix.
Its code intended to fix a existing problem not already comitted code. But
otherwise I definitely agree.

Andres

--
Sent via pgsql-hackers mailing list (pgsql-hackers(a)postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

From: Simon Riggs on
On Wed, 2010-01-20 at 17:40 +0100, Andres Freund wrote:
> > > or similar things with LWLockAcquire in a signal handler
> >
> > [ grows visibly pale ] *Please* tell me we are not trying to take
> > locks in a signal handler. What happens if it interrupts code that
> > is already holding that lock?

> Yes the patch does that at two places.

I think it would be more sensible to discuss specific code and issues,
rather than have general discussions about various horrors.

You've already pointed out that I need to prevent multiple sigalrm
interrupts using boolean flags; I've already said that I would do that.
The use of locks themselves are clearly not a problem, since the
existing sigalrm handler takes LWlocks for deadlock detection. The
problem is just about being called multiple times.

The code in HoldingBufferPinThatDelaysRecovery() also needs protection
against being interrupted multiple times, but we should note that a
second signal of that type is not going to arrive from anywhere inside
the server and requires an explicit user action. The locking isn't
strictly necessary since the value is only read when the only process
that ever writes that value is sleeping on a semaphore. The single
integer value can always be read atomically anyway.

So I will remove the locking in XXXStartupBufferPinWaitBufId(), add in
the booleans and we're done.

--
Simon Riggs www.2ndQuadrant.com


--
Sent via pgsql-hackers mailing list (pgsql-hackers(a)postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

From: Hiroyuki Yamada on
>Deadlock bug was prevented by stop-gap measure in December commit.
>
>Full resolution patch attached for Startup process waits on buffer pins.
>
>Startup process sets SIGALRM when waiting on a buffer pin. If woken by
>alarm we send SIGUSR1 to all backends requesting that they check to see
>if they are blocking Startup process. If so, they throw ERROR/FATAL as
>for other conflict resolutions. Deadlock stop gap removed.
>max_standby_delay = -1 option removed to prevent deadlock.
>
>Reviews welcome, otherwise commit at end of week.
>

I think the patch has two problems.

* disable_standby_sig_alarm() does not clear standby_timeout_active flag
when it succeeds in disabling the alarm.

* Assertion check in HoldingBufferPinThatDelaysRecovery() can fail
with following scenario.

1. Two transactions, xact A and xact B, are running in a HotStandby server.
2. Xact A holds a pin on buffer X.
3. Startup process calls LockBufferForCleanup() for buffer X,
sets ProcGlobal->startupBufferPinWaitBufId = X,
sends PROCSIG_RECOVERY_CONFLICT_BUFFERPIN signal to both transactions,
and sleeps.
4. Xact A handles the signal,
aborts itself,
releases the pin on buffer X,
and awake startup process.
5. Startup process wakes up
and sets ProcGlobal->startupBufferPinWaitBufId = -1.
6. Xact B handles the signal,
checks ProcGlobal->startupBufferPinWaitBufId,
and fails in the assertion check in HoldingBufferPinThatDelaysRecovery().


regards,

--
Hiroyuki YAMADA
Kokolink Corporation
yamada(a)kokolink.net

--
Sent via pgsql-hackers mailing list (pgsql-hackers(a)postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

From: Simon Riggs on
On Thu, 2010-01-21 at 18:01 +0900, Hiroyuki Yamada wrote:

> I think the patch has two problems.
>
> * disable_standby_sig_alarm() does not clear standby_timeout_active flag
> when it succeeds in disabling the alarm.

Ah, thanks.

> * Assertion check in HoldingBufferPinThatDelaysRecovery() can fail
> with following scenario.

Agreed. Will remove Assert() because of race conditions.

Thanks,

--
Simon Riggs www.2ndQuadrant.com


--
Sent via pgsql-hackers mailing list (pgsql-hackers(a)postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

From: Simon Riggs on
On Thu, 2010-01-21 at 18:01 +0900, Hiroyuki Yamada wrote:
> >Deadlock bug was prevented by stop-gap measure in December commit.
> >
> >Full resolution patch attached for Startup process waits on buffer pins.
> >
> >Startup process sets SIGALRM when waiting on a buffer pin. If woken by
> >alarm we send SIGUSR1 to all backends requesting that they check to see
> >if they are blocking Startup process. If so, they throw ERROR/FATAL as
> >for other conflict resolutions. Deadlock stop gap removed.
> >max_standby_delay = -1 option removed to prevent deadlock.
> >
> >Reviews welcome, otherwise commit at end of week.
> >
>
> I think the patch has two problems.
>
> * disable_standby_sig_alarm() does not clear standby_timeout_active flag
> when it succeeds in disabling the alarm.
>
> * Assertion check in HoldingBufferPinThatDelaysRecovery() can fail
> with following scenario.

Updated patch, including changes from Andres and Hiroyuki.

--
Simon Riggs www.2ndQuadrant.com