PostgreSQL Source Code  git master
proc.h File Reference
#include "access/clog.h"
#include "access/xlogdefs.h"
#include "lib/ilist.h"
#include "storage/latch.h"
#include "storage/lock.h"
#include "storage/pg_sema.h"
#include "storage/proclist_types.h"
Include dependency graph for proc.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  XidCacheStatus
 
struct  XidCache
 
struct  PGPROC
 
struct  PROC_HDR
 

Macros

#define PGPROC_MAX_CACHED_SUBXIDS   64 /* XXX guessed-at value */
 
#define PROC_IS_AUTOVACUUM   0x01 /* is it an autovac worker? */
 
#define PROC_IN_VACUUM   0x02 /* currently running lazy vacuum */
 
#define PROC_IN_SAFE_IC
 
#define PROC_VACUUM_FOR_WRAPAROUND   0x08 /* set by autovac only */
 
#define PROC_IN_LOGICAL_DECODING
 
#define PROC_VACUUM_STATE_MASK   (PROC_IN_VACUUM | PROC_IN_SAFE_IC | PROC_VACUUM_FOR_WRAPAROUND)
 
#define FP_LOCK_SLOTS_PER_BACKEND   16
 
#define INVALID_PGPROCNO   PG_INT32_MAX
 
#define GetPGProcByNumber(n)   (&ProcGlobal->allProcs[(n)])
 
#define NUM_AUXILIARY_PROCS   4
 

Typedefs

typedef struct XidCacheStatus XidCacheStatus
 
typedef struct PROC_HDR PROC_HDR
 

Enumerations

enum  ProcWaitStatus { PROC_WAIT_STATUS_OK, PROC_WAIT_STATUS_WAITING, PROC_WAIT_STATUS_ERROR }
 

Functions

int ProcGlobalSemas (void)
 
Size ProcGlobalShmemSize (void)
 
void InitProcGlobal (void)
 
void InitProcess (void)
 
void InitProcessPhase2 (void)
 
void InitAuxiliaryProcess (void)
 
void PublishStartupProcessInformation (void)
 
void SetStartupBufferPinWaitBufId (int bufid)
 
int GetStartupBufferPinWaitBufId (void)
 
bool HaveNFreeProcs (int n)
 
void ProcReleaseLocks (bool isCommit)
 
void ProcQueueInit (PROC_QUEUE *queue)
 
ProcWaitStatus ProcSleep (LOCALLOCK *locallock, LockMethod lockMethodTable)
 
PGPROCProcWakeup (PGPROC *proc, ProcWaitStatus waitStatus)
 
void ProcLockWakeup (LockMethod lockMethodTable, LOCK *lock)
 
void CheckDeadLockAlert (void)
 
bool IsWaitingForLock (void)
 
void LockErrorCleanup (void)
 
void ProcWaitForSignal (uint32 wait_event_info)
 
void ProcSendSignal (int pid)
 
PGPROCAuxiliaryPidGetProc (int pid)
 
void BecomeLockGroupLeader (void)
 
bool BecomeLockGroupMember (PGPROC *leader, int pid)
 

Variables

PGDLLIMPORT PGPROCMyProc
 
PGDLLIMPORT PROC_HDRProcGlobal
 
PGPROCPreparedXactProcs
 
PGDLLIMPORT int DeadlockTimeout
 
PGDLLIMPORT int StatementTimeout
 
PGDLLIMPORT int LockTimeout
 
PGDLLIMPORT int IdleInTransactionSessionTimeout
 
PGDLLIMPORT int IdleSessionTimeout
 
bool log_lock_waits
 

Macro Definition Documentation

◆ FP_LOCK_SLOTS_PER_BACKEND

◆ GetPGProcByNumber

#define GetPGProcByNumber (   n)    (&ProcGlobal->allProcs[(n)])

◆ INVALID_PGPROCNO

◆ NUM_AUXILIARY_PROCS

#define NUM_AUXILIARY_PROCS   4

◆ PGPROC_MAX_CACHED_SUBXIDS

#define PGPROC_MAX_CACHED_SUBXIDS   64 /* XXX guessed-at value */

◆ PROC_IN_LOGICAL_DECODING

#define PROC_IN_LOGICAL_DECODING
Value:
0x10 /* currently doing logical
* decoding outside xact */

Definition at line 61 of file proc.h.

Referenced by ComputeXidHorizons(), GetSnapshotData(), ReplicationSlotRelease(), and StartupDecodingContext().

◆ PROC_IN_SAFE_IC

#define PROC_IN_SAFE_IC
Value:
0x04 /* currently running CREATE INDEX
* CONCURRENTLY or REINDEX
* CONCURRENTLY on non-expressional,
* non-partial index */

Definition at line 56 of file proc.h.

Referenced by ComputeXidHorizons(), set_indexsafe_procflags(), and WaitForOlderSnapshots().

◆ PROC_IN_VACUUM

#define PROC_IN_VACUUM   0x02 /* currently running lazy vacuum */

◆ PROC_IS_AUTOVACUUM

#define PROC_IS_AUTOVACUUM   0x01 /* is it an autovac worker? */

◆ PROC_VACUUM_FOR_WRAPAROUND

#define PROC_VACUUM_FOR_WRAPAROUND   0x08 /* set by autovac only */

Definition at line 60 of file proc.h.

Referenced by ProcSleep(), and vacuum_rel().

◆ PROC_VACUUM_STATE_MASK

#define PROC_VACUUM_STATE_MASK   (PROC_IN_VACUUM | PROC_IN_SAFE_IC | PROC_VACUUM_FOR_WRAPAROUND)

Typedef Documentation

◆ PROC_HDR

typedef struct PROC_HDR PROC_HDR

◆ XidCacheStatus

Enumeration Type Documentation

◆ ProcWaitStatus

Enumerator
PROC_WAIT_STATUS_OK 
PROC_WAIT_STATUS_WAITING 
PROC_WAIT_STATUS_ERROR 

Definition at line 82 of file proc.h.

Function Documentation

◆ AuxiliaryPidGetProc()

PGPROC* AuxiliaryPidGetProc ( int  pid)

Definition at line 984 of file proc.c.

References AuxiliaryProcs, name, NUM_AUXILIARY_PROCS, PGPROC::pid, ProcQueueInit(), and ShmemInitStruct().

Referenced by pg_stat_get_activity().

985 {
986  PGPROC *result = NULL;
987  int index;
988 
989  if (pid == 0) /* never match dummy PGPROCs */
990  return NULL;
991 
992  for (index = 0; index < NUM_AUXILIARY_PROCS; index++)
993  {
994  PGPROC *proc = &AuxiliaryProcs[index];
995 
996  if (proc->pid == pid)
997  {
998  result = proc;
999  break;
1000  }
1001  }
1002  return result;
1003 }
Definition: type.h:89
#define NUM_AUXILIARY_PROCS
Definition: proc.h:377
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:81
Definition: proc.h:121
int pid
Definition: proc.h:146

◆ BecomeLockGroupLeader()

void BecomeLockGroupLeader ( void  )

Definition at line 1938 of file proc.c.

References Assert, dlist_push_head(), PGPROC::lockGroupLeader, PGPROC::lockGroupLink, PGPROC::lockGroupMembers, LockHashPartitionLockByProc, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), and MyProc.

Referenced by LaunchParallelWorkers().

1939 {
1940  LWLock *leader_lwlock;
1941 
1942  /* If we already did it, we don't need to do it again. */
1943  if (MyProc->lockGroupLeader == MyProc)
1944  return;
1945 
1946  /* We had better not be a follower. */
1947  Assert(MyProc->lockGroupLeader == NULL);
1948 
1949  /* Create single-member group, containing only ourselves. */
1950  leader_lwlock = LockHashPartitionLockByProc(MyProc);
1951  LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
1954  LWLockRelease(leader_lwlock);
1955 }
Definition: lwlock.h:31
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:300
dlist_head lockGroupMembers
Definition: proc.h:252
PGPROC * MyProc
Definition: proc.c:68
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
dlist_node lockGroupLink
Definition: proc.h:253
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:533
#define Assert(condition)
Definition: c.h:804
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
PGPROC * lockGroupLeader
Definition: proc.h:251

◆ BecomeLockGroupMember()

bool BecomeLockGroupMember ( PGPROC leader,
int  pid 
)

Definition at line 1968 of file proc.c.

References Assert, dlist_push_tail(), PGPROC::lockGroupLeader, PGPROC::lockGroupLink, PGPROC::lockGroupMembers, LockHashPartitionLockByProc, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), and PGPROC::pid.

Referenced by ParallelWorkerMain().

1969 {
1970  LWLock *leader_lwlock;
1971  bool ok = false;
1972 
1973  /* Group leader can't become member of group */
1974  Assert(MyProc != leader);
1975 
1976  /* Can't already be a member of a group */
1977  Assert(MyProc->lockGroupLeader == NULL);
1978 
1979  /* PID must be valid. */
1980  Assert(pid != 0);
1981 
1982  /*
1983  * Get lock protecting the group fields. Note LockHashPartitionLockByProc
1984  * accesses leader->pgprocno in a PGPROC that might be free. This is safe
1985  * because all PGPROCs' pgprocno fields are set during shared memory
1986  * initialization and never change thereafter; so we will acquire the
1987  * correct lock even if the leader PGPROC is in process of being recycled.
1988  */
1989  leader_lwlock = LockHashPartitionLockByProc(leader);
1990  LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
1991 
1992  /* Is this the leader we're looking for? */
1993  if (leader->pid == pid && leader->lockGroupLeader == leader)
1994  {
1995  /* OK, join the group */
1996  ok = true;
1997  MyProc->lockGroupLeader = leader;
1999  }
2000  LWLockRelease(leader_lwlock);
2001 
2002  return ok;
2003 }
Definition: lwlock.h:31
dlist_head lockGroupMembers
Definition: proc.h:252
PGPROC * MyProc
Definition: proc.c:68
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition: ilist.h:317
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
dlist_node lockGroupLink
Definition: proc.h:253
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:533
#define Assert(condition)
Definition: c.h:804
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
int pid
Definition: proc.h:146
PGPROC * lockGroupLeader
Definition: proc.h:251

◆ CheckDeadLockAlert()

void CheckDeadLockAlert ( void  )

Definition at line 1862 of file proc.c.

References got_deadlock_timeout, MyLatch, and SetLatch().

Referenced by InitPostgres(), and RecoveryConflictInterrupt().

1863 {
1864  int save_errno = errno;
1865 
1866  got_deadlock_timeout = true;
1867 
1868  /*
1869  * Have to set the latch again, even if handle_sig_alarm already did. Back
1870  * then got_deadlock_timeout wasn't yet set... It's unlikely that this
1871  * ever would be a problem, but setting a set latch again is cheap.
1872  *
1873  * Note that, when this function runs inside procsignal_sigusr1_handler(),
1874  * the handler function sets the latch again after the latch is set here.
1875  */
1876  SetLatch(MyLatch);
1877  errno = save_errno;
1878 }
void SetLatch(Latch *latch)
Definition: latch.c:567
static volatile sig_atomic_t got_deadlock_timeout
Definition: proc.c:90
struct Latch * MyLatch
Definition: globals.c:55

◆ GetStartupBufferPinWaitBufId()

int GetStartupBufferPinWaitBufId ( void  )

Definition at line 656 of file proc.c.

References ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by HoldingBufferPinThatDelaysRecovery(), and RecoveryConflictInterrupt().

657 {
658  /* use volatile pointer to prevent code rearrangement */
659  volatile PROC_HDR *procglobal = ProcGlobal;
660 
661  return procglobal->startupBufferPinWaitBufId;
662 }
PROC_HDR * ProcGlobal
Definition: proc.c:80
Definition: proc.h:315
int startupBufferPinWaitBufId
Definition: proc.h:359

