From db5bdd8e1a350cf77b77884ec445b8f0f18f135a Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi Date: Fri, 15 Oct 2021 14:23:52 +0900 Subject: [PATCH v2 5/5] Get rid of the old BackendId at all Since we have got rid of the annoyging O(N) behavior in SIInsertDataEntries, sinvaladt.c can say good-by to the old packed Backend ID. Still CleanupInvalidationState and SICleanupQueue has O(N) behavior but they are executed rarely or ends in a short time in the most cases. --- src/backend/storage/ipc/sinvaladt.c | 67 ++++++----------------------- 1 file changed, 14 insertions(+), 53 deletions(-) diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c index ee3a3accfd..d56c77400f 100644 --- a/src/backend/storage/ipc/sinvaladt.c +++ b/src/backend/storage/ipc/sinvaladt.c @@ -193,8 +193,6 @@ static LocalTransactionId nextLocalTransactionId; static void CleanupInvalidationState(int status, Datum arg); -static int siindex; - /* * SInvalShmemSize --- return shared-memory space needed */ @@ -254,7 +252,6 @@ CreateSharedInvalidationState(void) void SharedInvalBackendInit(bool sendOnly) { - int index; ProcState *stateP = NULL; SISeg *segP = shmInvalBuffer; @@ -265,38 +262,15 @@ SharedInvalBackendInit(bool sendOnly) */ LWLockAcquire(SInvalWriteLock, LW_EXCLUSIVE); - /* Look for a free entry in the procState array */ - for (index = 0; index < segP->lastBackend; index++) - { - if (segP->procState[index].procPid == 0) /* inactive slot? */ - { - stateP = &segP->procState[index]; - break; - } - } + Assert (MyBackendId < MaxBackends); + stateP = &segP->procState[MyBackendId]; - if (stateP == NULL) - { - if (segP->lastBackend < segP->maxBackends) - { - stateP = &segP->procState[segP->lastBackend]; - Assert(stateP->procPid == 0); - segP->lastBackend++; - } - else - { - /* - * out of procState slots: MaxBackends exceeded -- report normally - */ - siindex = -1; - LWLockRelease(SInvalWriteLock); - ereport(FATAL, - (errcode(ERRCODE_TOO_MANY_CONNECTIONS), - errmsg("sorry, too many clients already"))); - } - } + /* this entry should be free */ + Assert (stateP->procPid == 0); - siindex = (stateP - &segP->procState[0]); + /* adjust lastBackend if needed */ + if (segP->lastBackend < MyBackendId) + segP->lastBackend = MyBackendId; /* Fetch next local transaction ID into local memory */ nextLocalTransactionId = stateP->nextLXID; @@ -313,8 +287,6 @@ SharedInvalBackendInit(bool sendOnly) /* register exit routine to mark my entry inactive at exit */ on_shmem_exit(CleanupInvalidationState, PointerGetDatum(segP)); - - elog(DEBUG4, "my SI slot index is %d", siindex); } /* @@ -336,7 +308,7 @@ CleanupInvalidationState(int status, Datum arg) LWLockAcquire(SInvalWriteLock, LW_EXCLUSIVE); - stateP = &segP->procState[siindex]; + stateP = &segP->procState[MyBackendId]; /* Update next local transaction ID for next holder of this backendID */ stateP->nextLXID = nextLocalTransactionId; @@ -349,7 +321,7 @@ CleanupInvalidationState(int status, Datum arg) stateP->signaled = false; /* Recompute index of last active backend */ - for (i = segP->lastBackend; i > 0; i--) + for (i = segP->lastBackend; i >= 0; i--) { if (segP->procState[i - 1].procPid != 0) break; @@ -368,27 +340,16 @@ CleanupInvalidationState(int status, Datum arg) void BackendIdGetTransactionIds(int backendID, TransactionId *xid, TransactionId *xmin) { - SISeg *segP = shmInvalBuffer; - *xid = InvalidTransactionId; *xmin = InvalidTransactionId; - /* Need to lock out additions/removals of backends */ - LWLockAcquire(SInvalWriteLock, LW_SHARED); - - if (backendID > 0 && backendID <= segP->lastBackend) + if (backendID >= 0 && backendID < MaxBackends) { - ProcState *stateP = &segP->procState[backendID - 1]; - PGPROC *proc = stateP->proc; + PGPROC *proc = &ProcGlobal->allProcs[backendID]; - if (proc != NULL) - { - *xid = proc->xid; - *xmin = proc->xmin; - } + *xid = proc->xid; + *xmin = proc->xmin; } - - LWLockRelease(SInvalWriteLock); } /* @@ -495,7 +456,7 @@ SIGetDataEntries(SharedInvalidationMessage *data, int datasize) int n; segP = shmInvalBuffer; - stateP = &segP->procState[siindex]; + stateP = &segP->procState[MyBackendId]; /* * Before starting to take locks, do a quick, unlocked test to see whether -- 2.27.0