From 2a314add00c2d78d0fcf21a144292407b8652613 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 29 Sep 2001 15:29:48 +0000 Subject: [PATCH] Whoops, I was a tad too enthusiastic about using shared lock mode for SInvalLock. GetSnapshotData(true) has to use exclusive lock, since it sets MyProc->xmin. --- src/backend/storage/ipc/sinval.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c index 24506b9729..4a3b1114a9 100644 --- a/src/backend/storage/ipc/sinval.c +++ b/src/backend/storage/ipc/sinval.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.41 2001/09/29 04:02:24 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.42 2001/09/29 15:29:48 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -310,19 +310,24 @@ GetSnapshotData(bool serializable) if (snapshot == NULL) elog(ERROR, "Memory exhausted in GetSnapshotData"); - snapshot->xmin = GetCurrentTransactionId(); - - LWLockAcquire(SInvalLock, LW_SHARED); - /* - * There can be no more than lastBackend active transactions, so this - * is enough space: + * Allocating space for MaxBackends xids is usually overkill; + * lastBackend would be sufficient. But it seems better to do the + * malloc while not holding the lock, so we can't look at lastBackend. */ snapshot->xip = (TransactionId *) - malloc(segP->lastBackend * sizeof(TransactionId)); + malloc(MaxBackends * sizeof(TransactionId)); if (snapshot->xip == NULL) elog(ERROR, "Memory exhausted in GetSnapshotData"); + snapshot->xmin = GetCurrentTransactionId(); + + /* + * If we are going to set MyProc->xmin then we'd better get exclusive + * lock; if not, this is a read-only operation so it can be shared. + */ + LWLockAcquire(SInvalLock, serializable ? LW_EXCLUSIVE : LW_SHARED); + /*-------------------- * Unfortunately, we have to call ReadNewTransactionId() after acquiring * SInvalLock above. It's not good because ReadNewTransactionId() does