Re: lock on object is already held - Mailing list pgsql-hackers

From Tom Lane
Subject Re: lock on object is already held
Date
Msg-id 13298.1385756031@sss.pgh.pa.us
Whole thread Raw
In response to lock on object is already held  (Daniel Wood <dwood@salesforce.com>)
Responses Re: lock on object is already held  (Pavel Stehule <pavel.stehule@gmail.com>)
List pgsql-hackers
Daniel Wood <dwood@salesforce.com> writes:
> ... Presuming your fix is putting PG_SETMASK(&UnBlockSig)
> immediately before each of the 6 calls to ereport(ERROR,...) I've been
> running the stress test with both this fix and the lock already held fix.

I'm now planning to put it in error cleanup instead, but that's good
enough for proving that the problem is what I thought it was.

> I get plenty of lock timeout errors as expected.  However, once in a great
> while I get:  sqlcode = -400, sqlstate = 57014, sqlerrmc = canceling
> statement due to user request
> My stress test certainly doesn't do a user cancel.  Should this be expected?

I think I see what must be happening there: the lock timeout interrupt is
happening at some point after the lock has been granted, but before
ProcSleep reaches its disable_timeouts call.  QueryCancelPending gets set,
and will be honored next time something does CHECK_FOR_INTERRUPTS.
But because ProcSleep told disable_timeouts to clear the LOCK_TIMEOUT
indicator bit, ProcessInterrupts thinks the cancel must've been a plain
user SIGINT, and reports it that way.

What we should probably do about this is change ProcSleep to not clear the 
LOCK_TIMEOUT indicator bit, same as we already do in LockErrorCleanup,
which is the less-race-condition-y path out of a lock timeout.

(It would be cooler if the timeout handler had a way to realize that the
lock is already granted, and not issue a query cancel in the first place.
But having a signal handler poking at shared memory state is a little too
scary for my taste.)

It strikes me that this also means that places where we throw away pending
cancels by clearing QueryCancelPending, such as the sigsetjmp stanza in
postgres.c, had better reset the LOCK_TIMEOUT indicator bit.  Otherwise,
a thrown-away lock timeout cancel might cause a later SIGINT cancel to be
misreported.
        regards, tom lane



pgsql-hackers by date:

Previous
From: Greg Stark
Date:
Subject: Re: [RFC] overflow checks optimized away
Next
From: Marko Kreen
Date:
Subject: Re: fe-secure.c and SSL/TLS