◆ HaveNFreeProcs()

bool HaveNFreeProcs ( int  n)

Definition at line 670 of file proc.c.

References PROC_HDR::freeProcs, PGPROC::links, SHM_QUEUE::next, ProcStructLock, SpinLockAcquire, and SpinLockRelease.

Referenced by InitPostgres().

671 {
672  PGPROC *proc;
673 
675 
676  proc = ProcGlobal->freeProcs;
677 
678  while (n > 0 && proc != NULL)
679  {
680  proc = (PGPROC *) proc->links.next;
681  n--;
682  }
683 
685 
686  return (n <= 0);
687 }
SHM_QUEUE links
Definition: proc.h:124
struct SHM_QUEUE * next
Definition: shmem.h:31
PROC_HDR * ProcGlobal
Definition: proc.c:80
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
PGPROC * freeProcs
Definition: proc.h:338
Definition: proc.h:121

◆ InitAuxiliaryProcess()

void InitAuxiliaryProcess ( void  )

Definition at line 514 of file proc.c.

References Assert, AuxiliaryProcKill(), AuxiliaryProcs, PGPROC::backendId, PGPROC::databaseId, PGPROC::delayChkpt, dlist_is_empty(), elog, ERROR, FATAL, PGPROC::fpLocalTransactionId, PGPROC::fpVXIDLock, i, Int32GetDatum, InvalidBackendId, InvalidLocalTransactionId, InvalidOid, InvalidTransactionId, IsBackgroundWorker, PGPROC::isBackgroundWorker, PGPROC::links, PGPROC::lockGroupLeader, PGPROC::lockGroupMembers, PGPROC::lwWaiting, PGPROC::lwWaitMode, PGPROC::lxid, PGPROC::myProcLocks, MyProcPid, NUM_AUXILIARY_PROCS, NUM_LOCK_PARTITIONS, on_shmem_exit(), OwnLatch(), PANIC, pg_atomic_write_u64(), PGSemaphoreReset(), PGPROC::pid, PROC_WAIT_STATUS_OK, PGPROC::procLatch, ProcStructLock, PGPROC::roleId, PGPROC::sem, set_spins_per_delay(), SHMQueueElemInit(), SHMQueueEmpty(), SpinLockAcquire, SpinLockRelease, PROC_HDR::spins_per_delay, PGPROC::statusFlags, SwitchToSharedLatch(), PGPROC::tempNamespaceId, PGPROC::waitLock, PGPROC::waitProcLock, PGPROC::waitStart, PGPROC::waitStatus, PGPROC::xid, and PGPROC::xmin.

Referenced by AuxiliaryProcessMain(), and BackendRun().

515 {
516  PGPROC *auxproc;
517  int proctype;
518 
519  /*
520  * ProcGlobal should be set up already (if we are a backend, we inherit
521  * this by fork() or EXEC_BACKEND mechanism from the postmaster).
522  */
523  if (ProcGlobal == NULL || AuxiliaryProcs == NULL)
524  elog(PANIC, "proc header uninitialized");
525 
526  if (MyProc != NULL)
527  elog(ERROR, "you already exist");
528 
529  /*
530  * We use the ProcStructLock to protect assignment and releasing of
531  * AuxiliaryProcs entries.
532  *
533  * While we are holding the ProcStructLock, also copy the current shared
534  * estimate of spins_per_delay to local storage.
535  */
537 
539 
540  /*
541  * Find a free auxproc ... *big* trouble if there isn't one ...
542  */
543  for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++)
544  {
545  auxproc = &AuxiliaryProcs[proctype];
546  if (auxproc->pid == 0)
547  break;
548  }
549  if (proctype >= NUM_AUXILIARY_PROCS)
550  {
552  elog(FATAL, "all AuxiliaryProcs are in use");
553  }
554 
555  /* Mark auxiliary proc as in use by me */
556  /* use volatile pointer to prevent code rearrangement */
557  ((volatile PGPROC *) auxproc)->pid = MyProcPid;
558 
559  MyProc = auxproc;
560 
562 
563  /*
564  * Initialize all fields of MyProc, except for those previously
565  * initialized by InitProcGlobal.
566  */
570  MyProc->fpVXIDLock = false;
579  MyProc->delayChkpt = false;
580  MyProc->statusFlags = 0;
581  MyProc->lwWaiting = false;
582  MyProc->lwWaitMode = 0;
583  MyProc->waitLock = NULL;
584  MyProc->waitProcLock = NULL;
586 #ifdef USE_ASSERT_CHECKING
587  {
588  int i;
589 
590  /* Last process should have released all locks. */
591  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
593  }
594 #endif
595 
596  /*
597  * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
598  * on it. That allows us to repoint the process latch, which so far
599  * points to process local one, to the shared one.
600  */
603 
604  /* Check that group locking fields are in a proper initial state. */
605  Assert(MyProc->lockGroupLeader == NULL);
607 
608  /*
609  * We might be reusing a semaphore that belonged to a failed process. So
610  * be careful and reinitialize its value here. (This is not strictly
611  * necessary anymore, but seems like a good idea for cleanliness.)
612  */
614 
615  /*
616  * Arrange to clean up at process exit.
617  */
619 }
static void AuxiliaryProcKill(int code, Datum arg)
Definition: proc.c:937
void set_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:195
int MyProcPid
Definition: globals.c:41
BackendId backendId
Definition: proc.h:153
dlist_head lockGroupMembers
Definition: proc.h:252
Oid tempNamespaceId
Definition: proc.h:157
PGPROC * MyProc
Definition: proc.c:68
SHM_QUEUE links
Definition: proc.h:124
void PGSemaphoreReset(PGSemaphore sema)
Definition: posix_sema.c:295
bool lwWaiting
Definition: proc.h:170
Oid roleId
Definition: proc.h:155
PROC_HDR * ProcGlobal
Definition: proc.c:80
uint8 statusFlags
Definition: proc.h:189
uint8 lwWaitMode
Definition: proc.h:171
ProcWaitStatus waitStatus
Definition: proc.h:128
bool fpVXIDLock
Definition: proc.h:243
#define PANIC
Definition: elog.h:55
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:438
Latch procLatch
Definition: proc.h:130
bool IsBackgroundWorker
Definition: globals.c:112
bool isBackgroundWorker
Definition: proc.h:160
#define SpinLockAcquire(lock)
Definition: spin.h:62
int spins_per_delay
Definition: proc.h:354
#define ERROR
Definition: elog.h:45
bool delayChkpt
Definition: proc.h:187
void OwnLatch(Latch *latch)
Definition: latch.c:404
#define FATAL
Definition: elog.h:54
TransactionId xmin
Definition: proc.h:138
PROCLOCK * waitProcLock
Definition: proc.h:180
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
#define InvalidTransactionId
Definition: transam.h:31
Oid databaseId
Definition: proc.h:154
LOCK * waitLock
Definition: proc.h:179
#define NUM_AUXILIARY_PROCS
Definition: proc.h:377
bool SHMQueueEmpty(const SHM_QUEUE *queue)
Definition: shmqueue.c:180
#define SpinLockRelease(lock)
Definition: spin.h:64
#define InvalidBackendId
Definition: backendid.h:23
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
void SwitchToSharedLatch(void)
Definition: miscinit.c:197
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:804
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:81
static bool dlist_is_empty(dlist_head *head)
Definition: ilist.h:289
TransactionId xid
Definition: proc.h:133
void SHMQueueElemInit(SHM_QUEUE *queue)
Definition: shmqueue.c:57
#define Int32GetDatum(X)
Definition: postgres.h:479
#define elog(elevel,...)
Definition: elog.h:227
#define InvalidLocalTransactionId
Definition: lock.h:69
int i
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:208
pg_atomic_uint64 waitStart
Definition: proc.h:184
PGSemaphore sem
Definition: proc.h:127
Definition: proc.h:121
int pid
Definition: proc.h:146
PGPROC * lockGroupLeader
Definition: proc.h:251
LocalTransactionId fpLocalTransactionId
Definition: proc.h:244
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:115
LocalTransactionId lxid
Definition: proc.h:143

◆ InitProcess()

void InitProcess ( void  )

Definition at line 303 of file proc.c.

References am_walsender, Assert, PROC_HDR::autovacFreeProcs, PGPROC::backendId, PROC_HDR::bgworkerFreeProcs, PGPROC::clogGroupMember, PGPROC::clogGroupMemberLsn, PGPROC::clogGroupMemberPage, PGPROC::clogGroupMemberXid, PGPROC::clogGroupMemberXidStatus, PGPROC::clogGroupNext, PGPROC::databaseId, PGPROC::delayChkpt, dlist_is_empty(), elog, ereport, errcode(), errmsg(), ERROR, FATAL, PGPROC::fpLocalTransactionId, PGPROC::fpVXIDLock, PROC_HDR::freeProcs, i, InitDeadLockChecking(), InitLWLockAccess(), INVALID_PGPROCNO, InvalidBackendId, InvalidLocalTransactionId, InvalidOid, InvalidTransactionId, InvalidXLogRecPtr, IsAnyAutoVacuumProcess, IsAutoVacuumLauncherProcess(), IsAutoVacuumWorkerProcess(), IsBackgroundWorker, PGPROC::isBackgroundWorker, IsUnderPostmaster, PGPROC::links, PGPROC::lockGroupLeader, PGPROC::lockGroupMembers, PGPROC::lwWaiting, PGPROC::lwWaitMode, PGPROC::lxid, MarkPostmasterChildActive(), max_wal_senders, PGPROC::myProcLocks, MyProcPid, SHM_QUEUE::next, NUM_LOCK_PARTITIONS, on_shmem_exit(), OwnLatch(), PANIC, pg_atomic_read_u32(), pg_atomic_write_u64(), PGSemaphoreReset(), PGPROC::pid, PROC_IS_AUTOVACUUM, PROC_WAIT_STATUS_OK, PGPROC::procArrayGroupMember, PGPROC::procArrayGroupMemberXid, PGPROC::procArrayGroupNext, PGPROC::procgloballist, ProcKill(), PGPROC::procLatch, ProcStructLock, PGPROC::recoveryConflictPending, PGPROC::roleId, PGPROC::sem, set_spins_per_delay(), SHMQueueElemInit(), SHMQueueEmpty(), SpinLockAcquire, SpinLockRelease, PROC_HDR::spins_per_delay, PGPROC::statusFlags, SwitchToSharedLatch(), SYNC_REP_NOT_WAITING, PGPROC::syncRepLinks, PGPROC::syncRepState, PGPROC::tempNamespaceId, TRANSACTION_STATUS_IN_PROGRESS, PGPROC::wait_event_info, PGPROC::waitLock, PGPROC::waitLSN, PGPROC::waitProcLock, PGPROC::waitStart, PGPROC::waitStatus, PROC_HDR::walsenderFreeProcs, PGPROC::xid, and PGPROC::xmin.

Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), BackendRun(), BootstrapModeMain(), PostgresMain(), and StartBackgroundWorker().

304 {
305  PGPROC *volatile *procgloballist;
306 
307  /*
308  * ProcGlobal should be set up already (if we are a backend, we inherit
309  * this by fork() or EXEC_BACKEND mechanism from the postmaster).
310  */
311  if (ProcGlobal == NULL)
312  elog(PANIC, "proc header uninitialized");
313 
314  if (MyProc != NULL)
315  elog(ERROR, "you already exist");
316 
317  /* Decide which list should supply our PGPROC. */
319  procgloballist = &ProcGlobal->autovacFreeProcs;
320  else if (IsBackgroundWorker)
321  procgloballist = &ProcGlobal->bgworkerFreeProcs;
322  else if (am_walsender)
323  procgloballist = &ProcGlobal->walsenderFreeProcs;
324  else
325  procgloballist = &ProcGlobal->freeProcs;
326 
327  /*
328  * Try to get a proc struct from the appropriate free list. If this
329  * fails, we must be out of PGPROC structures (not to mention semaphores).
330  *
331  * While we are holding the ProcStructLock, also copy the current shared
332  * estimate of spins_per_delay to local storage.
333  */
335 
337 
338  MyProc = *procgloballist;
339 
340  if (MyProc != NULL)
341  {
342  *procgloballist = (PGPROC *) MyProc->links.next;
344  }
345  else
346  {
347  /*
348  * If we reach here, all the PGPROCs are in use. This is one of the
349  * possible places to detect "too many backends", so give the standard
350  * error message. XXX do we need to give a different failure message
351  * in the autovacuum case?
352  */
354  if (am_walsender)
355  ereport(FATAL,
356  (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
357  errmsg("number of requested standby connections exceeds max_wal_senders (currently %d)",
358  max_wal_senders)));
359  ereport(FATAL,
360  (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
361  errmsg("sorry, too many clients already")));
362  }
363 
364  /*
365  * Cross-check that the PGPROC is of the type we expect; if this were not
366  * the case, it would get returned to the wrong list.
367  */
368  Assert(MyProc->procgloballist == procgloballist);
369 
370  /*
371  * Now that we have a PGPROC, mark ourselves as an active postmaster
372  * child; this is so that the postmaster can detect it if we exit without
373  * cleaning up. (XXX autovac launcher currently doesn't participate in
374  * this; it probably should.)
375  */
378 
379  /*
380  * Initialize all fields of MyProc, except for those previously
381  * initialized by InitProcGlobal.
382  */
386  MyProc->fpVXIDLock = false;
390  MyProc->pid = MyProcPid;
391  /* backendId, databaseId and roleId will be filled in later */
397  MyProc->delayChkpt = false;
398  MyProc->statusFlags = 0;
399  /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
402  MyProc->lwWaiting = false;
403  MyProc->lwWaitMode = 0;
404  MyProc->waitLock = NULL;
405  MyProc->waitProcLock = NULL;
407 #ifdef USE_ASSERT_CHECKING
408  {
409  int i;
410 
411  /* Last process should have released all locks. */
412  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
414  }
415 #endif
417 
418  /* Initialize fields for sync rep */
419  MyProc->waitLSN = 0;
422 
423  /* Initialize fields for group XID clearing. */
424  MyProc->procArrayGroupMember = false;
427 
428  /* Check that group locking fields are in a proper initial state. */
429  Assert(MyProc->lockGroupLeader == NULL);
431 
432  /* Initialize wait event information. */
433  MyProc->wait_event_info = 0;
434 
435  /* Initialize fields for group transaction status update. */
436  MyProc->clogGroupMember = false;
442 
443  /*
444  * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
445  * on it. That allows us to repoint the process latch, which so far
446  * points to process local one, to the shared one.
447  */
450 
451  /*
452  * We might be reusing a semaphore that belonged to a failed process. So
453  * be careful and reinitialize its value here. (This is not strictly
454  * necessary anymore, but seems like a good idea for cleanliness.)
455  */
457 
458  /*
459  * Arrange to clean up at backend exit.
460  */
462 
463  /*
464  * Now that we have a PGPROC, we could try to acquire locks, so initialize
465  * local state needed for LWLocks, and the deadlock checker.
466  */
469 }
bool procArrayGroupMember
Definition: proc.h:216
static void ProcKill(int code, Datum arg)
Definition: proc.c:814
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XidStatus clogGroupMemberXidStatus
Definition: proc.h:232
void set_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:195
int MyProcPid
Definition: globals.c:41
BackendId backendId
Definition: proc.h:153
uint32 wait_event_info
Definition: proc.h:226
XLogRecPtr clogGroupMemberLsn
Definition: proc.h:236
dlist_head lockGroupMembers
Definition: proc.h:252
Oid tempNamespaceId
Definition: proc.h:157
PGPROC * MyProc
Definition: proc.c:68
SHM_QUEUE links
Definition: proc.h:124
struct SHM_QUEUE * next
Definition: shmem.h:31
void PGSemaphoreReset(PGSemaphore sema)
Definition: posix_sema.c:295
bool lwWaiting
Definition: proc.h:170
#define SYNC_REP_NOT_WAITING
Definition: syncrep.h:31
PGPROC * bgworkerFreeProcs
Definition: proc.h:342
Oid roleId
Definition: proc.h:155
int errcode(int sqlerrcode)
Definition: elog.c:694
PROC_HDR * ProcGlobal
Definition: proc.c:80
uint8 statusFlags
Definition: proc.h:189
uint8 lwWaitMode
Definition: proc.h:171
pg_atomic_uint32 clogGroupNext
Definition: proc.h:230
ProcWaitStatus waitStatus
Definition: proc.h:128
bool fpVXIDLock
Definition: proc.h:243
#define PANIC
Definition: elog.h:55
PGPROC * autovacFreeProcs
Definition: proc.h:340
PGPROC * walsenderFreeProcs
Definition: proc.h:344
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:438
Latch procLatch
Definition: proc.h:130
bool IsBackgroundWorker
Definition: globals.c:112
bool isBackgroundWorker
Definition: proc.h:160
bool am_walsender
Definition: walsender.c:115
#define SpinLockAcquire(lock)
Definition: spin.h:62
int spins_per_delay
Definition: proc.h:354
#define ERROR
Definition: elog.h:45
bool delayChkpt
Definition: proc.h:187
void OwnLatch(Latch *latch)
Definition: latch.c:404
#define FATAL
Definition: elog.h:54
TransactionId xmin
Definition: proc.h:138
PROCLOCK * waitProcLock
Definition: proc.h:180
void InitDeadLockChecking(void)
Definition: deadlock.c:143
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
int clogGroupMemberPage
Definition: proc.h:234
bool recoveryConflictPending
Definition: proc.h:167
bool IsUnderPostmaster
Definition: globals.c:110
#define InvalidTransactionId
Definition: transam.h:31
TransactionId clogGroupMemberXid
Definition: proc.h:231
Oid databaseId
Definition: proc.h:154
PGPROC ** procgloballist
Definition: proc.h:125
LOCK * waitLock
Definition: proc.h:179
bool IsAutoVacuumWorkerProcess(void)
Definition: autovacuum.c:3395
#define INVALID_PGPROCNO
Definition: proc.h:80
pg_atomic_uint32 procArrayGroupNext
Definition: proc.h:218
int max_wal_senders
Definition: walsender.c:121
bool SHMQueueEmpty(const SHM_QUEUE *queue)
Definition: shmqueue.c:180
#define SpinLockRelease(lock)
Definition: spin.h:64
#define InvalidBackendId
Definition: backendid.h:23
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
void SwitchToSharedLatch(void)
Definition: miscinit.c:197
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:155
#define IsAnyAutoVacuumProcess()
Definition: autovacuum.h:55
bool IsAutoVacuumLauncherProcess(void)
Definition: autovacuum.c:3389
#define Assert(condition)
Definition: c.h:804
static bool dlist_is_empty(dlist_head *head)
Definition: ilist.h:289
PGPROC * freeProcs
Definition: proc.h:338
SHM_QUEUE syncRepLinks
Definition: proc.h:201
TransactionId xid
Definition: proc.h:133
void SHMQueueElemInit(SHM_QUEUE *queue)
Definition: shmqueue.c:57
int errmsg(const char *fmt,...)
Definition: elog.c:905
bool clogGroupMember
Definition: proc.h:229
#define elog(elevel,...)
Definition: elog.h:227
#define InvalidLocalTransactionId
Definition: lock.h:69
int i
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:208
pg_atomic_uint64 waitStart
Definition: proc.h:184
PGSemaphore sem
Definition: proc.h:127
int syncRepState
Definition: proc.h:200
Definition: proc.h:121
int pid
Definition: proc.h:146
XLogRecPtr waitLSN
Definition: proc.h:199
PGPROC * lockGroupLeader
Definition: proc.h:251
LocalTransactionId fpLocalTransactionId
Definition: proc.h:244
#define PROC_IS_AUTOVACUUM
Definition: proc.h:54
TransactionId procArrayGroupMemberXid
Definition: proc.h:224
void InitLWLockAccess(void)
Definition: lwlock.c:581
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:115
#define TRANSACTION_STATUS_IN_PROGRESS
Definition: clog.h:27
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:241
void MarkPostmasterChildActive(void)
Definition: pmsignal.c:291
LocalTransactionId lxid
Definition: proc.h:143

◆ InitProcessPhase2()

void InitProcessPhase2 ( void  )

Definition at line 479 of file proc.c.

References Assert, on_shmem_exit(), ProcArrayAdd(), and RemoveProcFromArray().

Referenced by InitPostgres().

480 {
481  Assert(MyProc != NULL);
482 
483  /*
484  * Add our PGPROC to the PGPROC array in shared memory.
485  */
487 
488  /*
489  * Arrange to clean that up at backend exit.
490  */
492 }
static void RemoveProcFromArray(int code, Datum arg)
Definition: proc.c:803
PGPROC * MyProc
Definition: proc.c:68
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
#define Assert(condition)
Definition: c.h:804
void ProcArrayAdd(PGPROC *proc)
Definition: procarray.c:445

◆ InitProcGlobal()

void InitProcGlobal ( void  )

Definition at line 159 of file proc.c.

References PROC_HDR::allProcCount, PROC_HDR::allProcs, Assert, PROC_HDR::autovacFreeProcs, autovacuum_max_workers, AuxiliaryProcs, PROC_HDR::bgworkerFreeProcs, PROC_HDR::checkpointerLatch, PROC_HDR::clogGroupFirst, DEFAULT_SPINS_PER_DELAY, dlist_init(), PROC_HDR::freeProcs, i, InitSharedLatch(), INVALID_PGPROCNO, PGPROC::links, LWLockInitialize(), LWTRANCHE_LOCK_FASTPATH, max_prepared_xacts, max_worker_processes, MaxBackends, MaxConnections, MemSet, SHM_QUEUE::next, NUM_AUXILIARY_PROCS, NUM_LOCK_PARTITIONS, pg_atomic_init_u32(), pg_atomic_init_u64(), PGPROC::pgprocno, PGSemaphoreCreate(), PROC_HDR::procArrayGroupFirst, PGPROC::procgloballist, ProcStructLock, PGPROC::sem, ShmemAlloc(), ShmemInitStruct(), SHMQueueInit(), SpinLockInit, PROC_HDR::spins_per_delay, PROC_HDR::startupBufferPinWaitBufId, PROC_HDR::startupProc, PROC_HDR::startupProcPid, PROC_HDR::statusFlags, PROC_HDR::subxidStates, PROC_HDR::walsenderFreeProcs, PROC_HDR::walwriterLatch, and PROC_HDR::xids.

Referenced by CreateSharedMemoryAndSemaphores().

