From 6bd4f401b0cb85f2e81caffc457e415e15e2ed5d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 8 Sep 2007 20:31:15 +0000 Subject: Replace the former method of determining snapshot xmax --- to wit, calling ReadNewTransactionId from GetSnapshotData --- with a "latestCompletedXid" variable that is updated during transaction commit or abort. Since latestCompletedXid is written only in places that had to lock ProcArrayLock exclusively anyway, and is read only in places that had to lock ProcArrayLock shared anyway, it adds no new locking requirements to the system despite being cluster-wide. Moreover, removing ReadNewTransactionId from snapshot acquisition eliminates the need to take both XidGenLock and ProcArrayLock at the same time. Since XidGenLock is sometimes held across I/O this can be a significant win. Some preliminary benchmarking suggested that this patch has no effect on average throughput but can significantly improve the worst-case transaction times seen in pgbench. Concept by Florian Pflug, implementation by Tom Lane. --- src/backend/access/transam/transam.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'src/backend/access/transam/transam.c') diff --git a/src/backend/access/transam/transam.c b/src/backend/access/transam/transam.c index 3466b50ef24..e53b05e04d5 100644 --- a/src/backend/access/transam/transam.c +++ b/src/backend/access/transam/transam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.70 2007/08/01 22:45:07 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.71 2007/09/08 20:31:14 tgl Exp $ * * NOTES * This file contains the high level access-method interface to the @@ -432,6 +432,33 @@ TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2) return (diff >= 0); } + +/* + * TransactionIdLatest --- get latest XID among a main xact and its children + */ +TransactionId +TransactionIdLatest(TransactionId mainxid, + int nxids, const TransactionId *xids) +{ + TransactionId result; + + /* + * In practice it is highly likely that the xids[] array is sorted, and + * so we could save some cycles by just taking the last child XID, but + * this probably isn't so performance-critical that it's worth depending + * on that assumption. But just to show we're not totally stupid, scan + * the array back-to-front to avoid useless assignments. + */ + result = mainxid; + while (--nxids >= 0) + { + if (TransactionIdPrecedes(result, xids[nxids])) + result = xids[nxids]; + } + return result; +} + + /* * TransactionIdGetCommitLSN * -- cgit v1.2.3