mirror of
https://github.com/postgres/postgres.git
synced 2025-11-07 19:06:32 +03:00
Reduce ProcArrayLock contention by removing backends in batches.
When a write transaction commits, it must clear its XID advertised via the ProcArray, which requires that we hold ProcArrayLock in exclusive mode in order to prevent concurrent processes running GetSnapshotData from seeing inconsistent results. When many processes try to commit at once, ProcArrayLock must change hands repeatedly, with each concurrent process trying to commit waking up to acquire the lock in turn. To make things more efficient, when more than one backend is trying to commit a write transaction at the same time, have just one of them acquire ProcArrayLock in exclusive mode and clear the XIDs of all processes in the group. Benchmarking reveals that this is much more efficient at very high client counts. Amit Kapila, heavily revised by me, with some review also from Pavan Deolasee.
This commit is contained in:
@@ -181,6 +181,7 @@ InitProcGlobal(void)
|
||||
ProcGlobal->startupBufferPinWaitBufId = -1;
|
||||
ProcGlobal->walwriterLatch = NULL;
|
||||
ProcGlobal->checkpointerLatch = NULL;
|
||||
pg_atomic_init_u32(&ProcGlobal->nextClearXidElem, INVALID_PGPROCNO);
|
||||
|
||||
/*
|
||||
* Create and initialize all the PGPROC structures we'll need. There are
|
||||
@@ -393,6 +394,10 @@ InitProcess(void)
|
||||
MyProc->syncRepState = SYNC_REP_NOT_WAITING;
|
||||
SHMQueueElemInit(&(MyProc->syncRepLinks));
|
||||
|
||||
/* Initialize fields for group XID clearing. */
|
||||
MyProc->backendLatestXid = InvalidTransactionId;
|
||||
pg_atomic_init_u32(&MyProc->nextClearXidElem, INVALID_PGPROCNO);
|
||||
|
||||
/*
|
||||
* Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
|
||||
* on it. That allows us to repoint the process latch, which so far
|
||||
|
||||
Reference in New Issue
Block a user