Re: Nested transactions - Mailing list pgsql-hackers

From Alvaro Herrera
Subject Re: Nested transactions
Date
Msg-id 20030318205152.GA6920@dcc.uchile.cl
Whole thread Raw
In response to Re: Nested transactions  (Manfred Koizar <mkoi-pg@aon.at>)
List pgsql-hackers
On Tue, Mar 18, 2003 at 10:32:58AM +0100, Manfred Koizar wrote:
> On Tue, 18 Mar 2003 00:20:40 -0400, Alvaro Herrera
> <alvherre@dcc.uchile.cl> wrote:
> >We will add a field to TransactionStateData with the xid of the parent
> >transaction.  If it's set to InvalidTransactionId, then the transaction is a
> >parent transaction
> 
> We need a stack of currently executing transactions.

Oh, sure.

> >Whenever a transaction aborts, the backend is put into TRANS_ABORT state
> >only if it is a toplevel transaction.  If it is not, the backend is returned
> >to TRANS_INPROGRESS, the TransactionId goes back to the parent
> >(sub)transaction Id, and the pg_clog records the transaction as aborted.
> >The subtransaction tree may delete the corresponding branch.
> 
> First we have to work on the semantics.  Immediately aborting the
> subtransaction is not consistent.  Better stay in the subtransaction
> and mark it with a new SUBTRANS_ABORT state (or just TRANS_ABORT
> because we know we are in a subtransaction).

That's what TBLOCK_ABORT state is (note that it's different from
TRANS_ABORT).  On error, we go into TBLOCK_ABORT state.  On transaction
end, we go from there to TBLOCK_ENDABORT. (And TRANS_ABORT, finish
processing the transaction and get the parent transaction from the
stack.)

If we are in TBLOCK_ABORT state and are issued a BEGIN, a new
subtransaction starts and put in TBLOCK_ABORT state too.  (I think this
is what you intended to say?)  We cannot ignore the BEGIN, and while we
can start with TBLOCK_INPROGRESS state it's only a loss of information,
because at transaction end we can register "aborted" in pg_clog
immediately.


> Possible micro optimisation: don't assign a new xid, but keep track of
> nesting level.

And how do you register things in pg_clog?  I don't think it's optional.


> Do we need new convenience commands ROLLBACK ALL and/or COMMIT ALL?

Probably, but that won't be until the basic machinery is working (same
for SAVEPOINTs: they will create a named transaction and rollback to
that looking at the transaction stack).


> >Commit/abort protocol in pg_clog [...]
> >Tuple Visibility [...]
> 
> I had the strange feeling that this has already been done in more
> detail and was almost going to refer you to
> http://archives.postgresql.org/pgsql-hackers/2002-11/msg01124.php,
> but checking the link I realised that this one message is truncated
> near the beginning.  The rest of the thread is ok but the discussion
> looks a bit out of context :-(

I read the whole thread from Google.  I borrowed Tom's proposal (in
.../2002-11/msg01129.php IIRC); it seems the simplest correct mechanism.

> |The trick here is, that subtransaction status is immediately updated
> |in pg_clog on commit/abort.  Main transaction commit is atomic (just
> |set its commit bit).  Status 11 is short-lived, it is replaced with
> |the final status by one or more of
> |
> |    - COMMIT/ROLLBACK of the main transaction
> |    - a later visibility check (as a side effect)
> |    - VACUUM

I think we obtain the same benefits without using the 11 state.  The
only downside is that non-aborted subtransactions will have their status
updated only at toplevel transaction commit.  We have two ways of doing
this:
1. create a new clog function that allows a list of xid's to be marked
committed (pg_clog lock is held longer),

2. call TransactionIdSetStatus multiple times (lock is held in multiple,
short amounts of time).  I think this will create more contention at
toplevel transaction commit, because when checking for a subtransaction
whose toplevel xact is just committing, the caller will have to obtain
the lock multiple times to get the final status (one for the subtrans,
another for the parent, another for the subtrans again).


> >I don't know how this will be, but the subsystem will have to answer the
> >following questions:
> >
> >- Xid of my parent transaction
> 
> Yes, and not only *my* but *any* transaction.  So this has to be
> globally visible.

Oh, sure.  It's the only reason why we need pg_subtrans to be shared,
AFAIU; else we could save this in local memory and be done with it.

> >- List of Xids of non-aborted child transactions
> 
> Only if we do "parent commit updates all child states" as suggested by
> Tom in
> http://archives.postgresql.org/pgsql-hackers/2002-11/msg01129.php.

Yes, I think this is the best proposal so far.

-- 
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
Voy a acabar con todos los humanos / con los humanos yo acabaré
voy a acabar con todos / con todos los humanos acabaré (Bender)


pgsql-hackers by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: analyze after a database restore?
Next
From: Peter Eisentraut
Date:
Subject: Re: [INTERFACES] Roadmap for FE/BE protocol redesign