160 {
161  PGPROC *procs;
162  int i,
163  j;
164  bool found;
166 
167  /* Create the ProcGlobal shared structure */
168  ProcGlobal = (PROC_HDR *)
169  ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
170  Assert(!found);
171 
172  /*
173  * Initialize the data structures.
174  */
176  ProcGlobal->freeProcs = NULL;
180  ProcGlobal->startupProc = NULL;
183  ProcGlobal->walwriterLatch = NULL;
187 
188  /*
189  * Create and initialize all the PGPROC structures we'll need. There are
190  * five separate consumers: (1) normal backends, (2) autovacuum workers
191  * and the autovacuum launcher, (3) background workers, (4) auxiliary
192  * processes, and (5) prepared transactions. Each PGPROC structure is
193  * dedicated to exactly one of these purposes, and they do not move
194  * between groups.
195  */
196  procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC));
197  MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
198  ProcGlobal->allProcs = procs;
199  /* XXX allProcCount isn't really all of them; it excludes prepared xacts */
201 
202  /*
203  * Allocate arrays mirroring PGPROC fields in a dense manner. See
204  * PROC_HDR.
205  *
206  * XXX: It might make sense to increase padding for these arrays, given
207  * how hotly they are accessed.
208  */
209  ProcGlobal->xids =
210  (TransactionId *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->xids));
211  MemSet(ProcGlobal->xids, 0, TotalProcs * sizeof(*ProcGlobal->xids));
213  MemSet(ProcGlobal->subxidStates, 0, TotalProcs * sizeof(*ProcGlobal->subxidStates));
214  ProcGlobal->statusFlags = (uint8 *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->statusFlags));
215  MemSet(ProcGlobal->statusFlags, 0, TotalProcs * sizeof(*ProcGlobal->statusFlags));
216 
217  for (i = 0; i < TotalProcs; i++)
218  {
219  /* Common initialization for all PGPROCs, regardless of type. */
220 
221  /*
222  * Set up per-PGPROC semaphore, latch, and fpInfoLock. Prepared xact
223  * dummy PGPROCs don't need these though - they're never associated
224  * with a real process
225  */
226  if (i < MaxBackends + NUM_AUXILIARY_PROCS)
227  {
228  procs[i].sem = PGSemaphoreCreate();
229  InitSharedLatch(&(procs[i].procLatch));
230  LWLockInitialize(&(procs[i].fpInfoLock), LWTRANCHE_LOCK_FASTPATH);
231  }
232  procs[i].pgprocno = i;
233 
234  /*
235  * Newly created PGPROCs for normal backends, autovacuum and bgworkers
236  * must be queued up on the appropriate free list. Because there can
237  * only ever be a small, fixed number of auxiliary processes, no free
238  * list is used in that case; InitAuxiliaryProcess() instead uses a
239  * linear search. PGPROCs for prepared transactions are added to a
240  * free list by TwoPhaseShmemInit().
241  */
242  if (i < MaxConnections)
243  {
244  /* PGPROC for normal backend, add to freeProcs list */
245  procs[i].links.next = (SHM_QUEUE *) ProcGlobal->freeProcs;
246  ProcGlobal->freeProcs = &procs[i];
247  procs[i].procgloballist = &ProcGlobal->freeProcs;
248  }
249  else if (i < MaxConnections + autovacuum_max_workers + 1)
250  {
251  /* PGPROC for AV launcher/worker, add to autovacFreeProcs list */
253  ProcGlobal->autovacFreeProcs = &procs[i];
255  }
257  {
258  /* PGPROC for bgworker, add to bgworkerFreeProcs list */
260  ProcGlobal->bgworkerFreeProcs = &procs[i];
262  }
263  else if (i < MaxBackends)
264  {
265  /* PGPROC for walsender, add to walsenderFreeProcs list */
267  ProcGlobal->walsenderFreeProcs = &procs[i];
269  }
270 
271  /* Initialize myProcLocks[] shared memory queues. */
272  for (j = 0; j < NUM_LOCK_PARTITIONS; j++)
273  SHMQueueInit(&(procs[i].myProcLocks[j]));
274 
275  /* Initialize lockGroupMembers list. */
276  dlist_init(&procs[i].lockGroupMembers);
277 
278  /*
279  * Initialize the atomic variables, otherwise, it won't be safe to
280  * access them for backends that aren't currently in use.
281  */
282  pg_atomic_init_u32(&(procs[i].procArrayGroupNext), INVALID_PGPROCNO);
283  pg_atomic_init_u32(&(procs[i].clogGroupNext), INVALID_PGPROCNO);
284  pg_atomic_init_u64(&(procs[i].waitStart), 0);
285  }
286 
287  /*
288  * Save pointers to the blocks of PGPROC structures reserved for auxiliary
289  * processes and prepared transactions.
290  */
291  AuxiliaryProcs = &procs[MaxBackends];
293 
294  /* Create ProcStructLock spinlock, too */
295  ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t));
297 }
int slock_t
Definition: s_lock.h:934
void InitSharedLatch(Latch *latch)
Definition: latch.c:371
uint32 TransactionId
Definition: c.h:587
XidCacheStatus * subxidStates
Definition: proc.h:327
SHM_QUEUE links
Definition: proc.h:124
struct SHM_QUEUE * next
Definition: shmem.h:31
#define SpinLockInit(lock)
Definition: spin.h:60
unsigned char uint8
Definition: c.h:439
PGPROC * PreparedXactProcs
Definition: proc.c:82
PGPROC * bgworkerFreeProcs
Definition: proc.h:342
PROC_HDR * ProcGlobal
Definition: proc.c:80
#define MemSet(start, val, len)
Definition: c.h:1008
void * ShmemAlloc(Size size)
Definition: shmem.c:161
PGSemaphore PGSemaphoreCreate(void)
Definition: posix_sema.c:262
PGPROC * autovacFreeProcs
Definition: proc.h:340
PGPROC * walsenderFreeProcs
Definition: proc.h:344
static void pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:415
Latch * walwriterLatch
Definition: proc.h:350
int spins_per_delay
Definition: proc.h:354
int max_prepared_xacts
Definition: twophase.c:117
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:396
int MaxBackends
Definition: globals.c:137
TransactionId * xids
Definition: proc.h:321
unsigned int uint32
Definition: c.h:441
PGPROC ** procgloballist
Definition: proc.h:125
#define NUM_AUXILIARY_PROCS
Definition: proc.h:377
#define INVALID_PGPROCNO
Definition: proc.h:80
Definition: proc.h:315
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:743
int startupProcPid
Definition: proc.h:357
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
int MaxConnections
Definition: globals.c:134
int autovacuum_max_workers
Definition: autovacuum.c:115
static void dlist_init(dlist_head *head)
Definition: ilist.h:278
Latch * checkpointerLatch
Definition: proc.h:352
#define Assert(condition)
Definition: c.h:804
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:81
PGPROC * freeProcs
Definition: proc.h:338
uint32 allProcCount
Definition: proc.h:336
pg_atomic_uint32 clogGroupFirst
Definition: proc.h:348
int pgprocno
Definition: proc.h:150
pg_atomic_uint32 procArrayGroupFirst
Definition: proc.h:346
void SHMQueueInit(SHM_QUEUE *queue)
Definition: shmqueue.c:36
int startupBufferPinWaitBufId
Definition: proc.h:359
int i
int max_worker_processes
Definition: globals.c:135
PGPROC * allProcs
Definition: proc.h:318
PGPROC * startupProc
Definition: proc.h:356
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:223
uint8 * statusFlags
Definition: proc.h:333
PGSemaphore sem
Definition: proc.h:127
Definition: proc.h:121
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:115
#define DEFAULT_SPINS_PER_DELAY
Definition: s_lock.h:1012

◆ IsWaitingForLock()

bool IsWaitingForLock ( void  )

Definition at line 693 of file proc.c.

Referenced by RecoveryConflictInterrupt().

694 {
695  if (lockAwaited == NULL)
696  return false;
697 
698  return true;
699 }
static LOCALLOCK * lockAwaited
Definition: proc.c:85

◆ LockErrorCleanup()

void LockErrorCleanup ( void  )

Definition at line 710 of file proc.c.

References AbortStrongLockAcquire(), DEADLOCK_TIMEOUT, disable_timeouts(), GrantAwaitedLock(), LOCALLOCK::hashcode, HOLD_INTERRUPTS, DisableTimeoutParams::id, DisableTimeoutParams::keep_indicator, PGPROC::links, LOCK_TIMEOUT, LockHashPartitionLock, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), SHM_QUEUE::next, PROC_WAIT_STATUS_OK, RemoveFromWaitQueue(), RESUME_INTERRUPTS, and PGPROC::waitStatus.

Referenced by AbortSubTransaction(), AbortTransaction(), ProcessInterrupts(), and ProcReleaseLocks().

711 {
712  LWLock *partitionLock;
713  DisableTimeoutParams timeouts[2];
714 
715  HOLD_INTERRUPTS();
716 
718 
719  /* Nothing to do if we weren't waiting for a lock */
720  if (lockAwaited == NULL)
721  {
723  return;
724  }
725 
726  /*
727  * Turn off the deadlock and lock timeout timers, if they are still
728  * running (see ProcSleep). Note we must preserve the LOCK_TIMEOUT
729  * indicator flag, since this function is executed before
730  * ProcessInterrupts when responding to SIGINT; else we'd lose the
731  * knowledge that the SIGINT came from a lock timeout and not an external
732  * source.
733  */
734  timeouts[0].id = DEADLOCK_TIMEOUT;
735  timeouts[0].keep_indicator = false;
736  timeouts[1].id = LOCK_TIMEOUT;
737  timeouts[1].keep_indicator = true;
738  disable_timeouts(timeouts, 2);
739 
740  /* Unlink myself from the wait queue, if on it (might not be anymore!) */
741  partitionLock = LockHashPartitionLock(lockAwaited->hashcode);
742  LWLockAcquire(partitionLock, LW_EXCLUSIVE);
743 
744  if (MyProc->links.next != NULL)
745  {
746  /* We could not have been granted the lock yet */
748  }
749  else
750  {
751  /*
752  * Somebody kicked us off the lock queue already. Perhaps they
753  * granted us the lock, or perhaps they detected a deadlock. If they
754  * did grant us the lock, we'd better remember it in our local lock
755  * table.
756  */
759  }
760 
761  lockAwaited = NULL;
762 
763  LWLockRelease(partitionLock);
764 
766 }
uint32 hashcode
Definition: lock.h:423
Definition: lwlock.h:31
void GrantAwaitedLock(void)
Definition: lock.c:1785
PGPROC * MyProc
Definition: proc.c:68
SHM_QUEUE links
Definition: proc.h:124
struct SHM_QUEUE * next
Definition: shmem.h:31
#define LockHashPartitionLock(hashcode)
Definition: lock.h:518
ProcWaitStatus waitStatus
Definition: proc.h:128
void disable_timeouts(const DisableTimeoutParams *timeouts, int count)
Definition: timeout.c:654
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:119
TimeoutId id
Definition: timeout.h:66
void AbortStrongLockAcquire(void)
Definition: lock.c:1756
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition: lock.c:1917
static LOCALLOCK * lockAwaited
Definition: proc.c:85
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:117

◆ ProcGlobalSemas()

int ProcGlobalSemas ( void  )

Definition at line 124 of file proc.c.

References MaxBackends, and NUM_AUXILIARY_PROCS.

Referenced by CreateSharedMemoryAndSemaphores().

125 {
126  /*
127  * We need a sema per backend (including autovacuum), plus one for each
128  * auxiliary process.
129  */
131 }
int MaxBackends
Definition: globals.c:137
#define NUM_AUXILIARY_PROCS
Definition: proc.h:377

◆ ProcGlobalShmemSize()

Size ProcGlobalShmemSize ( void  )

Definition at line 102 of file proc.c.

References add_size(), max_prepared_xacts, MaxBackends, mul_size(), NUM_AUXILIARY_PROCS, PROC_HDR::statusFlags, PROC_HDR::subxidStates, and PROC_HDR::xids.

Referenced by CreateSharedMemoryAndSemaphores().

103 {
104  Size size = 0;
105  Size TotalProcs =
107 
108  /* ProcGlobal */
109  size = add_size(size, sizeof(PROC_HDR));
110  size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC)));
111  size = add_size(size, sizeof(slock_t));
112 
113  size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids)));
114  size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates)));
115  size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags)));
116 
117  return size;
118 }
int slock_t
Definition: s_lock.h:934
XidCacheStatus * subxidStates
Definition: proc.h:327
PROC_HDR * ProcGlobal
Definition: proc.c:80
int max_prepared_xacts
Definition: twophase.c:117
int MaxBackends
Definition: globals.c:137
TransactionId * xids
Definition: proc.h:321
#define NUM_AUXILIARY_PROCS
Definition: proc.h:377
Definition: proc.h:315
Size mul_size(Size s1, Size s2)
Definition: shmem.c:519
Size add_size(Size s1, Size s2)
Definition: shmem.c:502
size_t Size
Definition: c.h:540
uint8 * statusFlags
Definition: proc.h:333
Definition: proc.h:121

