On Wed, 2008-10-22 at 21:47 +0100, Simon Riggs wrote: > But once you reach 64 transactions, you'll need to write an extra WAL > record for every subtransaction, which currently I've managed to avoid.
Some further notes/tests on the optimisation you discovered. Because of the way I have changed tqual.c, we only need to write to subtrans if a proc's subxid cache overflows. (I think we would need to change tqual.c in a similar way in any of the ways so far discussed). Anyway, quick test with a representative test case shows 3-5% performance gain from skipping the subtrans updates. I only the test case files here and the test patch. The test is a simple PL/pgSQL function with one EXCEPTION clause, so fairly real world. The patch isn't ready to apply standalone because we need to include the changes to XidInMVCCSnapshot() also, which would take a little while to extract. Let me know if that is worth producing a standalone patch for. -- Simon Riggs www.2ndQuadrant.com PostgreSQL Training, Services and Support
SELECT new_order();
CREATE TABLE orders (ordid SERIAL NOT NULL PRIMARY KEY); CREATE FUNCTION new_order() RETURNS VOID LANGUAGE PLPGSQL AS $$ DECLARE BEGIN INSERT INTO orders DEFAULT VALUES; EXCEPTION WHEN unique_violation THEN --do nothing END; $$;
Index: src/backend/access/transam/varsup.c =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/transam/varsup.c,v retrieving revision 1.81 diff -c -r1.81 varsup.c *** src/backend/access/transam/varsup.c 1 Jan 2008 19:45:48 -0000 1.81 --- src/backend/access/transam/varsup.c 23 Oct 2008 04:36:04 -0000 *************** *** 36,44 **** * The new XID is also stored into MyProc before returning. */ TransactionId ! GetNewTransactionId(bool isSubXact) { ! TransactionId xid; /* * During bootstrap initialization, we return the special bootstrap --- 36,45 ---- * The new XID is also stored into MyProc before returning. */ TransactionId ! GetNewTransactionId(TransactionId parentXid) { ! TransactionId xid; ! bool isSubXact = TransactionIdIsValid(parentXid); /* * During bootstrap initialization, we return the special bootstrap *************** *** 176,181 **** --- 177,191 ---- LWLockRelease(XidGenLock); + /* + * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in + * shared storage other than PG_PROC; because if there's no room for it in + * PG_PROC, the subtrans entry is needed to ensure that other backends see + * the Xid as "running". + */ + if (isSubXact && MyProc->subxids.overflowed) + SubTransSetParent(xid, parentXid); + return xid; } Index: src/backend/access/transam/xact.c =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/transam/xact.c,v retrieving revision 1.266 diff -c -r1.266 xact.c *** src/backend/access/transam/xact.c 20 Oct 2008 19:18:18 -0000 1.266 --- src/backend/access/transam/xact.c 23 Oct 2008 04:38:02 -0000 *************** *** 391,396 **** --- 391,397 ---- { bool isSubXact = (s->parent != NULL); ResourceOwner currentOwner; + TransactionId parentXid = InvalidTransactionId; /* Assert that caller didn't screw up */ Assert(!TransactionIdIsValid(s->transactionId)); *************** *** 404,420 **** AssignTransactionId(s->parent); /* ! * Generate a new Xid and record it in PG_PROC and pg_subtrans. ! * ! * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in ! * shared storage other than PG_PROC; because if there's no room for it in ! * PG_PROC, the subtrans entry is needed to ensure that other backends see ! * the Xid as "running". See GetNewTransactionId. */ - s->transactionId = GetNewTransactionId(isSubXact); - if (isSubXact) ! SubTransSetParent(s->transactionId, s->parent->transactionId); /* * Acquire lock on the transaction XID. (We assume this cannot block.) We --- 405,415 ---- AssignTransactionId(s->parent); /* ! * Generate a new Xid and record it in PG_PROC and pg_subtrans, if required */ if (isSubXact) ! parentXid = s->parent->transactionId; ! s->transactionId = GetNewTransactionId(parentXid); /* * Acquire lock on the transaction XID. (We assume this cannot block.) We Index: src/include/access/transam.h =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/include/access/transam.h,v retrieving revision 1.66 diff -c -r1.66 transam.h *** src/include/access/transam.h 20 Oct 2008 19:18:18 -0000 1.66 --- src/include/access/transam.h 23 Oct 2008 04:37:04 -0000 *************** *** 152,158 **** extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid); /* in transam/varsup.c */ ! extern TransactionId GetNewTransactionId(bool isSubXact); extern TransactionId ReadNewTransactionId(void); extern void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Name oldest_datname); --- 152,158 ---- extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid); /* in transam/varsup.c */ ! extern TransactionId GetNewTransactionId(TransactionId parentXid); extern TransactionId ReadNewTransactionId(void); extern void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Name oldest_datname);
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers