diff options
Diffstat (limited to 'src/backend/storage/ipc/procarray.c')
-rw-r--r-- | src/backend/storage/ipc/procarray.c | 66 |
1 files changed, 43 insertions, 23 deletions
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 0bf20a49375..224da4f9510 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -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; } |