◆ ProcLockWakeup()

void ProcLockWakeup ( LockMethod  lockMethodTable,
LOCK lock 
)

Definition at line 1717 of file proc.c.

References Assert, LockMethodData::conflictTab, GrantLock(), PROC_QUEUE::links, PGPROC::links, LOCKBIT_ON, LockCheckConflicts(), SHM_QUEUE::next, PROC_WAIT_STATUS_OK, ProcWakeup(), PROC_QUEUE::size, PGPROC::waitLockMode, PGPROC::waitProcLock, and LOCK::waitProcs.

Referenced by CleanUpLock(), and DeadLockCheck().

1718 {
1719  PROC_QUEUE *waitQueue = &(lock->waitProcs);
1720  int queue_size = waitQueue->size;
1721  PGPROC *proc;
1722  LOCKMASK aheadRequests = 0;
1723 
1724  Assert(queue_size >= 0);
1725 
1726  if (queue_size == 0)
1727  return;
1728 
1729  proc = (PGPROC *) waitQueue->links.next;
1730 
1731  while (queue_size-- > 0)
1732  {
1733  LOCKMODE lockmode = proc->waitLockMode;
1734 
1735  /*
1736  * Waken if (a) doesn't conflict with requests of earlier waiters, and
1737  * (b) doesn't conflict with already-held locks.
1738  */
1739  if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1740  !LockCheckConflicts(lockMethodTable, lockmode, lock,
1741  proc->waitProcLock))
1742  {
1743  /* OK to waken */
1744  GrantLock(lock, proc->waitProcLock, lockmode);
1745  proc = ProcWakeup(proc, PROC_WAIT_STATUS_OK);
1746 
1747  /*
1748  * ProcWakeup removes proc from the lock's waiting process queue
1749  * and returns the next proc in chain; don't use proc's next-link,
1750  * because it's been cleared.
1751  */
1752  }
1753  else
1754  {
1755  /*
1756  * Cannot wake this guy. Remember his request for later checks.
1757  */
1758  aheadRequests |= LOCKBIT_ON(lockmode);
1759  proc = (PGPROC *) proc->links.next;
1760  }
1761  }
1762 
1763  Assert(waitQueue->size >= 0);
1764 }
int LOCKMODE
Definition: lockdefs.h:26
SHM_QUEUE links
Definition: lock.h:32
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
Definition: lock.c:1554
SHM_QUEUE links
Definition: proc.h:124
struct SHM_QUEUE * next
Definition: shmem.h:31
LOCKMODE waitLockMode
Definition: proc.h:181
const LOCKMASK * conflictTab
Definition: lock.h:115
PROC_QUEUE waitProcs
Definition: lock.h:308
PGPROC * ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus)
Definition: proc.c:1680
PROCLOCK * waitProcLock
Definition: proc.h:180
bool LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
Definition: lock.c:1419
#define Assert(condition)
Definition: c.h:804
int LOCKMASK
Definition: lockdefs.h:25
#define LOCKBIT_ON(lockmode)
Definition: lock.h:88
int size
Definition: lock.h:33
Definition: proc.h:121

◆ ProcQueueInit()

void ProcQueueInit ( PROC_QUEUE queue)

Definition at line 1037 of file proc.c.

References PROC_QUEUE::links, SHMQueueInit(), and PROC_QUEUE::size.

Referenced by AuxiliaryPidGetProc(), DeadLockCheck(), lock_twophase_recover(), and SetupLockInTable().

1038 {
1039  SHMQueueInit(&(queue->links));
1040  queue->size = 0;
1041 }
SHM_QUEUE links
Definition: lock.h:32
void SHMQueueInit(SHM_QUEUE *queue)
Definition: shmqueue.c:36
int size
Definition: lock.h:33

◆ ProcReleaseLocks()

void ProcReleaseLocks ( bool  isCommit)

Definition at line 786 of file proc.c.

References DEFAULT_LOCKMETHOD, LockErrorCleanup(), LockReleaseAll(), and USER_LOCKMETHOD.

Referenced by ResourceOwnerReleaseInternal().

787 {
788  if (!MyProc)
789  return;
790  /* If waiting, get off wait queue (should only be needed after error) */
792  /* Release standard locks, including session-level if aborting */
794  /* Release transaction-level advisory locks */
796 }
PGPROC * MyProc
Definition: proc.c:68
#define DEFAULT_LOCKMETHOD
Definition: lock.h:129
#define USER_LOCKMETHOD
Definition: lock.h:130
void LockErrorCleanup(void)
Definition: proc.c:710
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition: lock.c:2179

◆ ProcSendSignal()

void ProcSendSignal ( int  pid)

Definition at line 1900 of file proc.c.

References BackendPidGetProc(), PGPROC::procLatch, ProcStructLock, RecoveryInProgress(), SetLatch(), SpinLockAcquire, SpinLockRelease, PROC_HDR::startupProc, and PROC_HDR::startupProcPid.

Referenced by ReleasePredicateLocks(), and UnpinBuffer().

1901 {
1902  PGPROC *proc = NULL;
1903 
1904  if (RecoveryInProgress())
1905  {
1907 
1908  /*
1909  * Check to see whether it is the Startup process we wish to signal.
1910  * This call is made by the buffer manager when it wishes to wake up a
1911  * process that has been waiting for a pin in so it can obtain a
1912  * cleanup lock using LockBufferForCleanup(). Startup is not a normal
1913  * backend, so BackendPidGetProc() will not return any pid at all. So
1914  * we remember the information for this special case.
1915  */
1916  if (pid == ProcGlobal->startupProcPid)
1917  proc = ProcGlobal->startupProc;
1918 
1920  }
1921 
1922  if (proc == NULL)
1923  proc = BackendPidGetProc(pid);
1924 
1925  if (proc != NULL)
1926  {
1927  SetLatch(&proc->procLatch);
1928  }
1929 }
PGPROC * BackendPidGetProc(int pid)
Definition: procarray.c:3062
PROC_HDR * ProcGlobal
Definition: proc.c:80
bool RecoveryInProgress(void)
Definition: xlog.c:8132
void SetLatch(Latch *latch)
Definition: latch.c:567
Latch procLatch
Definition: proc.h:130
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
int startupProcPid
Definition: proc.h:357
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
PGPROC * startupProc
Definition: proc.h:356
Definition: proc.h:121

◆ ProcSleep()

ProcWaitStatus ProcSleep ( LOCALLOCK locallock,
LockMethod  lockMethodTable 
)

Definition at line 1061 of file proc.c.

References AccessExclusiveLock, appendStringInfo(), Assert, buf, CHECK_FOR_INTERRUPTS, CheckDeadLock(), CheckRecoveryConflictDeadlock(), LockMethodData::conflictTab, StringInfoData::data, deadlock_state, DEADLOCK_TIMEOUT, DeadlockTimeout, DEBUG1, EnableTimeoutParams::delay_ms, DescribeLockTag(), disable_timeout(), disable_timeouts(), DS_BLOCKED_BY_AUTOVACUUM, DS_HARD_DEADLOCK, DS_NO_DEADLOCK, DS_NOT_YET_CHECKED, DS_SOFT_DEADLOCK, enable_timeout_after(), enable_timeouts(), ereport, errdetail_log(), errdetail_log_plural(), errmsg(), errmsg_internal(), get_timeout_start_time(), GetBlockingAutoVacuumPgproc(), GetCurrentTimestamp(), GetLockConflicts(), GetLockmodeName(), got_deadlock_timeout, GrantAwaitedLock(), GrantLock(), PROCLOCK::groupLeader, LOCALLOCK::hashcode, PGPROC::heldLocks, PROCLOCK::holdMask, i, EnableTimeoutParams::id, DisableTimeoutParams::id, InHotStandby, initStringInfo(), InRecovery, DisableTimeoutParams::keep_indicator, kill, PROC_QUEUE::links, PGPROC::links, LOCALLOCKTAG::lock, LOCALLOCK::lock, LOCK_TIMEOUT, LOCKBIT_ON, LockCheckConflicts(), PGPROC::lockGroupLeader, LockHashPartitionLock, PROCLOCK::lockLink, LOCKTAG::locktag_lockmethodid, LOCKTAG::locktag_type, LockTimeout, LOG, log_lock_waits, log_recovery_conflict_waits, LogRecoveryConflict(), LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), message_level_is_interesting(), LOCALLOCKTAG::mode, MyLatch, PROCLOCKTAG::myProc, MyProcPid, SHM_QUEUE::next, now(), offsetof, pfree(), pg_atomic_write_u64(), PG_WAIT_LOCK, PGPROC::pgxactoff, PGPROC::pid, PROC_IS_AUTOVACUUM, PROC_VACUUM_FOR_WRAPAROUND, PROC_WAIT_STATUS_ERROR, PROC_WAIT_STATUS_OK, PROC_WAIT_STATUS_WAITING, LOCALLOCK::proclock, LOCK::procLocks, PROCSIG_RECOVERY_CONFLICT_LOCK, RecoveryInProgress(), RememberSimpleDeadLock(), RemoveFromWaitQueue(), ResetLatch(), ResolveRecoveryConflictWithLock(), SHMQueueInsertBefore(), SHMQueueNext(), PROC_QUEUE::size, PROC_HDR::statusFlags, LOCK::tag, PROCLOCK::tag, LOCALLOCK::tag, TimestampDifference(), TimestampDifferenceExceeds(), TMPARAM_AFTER, EnableTimeoutParams::type, WaitLatch(), PGPROC::waitLock, PGPROC::waitLockMode, LOCK::waitMask, PGPROC::waitProcLock, LOCK::waitProcs, PGPROC::waitStart, PGPROC::waitStatus, WARNING, WL_EXIT_ON_PM_DEATH, and WL_LATCH_SET.

Referenced by WaitOnLock().

1062 {
1063  LOCKMODE lockmode = locallock->tag.mode;
1064  LOCK *lock = locallock->lock;
1065  PROCLOCK *proclock = locallock->proclock;
1066  uint32 hashcode = locallock->hashcode;
1067  LWLock *partitionLock = LockHashPartitionLock(hashcode);
1068  PROC_QUEUE *waitQueue = &(lock->waitProcs);
1069  LOCKMASK myHeldLocks = MyProc->heldLocks;
1070  TimestampTz standbyWaitStart = 0;
1071  bool early_deadlock = false;
1072  bool allow_autovacuum_cancel = true;
1073  bool logged_recovery_conflict = false;
1074  ProcWaitStatus myWaitStatus;
1075  PGPROC *proc;
1076  PGPROC *leader = MyProc->lockGroupLeader;
1077  int i;
1078 
1079  /*
1080  * If group locking is in use, locks held by members of my locking group
1081  * need to be included in myHeldLocks. This is not required for relation
1082  * extension or page locks which conflict among group members. However,
1083  * including them in myHeldLocks will give group members the priority to
1084  * get those locks as compared to other backends which are also trying to
1085  * acquire those locks. OTOH, we can avoid giving priority to group
1086  * members for that kind of locks, but there doesn't appear to be a clear
1087  * advantage of the same.
1088  */
1089  if (leader != NULL)
1090  {
1091  SHM_QUEUE *procLocks = &(lock->procLocks);
1092  PROCLOCK *otherproclock;
1093 
1094  otherproclock = (PROCLOCK *)
1095  SHMQueueNext(procLocks, procLocks, offsetof(PROCLOCK, lockLink));
1096  while (otherproclock != NULL)
1097  {
1098  if (otherproclock->groupLeader == leader)
1099  myHeldLocks |= otherproclock->holdMask;
1100  otherproclock = (PROCLOCK *)
1101  SHMQueueNext(procLocks, &otherproclock->lockLink,
1102  offsetof(PROCLOCK, lockLink));
1103  }
1104  }
1105 
1106  /*
1107  * Determine where to add myself in the wait queue.
1108  *
1109  * Normally I should go at the end of the queue. However, if I already
1110  * hold locks that conflict with the request of any previous waiter, put
1111  * myself in the queue just in front of the first such waiter. This is not
1112  * a necessary step, since deadlock detection would move me to before that
1113  * waiter anyway; but it's relatively cheap to detect such a conflict
1114  * immediately, and avoid delaying till deadlock timeout.
1115  *
1116  * Special case: if I find I should go in front of some waiter, check to
1117  * see if I conflict with already-held locks or the requests before that
1118  * waiter. If not, then just grant myself the requested lock immediately.
1119  * This is the same as the test for immediate grant in LockAcquire, except
1120  * we are only considering the part of the wait queue before my insertion
1121  * point.
1122  */
1123  if (myHeldLocks != 0)
1124  {
1125  LOCKMASK aheadRequests = 0;
1126 
1127  proc = (PGPROC *) waitQueue->links.next;
1128  for (i = 0; i < waitQueue->size; i++)
1129  {
1130  /*
1131  * If we're part of the same locking group as this waiter, its
1132  * locks neither conflict with ours nor contribute to
1133  * aheadRequests.
1134  */
1135  if (leader != NULL && leader == proc->lockGroupLeader)
1136  {
1137  proc = (PGPROC *) proc->links.next;
1138  continue;
1139  }
1140  /* Must he wait for me? */
1141  if (lockMethodTable->conflictTab[proc->waitLockMode] & myHeldLocks)
1142  {
1143  /* Must I wait for him ? */
1144  if (lockMethodTable->conflictTab[lockmode] & proc->heldLocks)
1145  {
1146  /*
1147  * Yes, so we have a deadlock. Easiest way to clean up
1148  * correctly is to call RemoveFromWaitQueue(), but we
1149  * can't do that until we are *on* the wait queue. So, set
1150  * a flag to check below, and break out of loop. Also,
1151  * record deadlock info for later message.
1152  */
1153  RememberSimpleDeadLock(MyProc, lockmode, lock, proc);
1154  early_deadlock = true;
1155  break;
1156  }
1157  /* I must go before this waiter. Check special case. */
1158  if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1159  !LockCheckConflicts(lockMethodTable, lockmode, lock,
1160  proclock))
1161  {
1162  /* Skip the wait and just grant myself the lock. */
1163  GrantLock(lock, proclock, lockmode);
1164  GrantAwaitedLock();
1165  return PROC_WAIT_STATUS_OK;
1166  }
1167  /* Break out of loop to put myself before him */
1168  break;
1169  }
1170  /* Nope, so advance to next waiter */
1171  aheadRequests |= LOCKBIT_ON(proc->waitLockMode);
1172  proc = (PGPROC *) proc->links.next;
1173  }
1174 
1175  /*
1176  * If we fall out of loop normally, proc points to waitQueue head, so
1177  * we will insert at tail of queue as desired.
1178  */
1179  }
1180  else
1181  {
1182  /* I hold no locks, so I can't push in front of anyone. */
1183  proc = (PGPROC *) &(waitQueue->links);
1184  }
1185 
1186  /*
1187  * Insert self into queue, ahead of the given proc (or at tail of queue).
1188  */
1189  SHMQueueInsertBefore(&(proc->links), &(MyProc->links));
1190  waitQueue->size++;
1191 
1192  lock->waitMask |= LOCKBIT_ON(lockmode);
1193 
1194  /* Set up wait information in PGPROC object, too */
1195  MyProc->waitLock = lock;
1196  MyProc->waitProcLock = proclock;
1197  MyProc->waitLockMode = lockmode;
1198 
1200 
1201  /*
1202  * If we detected deadlock, give up without waiting. This must agree with
1203  * CheckDeadLock's recovery code.
1204  */
1205  if (early_deadlock)
1206  {
1207  RemoveFromWaitQueue(MyProc, hashcode);
1208  return PROC_WAIT_STATUS_ERROR;
1209  }
1210 
1211  /* mark that we are waiting for a lock */
1212  lockAwaited = locallock;
1213 
1214  /*
1215  * Release the lock table's partition lock.
1216  *
1217  * NOTE: this may also cause us to exit critical-section state, possibly
1218  * allowing a cancel/die interrupt to be accepted. This is OK because we
1219  * have recorded the fact that we are waiting for a lock, and so
1220  * LockErrorCleanup will clean up if cancel/die happens.
1221  */
1222  LWLockRelease(partitionLock);
1223 
1224  /*
1225  * Also, now that we will successfully clean up after an ereport, it's
1226  * safe to check to see if there's a buffer pin deadlock against the
1227  * Startup process. Of course, that's only necessary if we're doing Hot
1228  * Standby and are not the Startup process ourselves.
1229  */
1230  if (RecoveryInProgress() && !InRecovery)
1232 
1233  /* Reset deadlock_state before enabling the timeout handler */
1235  got_deadlock_timeout = false;
1236 
1237  /*
1238  * Set timer so we can wake up after awhile and check for a deadlock. If a
1239  * deadlock is detected, the handler sets MyProc->waitStatus =
1240  * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure rather
1241  * than success.
1242  *
1243  * By delaying the check until we've waited for a bit, we can avoid
1244  * running the rather expensive deadlock-check code in most cases.
1245  *
1246  * If LockTimeout is set, also enable the timeout for that. We can save a
1247  * few cycles by enabling both timeout sources in one call.
1248  *
1249  * If InHotStandby we set lock waits slightly later for clarity with other
1250  * code.
1251  */
1252  if (!InHotStandby)
1253  {
1254  if (LockTimeout > 0)
1255  {
1256  EnableTimeoutParams timeouts[2];
1257 
1258  timeouts[0].id = DEADLOCK_TIMEOUT;
1259  timeouts[0].type = TMPARAM_AFTER;
1260  timeouts[0].delay_ms = DeadlockTimeout;
1261  timeouts[1].id = LOCK_TIMEOUT;
1262  timeouts[1].type = TMPARAM_AFTER;
1263  timeouts[1].delay_ms = LockTimeout;
1264  enable_timeouts(timeouts, 2);
1265  }
1266  else
1268 
1269  /*
1270  * Use the current time obtained for the deadlock timeout timer as
1271  * waitStart (i.e., the time when this process started waiting for the
1272  * lock). Since getting the current time newly can cause overhead, we
1273  * reuse the already-obtained time to avoid that overhead.
1274  *
1275  * Note that waitStart is updated without holding the lock table's
1276  * partition lock, to avoid the overhead by additional lock
1277  * acquisition. This can cause "waitstart" in pg_locks to become NULL
1278  * for a very short period of time after the wait started even though
1279  * "granted" is false. This is OK in practice because we can assume
1280  * that users are likely to look at "waitstart" when waiting for the
1281  * lock for a long time.
1282  */
1285  }
1286  else if (log_recovery_conflict_waits)
1287  {
1288  /*
1289  * Set the wait start timestamp if logging is enabled and in hot
1290  * standby.
1291  */
1292  standbyWaitStart = GetCurrentTimestamp();
1293  }
1294 
1295  /*
1296  * If somebody wakes us between LWLockRelease and WaitLatch, the latch
1297  * will not wait. But a set latch does not necessarily mean that the lock
1298  * is free now, as there are many other sources for latch sets than
1299  * somebody releasing the lock.
1300  *
1301  * We process interrupts whenever the latch has been set, so cancel/die
1302  * interrupts are processed quickly. This means we must not mind losing
1303  * control to a cancel/die interrupt here. We don't, because we have no
1304  * shared-state-change work to do after being granted the lock (the
1305  * grantor did it all). We do have to worry about canceling the deadlock
1306  * timeout and updating the locallock table, but if we lose control to an
1307  * error, LockErrorCleanup will fix that up.
1308  */
1309  do
1310  {
1311  if (InHotStandby)
1312  {
1313  bool maybe_log_conflict =
1314  (standbyWaitStart != 0 && !logged_recovery_conflict);
1315 
1316  /* Set a timer and wait for that or for the lock to be granted */
1318  maybe_log_conflict);
1319 
1320  /*
1321  * Emit the log message if the startup process is waiting longer
1322  * than deadlock_timeout for recovery conflict on lock.
1323  */
1324  if (maybe_log_conflict)
1325  {
1327 
1328  if (TimestampDifferenceExceeds(standbyWaitStart, now,
1329  DeadlockTimeout))
1330  {
1331  VirtualTransactionId *vxids;
1332  int cnt;
1333 
1334  vxids = GetLockConflicts(&locallock->tag.lock,
1335  AccessExclusiveLock, &cnt);
1336 
1337  /*
1338  * Log the recovery conflict and the list of PIDs of
1339  * backends holding the conflicting lock. Note that we do
1340  * logging even if there are no such backends right now
1341  * because the startup process here has already waited
1342  * longer than deadlock_timeout.
1343  */
1345  standbyWaitStart, now,
1346  cnt > 0 ? vxids : NULL, true);
1347  logged_recovery_conflict = true;
1348  }
1349  }
1350  }
1351  else
1352  {
1354  PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
1356  /* check for deadlocks first, as that's probably log-worthy */
1358  {
1359  CheckDeadLock();
1360  got_deadlock_timeout = false;
1361  }
1363  }
1364 
1365  /*
1366  * waitStatus could change from PROC_WAIT_STATUS_WAITING to something else
1367  * asynchronously. Read it just once per loop to prevent surprising
1368  * behavior (such as missing log messages).
1369  */
1370  myWaitStatus = *((volatile ProcWaitStatus *) &MyProc->waitStatus);
1371 
1372  /*
1373  * If we are not deadlocked, but are waiting on an autovacuum-induced
1374  * task, send a signal to interrupt it.
1375  */
1376  if (deadlock_state == DS_BLOCKED_BY_AUTOVACUUM && allow_autovacuum_cancel)
1377  {
1378  PGPROC *autovac = GetBlockingAutoVacuumPgproc();
1379  uint8 statusFlags;
1380  uint8 lockmethod_copy;
1381  LOCKTAG locktag_copy;
1382 
1383  /*
1384  * Grab info we need, then release lock immediately. Note this
1385  * coding means that there is a tiny chance that the process
1386  * terminates its current transaction and starts a different one
1387  * before we have a change to send the signal; the worst possible
1388  * consequence is that a for-wraparound vacuum is cancelled. But
1389  * that could happen in any case unless we were to do kill() with
1390  * the lock held, which is much more undesirable.
1391  */
1392  LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1393  statusFlags = ProcGlobal->statusFlags[autovac->pgxactoff];
1394  lockmethod_copy = lock->tag.locktag_lockmethodid;
1395  locktag_copy = lock->tag;
1396  LWLockRelease(ProcArrayLock);
1397 
1398  /*
1399  * Only do it if the worker is not working to protect against Xid
1400  * wraparound.
1401  */
1402  if ((statusFlags & PROC_IS_AUTOVACUUM) &&
1403  !(statusFlags & PROC_VACUUM_FOR_WRAPAROUND))
1404  {
1405  int pid = autovac->pid;
1406 
1407  /* report the case, if configured to do so */
1409  {
1410  StringInfoData locktagbuf;
1411  StringInfoData logbuf; /* errdetail for server log */
1412 
1413  initStringInfo(&locktagbuf);
1414  initStringInfo(&logbuf);
1415  DescribeLockTag(&locktagbuf, &locktag_copy);
1416  appendStringInfo(&logbuf,
1417  "Process %d waits for %s on %s.",
1418  MyProcPid,
1419  GetLockmodeName(lockmethod_copy, lockmode),
1420  locktagbuf.data);
1421 
1422  ereport(DEBUG1,
1423  (errmsg_internal("sending cancel to blocking autovacuum PID %d",
1424  pid),
1425  errdetail_log("%s", logbuf.data)));
1426 
1427  pfree(locktagbuf.data);
1428  pfree(logbuf.data);
1429  }
1430 
1431  /* send the autovacuum worker Back to Old Kent Road */
1432  if (kill(pid, SIGINT) < 0)
1433  {
1434  /*
1435  * There's a race condition here: once we release the
1436  * ProcArrayLock, it's possible for the autovac worker to
1437  * close up shop and exit before we can do the kill().
1438  * Therefore, we do not whinge about no-such-process.
1439  * Other errors such as EPERM could conceivably happen if
1440  * the kernel recycles the PID fast enough, but such cases
1441  * seem improbable enough that it's probably best to issue
1442  * a warning if we see some other errno.
1443  */
1444  if (errno != ESRCH)
1445  ereport(WARNING,
1446  (errmsg("could not send signal to process %d: %m",
1447  pid)));
1448  }
1449  }
1450 
1451  /* prevent signal from being sent again more than once */
1452  allow_autovacuum_cancel = false;
1453  }
1454 
1455  /*
1456  * If awoken after the deadlock check interrupt has run, and
1457  * log_lock_waits is on, then report about the wait.
1458  */
1460  {
1462  lock_waiters_sbuf,
1463  lock_holders_sbuf;
1464  const char *modename;
1465  long secs;
1466  int usecs;
1467  long msecs;
1468  SHM_QUEUE *procLocks;
1469  PROCLOCK *proclock;
1470  bool first_holder = true,
1471  first_waiter = true;
1472  int lockHoldersNum = 0;
1473 
1474  initStringInfo(&buf);
1475  initStringInfo(&lock_waiters_sbuf);
1476  initStringInfo(&lock_holders_sbuf);
1477 
1478  DescribeLockTag(&buf, &locallock->tag.lock);
1479  modename = GetLockmodeName(locallock->tag.lock.locktag_lockmethodid,
1480  lockmode);
1483  &secs, &usecs);
1484  msecs = secs * 1000 + usecs / 1000;
1485  usecs = usecs % 1000;
1486 
1487  /*
1488  * we loop over the lock's procLocks to gather a list of all
1489  * holders and waiters. Thus we will be able to provide more
1490  * detailed information for lock debugging purposes.
1491  *
1492  * lock->procLocks contains all processes which hold or wait for
1493  * this lock.
1494  */
1495 
1496  LWLockAcquire(partitionLock, LW_SHARED);
1497 
1498  procLocks = &(lock->procLocks);
1499  proclock = (PROCLOCK *) SHMQueueNext(procLocks, procLocks,
1500  offsetof(PROCLOCK, lockLink));
1501 
1502  while (proclock)
1503  {
1504  /*
1505  * we are a waiter if myProc->waitProcLock == proclock; we are
1506  * a holder if it is NULL or something different
1507  */
1508  if (proclock->tag.myProc->waitProcLock == proclock)
1509  {
1510  if (first_waiter)
1511  {
1512  appendStringInfo(&lock_waiters_sbuf, "%d",
1513  proclock->tag.myProc->pid);
1514  first_waiter = false;
1515  }
1516  else
1517  appendStringInfo(&lock_waiters_sbuf, ", %d",
1518  proclock->tag.myProc->pid);
1519  }
1520  else
1521  {
1522  if (first_holder)
1523  {
1524  appendStringInfo(&lock_holders_sbuf, "%d",
1525  proclock->tag.myProc->pid);
1526  first_holder = false;
1527  }
1528  else
1529  appendStringInfo(&lock_holders_sbuf, ", %d",
1530  proclock->tag.myProc->pid);
1531 
1532  lockHoldersNum++;
1533  }
1534 
1535  proclock = (PROCLOCK *) SHMQueueNext(procLocks, &proclock->lockLink,
1536  offsetof(PROCLOCK, lockLink));
1537  }
1538 
1539  LWLockRelease(partitionLock);
1540 
1542  ereport(LOG,
1543  (errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
1544  MyProcPid, modename, buf.data, msecs, usecs),
1545  (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1546  "Processes holding the lock: %s. Wait queue: %s.",
1547  lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1548  else if (deadlock_state == DS_HARD_DEADLOCK)
1549  {
1550  /*
1551  * This message is a bit redundant with the error that will be
1552  * reported subsequently, but in some cases the error report
1553  * might not make it to the log (eg, if it's caught by an
1554  * exception handler), and we want to ensure all long-wait
1555  * events get logged.
1556  */
1557  ereport(LOG,
1558  (errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
1559  MyProcPid, modename, buf.data, msecs, usecs),
1560  (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1561  "Processes holding the lock: %s. Wait queue: %s.",
1562  lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1563  }
1564 
1565  if (myWaitStatus == PROC_WAIT_STATUS_WAITING)
1566  ereport(LOG,
1567  (errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
1568  MyProcPid, modename, buf.data, msecs, usecs),
1569  (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1570  "Processes holding the lock: %s. Wait queue: %s.",
1571  lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1572  else if (myWaitStatus == PROC_WAIT_STATUS_OK)
1573  ereport(LOG,
1574  (errmsg("process %d acquired %s on %s after %ld.%03d ms",
1575  MyProcPid, modename, buf.data, msecs, usecs)));
1576  else
1577  {
1578  Assert(myWaitStatus == PROC_WAIT_STATUS_ERROR);
1579 
1580  /*
1581  * Currently, the deadlock checker always kicks its own
1582  * process, which means that we'll only see PROC_WAIT_STATUS_ERROR when
1583  * deadlock_state == DS_HARD_DEADLOCK, and there's no need to
1584  * print redundant messages. But for completeness and
1585  * future-proofing, print a message if it looks like someone
1586  * else kicked us off the lock.
1587  */
1589  ereport(LOG,
1590  (errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
1591  MyProcPid, modename, buf.data, msecs, usecs),
1592  (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1593  "Processes holding the lock: %s. Wait queue: %s.",
1594  lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1595  }
1596 
1597  /*
1598  * At this point we might still need to wait for the lock. Reset
1599  * state so we don't print the above messages again.
1600  */
1602 
1603  pfree(buf.data);
1604  pfree(lock_holders_sbuf.data);
1605  pfree(lock_waiters_sbuf.data);
1606  }
1607  } while (myWaitStatus == PROC_WAIT_STATUS_WAITING);
1608 
1609  /*
1610  * Disable the timers, if they are still running. As in LockErrorCleanup,
1611  * we must preserve the LOCK_TIMEOUT indicator flag: if a lock timeout has
1612  * already caused QueryCancelPending to become set, we want the cancel to
1613  * be reported as a lock timeout, not a user cancel.
1614  */
1615  if (!InHotStandby)
1616  {
1617  if (LockTimeout > 0)
1618  {
1619  DisableTimeoutParams timeouts[2];
1620 
1621  timeouts[0].id = DEADLOCK_TIMEOUT;
1622  timeouts[0].keep_indicator = false;
1623  timeouts[1].id = LOCK_TIMEOUT;
1624  timeouts[1].keep_indicator = true;
1625  disable_timeouts(timeouts, 2);
1626  }
1627  else
1629  }
1630 
1631  /*
1632  * Emit the log message if recovery conflict on lock was resolved but the
1633  * startup process waited longer than deadlock_timeout for it.
1634  */
1635  if (InHotStandby && logged_recovery_conflict)
1637  standbyWaitStart, GetCurrentTimestamp(),
1638  NULL, false);
1639 
1640  /*
1641  * Re-acquire the lock table's partition lock. We have to do this to hold
1642  * off cancel/die interrupts before we can mess with lockAwaited (else we
1643  * might have a missed or duplicated locallock update).
1644  */
1645  LWLockAcquire(partitionLock, LW_EXCLUSIVE);
1646 
1647  /*
1648  * We no longer want LockErrorCleanup to do anything.
1649  */
1650  lockAwaited = NULL;
1651 
1652  /*
1653  * If we got the lock, be sure to remember it in the locallock table.
1654  */
1656  GrantAwaitedLock();
1657 
1658  /*
1659  * We don't have to do anything else, because the awaker did all the
1660  * necessary update of the lock table and MyProc.
1661  */
1662  return MyProc->waitStatus;
1663 }
TimestampTz get_timeout_start_time(TimeoutId id)
Definition: timeout.c:749
PROCLOCKTAG tag
Definition: lock.h:363
uint32 hashcode
Definition: lock.h:423
#define PG_WAIT_LOCK
Definition: pgstat.h:896
Definition: lwlock.h:31
TimeoutId id
Definition: timeout.h:55
LOCALLOCKTAG tag
Definition: lock.h:420
#define DEBUG1
Definition: elog.h:25
int MyProcPid
Definition: globals.c:41
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
Definition: lock.c:4014
LOCKTAG lock
Definition: lock.h:401
void GrantAwaitedLock(void)
Definition: lock.c:1785
int LOCKMODE
Definition: lockdefs.h:26
LOCKMODE mode
Definition: lock.h:402
PROCLOCK * proclock
Definition: lock.h:425
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1578
SHM_QUEUE links
Definition: lock.h:32
PGPROC * MyProc
Definition: proc.c:68
int64 TimestampTz
Definition: timestamp.h:39
LOCKMASK holdMask
Definition: lock.h:367
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
Definition: lock.c:1554
SHM_QUEUE links
Definition: proc.h:124
TimeoutType type
Definition: timeout.h:56
struct SHM_QUEUE * next
Definition: shmem.h:31
LOCKMODE waitLockMode
Definition: proc.h:181
bool InRecovery
Definition: xlog.c:206
LOCKTAG tag
Definition: lock.h:302
#define PROC_VACUUM_FOR_WRAPAROUND
Definition: proc.h:60
unsigned char uint8
Definition: c.h:439
Definition: lock.h:166
const LOCKMASK * conflictTab
Definition: lock.h:115
void LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
Definition: standby.c:234
#define LockHashPartitionLock(hashcode)
Definition: lock.h:518
SHM_QUEUE lockLink
Definition: lock.h:369
#define InHotStandby
Definition: xlog.h:74
PROC_HDR * ProcGlobal
Definition: proc.c:80
#define kill(pid, sig)
Definition: win32_port.h:454
void SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem)
Definition: shmqueue.c:89
ProcWaitStatus waitStatus
Definition: proc.h:128
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:8132
void disable_timeouts(const DisableTimeoutParams *timeouts, int count)
Definition: timeout.c:654
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
Definition: timestamp.c:1709
void ResetLatch(Latch *latch)
Definition: latch.c:660
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:438
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:452
PROC_QUEUE waitProcs
Definition: lock.h:308
void RememberSimpleDeadLock(PGPROC *proc1, LOCKMODE lockmode, LOCK *lock, PGPROC *proc2)
Definition: deadlock.c:1162
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
void enable_timeouts(const EnableTimeoutParams *timeouts, int count)
Definition: timeout.c:572
void pfree(void *pointer)
Definition: mcxt.c:1057
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
static DeadLockState deadlock_state
Definition: proc.c:87
TimeoutId id
Definition: timeout.h:66
void DescribeLockTag(StringInfo buf, const LOCKTAG *tag)
Definition: lmgr.c:1099
PROCLOCK * waitProcLock
Definition: proc.h:180
bool message_level_is_interesting(int elevel)
Definition: elog.c:270
void ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict)
Definition: standby.c:568
static char * buf
Definition: pg_test_fsync.c:68
static volatile sig_atomic_t got_deadlock_timeout
Definition: proc.c:90
unsigned int uint32
Definition: c.h:441
int errdetail_log(const char *fmt,...)
Definition: elog.c:1086
void CheckRecoveryConflictDeadlock(void)
Definition: standby.c:847
Definition: lock.h:299
LOCK * waitLock
Definition: proc.h:179
bool log_recovery_conflict_waits
Definition: standby.c:42
LOCKMASK waitMask
Definition: lock.h:306
SHM_QUEUE procLocks
Definition: lock.h:307
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define WARNING
Definition: elog.h:40
Pointer SHMQueueNext(const SHM_QUEUE *queue, const SHM_QUEUE *curElem, Size linkOffset)
Definition: shmqueue.c:145
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition: lock.c:1917
ProcWaitStatus
Definition: proc.h:82
int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1107
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
Definition: lock.c:2909
#define ereport(elevel,...)
Definition: elog.h:155
bool LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
Definition: lock.c:1419
int errmsg_internal(const char *fmt,...)
Definition: elog.c:992
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:524
uint8 locktag_type
Definition: lock.h:172
#define Assert(condition)
Definition: c.h:804
bool log_lock_waits
Definition: proc.c:65
static LOCALLOCK * lockAwaited
Definition: proc.c:85
int LockTimeout
Definition: proc.c:62
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
LOCK * lock
Definition: lock.h:424
int LOCKMASK
Definition: lockdefs.h:25
static void CheckDeadLock(void)
Definition: proc.c:1776
uint8 locktag_lockmethodid
Definition: lock.h:173
PGPROC * myProc
Definition: lock.h:357
#define LOCKBIT_ON(lockmode)
Definition: lock.h:88
#define AccessExclusiveLock
Definition: lockdefs.h:45
Definition: lock.h:360
int errmsg(const char *fmt,...)
Definition: elog.c:905
int i
int pgxactoff
Definition: proc.h:148
int size
Definition: lock.h:33
struct Latch * MyLatch
Definition: globals.c:55
int DeadlockTimeout
Definition: proc.c:60
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:100
PGPROC * GetBlockingAutoVacuumPgproc(void)
Definition: deadlock.c:293
uint8 * statusFlags
Definition: proc.h:333
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:621
pg_atomic_uint64 waitStart
Definition: proc.h:184
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition: timestamp.c:1654
Definition: proc.h:121
int pid
Definition: proc.h:146
#define WL_LATCH_SET
Definition: latch.h:125
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1542
PGPROC * lockGroupLeader
Definition: proc.h:251
#define PROC_IS_AUTOVACUUM
Definition: proc.h:54
#define offsetof(type, field)
Definition: c.h:727
LOCKMASK heldLocks
Definition: proc.h:182
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:130
PGPROC * groupLeader
Definition: lock.h:366

◆ ProcWaitForSignal()

void ProcWaitForSignal ( uint32  wait_event_info)

Definition at line 1888 of file proc.c.

References CHECK_FOR_INTERRUPTS, MyLatch, ResetLatch(), WaitLatch(), WL_EXIT_ON_PM_DEATH, and WL_LATCH_SET.

Referenced by GetSafeSnapshot(), LockBufferForCleanup(), ResolveRecoveryConflictWithBufferPin(), and ResolveRecoveryConflictWithLock().

1889 {
1891  wait_event_info);
1894 }
void ResetLatch(Latch *latch)
Definition: latch.c:660
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:452
struct Latch * MyLatch
Definition: globals.c:55
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:100
#define WL_LATCH_SET
Definition: latch.h:125
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:130

◆ ProcWakeup()

PGPROC* ProcWakeup ( PGPROC proc,
ProcWaitStatus  waitStatus 
)

Definition at line 1680 of file proc.c.

References Assert, PGPROC::links, SHM_QUEUE::next, pg_atomic_write_u64(), SHM_QUEUE::prev, PROC_WAIT_STATUS_WAITING, PGPROC::procLatch, SetLatch(), SHMQueueDelete(), PROC_QUEUE::size, PGPROC::waitLock, PGPROC::waitProcLock, LOCK::waitProcs, PGPROC::waitStart, and PGPROC::waitStatus.

Referenced by ProcLockWakeup().

1681 {
1682  PGPROC *retProc;
1683 
1684  /* Proc should be sleeping ... */
1685  if (proc->links.prev == NULL ||
1686  proc->links.next == NULL)
1687  return NULL;
1689 
1690  /* Save next process before we zap the list link */
1691  retProc = (PGPROC *) proc->links.next;
1692 
1693  /* Remove process from wait queue */
1694  SHMQueueDelete(&(proc->links));
1695  (proc->waitLock->waitProcs.size)--;
1696 
1697  /* Clean up process' state and pass it the ok/fail signal */
1698  proc->waitLock = NULL;
1699  proc->waitProcLock = NULL;
1700  proc->waitStatus = waitStatus;
1702 
1703  /* And awaken it */
1704  SetLatch(&proc->procLatch);
1705 
1706  return retProc;
1707 }
PGPROC * MyProc
Definition: proc.c:68
SHM_QUEUE links
Definition: proc.h:124
struct SHM_QUEUE * next
Definition: shmem.h:31
ProcWaitStatus waitStatus
Definition: proc.h:128
void SetLatch(Latch *latch)
Definition: latch.c:567
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:438
Latch procLatch
Definition: proc.h:130
PROC_QUEUE waitProcs
Definition: lock.h:308
PROCLOCK * waitProcLock
Definition: proc.h:180
LOCK * waitLock
Definition: proc.h:179
struct SHM_QUEUE * prev
Definition: shmem.h:30
#define Assert(condition)
Definition: c.h:804
int size
Definition: lock.h:33
void SHMQueueDelete(SHM_QUEUE *queue)
Definition: shmqueue.c:68
pg_atomic_uint64 waitStart
Definition: proc.h:184
Definition: proc.h:121

◆ PublishStartupProcessInformation()

void PublishStartupProcessInformation ( void  )

Definition at line 626 of file proc.c.

References MyProc, MyProcPid, ProcStructLock, SpinLockAcquire, SpinLockRelease, PROC_HDR::startupProc, and PROC_HDR::startupProcPid.

Referenced by StartupXLOG().

627 {
629 
632 
634 }
int MyProcPid
Definition: globals.c:41
PGPROC * MyProc
Definition: proc.c:68
PROC_HDR * ProcGlobal
Definition: proc.c:80
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
int startupProcPid
Definition: proc.h:357
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
PGPROC * startupProc
Definition: proc.h:356

◆ SetStartupBufferPinWaitBufId()

void SetStartupBufferPinWaitBufId ( int  bufid)

Definition at line 644 of file proc.c.

References ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by LockBufferForCleanup().

645 {
646  /* use volatile pointer to prevent code rearrangement */
647  volatile PROC_HDR *procglobal = ProcGlobal;
648 
649  procglobal->startupBufferPinWaitBufId = bufid;
650 }
PROC_HDR * ProcGlobal
Definition: proc.c:80
Definition: proc.h:315
int startupBufferPinWaitBufId
Definition: proc.h:359

Variable Documentation

◆ DeadlockTimeout

◆ IdleInTransactionSessionTimeout

PGDLLIMPORT int IdleInTransactionSessionTimeout

Definition at line 63 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

◆ IdleSessionTimeout

PGDLLIMPORT int IdleSessionTimeout

Definition at line 64 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

◆ LockTimeout

PGDLLIMPORT int LockTimeout

Definition at line 62 of file proc.c.

Referenced by ProcSleep().

◆ log_lock_waits

bool log_lock_waits

Definition at line 65 of file proc.c.

Referenced by ProcSleep().

◆ MyProc

Definition at line 68 of file proc.c.

Referenced by AbortTransaction(), AtEOSubXact_Namespace(), AtEOXact_Namespace(), AtEOXact_Snapshot(), attach_to_queues(), AutoVacWorkerMain(), AuxiliaryProcKill(), BackgroundWriterMain(), BecomeLockGroupLeader(), CheckpointerMain(), CommitTransaction(), ComputeXidHorizons(), ConditionVariableBroadcast(), ConditionVariableCancelSleep(), ConditionVariablePrepareToSleep(), ConditionVariableTimedSleep(), CountOtherDBBackends(), CreateReplicationSlot(), DefineIndex(), EndPrepare(), errdetail_abort(), exec_eval_simple_expr(), exec_simple_check_plan(), exec_stmt_call(), ExecParallelGetReceiver(), ExecParallelSetupTupleQueues(), ExportSnapshot(), FastPathGetRelationLockEntry(), FastPathGrantRelationLock(), FastPathUnGrantRelationLock(), FindLockCycleRecurseMember(), fmgr_sql(), get_cast_hashentry(), GetCurrentVirtualXIDs(), GetLockConflicts(), GetLockmodeName(), GetNewTransactionId(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), GetSnapshotDataReuse(), GetStableLatestTransactionId(), init_sql_fcache(), InitializeParallelDSM(), InitializeSessionUserId(), InitPostgres(), InitTempTableNamespace(), InitWalSenderSlot(), lock_and_open_sequence(), LockAcquireExtended(), LockCheckConflicts(), LockRelease(), LockReleaseAll(), log_line_prefix(), logicalrep_worker_attach(), LWLockAcquire(), LWLockAcquireOrWait(), LWLockAttemptLock(), LWLockDequeueSelf(), LWLockQueueSelf(), LWLockWaitForVar(), MarkBufferDirtyHint(), MinimumActiveBackends(), ParallelWorkerMain(), pgstat_report_activity(), pgstat_report_wait_end(), pgstat_report_wait_start(), PhysicalReplicationSlotNewXmin(), PostPrepare_Locks(), PrepareTransaction(), ProcArrayGroupClearXid(), ProcArrayInstallImportedXmin(), ProcArrayInstallRestoredXmin(), ProcessStandbyHSFeedbackMessage(), ProcKill(), PublishStartupProcessInformation(), RecordTransactionCommit(), RecordTransactionCommitPrepared(), RecoveryConflictInterrupt(), ReinitializeParallelDSM(), ReplicationSlotRelease(), ResolveRecoveryConflictWithLock(), set_indexsafe_procflags(), setup_dynamic_shared_memory(), SharedInvalBackendInit(), shm_mq_attach(), shm_mq_detach_internal(), shm_mq_receive(), shm_mq_sendv(), shm_mq_wait_for_attach(), SnapBuildInitialSnapshot(), SnapshotResetXmin(), StartTransaction(), StartupDecodingContext(), SwitchBackToLocalLatch(), SwitchToSharedLatch(), SyncRepCancelWait(), SyncRepCleanupAtProcExit(), SyncRepQueueInsert(), SyncRepWaitForLSN(), TerminateOtherDBBackends(), TransactionGroupUpdateXidStatus(), TransactionIdIsInProgress(), TransactionIdLimitedForOldSnapshots(), TransactionIdSetPageStatus(), TruncateMultiXact(), vacuum_rel(), VirtualXactLockTableCleanup(), VirtualXactLockTableInsert(), WaitXLogInsertionsToFinish(), WALInsertLockAcquire(), WalReceiverMain(), WalWriterMain(), write_csvlog(), XidCacheRemoveRunningXids(), and XLogSaveBufferForHint().

◆ PreparedXactProcs

PGPROC* PreparedXactProcs

Definition at line 82 of file proc.c.

Referenced by PostmasterMarkPIDForWorkerNotify(), and TwoPhaseShmemInit().

◆ ProcGlobal

◆ StatementTimeout

PGDLLIMPORT int StatementTimeout

Definition at line 61 of file proc.c.

Referenced by enable_statement_timeout().