mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03:00
Change ProcSendSignal() to take pgprocno.
Instead of referring to target backends by pid, use pgprocno. This means that we don't have to scan the ProcArray and we can drop some special case code for dealing with the startup process. Discussion: https://postgr.es/m/CA%2BhUKGLYRyDaneEwz5Uya_OgFLMx5BgJfkQSD%3Dq9HmwsfRRb-w%40mail.gmail.com Reviewed-by: Soumyadeep Chakraborty <soumyadeep2007@gmail.com> Reviewed-by: Ashwin Agrawal <ashwinstar@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de>
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "storage/buf_internals.h"
|
||||
#include "storage/bufmgr.h"
|
||||
#include "storage/proc.h"
|
||||
|
||||
BufferDescPadded *BufferDescriptors;
|
||||
char *BufferBlocks;
|
||||
@@ -118,7 +119,7 @@ InitBufferPool(void)
|
||||
CLEAR_BUFFERTAG(buf->tag);
|
||||
|
||||
pg_atomic_init_u32(&buf->state, 0);
|
||||
buf->wait_backend_pid = 0;
|
||||
buf->wait_backend_pgprocno = INVALID_PGPROCNO;
|
||||
|
||||
buf->buf_id = i;
|
||||
|
||||
|
@@ -1899,11 +1899,11 @@ UnpinBuffer(BufferDesc *buf, bool fixOwner)
|
||||
BUF_STATE_GET_REFCOUNT(buf_state) == 1)
|
||||
{
|
||||
/* we just released the last pin other than the waiter's */
|
||||
int wait_backend_pid = buf->wait_backend_pid;
|
||||
int wait_backend_pgprocno = buf->wait_backend_pgprocno;
|
||||
|
||||
buf_state &= ~BM_PIN_COUNT_WAITER;
|
||||
UnlockBufHdr(buf, buf_state);
|
||||
ProcSendSignal(wait_backend_pid);
|
||||
ProcSendSignal(wait_backend_pgprocno);
|
||||
}
|
||||
else
|
||||
UnlockBufHdr(buf, buf_state);
|
||||
@@ -3980,7 +3980,7 @@ UnlockBuffers(void)
|
||||
* got a cancel/die interrupt before getting the signal.
|
||||
*/
|
||||
if ((buf_state & BM_PIN_COUNT_WAITER) != 0 &&
|
||||
buf->wait_backend_pid == MyProcPid)
|
||||
buf->wait_backend_pgprocno == MyProc->pgprocno)
|
||||
buf_state &= ~BM_PIN_COUNT_WAITER;
|
||||
|
||||
UnlockBufHdr(buf, buf_state);
|
||||
@@ -4116,7 +4116,7 @@ LockBufferForCleanup(Buffer buffer)
|
||||
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
|
||||
elog(ERROR, "multiple backends attempting to wait for pincount 1");
|
||||
}
|
||||
bufHdr->wait_backend_pid = MyProcPid;
|
||||
bufHdr->wait_backend_pgprocno = MyProc->pgprocno;
|
||||
PinCountWaitBuf = bufHdr;
|
||||
buf_state |= BM_PIN_COUNT_WAITER;
|
||||
UnlockBufHdr(bufHdr, buf_state);
|
||||
@@ -4187,7 +4187,7 @@ LockBufferForCleanup(Buffer buffer)
|
||||
*/
|
||||
buf_state = LockBufHdr(bufHdr);
|
||||
if ((buf_state & BM_PIN_COUNT_WAITER) != 0 &&
|
||||
bufHdr->wait_backend_pid == MyProcPid)
|
||||
bufHdr->wait_backend_pgprocno == MyProc->pgprocno)
|
||||
buf_state &= ~BM_PIN_COUNT_WAITER;
|
||||
UnlockBufHdr(bufHdr, buf_state);
|
||||
|
||||
|
@@ -1277,6 +1277,7 @@ InitPredicateLocks(void)
|
||||
PredXact->OldCommittedSxact->xmin = InvalidTransactionId;
|
||||
PredXact->OldCommittedSxact->flags = SXACT_FLAG_COMMITTED;
|
||||
PredXact->OldCommittedSxact->pid = 0;
|
||||
PredXact->OldCommittedSxact->pgprocno = INVALID_PGPROCNO;
|
||||
}
|
||||
/* This never changes, so let's keep a local copy. */
|
||||
OldCommittedSxact = PredXact->OldCommittedSxact;
|
||||
@@ -1876,6 +1877,7 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot,
|
||||
sxact->finishedBefore = InvalidTransactionId;
|
||||
sxact->xmin = snapshot->xmin;
|
||||
sxact->pid = MyProcPid;
|
||||
sxact->pgprocno = MyProc->pgprocno;
|
||||
SHMQueueInit(&(sxact->predicateLocks));
|
||||
SHMQueueElemInit(&(sxact->finishedLink));
|
||||
sxact->flags = 0;
|
||||
@@ -3669,7 +3671,7 @@ ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe)
|
||||
*/
|
||||
if (SxactIsDeferrableWaiting(roXact) &&
|
||||
(SxactIsROUnsafe(roXact) || SxactIsROSafe(roXact)))
|
||||
ProcSendSignal(roXact->pid);
|
||||
ProcSendSignal(roXact->pgprocno);
|
||||
|
||||
possibleUnsafeConflict = nextConflict;
|
||||
}
|
||||
@@ -5006,6 +5008,7 @@ PostPrepare_PredicateLocks(TransactionId xid)
|
||||
Assert(SxactIsPrepared(MySerializableXact));
|
||||
|
||||
MySerializableXact->pid = 0;
|
||||
MySerializableXact->pgprocno = INVALID_PGPROCNO;
|
||||
|
||||
hash_destroy(LocalPredicateLockHash);
|
||||
LocalPredicateLockHash = NULL;
|
||||
@@ -5081,6 +5084,7 @@ predicatelock_twophase_recover(TransactionId xid, uint16 info,
|
||||
sxact->vxid.backendId = InvalidBackendId;
|
||||
sxact->vxid.localTransactionId = (LocalTransactionId) xid;
|
||||
sxact->pid = 0;
|
||||
sxact->pgprocno = INVALID_PGPROCNO;
|
||||
|
||||
/* a prepared xact hasn't committed yet */
|
||||
sxact->prepareSeqNo = RecoverySerCommitSeqNo;
|
||||
|
@@ -177,8 +177,6 @@ InitProcGlobal(void)
|
||||
ProcGlobal->autovacFreeProcs = NULL;
|
||||
ProcGlobal->bgworkerFreeProcs = NULL;
|
||||
ProcGlobal->walsenderFreeProcs = NULL;
|
||||
ProcGlobal->startupProc = NULL;
|
||||
ProcGlobal->startupProcPid = 0;
|
||||
ProcGlobal->startupBufferPinWaitBufId = -1;
|
||||
ProcGlobal->walwriterLatch = NULL;
|
||||
ProcGlobal->checkpointerLatch = NULL;
|
||||
@@ -624,21 +622,6 @@ InitAuxiliaryProcess(void)
|
||||
on_shmem_exit(AuxiliaryProcKill, Int32GetDatum(proctype));
|
||||
}
|
||||
|
||||
/*
|
||||
* Record the PID and PGPROC structures for the Startup process, for use in
|
||||
* ProcSendSignal(). See comments there for further explanation.
|
||||
*/
|
||||
void
|
||||
PublishStartupProcessInformation(void)
|
||||
{
|
||||
SpinLockAcquire(ProcStructLock);
|
||||
|
||||
ProcGlobal->startupProc = MyProc;
|
||||
ProcGlobal->startupProcPid = MyProcPid;
|
||||
|
||||
SpinLockRelease(ProcStructLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Used from bufmgr to share the value of the buffer that Startup waits on,
|
||||
* or to reset the value to "not waiting" (-1). This allows processing
|
||||
@@ -1903,38 +1886,15 @@ ProcWaitForSignal(uint32 wait_event_info)
|
||||
}
|
||||
|
||||
/*
|
||||
* ProcSendSignal - send a signal to a backend identified by PID
|
||||
* ProcSendSignal - set the latch of a backend identified by pgprocno
|
||||
*/
|
||||
void
|
||||
ProcSendSignal(int pid)
|
||||
ProcSendSignal(int pgprocno)
|
||||
{
|
||||
PGPROC *proc = NULL;
|
||||
if (pgprocno < 0 || pgprocno >= ProcGlobal->allProcCount)
|
||||
elog(ERROR, "pgprocno out of range");
|
||||
|
||||
if (RecoveryInProgress())
|
||||
{
|
||||
SpinLockAcquire(ProcStructLock);
|
||||
|
||||
/*
|
||||
* Check to see whether it is the Startup process we wish to signal.
|
||||
* This call is made by the buffer manager when it wishes to wake up a
|
||||
* process that has been waiting for a pin in so it can obtain a
|
||||
* cleanup lock using LockBufferForCleanup(). Startup is not a normal
|
||||
* backend, so BackendPidGetProc() will not return any pid at all. So
|
||||
* we remember the information for this special case.
|
||||
*/
|
||||
if (pid == ProcGlobal->startupProcPid)
|
||||
proc = ProcGlobal->startupProc;
|
||||
|
||||
SpinLockRelease(ProcStructLock);
|
||||
}
|
||||
|
||||
if (proc == NULL)
|
||||
proc = BackendPidGetProc(pid);
|
||||
|
||||
if (proc != NULL)
|
||||
{
|
||||
SetLatch(&proc->procLatch);
|
||||
}
|
||||
SetLatch(&ProcGlobal->allProcs[pgprocno].procLatch);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user