summaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
authorTom Lane2006-09-03 15:59:39 +0000
committerTom Lane2006-09-03 15:59:39 +0000
commit8fad2e3ff4d86e279366c9d0a398f1f2371493f3 (patch)
treece3dcb3333b752d927dac4207c573626bef5c9b8 /src/backend/access
parentf79f57a0af619c071054c23763519b93e1f2f4fe (diff)
Arrange for GetSnapshotData to copy live-subtransaction XIDs from the
PGPROC array into snapshots, and use this information to avoid visits to pg_subtrans in HeapTupleSatisfiesSnapshot. This appears to solve the pg_subtrans-related context swap storm problem that's been reported by several people for 8.1. While at it, modify GetSnapshotData to not take an exclusive lock on ProcArrayLock, as closer analysis shows that shared lock is always sufficient. Itagaki Takahiro and Tom Lane
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/transam/varsup.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 443dab4b0eb..8db94f2a924 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -6,7 +6,7 @@
* Copyright (c) 2000-2006, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.72 2006/07/14 14:52:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.73 2006/09/03 15:59:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -131,17 +131,28 @@ GetNewTransactionId(bool isSubXact)
*/
if (MyProc != NULL)
{
+ /*
+ * Use volatile pointer to prevent code rearrangement; other backends
+ * could be examining my subxids info concurrently, and we don't
+ * want them to see an invalid intermediate state, such as
+ * incrementing nxids before filling the array entry. Note we are
+ * assuming that TransactionId and int fetch/store are atomic.
+ */
+ volatile PGPROC *myproc = MyProc;
+
if (!isSubXact)
- MyProc->xid = xid;
+ myproc->xid = xid;
else
{
- if (MyProc->subxids.nxids < PGPROC_MAX_CACHED_SUBXIDS)
+ int nxids = myproc->subxids.nxids;
+
+ if (nxids < PGPROC_MAX_CACHED_SUBXIDS)
{
- MyProc->subxids.xids[MyProc->subxids.nxids] = xid;
- MyProc->subxids.nxids++;
+ myproc->subxids.xids[nxids] = xid;
+ myproc->subxids.nxids = nxids + 1;
}
else
- MyProc->subxids.overflowed = true;
+ myproc->subxids.overflowed = true;
}
}