Re: [WIP PATCH] Lazily assign xids for toplevel Transactions - Mailing list pgsql-hackers

From Tom Lane
Subject Re: [WIP PATCH] Lazily assign xids for toplevel Transactions
Date
Msg-id 22365.1188154346@sss.pgh.pa.us
Whole thread Raw
In response to Re: [WIP PATCH] Lazily assign xids for toplevel Transactions  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: [WIP PATCH] Lazily assign xids for toplevel Transactions  ("Florian G. Pflug" <fgp@phlo.org>)
List pgsql-hackers
I wrote:
> "Florian G. Pflug" <fgp@phlo.org> writes:
>> Yeah - I do not really like that dual-locking thing either. But it makes
>> prepared transaction handling much easier - if we were to only lock the
>> RID, we'd have to store the rid<->xid mapping for prepared transactions

> Hmmm .... that's a good point.  Not sure how to include prepared xacts
> in the scheme.

After further thought I think we should avoid depending on PIDs as part
of a lock tag --- their behavior is too system-dependent, in particular
we have no right to assume that when a backend exits the same PID won't
be reassigned shortly after, possibly leading to confusion.

Instead, I suggest that we keep a session counter in shared memory and
have each backend assign itself a session ID at startup using that.
A 32-bit session ID in combination with a 32-bit locally assigned
transaction number should be sufficiently unique to identify a
transaction (prepared or otherwise) for the purposes of locking.
These "transient XIDs" only need to be unique as long as the transaction
exists plus shortly thereafter (to avoid race conditions when someone
waits for a transaction that actually terminated a moment before).
So wraparound of the counters isn't a problem, although we probably
want to reserve zero as an invalid value.

I think we only need a transient XID of this sort for top-level
transactions, not subtransactions.

I thought for awhile about how to avoid taking a lock on the regular XID
as well as the transient XID, but it seems pretty messy, particularly
if we don't want to assign transient XIDs to subtransactions.  Probably
best not to go there, at least not in the first-cut patch.

To make CREATE INDEX CONCURRENTLY work, we'd need two things:

* GetLockConflicts would need to report the transient XIDs of the conflicting xacts, not regular XIDs, since they might
nothave regular XIDs.  Then we'd wait on those locks instead of regular-XID locks.
 

* The second phase where we wait out transactions that can still see old tuples doesn't work because such transactions
won'tnecessarily be listed in the snapshot.  Instead, what we have to do is look through the ProcArray for transactions
whoseadvertised xmin is less than the xmax of our reference snapshot.  When we find one, wait for it using its
transientXID.
 

AFAICT, C.I.C. is currently the only place in the system where we
really need transient XIDs at all.  Everyplace else that we need to
wait for a transaction, it's because we found its regular XID in
a tuple we want to lock or modify.  So the whole thing is a bit
annoying.  Maybe we could get rid of the extra overhead with some
shenanigans inside the lock manager, like not bothering to create
a data structure representing the holding of a transient-XID lock
until such time as C.I.C. actually tries to wait for it.  But
again, that seems like a second-pass optimization.

Can anyone suggest better terminology than "transient XID"?
        regards, tom lane


pgsql-hackers by date:

Previous
From: Gregory Stark
Date:
Subject: Re: Final background writer cleanup for 8.3
Next
From: "Kevin Grittner"
Date:
Subject: Re: Final background writer cleanup for 8.3