On Tue, Jul 19, 2011 at 8:49 PM, Heikki Linnakangas
<heikki.linnakan...@enterprisedb.com> wrote:
> On 19.07.2011 19:22, Simon Riggs wrote:
>>
>> Remove O(N^2) performance issue with multiple SAVEPOINTs.
>> Subtransaction locks now released en masse at main commit, rather than
>> repeatedly re-scanning for locks as we ascend the nested transaction tree.
>> Split transaction state TBLOCK_SUBEND into two states, TBLOCK_SUBCOMMIT
>> and TBLOCK_SUBRELEASE to allow the commit path to be optimised using
>> the existing code in ResourceOwnerRelease() which appears to have been
>> intended for this usage, judging from comments therein.
>
> CommitSubTransaction(true) does this:
>
> ResourceOwnerRelease(s->curTransactionOwner, RESOURCE_RELEASE_LOCKS, true,
> isTopLevel /* == true */);
> ...
> ResourceOwnerDelete(s->curTransactionOwner);
>
> Because isTopLevel is passed as true, ResourceOwnerRelease() doesn't release
> or transfer the locks belonging to the resource owner. After the call, they
> still point to s->curTransactionOwner. Then, the resource owner is deleted.
> After those two calls, the locks still have pointers to the now-pfree'd
> ResourceOwner object. Looking at lock.c, we apparently never dereference
> LOCALLOCKOWNER.owner field. Nevertheless, a dangling pointer like that seems
> like a recipe for trouble. After releasing all subtransactions, we still
> fire deferred triggers, for example, which can do arbitrarily complex
> things. For example, you might allocate new resource owners, which if you're
> really unlucky might get allocated at the same address as the
> already-pfree'd resource owner. I'm not sure what would happen then, but it
> can't be good.
>
> Instead of leaving the locks dangling to an already-destroyed resource
> owner, how about assigning all locks directly to the top-level resource
> owner in one sweep? That'd still be much better than the old way of
> recursively reassigning them up the subtransaction tree, one level at a
> time.

Yes, I did see what the code was doing.

My feeling was the code was specifically written that way, just never
used. So I wired it up to be used the way intended. Have a look at
ResourceOwnerReleaseInternal()... not code I wrote or touched on this
patch.

You might persuade me to do it another way, but I can't see how to
make that way work. Your case seems a stretch. Not sure why you
mention it now, >7 weeks after review.

-- 
 Simon Riggs                   http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services

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

Reply via email to