mirror of
https://github.com/postgres/postgres.git
synced 2025-11-19 13:42:17 +03:00
snapshot scalability: Move PGXACT->xmin back to PGPROC.
Now that xmin isn't needed for GetSnapshotData() anymore, it leads to
unnecessary cacheline ping-pong to have it in PGXACT, as it is updated
considerably more frequently than the other PGXACT members.
After the changes in dc7420c2c9, this is a very straight-forward change.
For highly concurrent, snapshot acquisition heavy, workloads this change alone
can significantly increase scalability. E.g. plain pgbench on a smaller 2
socket machine gains 1.07x for read-only pgbench, 1.22x for read-only pgbench
when submitting queries in batches of 100, and 2.85x for batches of 100
'SELECT';. The latter numbers are obviously not to be expected in the
real-world, but micro-benchmark the snapshot computation
scalability (previously spending ~80% of the time in GetSnapshotData()).
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:
@@ -587,9 +587,9 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
|
||||
Assert(!TransactionIdIsValid(allPgXact[proc->pgprocno].xid));
|
||||
|
||||
proc->lxid = InvalidLocalTransactionId;
|
||||
pgxact->xmin = InvalidTransactionId;
|
||||
/* 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;
|
||||
|
||||
@@ -609,9 +609,9 @@ ProcArrayEndTransactionInternal(PGPROC *proc, PGXACT *pgxact,
|
||||
{
|
||||
pgxact->xid = InvalidTransactionId;
|
||||
proc->lxid = InvalidLocalTransactionId;
|
||||
pgxact->xmin = InvalidTransactionId;
|
||||
/* 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;
|
||||
|
||||
@@ -763,7 +763,7 @@ ProcArrayClearTransaction(PGPROC *proc)
|
||||
*/
|
||||
pgxact->xid = InvalidTransactionId;
|
||||
proc->lxid = InvalidLocalTransactionId;
|
||||
pgxact->xmin = InvalidTransactionId;
|
||||
proc->xmin = InvalidTransactionId;
|
||||
proc->recoveryConflictPending = false;
|
||||
|
||||
/* redundant, but just in case */
|
||||
@@ -1563,7 +1563,7 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
|
||||
|
||||
/* Fetch xid just once - see GetNewTransactionId */
|
||||
xid = UINT32_ACCESS_ONCE(pgxact->xid);
|
||||
xmin = UINT32_ACCESS_ONCE(pgxact->xmin);
|
||||
xmin = UINT32_ACCESS_ONCE(proc->xmin);
|
||||
|
||||
/*
|
||||
* Consider both the transaction's Xmin, and its Xid.
|
||||
@@ -1838,7 +1838,7 @@ GetMaxSnapshotSubxidCount(void)
|
||||
*
|
||||
* We also update the following backend-global variables:
|
||||
* TransactionXmin: the oldest xmin of any snapshot in use in the
|
||||
* current transaction (this is the same as MyPgXact->xmin).
|
||||
* current transaction (this is the same as MyProc->xmin).
|
||||
* RecentXmin: the xmin computed for the most recent snapshot. XIDs
|
||||
* older than this are known not running any more.
|
||||
*
|
||||
@@ -1899,7 +1899,7 @@ GetSnapshotData(Snapshot snapshot)
|
||||
|
||||
/*
|
||||
* It is sufficient to get shared lock on ProcArrayLock, even if we are
|
||||
* going to set MyPgXact->xmin.
|
||||
* going to set MyProc->xmin.
|
||||
*/
|
||||
LWLockAcquire(ProcArrayLock, LW_SHARED);
|
||||
|
||||
@@ -2051,8 +2051,8 @@ GetSnapshotData(Snapshot snapshot)
|
||||
replication_slot_xmin = procArray->replication_slot_xmin;
|
||||
replication_slot_catalog_xmin = procArray->replication_slot_catalog_xmin;
|
||||
|
||||
if (!TransactionIdIsValid(MyPgXact->xmin))
|
||||
MyPgXact->xmin = TransactionXmin = xmin;
|
||||
if (!TransactionIdIsValid(MyProc->xmin))
|
||||
MyProc->xmin = TransactionXmin = xmin;
|
||||
|
||||
LWLockRelease(ProcArrayLock);
|
||||
|
||||
@@ -2172,7 +2172,7 @@ GetSnapshotData(Snapshot snapshot)
|
||||
}
|
||||
|
||||
/*
|
||||
* ProcArrayInstallImportedXmin -- install imported xmin into MyPgXact->xmin
|
||||
* ProcArrayInstallImportedXmin -- install imported xmin into MyProc->xmin
|
||||
*
|
||||
* This is called when installing a snapshot imported from another
|
||||
* transaction. To ensure that OldestXmin doesn't go backwards, we must
|
||||
@@ -2225,7 +2225,7 @@ ProcArrayInstallImportedXmin(TransactionId xmin,
|
||||
/*
|
||||
* Likewise, let's just make real sure its xmin does cover us.
|
||||
*/
|
||||
xid = UINT32_ACCESS_ONCE(pgxact->xmin);
|
||||
xid = UINT32_ACCESS_ONCE(proc->xmin);
|
||||
if (!TransactionIdIsNormal(xid) ||
|
||||
!TransactionIdPrecedesOrEquals(xid, xmin))
|
||||
continue;
|
||||
@@ -2236,7 +2236,7 @@ ProcArrayInstallImportedXmin(TransactionId xmin,
|
||||
* GetSnapshotData first, we'll be overwriting a valid xmin here, so
|
||||
* we don't check that.)
|
||||
*/
|
||||
MyPgXact->xmin = TransactionXmin = xmin;
|
||||
MyProc->xmin = TransactionXmin = xmin;
|
||||
|
||||
result = true;
|
||||
break;
|
||||
@@ -2248,7 +2248,7 @@ ProcArrayInstallImportedXmin(TransactionId xmin,
|
||||
}
|
||||
|
||||
/*
|
||||
* ProcArrayInstallRestoredXmin -- install restored xmin into MyPgXact->xmin
|
||||
* ProcArrayInstallRestoredXmin -- install restored xmin into MyProc->xmin
|
||||
*
|
||||
* This is like ProcArrayInstallImportedXmin, but we have a pointer to the
|
||||
* PGPROC of the transaction from which we imported the snapshot, rather than
|
||||
@@ -2261,7 +2261,6 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
|
||||
{
|
||||
bool result = false;
|
||||
TransactionId xid;
|
||||
PGXACT *pgxact;
|
||||
|
||||
Assert(TransactionIdIsNormal(xmin));
|
||||
Assert(proc != NULL);
|
||||
@@ -2269,20 +2268,18 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
|
||||
/* Get lock so source xact can't end while we're doing this */
|
||||
LWLockAcquire(ProcArrayLock, LW_SHARED);
|
||||
|
||||
pgxact = &allPgXact[proc->pgprocno];
|
||||
|
||||
/*
|
||||
* Be certain that the referenced PGPROC has an advertised xmin which is
|
||||
* no later than the one we're installing, so that the system-wide xmin
|
||||
* can't go backwards. Also, make sure it's running in the same database,
|
||||
* so that the per-database xmin cannot go backwards.
|
||||
*/
|
||||
xid = UINT32_ACCESS_ONCE(pgxact->xmin);
|
||||
xid = UINT32_ACCESS_ONCE(proc->xmin);
|
||||
if (proc->databaseId == MyDatabaseId &&
|
||||
TransactionIdIsNormal(xid) &&
|
||||
TransactionIdPrecedesOrEquals(xid, xmin))
|
||||
{
|
||||
MyPgXact->xmin = TransactionXmin = xmin;
|
||||
MyProc->xmin = TransactionXmin = xmin;
|
||||
result = true;
|
||||
}
|
||||
|
||||
@@ -2908,7 +2905,7 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0,
|
||||
if (allDbs || proc->databaseId == MyDatabaseId)
|
||||
{
|
||||
/* Fetch xmin just once - might change on us */
|
||||
TransactionId pxmin = UINT32_ACCESS_ONCE(pgxact->xmin);
|
||||
TransactionId pxmin = UINT32_ACCESS_ONCE(proc->xmin);
|
||||
|
||||
if (excludeXmin0 && !TransactionIdIsValid(pxmin))
|
||||
continue;
|
||||
@@ -2994,7 +2991,6 @@ GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
|
||||
{
|
||||
int pgprocno = arrayP->pgprocnos[index];
|
||||
PGPROC *proc = &allProcs[pgprocno];
|
||||
PGXACT *pgxact = &allPgXact[pgprocno];
|
||||
|
||||
/* Exclude prepared transactions */
|
||||
if (proc->pid == 0)
|
||||
@@ -3004,7 +3000,7 @@ GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
|
||||
proc->databaseId == dbOid)
|
||||
{
|
||||
/* Fetch xmin just once - can't change on us, but good coding */
|
||||
TransactionId pxmin = UINT32_ACCESS_ONCE(pgxact->xmin);
|
||||
TransactionId pxmin = UINT32_ACCESS_ONCE(proc->xmin);
|
||||
|
||||
/*
|
||||
* We ignore an invalid pxmin because this means that backend has
|
||||
|
||||
@@ -420,7 +420,7 @@ BackendIdGetTransactionIds(int backendID, TransactionId *xid, TransactionId *xmi
|
||||
PGXACT *xact = &ProcGlobal->allPgXact[proc->pgprocno];
|
||||
|
||||
*xid = xact->xid;
|
||||
*xmin = xact->xmin;
|
||||
*xmin = proc->xmin;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user