mirror of
https://github.com/postgres/postgres.git
synced 2025-11-19 13:42:17 +03:00
snapshot scalability: Move PGXACT->vacuumFlags to ProcGlobal->vacuumFlags.
Similar to the previous commit this increases the chance that data frequently needed by GetSnapshotData() stays in l2 cache. As we now take care to not unnecessarily write to ProcGlobal->vacuumFlags, there should be very few modifications to the ProcGlobal->vacuumFlags array. Author: Andres Freund <andres@anarazel.de> Reviewed-By: Robert Haas <robertmhaas@gmail.com> Reviewed-By: Thomas Munro <thomas.munro@gmail.com> Reviewed-By: David Rowley <dgrowleyml@gmail.com> Discussion: https://postgr.es/m/20200301083601.ews6hz5dduc3w2se@alap3.anarazel.de
This commit is contained in:
@@ -476,9 +476,12 @@ ProcArrayAdd(PGPROC *proc)
|
||||
(arrayP->numProcs - index) * sizeof(*arrayP->pgprocnos));
|
||||
memmove(&ProcGlobal->xids[index + 1], &ProcGlobal->xids[index],
|
||||
(arrayP->numProcs - index) * sizeof(*ProcGlobal->xids));
|
||||
memmove(&ProcGlobal->vacuumFlags[index + 1], &ProcGlobal->vacuumFlags[index],
|
||||
(arrayP->numProcs - index) * sizeof(*ProcGlobal->vacuumFlags));
|
||||
|
||||
arrayP->pgprocnos[index] = proc->pgprocno;
|
||||
ProcGlobal->xids[index] = proc->xid;
|
||||
ProcGlobal->vacuumFlags[index] = proc->vacuumFlags;
|
||||
|
||||
arrayP->numProcs++;
|
||||
|
||||
@@ -539,6 +542,7 @@ ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
|
||||
}
|
||||
|
||||
Assert(TransactionIdIsValid(ProcGlobal->xids[proc->pgxactoff] == 0));
|
||||
ProcGlobal->vacuumFlags[proc->pgxactoff] = 0;
|
||||
|
||||
for (index = 0; index < arrayP->numProcs; index++)
|
||||
{
|
||||
@@ -549,6 +553,8 @@ ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
|
||||
(arrayP->numProcs - index - 1) * sizeof(*arrayP->pgprocnos));
|
||||
memmove(&ProcGlobal->xids[index], &ProcGlobal->xids[index + 1],
|
||||
(arrayP->numProcs - index - 1) * sizeof(*ProcGlobal->xids));
|
||||
memmove(&ProcGlobal->vacuumFlags[index], &ProcGlobal->vacuumFlags[index + 1],
|
||||
(arrayP->numProcs - index - 1) * sizeof(*ProcGlobal->vacuumFlags));
|
||||
|
||||
arrayP->pgprocnos[arrayP->numProcs - 1] = -1; /* for debugging */
|
||||
arrayP->numProcs--;
|
||||
@@ -626,14 +632,24 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
|
||||
Assert(!TransactionIdIsValid(proc->xid));
|
||||
|
||||
proc->lxid = InvalidLocalTransactionId;
|
||||
/* must be cleared with xid/xmin: */
|
||||
pgxact->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
|
||||
proc->xmin = InvalidTransactionId;
|
||||
proc->delayChkpt = false; /* be sure this is cleared in abort */
|
||||
proc->recoveryConflictPending = false;
|
||||
|
||||
Assert(pgxact->nxids == 0);
|
||||
Assert(pgxact->overflowed == false);
|
||||
|
||||
/* must be cleared with xid/xmin: */
|
||||
/* avoid unnecessarily dirtying shared cachelines */
|
||||
if (proc->vacuumFlags & PROC_VACUUM_STATE_MASK)
|
||||
{
|
||||
Assert(!LWLockHeldByMe(ProcArrayLock));
|
||||
LWLockAcquire(ProcArrayLock, LW_SHARED);
|
||||
Assert(proc->vacuumFlags == ProcGlobal->vacuumFlags[proc->pgxactoff]);
|
||||
proc->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
|
||||
ProcGlobal->vacuumFlags[proc->pgxactoff] = proc->vacuumFlags;
|
||||
LWLockRelease(ProcArrayLock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,12 +670,18 @@ ProcArrayEndTransactionInternal(PGPROC *proc, PGXACT *pgxact,
|
||||
ProcGlobal->xids[pgxactoff] = InvalidTransactionId;
|
||||
proc->xid = InvalidTransactionId;
|
||||
proc->lxid = InvalidLocalTransactionId;
|
||||
/* must be cleared with xid/xmin: */
|
||||
pgxact->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
|
||||
proc->xmin = InvalidTransactionId;
|
||||
proc->delayChkpt = false; /* be sure this is cleared in abort */
|
||||
proc->recoveryConflictPending = false;
|
||||
|
||||
/* must be cleared with xid/xmin: */
|
||||
/* avoid unnecessarily dirtying shared cachelines */
|
||||
if (proc->vacuumFlags & PROC_VACUUM_STATE_MASK)
|
||||
{
|
||||
proc->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
|
||||
ProcGlobal->vacuumFlags[proc->pgxactoff] = proc->vacuumFlags;
|
||||
}
|
||||
|
||||
/* Clear the subtransaction-XID cache too while holding the lock */
|
||||
pgxact->nxids = 0;
|
||||
pgxact->overflowed = false;
|
||||
@@ -819,9 +841,8 @@ ProcArrayClearTransaction(PGPROC *proc)
|
||||
proc->xmin = InvalidTransactionId;
|
||||
proc->recoveryConflictPending = false;
|
||||
|
||||
/* redundant, but just in case */
|
||||
pgxact->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
|
||||
proc->delayChkpt = false;
|
||||
Assert(!(proc->vacuumFlags & PROC_VACUUM_STATE_MASK));
|
||||
Assert(!proc->delayChkpt);
|
||||
|
||||
/* Clear the subtransaction-XID cache too */
|
||||
pgxact->nxids = 0;
|
||||
@@ -1623,7 +1644,7 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
|
||||
{
|
||||
int pgprocno = arrayP->pgprocnos[index];
|
||||
PGPROC *proc = &allProcs[pgprocno];
|
||||
PGXACT *pgxact = &allPgXact[pgprocno];
|
||||
int8 vacuumFlags = ProcGlobal->vacuumFlags[index];
|
||||
TransactionId xid;
|
||||
TransactionId xmin;
|
||||
|
||||
@@ -1640,8 +1661,8 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
|
||||
*/
|
||||
xmin = TransactionIdOlder(xmin, xid);
|
||||
|
||||
/* if neither is set, this proc doesn't influence the horizon */
|
||||
if (!TransactionIdIsValid(xmin))
|
||||
/* if neither is set, this proc doesn't influence the horizon */
|
||||
if (!TransactionIdIsValid(xmin))
|
||||
continue;
|
||||
|
||||
/*
|
||||
@@ -1658,7 +1679,7 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
|
||||
* removed, as long as pg_subtrans is not truncated) or doing logical
|
||||
* decoding (which manages xmin separately, check below).
|
||||
*/
|
||||
if (pgxact->vacuumFlags & (PROC_IN_VACUUM | PROC_IN_LOGICAL_DECODING))
|
||||
if (vacuumFlags & (PROC_IN_VACUUM | PROC_IN_LOGICAL_DECODING))
|
||||
continue;
|
||||
|
||||
/* shared tables need to take backends in all database into account */
|
||||
@@ -1998,6 +2019,7 @@ GetSnapshotData(Snapshot snapshot)
|
||||
size_t numProcs = arrayP->numProcs;
|
||||
TransactionId *xip = snapshot->xip;
|
||||
int *pgprocnos = arrayP->pgprocnos;
|
||||
uint8 *allVacuumFlags = ProcGlobal->vacuumFlags;
|
||||
|
||||
/*
|
||||
* First collect set of pgxactoff/xids that need to be included in the
|
||||
@@ -2007,8 +2029,6 @@ GetSnapshotData(Snapshot snapshot)
|
||||
{
|
||||
/* Fetch xid just once - see GetNewTransactionId */
|
||||
TransactionId xid = UINT32_ACCESS_ONCE(other_xids[pgxactoff]);
|
||||
int pgprocno;
|
||||
PGXACT *pgxact;
|
||||
uint8 vacuumFlags;
|
||||
|
||||
Assert(allProcs[arrayP->pgprocnos[pgxactoff]].pgxactoff == pgxactoff);
|
||||
@@ -2044,14 +2064,11 @@ GetSnapshotData(Snapshot snapshot)
|
||||
if (!NormalTransactionIdPrecedes(xid, xmax))
|
||||
continue;
|
||||
|
||||
pgprocno = pgprocnos[pgxactoff];
|
||||
pgxact = &allPgXact[pgprocno];
|
||||
vacuumFlags = pgxact->vacuumFlags;
|
||||
|
||||
/*
|
||||
* Skip over backends doing logical decoding which manages xmin
|
||||
* separately (check below) and ones running LAZY VACUUM.
|
||||
*/
|
||||
vacuumFlags = allVacuumFlags[pgxactoff];
|
||||
if (vacuumFlags & (PROC_IN_LOGICAL_DECODING | PROC_IN_VACUUM))
|
||||
continue;
|
||||
|
||||
@@ -2078,6 +2095,9 @@ GetSnapshotData(Snapshot snapshot)
|
||||
*/
|
||||
if (!suboverflowed)
|
||||
{
|
||||
int pgprocno = pgprocnos[pgxactoff];
|
||||
PGXACT *pgxact = &allPgXact[pgprocno];
|
||||
|
||||
if (pgxact->overflowed)
|
||||
suboverflowed = true;
|
||||
else
|
||||
@@ -2296,11 +2316,11 @@ ProcArrayInstallImportedXmin(TransactionId xmin,
|
||||
{
|
||||
int pgprocno = arrayP->pgprocnos[index];
|
||||
PGPROC *proc = &allProcs[pgprocno];
|
||||
PGXACT *pgxact = &allPgXact[pgprocno];
|
||||
int vacuumFlags = ProcGlobal->vacuumFlags[index];
|
||||
TransactionId xid;
|
||||
|
||||
/* Ignore procs running LAZY VACUUM */
|
||||
if (pgxact->vacuumFlags & PROC_IN_VACUUM)
|
||||
if (vacuumFlags & PROC_IN_VACUUM)
|
||||
continue;
|
||||
|
||||
/* We are only interested in the specific virtual transaction. */
|
||||
@@ -2990,12 +3010,12 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0,
|
||||
{
|
||||
int pgprocno = arrayP->pgprocnos[index];
|
||||
PGPROC *proc = &allProcs[pgprocno];
|
||||
PGXACT *pgxact = &allPgXact[pgprocno];
|
||||
uint8 vacuumFlags = ProcGlobal->vacuumFlags[index];
|
||||
|
||||
if (proc == MyProc)
|
||||
continue;
|
||||
|
||||
if (excludeVacuum & pgxact->vacuumFlags)
|
||||
if (excludeVacuum & vacuumFlags)
|
||||
continue;
|
||||
|
||||
if (allDbs || proc->databaseId == MyDatabaseId)
|
||||
@@ -3410,7 +3430,7 @@ CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared)
|
||||
{
|
||||
int pgprocno = arrayP->pgprocnos[index];
|
||||
PGPROC *proc = &allProcs[pgprocno];
|
||||
PGXACT *pgxact = &allPgXact[pgprocno];
|
||||
uint8 vacuumFlags = ProcGlobal->vacuumFlags[index];
|
||||
|
||||
if (proc->databaseId != databaseId)
|
||||
continue;
|
||||
@@ -3424,7 +3444,7 @@ CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared)
|
||||
else
|
||||
{
|
||||
(*nbackends)++;
|
||||
if ((pgxact->vacuumFlags & PROC_IS_AUTOVACUUM) &&
|
||||
if ((vacuumFlags & PROC_IS_AUTOVACUUM) &&
|
||||
nautovacs < MAXAUTOVACPIDS)
|
||||
autovac_pids[nautovacs++] = proc->pid;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user