diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 19ff524..6986c57 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -1241,6 +1241,8 @@ GetSnapshotData(Snapshot snapshot) int count = 0; int subcount = 0; bool suboverflowed = false; + static TransactionId *xmins = NULL; + int numProcs; Assert(snapshot != NULL); @@ -1276,6 +1278,15 @@ GetSnapshotData(Snapshot snapshot) errmsg("out of memory"))); } + if (xmins == NULL) + { + xmins = malloc(procArray->maxProcs * sizeof(TransactionId)); + if (xmins == NULL) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"))); + } + /* * It is sufficient to get shared lock on ProcArrayLock, even if we are * going to set MyProc->xmin. @@ -1303,7 +1314,6 @@ GetSnapshotData(Snapshot snapshot) if (!snapshot->takenDuringRecovery) { int *pgprocnos = arrayP->pgprocnos; - int numProcs; /* * Spin over procArray checking xid, xmin, and subxids. The goal is @@ -1319,13 +1329,13 @@ GetSnapshotData(Snapshot snapshot) /* Ignore procs running LAZY VACUUM */ if (pgxact->vacuumFlags & PROC_IN_VACUUM) + { + xmins[index] = InvalidTransactionId; continue; + } /* Update globalxmin to be the smallest valid xmin */ - xid = pgxact->xmin; /* fetch just once */ - if (TransactionIdIsNormal(xid) && - TransactionIdPrecedes(xid, globalxmin)) - globalxmin = xid; + xmins[index] = pgxact->xmin; /* fetch just once */ /* Fetch xid just once - see GetNewTransactionId */ xid = pgxact->xid; @@ -1386,6 +1396,7 @@ GetSnapshotData(Snapshot snapshot) } else { + numProcs = 0; /* * We're in hot standby, so get XIDs from KnownAssignedXids. * @@ -1425,6 +1436,14 @@ GetSnapshotData(Snapshot snapshot) * different way of computing it than GetOldestXmin uses, but should give * the same result. */ + for (index = 0; index < numProcs; index++) + { + TransactionId xid = xmins[index]; + if (TransactionIdIsNormal(xid) && + TransactionIdPrecedes(xid, globalxmin)) + globalxmin = xid; + } + if (TransactionIdPrecedes(xmin, globalxmin)) globalxmin = xmin;