mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03:00
snapshot scalability: Move delayChkpt from PGXACT to PGPROC.
The goal of separating hotly accessed per-backend data from PGPROC into PGXACT is to make accesses fast (GetSnapshotData() in particular). But delayChkpt is not actually accessed frequently; only when starting a checkpoint. As it is frequently modified (multiple times in the course of a single transaction), storing it in the same cacheline as hotly accessed data unnecessarily dirties a contended cacheline. Therefore move delayChkpt to PGPROC. This is part of a larger series of patches intending to improve GetSnapshotData() scalability. It is committed and pushed separately, as it is independently beneficial (small but measurable win, limited by the other frequent modifications of PGXACT). Author: Andres Freund Reviewed-By: Robert Haas, Thomas Munro, David Rowley Discussion: https://postgr.es/m/20200301083601.ews6hz5dduc3w2se@alap3.anarazel.de
This commit is contained in:
@@ -3587,7 +3587,7 @@ MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
|
||||
* essential that CreateCheckpoint waits for virtual transactions
|
||||
* rather than full transactionids.
|
||||
*/
|
||||
MyPgXact->delayChkpt = delayChkpt = true;
|
||||
MyProc->delayChkpt = delayChkpt = true;
|
||||
lsn = XLogSaveBufferForHint(buffer, buffer_std);
|
||||
}
|
||||
|
||||
@@ -3620,7 +3620,7 @@ MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
|
||||
UnlockBufHdr(bufHdr, buf_state);
|
||||
|
||||
if (delayChkpt)
|
||||
MyPgXact->delayChkpt = false;
|
||||
MyProc->delayChkpt = false;
|
||||
|
||||
if (dirtied)
|
||||
{
|
||||
|
@@ -436,7 +436,7 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
|
||||
pgxact->xmin = InvalidTransactionId;
|
||||
/* must be cleared with xid/xmin: */
|
||||
pgxact->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
|
||||
pgxact->delayChkpt = false; /* be sure this is cleared in abort */
|
||||
proc->delayChkpt = false; /* be sure this is cleared in abort */
|
||||
proc->recoveryConflictPending = false;
|
||||
|
||||
Assert(pgxact->nxids == 0);
|
||||
@@ -458,7 +458,7 @@ ProcArrayEndTransactionInternal(PGPROC *proc, PGXACT *pgxact,
|
||||
pgxact->xmin = InvalidTransactionId;
|
||||
/* must be cleared with xid/xmin: */
|
||||
pgxact->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
|
||||
pgxact->delayChkpt = false; /* be sure this is cleared in abort */
|
||||
proc->delayChkpt = false; /* be sure this is cleared in abort */
|
||||
proc->recoveryConflictPending = false;
|
||||
|
||||
/* Clear the subtransaction-XID cache too while holding the lock */
|
||||
@@ -616,7 +616,7 @@ ProcArrayClearTransaction(PGPROC *proc)
|
||||
|
||||
/* redundant, but just in case */
|
||||
pgxact->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
|
||||
pgxact->delayChkpt = false;
|
||||
proc->delayChkpt = false;
|
||||
|
||||
/* Clear the subtransaction-XID cache too */
|
||||
pgxact->nxids = 0;
|
||||
@@ -2257,7 +2257,7 @@ GetOldestSafeDecodingTransactionId(bool catalogOnly)
|
||||
* delaying checkpoint because they have critical actions in progress.
|
||||
*
|
||||
* Constructs an array of VXIDs of transactions that are currently in commit
|
||||
* critical sections, as shown by having delayChkpt set in their PGXACT.
|
||||
* critical sections, as shown by having delayChkpt set in their PGPROC.
|
||||
*
|
||||
* Returns a palloc'd array that should be freed by the caller.
|
||||
* *nvxids is the number of valid entries.
|
||||
@@ -2288,9 +2288,8 @@ GetVirtualXIDsDelayingChkpt(int *nvxids)
|
||||
{
|
||||
int pgprocno = arrayP->pgprocnos[index];
|
||||
PGPROC *proc = &allProcs[pgprocno];
|
||||
PGXACT *pgxact = &allPgXact[pgprocno];
|
||||
|
||||
if (pgxact->delayChkpt)
|
||||
if (proc->delayChkpt)
|
||||
{
|
||||
VirtualTransactionId vxid;
|
||||
|
||||
@@ -2328,12 +2327,11 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
|
||||
{
|
||||
int pgprocno = arrayP->pgprocnos[index];
|
||||
PGPROC *proc = &allProcs[pgprocno];
|
||||
PGXACT *pgxact = &allPgXact[pgprocno];
|
||||
VirtualTransactionId vxid;
|
||||
|
||||
GET_VXID_FROM_PGPROC(vxid, *proc);
|
||||
|
||||
if (pgxact->delayChkpt && VirtualTransactionIdIsValid(vxid))
|
||||
if (proc->delayChkpt && VirtualTransactionIdIsValid(vxid))
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@@ -397,7 +397,7 @@ InitProcess(void)
|
||||
MyProc->roleId = InvalidOid;
|
||||
MyProc->tempNamespaceId = InvalidOid;
|
||||
MyProc->isBackgroundWorker = IsBackgroundWorker;
|
||||
MyPgXact->delayChkpt = false;
|
||||
MyProc->delayChkpt = false;
|
||||
MyPgXact->vacuumFlags = 0;
|
||||
/* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
|
||||
if (IsAutoVacuumWorkerProcess())
|
||||
@@ -579,7 +579,7 @@ InitAuxiliaryProcess(void)
|
||||
MyProc->roleId = InvalidOid;
|
||||
MyProc->tempNamespaceId = InvalidOid;
|
||||
MyProc->isBackgroundWorker = IsBackgroundWorker;
|
||||
MyPgXact->delayChkpt = false;
|
||||
MyProc->delayChkpt = false;
|
||||
MyPgXact->vacuumFlags = 0;
|
||||
MyProc->lwWaiting = false;
|
||||
MyProc->lwWaitMode = 0;
|
||||
|
Reference in New Issue
Block a user