PostgreSQL Source Code git master
proc.c File Reference
#include "postgres.h"
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include "access/transam.h"
#include "access/twophase.h"
#include "access/xlogutils.h"
#include "access/xlogwait.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/autovacuum.h"
#include "replication/slotsync.h"
#include "replication/syncrep.h"
#include "storage/condition_variable.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/procsignal.h"
#include "storage/spin.h"
#include "storage/standby.h"
#include "utils/timeout.h"
#include "utils/timestamp.h"
Include dependency graph for proc.c:

Go to the source code of this file.

Functions

static void RemoveProcFromArray (int code, Datum arg)
 
static void ProcKill (int code, Datum arg)
 
static void AuxiliaryProcKill (int code, Datum arg)
 
static void CheckDeadLock (void)
 
static Size PGProcShmemSize (void)
 
static Size FastPathLockShmemSize (void)
 
Size ProcGlobalShmemSize (void)
 
int ProcGlobalSemas (void)
 
void InitProcGlobal (void)
 
void InitProcess (void)
 
void InitProcessPhase2 (void)
 
void InitAuxiliaryProcess (void)
 
void SetStartupBufferPinWaitBufId (int bufid)
 
int GetStartupBufferPinWaitBufId (void)
 
bool HaveNFreeProcs (int n, int *nfree)
 
void LockErrorCleanup (void)
 
void ProcReleaseLocks (bool isCommit)
 
PGPROCAuxiliaryPidGetProc (int pid)
 
ProcWaitStatus JoinWaitQueue (LOCALLOCK *locallock, LockMethod lockMethodTable, bool dontWait)
 
ProcWaitStatus ProcSleep (LOCALLOCK *locallock)
 
void ProcWakeup (PGPROC *proc, ProcWaitStatus waitStatus)
 
void ProcLockWakeup (LockMethod lockMethodTable, LOCK *lock)
 
void CheckDeadLockAlert (void)
 
void GetLockHoldersAndWaiters (LOCALLOCK *locallock, StringInfo lock_holders_sbuf, StringInfo lock_waiters_sbuf, int *lockHoldersNum)
 
void ProcWaitForSignal (uint32 wait_event_info)
 
void ProcSendSignal (ProcNumber procNumber)
 
void BecomeLockGroupLeader (void)
 
bool BecomeLockGroupMember (PGPROC *leader, int pid)
 

Variables

int DeadlockTimeout = 1000
 
int StatementTimeout = 0
 
int LockTimeout = 0
 
int IdleInTransactionSessionTimeout = 0
 
int TransactionTimeout = 0
 
int IdleSessionTimeout = 0
 
bool log_lock_waits = true
 
PGPROCMyProc = NULL
 
NON_EXEC_STATIC slock_t * ProcStructLock = NULL
 
PROC_HDRProcGlobal = NULL
 
NON_EXEC_STATIC PGPROCAuxiliaryProcs = NULL
 
PGPROCPreparedXactProcs = NULL
 
static DeadLockState deadlock_state = DS_NOT_YET_CHECKED
 
static volatile sig_atomic_t got_deadlock_timeout
 

Function Documentation

◆ AuxiliaryPidGetProc()

PGPROC * AuxiliaryPidGetProc ( int  pid)

Definition at line 1101 of file proc.c.

1102{
1103 PGPROC *result = NULL;
1104 int index;
1105
1106 if (pid == 0) /* never match dummy PGPROCs */
1107 return NULL;
1108
1109 for (index = 0; index < NUM_AUXILIARY_PROCS; index++)
1110 {
1111 PGPROC *proc = &AuxiliaryProcs[index];
1112
1113 if (proc->pid == pid)
1114 {
1115 result = proc;
1116 break;
1117 }
1118 }
1119 return result;
1120}
#define NUM_AUXILIARY_PROCS
Definition: proc.h:463
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:80
Definition: proc.h:179
int pid
Definition: proc.h:199
Definition: type.h:96

References AuxiliaryProcs, NUM_AUXILIARY_PROCS, and PGPROC::pid.

Referenced by pg_log_backend_memory_contexts(), pg_stat_get_activity(), pg_stat_reset_backend_stats(), and pgstat_fetch_stat_backend_by_pid().

◆ AuxiliaryProcKill()

static void AuxiliaryProcKill ( int  code,
Datum  arg 
)
static

Definition at line 1050 of file proc.c.

1051{
1052 int proctype = DatumGetInt32(arg);
1054 PGPROC *proc;
1055
1056 Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS);
1057
1058 /* not safe if forked by system(), etc. */
1059 if (MyProc->pid != (int) getpid())
1060 elog(PANIC, "AuxiliaryProcKill() called in child process");
1061
1062 auxproc = &AuxiliaryProcs[proctype];
1063
1064 Assert(MyProc == auxproc);
1065
1066 /* Release any LW locks I am holding (see notes above) */
1068
1069 /* Cancel any pending condition variable sleep, too */
1071
1072 /* look at the equivalent ProcKill() code for comments */
1075
1076 proc = MyProc;
1077 MyProc = NULL;
1079 DisownLatch(&proc->procLatch);
1080
1082
1083 /* Mark auxiliary proc no longer in use */
1084 proc->pid = 0;
1087
1088 /* Update shared estimate of spins_per_delay */
1090
1092}
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:228
bool ConditionVariableCancelSleep(void)
#define PANIC
Definition: elog.h:42
#define elog(elevel,...)
Definition: elog.h:226
ProcNumber MyProcNumber
Definition: globals.c:90
Assert(PointerIsAligned(start, uint64))
void DisownLatch(Latch *latch)
Definition: latch.c:144
void LWLockReleaseAll(void)
Definition: lwlock.c:1945
void SwitchBackToLocalLatch(void)
Definition: miscinit.c:242
void * arg
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:212
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
int update_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:218
#define SpinLockRelease(lock)
Definition: spin.h:61
#define SpinLockAcquire(lock)
Definition: spin.h:59
PGPROC * MyProc
Definition: proc.c:67
PROC_HDR * ProcGlobal
Definition: proc.c:79
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:76
LocalTransactionId lxid
Definition: proc.h:217
struct PGPROC::@130 vxid
ProcNumber procNumber
Definition: proc.h:212
Latch procLatch
Definition: proc.h:186
int spins_per_delay
Definition: proc.h:428
#define InvalidTransactionId
Definition: transam.h:31
void pgstat_reset_wait_event_storage(void)
Definition: wait_event.c:361

References arg, Assert(), AuxiliaryProcs, ConditionVariableCancelSleep(), DatumGetInt32(), DisownLatch(), elog, INVALID_PROC_NUMBER, InvalidTransactionId, LWLockReleaseAll(), PGPROC::lxid, MyProc, MyProcNumber, NUM_AUXILIARY_PROCS, PANIC, PG_USED_FOR_ASSERTS_ONLY, pgstat_reset_wait_event_storage(), PGPROC::pid, ProcGlobal, PGPROC::procLatch, PGPROC::procNumber, ProcStructLock, SpinLockAcquire, SpinLockRelease, PROC_HDR::spins_per_delay, SwitchBackToLocalLatch(), update_spins_per_delay(), and PGPROC::vxid.

Referenced by InitAuxiliaryProcess().

◆ BecomeLockGroupLeader()

void BecomeLockGroupLeader ( void  )

Definition at line 2011 of file proc.c.

2012{
2013 LWLock *leader_lwlock;
2014
2015 /* If we already did it, we don't need to do it again. */
2017 return;
2018
2019 /* We had better not be a follower. */
2020 Assert(MyProc->lockGroupLeader == NULL);
2021
2022 /* Create single-member group, containing only ourselves. */
2023 leader_lwlock = LockHashPartitionLockByProc(MyProc);
2024 LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
2027 LWLockRelease(leader_lwlock);
2028}
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:347
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:543
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1174
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1894
@ LW_EXCLUSIVE
Definition: lwlock.h:112
Definition: lwlock.h:42
dlist_head lockGroupMembers
Definition: proc.h:322
dlist_node lockGroupLink
Definition: proc.h:323
PGPROC * lockGroupLeader
Definition: proc.h:321

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

Referenced by LaunchParallelWorkers().

◆ BecomeLockGroupMember()

bool BecomeLockGroupMember ( PGPROC leader,
int  pid 
)

Definition at line 2041 of file proc.c.

2042{
2043 LWLock *leader_lwlock;
2044 bool ok = false;
2045
2046 /* Group leader can't become member of group */
2047 Assert(MyProc != leader);
2048
2049 /* Can't already be a member of a group */
2050 Assert(MyProc->lockGroupLeader == NULL);
2051
2052 /* PID must be valid. */
2053 Assert(pid != 0);
2054
2055 /*
2056 * Get lock protecting the group fields. Note LockHashPartitionLockByProc
2057 * calculates the proc number based on the PGPROC slot without looking at
2058 * its contents, so we will acquire the correct lock even if the leader
2059 * PGPROC is in process of being recycled.
2060 */
2061 leader_lwlock = LockHashPartitionLockByProc(leader);
2062 LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
2063
2064 /* Is this the leader we're looking for? */
2065 if (leader->pid == pid && leader->lockGroupLeader == leader)
2066 {
2067 /* OK, join the group */
2068 ok = true;
2069 MyProc->lockGroupLeader = leader;
2071 }
2072 LWLockRelease(leader_lwlock);
2073
2074 return ok;
2075}
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition: ilist.h:364

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

Referenced by ParallelWorkerMain().

◆ CheckDeadLock()

static void CheckDeadLock ( void  )
static

Definition at line 1797 of file proc.c.

1798{
1799 int i;
1800
1801 /*
1802 * Acquire exclusive lock on the entire shared lock data structures. Must
1803 * grab LWLocks in partition-number order to avoid LWLock deadlock.
1804 *
1805 * Note that the deadlock check interrupt had better not be enabled
1806 * anywhere that this process itself holds lock partition locks, else this
1807 * will wait forever. Also note that LWLockAcquire creates a critical
1808 * section, so that this routine cannot be interrupted by cancel/die
1809 * interrupts.
1810 */
1811 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
1813
1814 /*
1815 * Check to see if we've been awoken by anyone in the interim.
1816 *
1817 * If we have, we can return and resume our transaction -- happy day.
1818 * Before we are awoken the process releasing the lock grants it to us so
1819 * we know that we don't have to wait anymore.
1820 *
1821 * We check by looking to see if we've been unlinked from the wait queue.
1822 * This is safe because we hold the lock partition lock.
1823 */
1824 if (MyProc->links.prev == NULL ||
1825 MyProc->links.next == NULL)
1826 goto check_done;
1827
1828#ifdef LOCK_DEBUG
1829 if (Debug_deadlocks)
1830 DumpAllLocks();
1831#endif
1832
1833 /* Run the deadlock check, and set deadlock_state for use by ProcSleep */
1835
1837 {
1838 /*
1839 * Oops. We have a deadlock.
1840 *
1841 * Get this process out of wait state. (Note: we could do this more
1842 * efficiently by relying on lockAwaited, but use this coding to
1843 * preserve the flexibility to kill some other transaction than the
1844 * one detecting the deadlock.)
1845 *
1846 * RemoveFromWaitQueue sets MyProc->waitStatus to
1847 * PROC_WAIT_STATUS_ERROR, so ProcSleep will report an error after we
1848 * return from the signal handler.
1849 */
1850 Assert(MyProc->waitLock != NULL);
1852
1853 /*
1854 * We're done here. Transaction abort caused by the error that
1855 * ProcSleep will raise will cause any other locks we hold to be
1856 * released, thus allowing other processes to wake up; we don't need
1857 * to do that here. NOTE: an exception is that releasing locks we
1858 * hold doesn't consider the possibility of waiters that were blocked
1859 * behind us on the lock we just failed to get, and might now be
1860 * wakable because we're not in front of them anymore. However,
1861 * RemoveFromWaitQueue took care of waking up any such processes.
1862 */
1863 }
1864
1865 /*
1866 * And release locks. We do this in reverse order for two reasons: (1)
1867 * Anyone else who needs more than one of the locks will be trying to lock
1868 * them in increasing order; we don't want to release the other process
1869 * until it can get all the locks it needs. (2) This avoids O(N^2)
1870 * behavior inside LWLockRelease.
1871 */
1872check_done:
1873 for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
1875}
DeadLockState DeadLockCheck(PGPROC *proc)
Definition: deadlock.c:220
int i
Definition: isn.c:77
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition: lock.c:2046
uint32 LockTagHashCode(const LOCKTAG *locktag)
Definition: lock.c:557
@ DS_HARD_DEADLOCK
Definition: lock.h:515
#define LockHashPartitionLockByIndex(i)
Definition: lock.h:531
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:95
static DeadLockState deadlock_state
Definition: proc.c:83
LOCKTAG tag
Definition: lock.h:313
LOCK * waitLock
Definition: proc.h:249
dlist_node links
Definition: proc.h:180
dlist_node * next
Definition: ilist.h:140
dlist_node * prev
Definition: ilist.h:139

References Assert(), deadlock_state, DeadLockCheck(), DS_HARD_DEADLOCK, i, PGPROC::links, LockHashPartitionLockByIndex, LockTagHashCode(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MyProc, dlist_node::next, NUM_LOCK_PARTITIONS, dlist_node::prev, RemoveFromWaitQueue(), LOCK::tag, and PGPROC::waitLock.

Referenced by ProcSleep().

◆ CheckDeadLockAlert()

void CheckDeadLockAlert ( void  )

Definition at line 1883 of file proc.c.

1884{
1885 int save_errno = errno;
1886
1887 got_deadlock_timeout = true;
1888
1889 /*
1890 * Have to set the latch again, even if handle_sig_alarm already did. Back
1891 * then got_deadlock_timeout wasn't yet set... It's unlikely that this
1892 * ever would be a problem, but setting a set latch again is cheap.
1893 *
1894 * Note that, when this function runs inside procsignal_sigusr1_handler(),
1895 * the handler function sets the latch again after the latch is set here.
1896 */
1898 errno = save_errno;
1899}
struct Latch * MyLatch
Definition: globals.c:63
void SetLatch(Latch *latch)
Definition: latch.c:290
static volatile sig_atomic_t got_deadlock_timeout
Definition: proc.c:86

References got_deadlock_timeout, MyLatch, and SetLatch().

Referenced by InitPostgres(), and ProcessRecoveryConflictInterrupt().

◆ FastPathLockShmemSize()

static Size FastPathLockShmemSize ( void  )
static

Definition at line 116 of file proc.c.

117{
118 Size size = 0;
119 Size TotalProcs =
121 Size fpLockBitsSize,
122 fpRelIdSize;
123
124 /*
125 * Memory needed for PGPROC fast-path lock arrays. Make sure the sizes are
126 * nicely aligned in each backend.
127 */
128 fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
129 fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
130
131 size = add_size(size, mul_size(TotalProcs, (fpLockBitsSize + fpRelIdSize)));
132
133 return size;
134}
#define MAXALIGN(LEN)
Definition: c.h:813
uint64_t uint64
Definition: c.h:542
size_t Size
Definition: c.h:613
int MaxBackends
Definition: globals.c:146
int FastPathLockGroupsPerBackend
Definition: lock.c:202
unsigned int Oid
Definition: postgres_ext.h:32
#define FastPathLockSlotsPerBackend()
Definition: proc.h:93
Size add_size(Size s1, Size s2)
Definition: shmem.c:495
Size mul_size(Size s1, Size s2)
Definition: shmem.c:510
int max_prepared_xacts
Definition: twophase.c:116

References add_size(), FastPathLockGroupsPerBackend, FastPathLockSlotsPerBackend, max_prepared_xacts, MAXALIGN, MaxBackends, mul_size(), and NUM_AUXILIARY_PROCS.

Referenced by InitProcGlobal(), and ProcGlobalShmemSize().

◆ GetLockHoldersAndWaiters()

void GetLockHoldersAndWaiters ( LOCALLOCK locallock,
StringInfo  lock_holders_sbuf,
StringInfo  lock_waiters_sbuf,
int *  lockHoldersNum 
)

Definition at line 1910 of file proc.c.

1912{
1913 dlist_iter proc_iter;
1914 PROCLOCK *curproclock;
1915 LOCK *lock = locallock->lock;
1916 bool first_holder = true,
1917 first_waiter = true;
1918
1919#ifdef USE_ASSERT_CHECKING
1920 {
1921 uint32 hashcode = locallock->hashcode;
1922 LWLock *partitionLock = LockHashPartitionLock(hashcode);
1923
1924 Assert(LWLockHeldByMe(partitionLock));
1925 }
1926#endif
1927
1928 *lockHoldersNum = 0;
1929
1930 /*
1931 * Loop over the lock's procLocks to gather a list of all holders and
1932 * waiters. Thus we will be able to provide more detailed information for
1933 * lock debugging purposes.
1934 *
1935 * lock->procLocks contains all processes which hold or wait for this
1936 * lock.
1937 */
1938 dlist_foreach(proc_iter, &lock->procLocks)
1939 {
1940 curproclock =
1941 dlist_container(PROCLOCK, lockLink, proc_iter.cur);
1942
1943 /*
1944 * We are a waiter if myProc->waitProcLock == curproclock; we are a
1945 * holder if it is NULL or something different.
1946 */
1947 if (curproclock->tag.myProc->waitProcLock == curproclock)
1948 {
1949 if (first_waiter)
1950 {
1951 appendStringInfo(lock_waiters_sbuf, "%d",
1952 curproclock->tag.myProc->pid);
1953 first_waiter = false;
1954 }
1955 else
1956 appendStringInfo(lock_waiters_sbuf, ", %d",
1957 curproclock->tag.myProc->pid);
1958 }
1959 else
1960 {
1961 if (first_holder)
1962 {
1963 appendStringInfo(lock_holders_sbuf, "%d",
1964 curproclock->tag.myProc->pid);
1965 first_holder = false;
1966 }
1967 else
1968 appendStringInfo(lock_holders_sbuf, ", %d",
1969 curproclock->tag.myProc->pid);
1970
1971 (*lockHoldersNum)++;
1972 }
1973 }
1974}
uint32_t uint32
Definition: c.h:541
#define dlist_foreach(iter, lhead)
Definition: ilist.h:623
#define dlist_container(type, membername, ptr)
Definition: ilist.h:593
#define LockHashPartitionLock(hashcode)
Definition: lock.h:528
bool LWLockHeldByMe(LWLock *lock)
Definition: lwlock.c:1977
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
uint32 hashcode
Definition: lock.h:434
LOCK * lock
Definition: lock.h:435
Definition: lock.h:311
dlist_head procLocks
Definition: lock.h:318
PROCLOCK * waitProcLock
Definition: proc.h:250
PGPROC * myProc
Definition: lock.h:368
Definition: lock.h:372
PROCLOCKTAG tag
Definition: lock.h:374
dlist_node * cur
Definition: ilist.h:179

References appendStringInfo(), Assert(), dlist_iter::cur, dlist_container, dlist_foreach, LOCALLOCK::hashcode, LOCALLOCK::lock, LockHashPartitionLock, LWLockHeldByMe(), PROCLOCKTAG::myProc, PGPROC::pid, LOCK::procLocks, PROCLOCK::tag, and PGPROC::waitProcLock.

Referenced by LockAcquireExtended(), and ProcSleep().

◆ GetStartupBufferPinWaitBufId()

int GetStartupBufferPinWaitBufId ( void  )

Definition at line 771 of file proc.c.

772{
773 /* use volatile pointer to prevent code rearrangement */
774 volatile PROC_HDR *procglobal = ProcGlobal;
775
776 return procglobal->startupBufferPinWaitBufId;
777}
Definition: proc.h:386
int startupBufferPinWaitBufId
Definition: proc.h:430

References ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by HoldingBufferPinThatDelaysRecovery(), and ProcessRecoveryConflictInterrupt().

◆ HaveNFreeProcs()

bool HaveNFreeProcs ( int  n,
int *  nfree 
)

Definition at line 787 of file proc.c.

788{
789 dlist_iter iter;
790
791 Assert(n > 0);
792 Assert(nfree);
793
795
796 *nfree = 0;
798 {
799 (*nfree)++;
800 if (*nfree == n)
801 break;
802 }
803
805
806 return (*nfree == n);
807}
dlist_head freeProcs
Definition: proc.h:408

References Assert(), dlist_foreach, PROC_HDR::freeProcs, ProcGlobal, ProcStructLock, SpinLockAcquire, and SpinLockRelease.

Referenced by InitPostgres().

◆ InitAuxiliaryProcess()

void InitAuxiliaryProcess ( void  )

Definition at line 620 of file proc.c.

621{
622 PGPROC *auxproc;
623 int proctype;
624
625 /*
626 * ProcGlobal should be set up already (if we are a backend, we inherit
627 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
628 */
629 if (ProcGlobal == NULL || AuxiliaryProcs == NULL)
630 elog(PANIC, "proc header uninitialized");
631
632 if (MyProc != NULL)
633 elog(ERROR, "you already exist");
634
637
638 /*
639 * We use the ProcStructLock to protect assignment and releasing of
640 * AuxiliaryProcs entries.
641 *
642 * While we are holding the ProcStructLock, also copy the current shared
643 * estimate of spins_per_delay to local storage.
644 */
646
648
649 /*
650 * Find a free auxproc ... *big* trouble if there isn't one ...
651 */
652 for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++)
653 {
654 auxproc = &AuxiliaryProcs[proctype];
655 if (auxproc->pid == 0)
656 break;
657 }
658 if (proctype >= NUM_AUXILIARY_PROCS)
659 {
661 elog(FATAL, "all AuxiliaryProcs are in use");
662 }
663
664 /* Mark auxiliary proc as in use by me */
665 /* use volatile pointer to prevent code rearrangement */
666 ((volatile PGPROC *) auxproc)->pid = MyProcPid;
667
669
670 MyProc = auxproc;
672
673 /*
674 * Initialize all fields of MyProc, except for those previously
675 * initialized by InitProcGlobal.
676 */
679 MyProc->fpVXIDLock = false;
688 MyProc->isRegularBackend = false;
690 MyProc->statusFlags = 0;
692 MyProc->lwWaitMode = 0;
693 MyProc->waitLock = NULL;
694 MyProc->waitProcLock = NULL;
696#ifdef USE_ASSERT_CHECKING
697 {
698 int i;
699
700 /* Last process should have released all locks. */
701 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
703 }
704#endif
705
706 /*
707 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
708 * on it. That allows us to repoint the process latch, which so far
709 * points to process local one, to the shared one.
710 */
713
714 /* now that we have a proc, report wait events to shared memory */
716
717 /* Check that group locking fields are in a proper initial state. */
718 Assert(MyProc->lockGroupLeader == NULL);
720
721 /*
722 * We might be reusing a semaphore that belonged to a failed process. So
723 * be careful and reinitialize its value here. (This is not strictly
724 * necessary anymore, but seems like a good idea for cleanliness.)
725 */
727
728 /*
729 * Arrange to clean up at process exit.
730 */
732
733 /*
734 * Now that we have a PGPROC, we could try to acquire lightweight locks.
735 * Initialize local state needed for them. (Heavyweight locks cannot be
736 * acquired in aux processes.)
737 */
739
740#ifdef EXEC_BACKEND
741
742 /*
743 * Initialize backend-local pointers to all the shared data structures.
744 * (We couldn't do this until now because it needs LWLocks.)
745 */
747 AttachSharedMemoryStructs();
748#endif
749}
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:483
#define FATAL
Definition: elog.h:41
#define ERROR
Definition: elog.h:39
int MyProcPid
Definition: globals.c:47
bool IsUnderPostmaster
Definition: globals.c:120
static bool dlist_is_empty(const dlist_head *head)
Definition: ilist.h:336
static void dlist_node_init(dlist_node *node)
Definition: ilist.h:325
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:365
void OwnLatch(Latch *latch)
Definition: latch.c:126
#define InvalidLocalTransactionId
Definition: lock.h:67
void InitLWLockAccess(void)
Definition: lwlock.c:550
@ LW_WS_NOT_WAITING
Definition: lwlock.h:30
void SwitchToSharedLatch(void)
Definition: miscinit.c:215
void RegisterPostmasterChildActive(void)
Definition: pmsignal.c:290
void PGSemaphoreReset(PGSemaphore sema)
Definition: posix_sema.c:290
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:222
#define InvalidOid
Definition: postgres_ext.h:37
#define GetNumberFromPGProc(proc)
Definition: proc.h:441
@ PROC_WAIT_STATUS_OK
Definition: proc.h:141
void set_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:207
static void AuxiliaryProcKill(int code, Datum arg)
Definition: proc.c:1050
bool isRegularBackend
Definition: proc.h:230
TransactionId xmin
Definition: proc.h:194
uint8 lwWaitMode
Definition: proc.h:241
uint32 wait_event_info
Definition: proc.h:296
uint8 statusFlags
Definition: proc.h:259
Oid databaseId
Definition: proc.h:224
pg_atomic_uint64 waitStart
Definition: proc.h:254
bool fpVXIDLock
Definition: proc.h:313
TransactionId xid
Definition: proc.h:189
int delayChkptFlags
Definition: proc.h:257
LocalTransactionId fpLocalTransactionId
Definition: proc.h:314
PGSemaphore sem
Definition: proc.h:183
dlist_head myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:278
Oid roleId
Definition: proc.h:225
ProcWaitStatus waitStatus
Definition: proc.h:184
Oid tempNamespaceId
Definition: proc.h:227
uint8 lwWaiting
Definition: proc.h:240
void pgstat_set_wait_event_storage(uint32 *wait_event_info)
Definition: wait_event.c:349

References Assert(), AuxiliaryProcKill(), AuxiliaryProcs, PGPROC::databaseId, PGPROC::delayChkptFlags, dlist_is_empty(), dlist_node_init(), elog, ERROR, FATAL, PGPROC::fpLocalTransactionId, PGPROC::fpVXIDLock, GetNumberFromPGProc, i, InitLWLockAccess(), Int32GetDatum(), INVALID_PROC_NUMBER, InvalidLocalTransactionId, InvalidOid, InvalidTransactionId, PGPROC::isRegularBackend, IsUnderPostmaster, PGPROC::links, PGPROC::lockGroupLeader, PGPROC::lockGroupMembers, LW_WS_NOT_WAITING, PGPROC::lwWaiting, PGPROC::lwWaitMode, PGPROC::lxid, MyProc, PGPROC::myProcLocks, MyProcNumber, MyProcPid, NUM_AUXILIARY_PROCS, NUM_LOCK_PARTITIONS, on_shmem_exit(), OwnLatch(), PANIC, pg_atomic_write_u64(), PGSemaphoreReset(), pgstat_set_wait_event_storage(), PGPROC::pid, PROC_WAIT_STATUS_OK, ProcGlobal, PGPROC::procLatch, PGPROC::procNumber, ProcStructLock, RegisterPostmasterChildActive(), PGPROC::roleId, PGPROC::sem, set_spins_per_delay(), SpinLockAcquire, SpinLockRelease, PROC_HDR::spins_per_delay, PGPROC::statusFlags, SwitchToSharedLatch(), PGPROC::tempNamespaceId, PGPROC::vxid, PGPROC::wait_event_info, PGPROC::waitLock, PGPROC::waitProcLock, PGPROC::waitStart, PGPROC::waitStatus, PGPROC::xid, and PGPROC::xmin.

Referenced by AuxiliaryProcessMainCommon().

◆ InitProcess()

void InitProcess ( void  )

Definition at line 395 of file proc.c.

396{
397 dlist_head *procgloballist;
398
399 /*
400 * ProcGlobal should be set up already (if we are a backend, we inherit
401 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
402 */
403 if (ProcGlobal == NULL)
404 elog(PANIC, "proc header uninitialized");
405
406 if (MyProc != NULL)
407 elog(ERROR, "you already exist");
408
409 /*
410 * Before we start accessing the shared memory in a serious way, mark
411 * ourselves as an active postmaster child; this is so that the postmaster
412 * can detect it if we exit without cleaning up.
413 */
416
417 /*
418 * Decide which list should supply our PGPROC. This logic must match the
419 * way the freelists were constructed in InitProcGlobal().
420 */
422 procgloballist = &ProcGlobal->autovacFreeProcs;
423 else if (AmBackgroundWorkerProcess())
424 procgloballist = &ProcGlobal->bgworkerFreeProcs;
425 else if (AmWalSenderProcess())
426 procgloballist = &ProcGlobal->walsenderFreeProcs;
427 else
428 procgloballist = &ProcGlobal->freeProcs;
429
430 /*
431 * Try to get a proc struct from the appropriate free list. If this
432 * fails, we must be out of PGPROC structures (not to mention semaphores).
433 *
434 * While we are holding the ProcStructLock, also copy the current shared
435 * estimate of spins_per_delay to local storage.
436 */
438
440
441 if (!dlist_is_empty(procgloballist))
442 {
445 }
446 else
447 {
448 /*
449 * If we reach here, all the PGPROCs are in use. This is one of the
450 * possible places to detect "too many backends", so give the standard
451 * error message. XXX do we need to give a different failure message
452 * in the autovacuum case?
453 */
455 if (AmWalSenderProcess())
457 (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
458 errmsg("number of requested standby connections exceeds \"max_wal_senders\" (currently %d)",
461 (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
462 errmsg("sorry, too many clients already")));
463 }
465
466 /*
467 * Cross-check that the PGPROC is of the type we expect; if this were not
468 * the case, it would get returned to the wrong list.
469 */
470 Assert(MyProc->procgloballist == procgloballist);
471
472 /*
473 * Initialize all fields of MyProc, except for those previously
474 * initialized by InitProcGlobal.
475 */
478 MyProc->fpVXIDLock = false;
485 /* databaseId and roleId will be filled in later */
491 MyProc->statusFlags = 0;
492 /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
496 MyProc->lwWaitMode = 0;
497 MyProc->waitLock = NULL;
498 MyProc->waitProcLock = NULL;
500#ifdef USE_ASSERT_CHECKING
501 {
502 int i;
503
504 /* Last process should have released all locks. */
505 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
507 }
508#endif
510
511 /* Initialize fields for sync rep */
512 MyProc->waitLSN = 0;
515
516 /* Initialize fields for group XID clearing. */
520
521 /* Check that group locking fields are in a proper initial state. */
522 Assert(MyProc->lockGroupLeader == NULL);
524
525 /* Initialize wait event information. */
527
528 /* Initialize fields for group transaction status update. */
529 MyProc->clogGroupMember = false;
535
536 /*
537 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
538 * on it. That allows us to repoint the process latch, which so far
539 * points to process local one, to the shared one.
540 */
543
544 /* now that we have a proc, report wait events to shared memory */
546
547 /*
548 * We might be reusing a semaphore that belonged to a failed process. So
549 * be careful and reinitialize its value here. (This is not strictly
550 * necessary anymore, but seems like a good idea for cleanliness.)
551 */
553
554 /*
555 * Arrange to clean up at backend exit.
556 */
558
559 /*
560 * Now that we have a PGPROC, we could try to acquire locks, so initialize
561 * local state needed for LWLocks, and the deadlock checker.
562 */
565
566#ifdef EXEC_BACKEND
567
568 /*
569 * Initialize backend-local pointers to all the shared data structures.
570 * (We couldn't do this until now because it needs LWLocks.)
571 */
573 AttachSharedMemoryStructs();
574#endif
575}
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:237
#define TRANSACTION_STATUS_IN_PROGRESS
Definition: clog.h:27
void InitDeadLockChecking(void)
Definition: deadlock.c:144
int errcode(int sqlerrcode)
Definition: elog.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define ereport(elevel,...)
Definition: elog.h:150
static dlist_node * dlist_pop_head_node(dlist_head *head)
Definition: ilist.h:450
#define AmAutoVacuumWorkerProcess()
Definition: miscadmin.h:383
#define AmBackgroundWorkerProcess()
Definition: miscadmin.h:384
#define AmWalSenderProcess()
Definition: miscadmin.h:385
#define AmSpecialWorkerProcess()
Definition: miscadmin.h:396
#define AmRegularBackendProcess()
Definition: miscadmin.h:381
#define PROC_IS_AUTOVACUUM
Definition: proc.h:57
static void ProcKill(int code, Datum arg)
Definition: proc.c:924
bool procArrayGroupMember
Definition: proc.h:286
XLogRecPtr clogGroupMemberLsn
Definition: proc.h:306
pg_atomic_uint32 procArrayGroupNext
Definition: proc.h:288
dlist_head * procgloballist
Definition: proc.h:181
bool recoveryConflictPending
Definition: proc.h:237
TransactionId clogGroupMemberXid
Definition: proc.h:301
int64 clogGroupMemberPage
Definition: proc.h:304
bool clogGroupMember
Definition: proc.h:299
XLogRecPtr waitLSN
Definition: proc.h:269
dlist_node syncRepLinks
Definition: proc.h:271
int syncRepState
Definition: proc.h:270
pg_atomic_uint32 clogGroupNext
Definition: proc.h:300
XidStatus clogGroupMemberXidStatus
Definition: proc.h:302
TransactionId procArrayGroupMemberXid
Definition: proc.h:294
dlist_head autovacFreeProcs
Definition: proc.h:410
dlist_head walsenderFreeProcs
Definition: proc.h:414
dlist_head bgworkerFreeProcs
Definition: proc.h:412
#define SYNC_REP_NOT_WAITING
Definition: syncrep.h:30
int max_wal_senders
Definition: walsender.c:129
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
static struct link * links
Definition: zic.c:302

References AmAutoVacuumWorkerProcess, AmBackgroundWorkerProcess, AmRegularBackendProcess, AmSpecialWorkerProcess, AmWalSenderProcess, Assert(), PROC_HDR::autovacFreeProcs, PROC_HDR::bgworkerFreeProcs, PGPROC::clogGroupMember, PGPROC::clogGroupMemberLsn, PGPROC::clogGroupMemberPage, PGPROC::clogGroupMemberXid, PGPROC::clogGroupMemberXidStatus, PGPROC::clogGroupNext, PGPROC::databaseId, PGPROC::delayChkptFlags, dlist_container, dlist_is_empty(), dlist_node_init(), dlist_pop_head_node(), elog, ereport, errcode(), errmsg(), ERROR, FATAL, PGPROC::fpLocalTransactionId, PGPROC::fpVXIDLock, PROC_HDR::freeProcs, GetNumberFromPGProc, i, InitDeadLockChecking(), InitLWLockAccess(), INVALID_PROC_NUMBER, InvalidLocalTransactionId, InvalidOid, InvalidTransactionId, InvalidXLogRecPtr, PGPROC::isRegularBackend, IsUnderPostmaster, PGPROC::links, links, PGPROC::lockGroupLeader, PGPROC::lockGroupMembers, LW_WS_NOT_WAITING, PGPROC::lwWaiting, PGPROC::lwWaitMode, PGPROC::lxid, max_wal_senders, MyProc, PGPROC::myProcLocks, MyProcNumber, MyProcPid, NUM_LOCK_PARTITIONS, on_shmem_exit(), OwnLatch(), PANIC, pg_atomic_read_u32(), pg_atomic_write_u64(), PGSemaphoreReset(), pgstat_set_wait_event_storage(), PGPROC::pid, PROC_IS_AUTOVACUUM, PROC_WAIT_STATUS_OK, PGPROC::procArrayGroupMember, PGPROC::procArrayGroupMemberXid, PGPROC::procArrayGroupNext, ProcGlobal, PGPROC::procgloballist, ProcKill(), PGPROC::procLatch, PGPROC::procNumber, ProcStructLock, PGPROC::recoveryConflictPending, RegisterPostmasterChildActive(), PGPROC::roleId, PGPROC::sem, set_spins_per_delay(), 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::vxid, 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(), BackendMain(), BackgroundWorkerMain(), BootstrapModeMain(), PostgresSingleUserMain(), and ReplSlotSyncWorkerMain().

◆ InitProcessPhase2()

void InitProcessPhase2 ( void  )

Definition at line 585 of file proc.c.

586{
587 Assert(MyProc != NULL);
588
589 /*
590 * Add our PGPROC to the PGPROC array in shared memory.
591 */
593
594 /*
595 * Arrange to clean that up at backend exit.
596 */
598}
void ProcArrayAdd(PGPROC *proc)
Definition: procarray.c:468
static void RemoveProcFromArray(int code, Datum arg)
Definition: proc.c:913

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

Referenced by InitPostgres().

◆ InitProcGlobal()

void InitProcGlobal ( void  )

Definition at line 194 of file proc.c.

195{
196 PGPROC *procs;
197 int i,
198 j;
199 bool found;
201
202 /* Used for setup of per-backend fast-path slots. */
203 char *fpPtr,
204 *fpEndPtr PG_USED_FOR_ASSERTS_ONLY;
205 Size fpLockBitsSize,
206 fpRelIdSize;
207 Size requestSize;
208 char *ptr;
209
210 /* Create the ProcGlobal shared structure */
211 ProcGlobal = (PROC_HDR *)
212 ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
213 Assert(!found);
214
215 /*
216 * Initialize the data structures.
217 */
228
229 /*
230 * Create and initialize all the PGPROC structures we'll need. There are
231 * six separate consumers: (1) normal backends, (2) autovacuum workers and
232 * special workers, (3) background workers, (4) walsenders, (5) auxiliary
233 * processes, and (6) prepared transactions. (For largely-historical
234 * reasons, we combine autovacuum and special workers into one category
235 * with a single freelist.) Each PGPROC structure is dedicated to exactly
236 * one of these purposes, and they do not move between groups.
237 */
238 requestSize = PGProcShmemSize();
239
240 ptr = ShmemInitStruct("PGPROC structures",
241 requestSize,
242 &found);
243
244 MemSet(ptr, 0, requestSize);
245
246 procs = (PGPROC *) ptr;
247 ptr = ptr + TotalProcs * sizeof(PGPROC);
248
249 ProcGlobal->allProcs = procs;
250 /* XXX allProcCount isn't really all of them; it excludes prepared xacts */
252
253 /*
254 * Allocate arrays mirroring PGPROC fields in a dense manner. See
255 * PROC_HDR.
256 *
257 * XXX: It might make sense to increase padding for these arrays, given
258 * how hotly they are accessed.
259 */
260 ProcGlobal->xids = (TransactionId *) ptr;
261 ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->xids));
262
264 ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->subxidStates));
265
266 ProcGlobal->statusFlags = (uint8 *) ptr;
267 ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->statusFlags));
268
269 /* make sure wer didn't overflow */
270 Assert((ptr > (char *) procs) && (ptr <= (char *) procs + requestSize));
271
272 /*
273 * Allocate arrays for fast-path locks. Those are variable-length, so
274 * can't be included in PGPROC directly. We allocate a separate piece of
275 * shared memory and then divide that between backends.
276 */
277 fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
278 fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
279
280 requestSize = FastPathLockShmemSize();
281
282 fpPtr = ShmemInitStruct("Fast-Path Lock Array",
283 requestSize,
284 &found);
285
286 MemSet(fpPtr, 0, requestSize);
287
288 /* For asserts checking we did not overflow. */
289 fpEndPtr = fpPtr + requestSize;
290
291 /* Reserve space for semaphores. */
293
294 for (i = 0; i < TotalProcs; i++)
295 {
296 PGPROC *proc = &procs[i];
297
298 /* Common initialization for all PGPROCs, regardless of type. */
299
300 /*
301 * Set the fast-path lock arrays, and move the pointer. We interleave
302 * the two arrays, to (hopefully) get some locality for each backend.
303 */
304 proc->fpLockBits = (uint64 *) fpPtr;
305 fpPtr += fpLockBitsSize;
306
307 proc->fpRelId = (Oid *) fpPtr;
308 fpPtr += fpRelIdSize;
309
310 Assert(fpPtr <= fpEndPtr);
311
312 /*
313 * Set up per-PGPROC semaphore, latch, and fpInfoLock. Prepared xact
314 * dummy PGPROCs don't need these though - they're never associated
315 * with a real process
316 */
318 {
319 proc->sem = PGSemaphoreCreate();
320 InitSharedLatch(&(proc->procLatch));
321 LWLockInitialize(&(proc->fpInfoLock), LWTRANCHE_LOCK_FASTPATH);
322 }
323
324 /*
325 * Newly created PGPROCs for normal backends, autovacuum workers,
326 * special workers, bgworkers, and walsenders must be queued up on the
327 * appropriate free list. Because there can only ever be a small,
328 * fixed number of auxiliary processes, no free list is used in that
329 * case; InitAuxiliaryProcess() instead uses a linear search. PGPROCs
330 * for prepared transactions are added to a free list by
331 * TwoPhaseShmemInit().
332 */
333 if (i < MaxConnections)
334 {
335 /* PGPROC for normal backend, add to freeProcs list */
338 }
340 {
341 /* PGPROC for AV or special worker, add to autovacFreeProcs list */
344 }
346 {
347 /* PGPROC for bgworker, add to bgworkerFreeProcs list */
350 }
351 else if (i < MaxBackends)
352 {
353 /* PGPROC for walsender, add to walsenderFreeProcs list */
356 }
357
358 /* Initialize myProcLocks[] shared memory queues. */
359 for (j = 0; j < NUM_LOCK_PARTITIONS; j++)
360 dlist_init(&(proc->myProcLocks[j]));
361
362 /* Initialize lockGroupMembers list. */
364
365 /*
366 * Initialize the atomic variables, otherwise, it won't be safe to
367 * access them for backends that aren't currently in use.
368 */
371 pg_atomic_init_u64(&(proc->waitStart), 0);
372 }
373
374 /* Should have consumed exactly the expected amount of fast-path memory. */
375 Assert(fpPtr == fpEndPtr);
376
377 /*
378 * Save pointers to the blocks of PGPROC structures reserved for auxiliary
379 * processes and prepared transactions.
380 */
381 AuxiliaryProcs = &procs[MaxBackends];
383
384 /* Create ProcStructLock spinlock, too */
385 ProcStructLock = (slock_t *) ShmemInitStruct("ProcStructLock spinlock",
386 sizeof(slock_t),
387 &found);
389}
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:219
static void pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:451
int autovacuum_worker_slots
Definition: autovacuum.c:118
uint8_t uint8
Definition: c.h:539
#define MemSet(start, val, len)
Definition: c.h:1022
uint32 TransactionId
Definition: c.h:660
int MaxConnections
Definition: globals.c:143
int max_worker_processes
Definition: globals.c:144
static void dlist_init(dlist_head *head)
Definition: ilist.h:314
int j
Definition: isn.c:78
void InitSharedLatch(Latch *latch)
Definition: latch.c:93
struct PGPROC PGPROC
Definition: lock.h:30
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:698
void PGReserveSemaphores(int maxSemas)
Definition: posix_sema.c:196
PGSemaphore PGSemaphoreCreate(void)
Definition: posix_sema.c:257
#define NUM_SPECIAL_WORKER_PROCS
Definition: proc.h:450
#define DEFAULT_SPINS_PER_DELAY
Definition: s_lock.h:702
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:389
#define SpinLockInit(lock)
Definition: spin.h:57
PGPROC * PreparedXactProcs
Definition: proc.c:81
static Size PGProcShmemSize(void)
Definition: proc.c:98
static Size FastPathLockShmemSize(void)
Definition: proc.c:116
int ProcGlobalSemas(void)
Definition: proc.c:159
LWLock fpInfoLock
Definition: proc.h:310
Oid * fpRelId
Definition: proc.h:312
uint64 * fpLockBits
Definition: proc.h:311
uint8 * statusFlags
Definition: proc.h:403
XidCacheStatus * subxidStates
Definition: proc.h:397
ProcNumber checkpointerProc
Definition: proc.h:425
PGPROC * allProcs
Definition: proc.h:388
pg_atomic_uint32 clogGroupFirst
Definition: proc.h:418
TransactionId * xids
Definition: proc.h:391
ProcNumber walwriterProc
Definition: proc.h:424
pg_atomic_uint32 procArrayGroupFirst
Definition: proc.h:416
uint32 allProcCount
Definition: proc.h:406

References PROC_HDR::allProcCount, PROC_HDR::allProcs, Assert(), PROC_HDR::autovacFreeProcs, autovacuum_worker_slots, AuxiliaryProcs, PROC_HDR::bgworkerFreeProcs, PROC_HDR::checkpointerProc, PROC_HDR::clogGroupFirst, PGPROC::clogGroupNext, DEFAULT_SPINS_PER_DELAY, dlist_init(), dlist_push_tail(), FastPathLockGroupsPerBackend, FastPathLockShmemSize(), FastPathLockSlotsPerBackend, PGPROC::fpInfoLock, PGPROC::fpLockBits, PGPROC::fpRelId, PROC_HDR::freeProcs, i, InitSharedLatch(), INVALID_PROC_NUMBER, j, PGPROC::links, PGPROC::lockGroupMembers, LWLockInitialize(), max_prepared_xacts, max_worker_processes, MAXALIGN, MaxBackends, MaxConnections, MemSet, PGPROC::myProcLocks, NUM_AUXILIARY_PROCS, NUM_LOCK_PARTITIONS, NUM_SPECIAL_WORKER_PROCS, pg_atomic_init_u32(), pg_atomic_init_u64(), PG_USED_FOR_ASSERTS_ONLY, PGProcShmemSize(), PGReserveSemaphores(), PGSemaphoreCreate(), PreparedXactProcs, PROC_HDR::procArrayGroupFirst, PGPROC::procArrayGroupNext, ProcGlobal, PGPROC::procgloballist, ProcGlobalSemas(), PGPROC::procLatch, ProcStructLock, PGPROC::sem, ShmemInitStruct(), SpinLockInit, PROC_HDR::spins_per_delay, PROC_HDR::startupBufferPinWaitBufId, PROC_HDR::statusFlags, PROC_HDR::subxidStates, PGPROC::waitStart, PROC_HDR::walsenderFreeProcs, PROC_HDR::walwriterProc, and PROC_HDR::xids.

Referenced by CreateOrAttachShmemStructs().

◆ JoinWaitQueue()

ProcWaitStatus JoinWaitQueue ( LOCALLOCK locallock,
LockMethod  lockMethodTable,
bool  dontWait 
)

Definition at line 1150 of file proc.c.

1151{
1152 LOCKMODE lockmode = locallock->tag.mode;
1153 LOCK *lock = locallock->lock;
1154 PROCLOCK *proclock = locallock->proclock;
1155 uint32 hashcode = locallock->hashcode;
1156 LWLock *partitionLock PG_USED_FOR_ASSERTS_ONLY = LockHashPartitionLock(hashcode);
1157 dclist_head *waitQueue = &lock->waitProcs;
1158 PGPROC *insert_before = NULL;
1159 LOCKMASK myProcHeldLocks;
1160 LOCKMASK myHeldLocks;
1161 bool early_deadlock = false;
1162 PGPROC *leader = MyProc->lockGroupLeader;
1163
1164 Assert(LWLockHeldByMeInMode(partitionLock, LW_EXCLUSIVE));
1165
1166 /*
1167 * Set bitmask of locks this process already holds on this object.
1168 */
1169 myHeldLocks = MyProc->heldLocks = proclock->holdMask;
1170
1171 /*
1172 * Determine which locks we're already holding.
1173 *
1174 * If group locking is in use, locks held by members of my locking group
1175 * need to be included in myHeldLocks. This is not required for relation
1176 * extension lock which conflict among group members. However, including
1177 * them in myHeldLocks will give group members the priority to get those
1178 * locks as compared to other backends which are also trying to acquire
1179 * those locks. OTOH, we can avoid giving priority to group members for
1180 * that kind of locks, but there doesn't appear to be a clear advantage of
1181 * the same.
1182 */
1183 myProcHeldLocks = proclock->holdMask;
1184 myHeldLocks = myProcHeldLocks;
1185 if (leader != NULL)
1186 {
1187 dlist_iter iter;
1188
1189 dlist_foreach(iter, &lock->procLocks)
1190 {
1191 PROCLOCK *otherproclock;
1192
1193 otherproclock = dlist_container(PROCLOCK, lockLink, iter.cur);
1194
1195 if (otherproclock->groupLeader == leader)
1196 myHeldLocks |= otherproclock->holdMask;
1197 }
1198 }
1199
1200 /*
1201 * Determine where to add myself in the wait queue.
1202 *
1203 * Normally I should go at the end of the queue. However, if I already
1204 * hold locks that conflict with the request of any previous waiter, put
1205 * myself in the queue just in front of the first such waiter. This is not
1206 * a necessary step, since deadlock detection would move me to before that
1207 * waiter anyway; but it's relatively cheap to detect such a conflict
1208 * immediately, and avoid delaying till deadlock timeout.
1209 *
1210 * Special case: if I find I should go in front of some waiter, check to
1211 * see if I conflict with already-held locks or the requests before that
1212 * waiter. If not, then just grant myself the requested lock immediately.
1213 * This is the same as the test for immediate grant in LockAcquire, except
1214 * we are only considering the part of the wait queue before my insertion
1215 * point.
1216 */
1217 if (myHeldLocks != 0 && !dclist_is_empty(waitQueue))
1218 {
1219 LOCKMASK aheadRequests = 0;
1220 dlist_iter iter;
1221
1222 dclist_foreach(iter, waitQueue)
1223 {
1224 PGPROC *proc = dlist_container(PGPROC, links, iter.cur);
1225
1226 /*
1227 * If we're part of the same locking group as this waiter, its
1228 * locks neither conflict with ours nor contribute to
1229 * aheadRequests.
1230 */
1231 if (leader != NULL && leader == proc->lockGroupLeader)
1232 continue;
1233
1234 /* Must he wait for me? */
1235 if (lockMethodTable->conflictTab[proc->waitLockMode] & myHeldLocks)
1236 {
1237 /* Must I wait for him ? */
1238 if (lockMethodTable->conflictTab[lockmode] & proc->heldLocks)
1239 {
1240 /*
1241 * Yes, so we have a deadlock. Easiest way to clean up
1242 * correctly is to call RemoveFromWaitQueue(), but we
1243 * can't do that until we are *on* the wait queue. So, set
1244 * a flag to check below, and break out of loop. Also,
1245 * record deadlock info for later message.
1246 */
1247 RememberSimpleDeadLock(MyProc, lockmode, lock, proc);
1248 early_deadlock = true;
1249 break;
1250 }
1251 /* I must go before this waiter. Check special case. */
1252 if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1253 !LockCheckConflicts(lockMethodTable, lockmode, lock,
1254 proclock))
1255 {
1256 /* Skip the wait and just grant myself the lock. */
1257 GrantLock(lock, proclock, lockmode);
1258 return PROC_WAIT_STATUS_OK;
1259 }
1260
1261 /* Put myself into wait queue before conflicting process */
1262 insert_before = proc;
1263 break;
1264 }
1265 /* Nope, so advance to next waiter */
1266 aheadRequests |= LOCKBIT_ON(proc->waitLockMode);
1267 }
1268 }
1269
1270 /*
1271 * If we detected deadlock, give up without waiting. This must agree with
1272 * CheckDeadLock's recovery code.
1273 */
1274 if (early_deadlock)
1276
1277 /*
1278 * At this point we know that we'd really need to sleep. If we've been
1279 * commanded not to do that, bail out.
1280 */
1281 if (dontWait)
1283
1284 /*
1285 * Insert self into queue, at the position determined above.
1286 */
1287 if (insert_before)
1288 dclist_insert_before(waitQueue, &insert_before->links, &MyProc->links);
1289 else
1290 dclist_push_tail(waitQueue, &MyProc->links);
1291
1292 lock->waitMask |= LOCKBIT_ON(lockmode);
1293
1294 /* Set up wait information in PGPROC object, too */
1295 MyProc->heldLocks = myProcHeldLocks;
1296 MyProc->waitLock = lock;
1297 MyProc->waitProcLock = proclock;
1298 MyProc->waitLockMode = lockmode;
1299
1301
1303}
void RememberSimpleDeadLock(PGPROC *proc1, LOCKMODE lockmode, LOCK *lock, PGPROC *proc2)
Definition: deadlock.c:1147
static void dclist_push_tail(dclist_head *head, dlist_node *node)
Definition: ilist.h:709
static bool dclist_is_empty(const dclist_head *head)
Definition: ilist.h:682
static void dclist_insert_before(dclist_head *head, dlist_node *before, dlist_node *node)
Definition: ilist.h:745
#define dclist_foreach(iter, lhead)
Definition: ilist.h:970
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
Definition: lock.c:1658
bool LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
Definition: lock.c:1529
#define LOCKBIT_ON(lockmode)
Definition: lock.h:86
int LOCKMODE
Definition: lockdefs.h:26
int LOCKMASK
Definition: lockdefs.h:25
bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:2021
@ PROC_WAIT_STATUS_WAITING
Definition: proc.h:142
@ PROC_WAIT_STATUS_ERROR
Definition: proc.h:143
LOCKMODE mode
Definition: lock.h:413
PROCLOCK * proclock
Definition: lock.h:436
LOCALLOCKTAG tag
Definition: lock.h:431
dclist_head waitProcs
Definition: lock.h:319
LOCKMASK waitMask
Definition: lock.h:317
const LOCKMASK * conflictTab
Definition: lock.h:113
LOCKMODE waitLockMode
Definition: proc.h:251
LOCKMASK heldLocks
Definition: proc.h:252
LOCKMASK holdMask
Definition: lock.h:378
PGPROC * groupLeader
Definition: lock.h:377

References Assert(), LockMethodData::conflictTab, dlist_iter::cur, dclist_foreach, dclist_insert_before(), dclist_is_empty(), dclist_push_tail(), dlist_container, dlist_foreach, GrantLock(), PROCLOCK::groupLeader, LOCALLOCK::hashcode, PGPROC::heldLocks, PROCLOCK::holdMask, PGPROC::links, links, LOCALLOCK::lock, LOCKBIT_ON, LockCheckConflicts(), PGPROC::lockGroupLeader, LockHashPartitionLock, LW_EXCLUSIVE, LWLockHeldByMeInMode(), LOCALLOCKTAG::mode, MyProc, PG_USED_FOR_ASSERTS_ONLY, PROC_WAIT_STATUS_ERROR, PROC_WAIT_STATUS_OK, PROC_WAIT_STATUS_WAITING, LOCALLOCK::proclock, LOCK::procLocks, RememberSimpleDeadLock(), LOCALLOCK::tag, PGPROC::waitLock, PGPROC::waitLockMode, LOCK::waitMask, PGPROC::waitProcLock, LOCK::waitProcs, and PGPROC::waitStatus.

Referenced by LockAcquireExtended().

◆ LockErrorCleanup()

void LockErrorCleanup ( void  )

Definition at line 818 of file proc.c.

819{
820 LOCALLOCK *lockAwaited;
821 LWLock *partitionLock;
822 DisableTimeoutParams timeouts[2];
823
825
827
828 /* Nothing to do if we weren't waiting for a lock */
829 lockAwaited = GetAwaitedLock();
830 if (lockAwaited == NULL)
831 {
833 return;
834 }
835
836 /*
837 * Turn off the deadlock and lock timeout timers, if they are still
838 * running (see ProcSleep). Note we must preserve the LOCK_TIMEOUT
839 * indicator flag, since this function is executed before
840 * ProcessInterrupts when responding to SIGINT; else we'd lose the
841 * knowledge that the SIGINT came from a lock timeout and not an external
842 * source.
843 */
844 timeouts[0].id = DEADLOCK_TIMEOUT;
845 timeouts[0].keep_indicator = false;
846 timeouts[1].id = LOCK_TIMEOUT;
847 timeouts[1].keep_indicator = true;
848 disable_timeouts(timeouts, 2);
849
850 /* Unlink myself from the wait queue, if on it (might not be anymore!) */
851 partitionLock = LockHashPartitionLock(lockAwaited->hashcode);
852 LWLockAcquire(partitionLock, LW_EXCLUSIVE);
853
855 {
856 /* We could not have been granted the lock yet */
857 RemoveFromWaitQueue(MyProc, lockAwaited->hashcode);
858 }
859 else
860 {
861 /*
862 * Somebody kicked us off the lock queue already. Perhaps they
863 * granted us the lock, or perhaps they detected a deadlock. If they
864 * did grant us the lock, we'd better remember it in our local lock
865 * table.
866 */
869 }
870
872
873 LWLockRelease(partitionLock);
874
876}
static bool dlist_node_is_detached(const dlist_node *node)
Definition: ilist.h:525
void GrantAwaitedLock(void)
Definition: lock.c:1889
void ResetAwaitedLock(void)
Definition: lock.c:1907
void AbortStrongLockAcquire(void)
Definition: lock.c:1860
LOCALLOCK * GetAwaitedLock(void)
Definition: lock.c:1898
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:136
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:134
TimeoutId id
Definition: timeout.h:71
void disable_timeouts(const DisableTimeoutParams *timeouts, int count)
Definition: timeout.c:718
@ LOCK_TIMEOUT
Definition: timeout.h:28
@ DEADLOCK_TIMEOUT
Definition: timeout.h:27

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

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

◆ PGProcShmemSize()

static Size PGProcShmemSize ( void  )
static

Definition at line 98 of file proc.c.

99{
100 Size size = 0;
101 Size TotalProcs =
103
104 size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC)));
105 size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids)));
106 size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates)));
107 size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags)));
108
109 return size;
110}

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

Referenced by InitProcGlobal(), and ProcGlobalShmemSize().

◆ ProcGlobalSemas()

int ProcGlobalSemas ( void  )

Definition at line 159 of file proc.c.

160{
161 /*
162 * We need a sema per backend (including autovacuum), plus one for each
163 * auxiliary process.
164 */
166}

References MaxBackends, and NUM_AUXILIARY_PROCS.

Referenced by InitializeShmemGUCs(), InitProcGlobal(), and ProcGlobalShmemSize().

◆ ProcGlobalShmemSize()

Size ProcGlobalShmemSize ( void  )

Definition at line 140 of file proc.c.

141{
142 Size size = 0;
143
144 /* ProcGlobal */
145 size = add_size(size, sizeof(PROC_HDR));
146 size = add_size(size, sizeof(slock_t));
147
149 size = add_size(size, PGProcShmemSize());
150 size = add_size(size, FastPathLockShmemSize());
151
152 return size;
153}
Size PGSemaphoreShmemSize(int maxSemas)
Definition: posix_sema.c:165

References add_size(), FastPathLockShmemSize(), PGProcShmemSize(), PGSemaphoreShmemSize(), and ProcGlobalSemas().

Referenced by CalculateShmemSize().

◆ ProcKill()

static void ProcKill ( int  code,
Datum  arg 
)
static

Definition at line 924 of file proc.c.

925{
926 PGPROC *proc;
927 dlist_head *procgloballist;
928
929 Assert(MyProc != NULL);
930
931 /* not safe if forked by system(), etc. */
932 if (MyProc->pid != (int) getpid())
933 elog(PANIC, "ProcKill() called in child process");
934
935 /* Make sure we're out of the sync rep lists */
937
938#ifdef USE_ASSERT_CHECKING
939 {
940 int i;
941
942 /* Last process should have released all locks. */
943 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
945 }
946#endif
947
948 /*
949 * Release any LW locks I am holding. There really shouldn't be any, but
950 * it's cheap to check again before we cut the knees off the LWLock
951 * facility by releasing our PGPROC ...
952 */
954
955 /*
956 * Cleanup waiting for LSN if any.
957 */
959
960 /* Cancel any pending condition variable sleep, too */
962
963 /*
964 * Detach from any lock group of which we are a member. If the leader
965 * exits before all other group members, its PGPROC will remain allocated
966 * until the last group process exits; that process must return the
967 * leader's PGPROC to the appropriate list.
968 */
969 if (MyProc->lockGroupLeader != NULL)
970 {
971 PGPROC *leader = MyProc->lockGroupLeader;
972 LWLock *leader_lwlock = LockHashPartitionLockByProc(leader);
973
974 LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
977 if (dlist_is_empty(&leader->lockGroupMembers))
978 {
979 leader->lockGroupLeader = NULL;
980 if (leader != MyProc)
981 {
982 procgloballist = leader->procgloballist;
983
984 /* Leader exited first; return its PGPROC. */
986 dlist_push_head(procgloballist, &leader->links);
988 }
989 }
990 else if (leader != MyProc)
991 MyProc->lockGroupLeader = NULL;
992 LWLockRelease(leader_lwlock);
993 }
994
995 /*
996 * Reset MyLatch to the process local one. This is so that signal
997 * handlers et al can continue using the latch after the shared latch
998 * isn't ours anymore.
999 *
1000 * Similarly, stop reporting wait events to MyProc->wait_event_info.
1001 *
1002 * After that clear MyProc and disown the shared latch.
1003 */
1006
1007 proc = MyProc;
1008 MyProc = NULL;
1010 DisownLatch(&proc->procLatch);
1011
1012 /* Mark the proc no longer in use */
1013 proc->pid = 0;
1016
1017 procgloballist = proc->procgloballist;
1019
1020 /*
1021 * If we're still a member of a locking group, that means we're a leader
1022 * which has somehow exited before its children. The last remaining child
1023 * will release our PGPROC. Otherwise, release it now.
1024 */
1025 if (proc->lockGroupLeader == NULL)
1026 {
1027 /* Since lockGroupLeader is NULL, lockGroupMembers should be empty. */
1029
1030 /* Return PGPROC structure (and semaphore) to appropriate freelist */
1031 dlist_push_tail(procgloballist, &proc->links);
1032 }
1033
1034 /* Update shared estimate of spins_per_delay */
1036
1038
1039 /* wake autovac launcher if needed -- see comments in FreeWorkerInfo */
1040 if (AutovacuumLauncherPid != 0)
1042}
int AutovacuumLauncherPid
Definition: autovacuum.c:327
static void dlist_delete(dlist_node *node)
Definition: ilist.h:405
void SyncRepCleanupAtProcExit(void)
Definition: syncrep.c:416
#define kill(pid, sig)
Definition: win32_port.h:493
#define SIGUSR2
Definition: win32_port.h:171
void WaitLSNCleanup(void)
Definition: xlogwait.c:290

References Assert(), AutovacuumLauncherPid, ConditionVariableCancelSleep(), DisownLatch(), dlist_delete(), dlist_is_empty(), dlist_push_head(), dlist_push_tail(), elog, i, INVALID_PROC_NUMBER, InvalidTransactionId, kill, PGPROC::links, PGPROC::lockGroupLeader, PGPROC::lockGroupLink, PGPROC::lockGroupMembers, LockHashPartitionLockByProc, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), LWLockReleaseAll(), PGPROC::lxid, MyProc, PGPROC::myProcLocks, MyProcNumber, NUM_LOCK_PARTITIONS, PANIC, pgstat_reset_wait_event_storage(), PGPROC::pid, ProcGlobal, PGPROC::procgloballist, PGPROC::procLatch, PGPROC::procNumber, ProcStructLock, SIGUSR2, SpinLockAcquire, SpinLockRelease, PROC_HDR::spins_per_delay, SwitchBackToLocalLatch(), SyncRepCleanupAtProcExit(), update_spins_per_delay(), PGPROC::vxid, and WaitLSNCleanup().

Referenced by InitProcess().

◆ ProcLockWakeup()

void ProcLockWakeup ( LockMethod  lockMethodTable,
LOCK lock 
)

Definition at line 1749 of file proc.c.

1750{
1751 dclist_head *waitQueue = &lock->waitProcs;
1752 LOCKMASK aheadRequests = 0;
1753 dlist_mutable_iter miter;
1754
1755 if (dclist_is_empty(waitQueue))
1756 return;
1757
1758 dclist_foreach_modify(miter, waitQueue)
1759 {
1760 PGPROC *proc = dlist_container(PGPROC, links, miter.cur);
1761 LOCKMODE lockmode = proc->waitLockMode;
1762
1763 /*
1764 * Waken if (a) doesn't conflict with requests of earlier waiters, and
1765 * (b) doesn't conflict with already-held locks.
1766 */
1767 if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1768 !LockCheckConflicts(lockMethodTable, lockmode, lock,
1769 proc->waitProcLock))
1770 {
1771 /* OK to waken */
1772 GrantLock(lock, proc->waitProcLock, lockmode);
1773 /* removes proc from the lock's waiting process queue */
1775 }
1776 else
1777 {
1778 /*
1779 * Lock conflicts: Don't wake, but remember requested mode for
1780 * later checks.
1781 */
1782 aheadRequests |= LOCKBIT_ON(lockmode);
1783 }
1784 }
1785}
#define dclist_foreach_modify(iter, lhead)
Definition: ilist.h:973
void ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus)
Definition: proc.c:1721
dlist_node * cur
Definition: ilist.h:200

References LockMethodData::conflictTab, dlist_mutable_iter::cur, dclist_foreach_modify, dclist_is_empty(), dlist_container, GrantLock(), links, LOCKBIT_ON, LockCheckConflicts(), PROC_WAIT_STATUS_OK, ProcWakeup(), PGPROC::waitLockMode, PGPROC::waitProcLock, and LOCK::waitProcs.

Referenced by CleanUpLock(), and DeadLockCheck().

◆ ProcReleaseLocks()

void ProcReleaseLocks ( bool  isCommit)

Definition at line 896 of file proc.c.

897{
898 if (!MyProc)
899 return;
900 /* If waiting, get off wait queue (should only be needed after error) */
902 /* Release standard locks, including session-level if aborting */
904 /* Release transaction-level advisory locks */
906}
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition: lock.c:2307
#define DEFAULT_LOCKMETHOD
Definition: lock.h:127
#define USER_LOCKMETHOD
Definition: lock.h:128
void LockErrorCleanup(void)
Definition: proc.c:818

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

Referenced by ResourceOwnerReleaseInternal().

◆ ProcSendSignal()

void ProcSendSignal ( ProcNumber  procNumber)

Definition at line 1996 of file proc.c.

1997{
1998 if (procNumber < 0 || procNumber >= ProcGlobal->allProcCount)
1999 elog(ERROR, "procNumber out of range");
2000
2001 SetLatch(&ProcGlobal->allProcs[procNumber].procLatch);
2002}

References PROC_HDR::allProcCount, PROC_HDR::allProcs, elog, ERROR, ProcGlobal, PGPROC::procLatch, and SetLatch().

Referenced by ReleasePredicateLocks(), and WakePinCountWaiter().

◆ ProcSleep()

ProcWaitStatus ProcSleep ( LOCALLOCK locallock)

Definition at line 1319 of file proc.c.

1320{
1321 LOCKMODE lockmode = locallock->tag.mode;
1322 LOCK *lock = locallock->lock;
1323 uint32 hashcode = locallock->hashcode;
1324 LWLock *partitionLock = LockHashPartitionLock(hashcode);
1325 TimestampTz standbyWaitStart = 0;
1326 bool allow_autovacuum_cancel = true;
1327 bool logged_recovery_conflict = false;
1328 ProcWaitStatus myWaitStatus;
1329
1330 /* The caller must've armed the on-error cleanup mechanism */
1331 Assert(GetAwaitedLock() == locallock);
1332 Assert(!LWLockHeldByMe(partitionLock));
1333
1334 /*
1335 * Now that we will successfully clean up after an ereport, it's safe to
1336 * check to see if there's a buffer pin deadlock against the Startup
1337 * process. Of course, that's only necessary if we're doing Hot Standby
1338 * and are not the Startup process ourselves.
1339 */
1342
1343 /* Reset deadlock_state before enabling the timeout handler */
1345 got_deadlock_timeout = false;
1346
1347 /*
1348 * Set timer so we can wake up after awhile and check for a deadlock. If a
1349 * deadlock is detected, the handler sets MyProc->waitStatus =
1350 * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure
1351 * rather than success.
1352 *
1353 * By delaying the check until we've waited for a bit, we can avoid
1354 * running the rather expensive deadlock-check code in most cases.
1355 *
1356 * If LockTimeout is set, also enable the timeout for that. We can save a
1357 * few cycles by enabling both timeout sources in one call.
1358 *
1359 * If InHotStandby we set lock waits slightly later for clarity with other
1360 * code.
1361 */
1362 if (!InHotStandby)
1363 {
1364 if (LockTimeout > 0)
1365 {
1366 EnableTimeoutParams timeouts[2];
1367
1368 timeouts[0].id = DEADLOCK_TIMEOUT;
1369 timeouts[0].type = TMPARAM_AFTER;
1370 timeouts[0].delay_ms = DeadlockTimeout;
1371 timeouts[1].id = LOCK_TIMEOUT;
1372 timeouts[1].type = TMPARAM_AFTER;
1373 timeouts[1].delay_ms = LockTimeout;
1374 enable_timeouts(timeouts, 2);
1375 }
1376 else
1378
1379 /*
1380 * Use the current time obtained for the deadlock timeout timer as
1381 * waitStart (i.e., the time when this process started waiting for the
1382 * lock). Since getting the current time newly can cause overhead, we
1383 * reuse the already-obtained time to avoid that overhead.
1384 *
1385 * Note that waitStart is updated without holding the lock table's
1386 * partition lock, to avoid the overhead by additional lock
1387 * acquisition. This can cause "waitstart" in pg_locks to become NULL
1388 * for a very short period of time after the wait started even though
1389 * "granted" is false. This is OK in practice because we can assume
1390 * that users are likely to look at "waitstart" when waiting for the
1391 * lock for a long time.
1392 */
1395 }
1397 {
1398 /*
1399 * Set the wait start timestamp if logging is enabled and in hot
1400 * standby.
1401 */
1402 standbyWaitStart = GetCurrentTimestamp();
1403 }
1404
1405 /*
1406 * If somebody wakes us between LWLockRelease and WaitLatch, the latch
1407 * will not wait. But a set latch does not necessarily mean that the lock
1408 * is free now, as there are many other sources for latch sets than
1409 * somebody releasing the lock.
1410 *
1411 * We process interrupts whenever the latch has been set, so cancel/die
1412 * interrupts are processed quickly. This means we must not mind losing
1413 * control to a cancel/die interrupt here. We don't, because we have no
1414 * shared-state-change work to do after being granted the lock (the
1415 * grantor did it all). We do have to worry about canceling the deadlock
1416 * timeout and updating the locallock table, but if we lose control to an
1417 * error, LockErrorCleanup will fix that up.
1418 */
1419 do
1420 {
1421 if (InHotStandby)
1422 {
1423 bool maybe_log_conflict =
1424 (standbyWaitStart != 0 && !logged_recovery_conflict);
1425
1426 /* Set a timer and wait for that or for the lock to be granted */
1428 maybe_log_conflict);
1429
1430 /*
1431 * Emit the log message if the startup process is waiting longer
1432 * than deadlock_timeout for recovery conflict on lock.
1433 */
1434 if (maybe_log_conflict)
1435 {
1437
1438 if (TimestampDifferenceExceeds(standbyWaitStart, now,
1440 {
1441 VirtualTransactionId *vxids;
1442 int cnt;
1443
1444 vxids = GetLockConflicts(&locallock->tag.lock,
1445 AccessExclusiveLock, &cnt);
1446
1447 /*
1448 * Log the recovery conflict and the list of PIDs of
1449 * backends holding the conflicting lock. Note that we do
1450 * logging even if there are no such backends right now
1451 * because the startup process here has already waited
1452 * longer than deadlock_timeout.
1453 */
1455 standbyWaitStart, now,
1456 cnt > 0 ? vxids : NULL, true);
1457 logged_recovery_conflict = true;
1458 }
1459 }
1460 }
1461 else
1462 {
1464 PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
1466 /* check for deadlocks first, as that's probably log-worthy */
1468 {
1469 CheckDeadLock();
1470 got_deadlock_timeout = false;
1471 }
1473 }
1474
1475 /*
1476 * waitStatus could change from PROC_WAIT_STATUS_WAITING to something
1477 * else asynchronously. Read it just once per loop to prevent
1478 * surprising behavior (such as missing log messages).
1479 */
1480 myWaitStatus = *((volatile ProcWaitStatus *) &MyProc->waitStatus);
1481
1482 /*
1483 * If we are not deadlocked, but are waiting on an autovacuum-induced
1484 * task, send a signal to interrupt it.
1485 */
1486 if (deadlock_state == DS_BLOCKED_BY_AUTOVACUUM && allow_autovacuum_cancel)
1487 {
1489 uint8 statusFlags;
1490 uint8 lockmethod_copy;
1491 LOCKTAG locktag_copy;
1492
1493 /*
1494 * Grab info we need, then release lock immediately. Note this
1495 * coding means that there is a tiny chance that the process
1496 * terminates its current transaction and starts a different one
1497 * before we have a change to send the signal; the worst possible
1498 * consequence is that a for-wraparound vacuum is canceled. But
1499 * that could happen in any case unless we were to do kill() with
1500 * the lock held, which is much more undesirable.
1501 */
1502 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1503 statusFlags = ProcGlobal->statusFlags[autovac->pgxactoff];
1504 lockmethod_copy = lock->tag.locktag_lockmethodid;
1505 locktag_copy = lock->tag;
1506 LWLockRelease(ProcArrayLock);
1507
1508 /*
1509 * Only do it if the worker is not working to protect against Xid
1510 * wraparound.
1511 */
1512 if ((statusFlags & PROC_IS_AUTOVACUUM) &&
1513 !(statusFlags & PROC_VACUUM_FOR_WRAPAROUND))
1514 {
1515 int pid = autovac->pid;
1516
1517 /* report the case, if configured to do so */
1519 {
1520 StringInfoData locktagbuf;
1521 StringInfoData logbuf; /* errdetail for server log */
1522
1523 initStringInfo(&locktagbuf);
1524 initStringInfo(&logbuf);
1525 DescribeLockTag(&locktagbuf, &locktag_copy);
1526 appendStringInfo(&logbuf,
1527 "Process %d waits for %s on %s.",
1528 MyProcPid,
1529 GetLockmodeName(lockmethod_copy, lockmode),
1530 locktagbuf.data);
1531
1533 (errmsg_internal("sending cancel to blocking autovacuum PID %d",
1534 pid),
1535 errdetail_log("%s", logbuf.data)));
1536
1537 pfree(locktagbuf.data);
1538 pfree(logbuf.data);
1539 }
1540
1541 /* send the autovacuum worker Back to Old Kent Road */
1542 if (kill(pid, SIGINT) < 0)
1543 {
1544 /*
1545 * There's a race condition here: once we release the
1546 * ProcArrayLock, it's possible for the autovac worker to
1547 * close up shop and exit before we can do the kill().
1548 * Therefore, we do not whinge about no-such-process.
1549 * Other errors such as EPERM could conceivably happen if
1550 * the kernel recycles the PID fast enough, but such cases
1551 * seem improbable enough that it's probably best to issue
1552 * a warning if we see some other errno.
1553 */
1554 if (errno != ESRCH)
1556 (errmsg("could not send signal to process %d: %m",
1557 pid)));
1558 }
1559 }
1560
1561 /* prevent signal from being sent again more than once */
1562 allow_autovacuum_cancel = false;
1563 }
1564
1565 /*
1566 * If awoken after the deadlock check interrupt has run, and
1567 * log_lock_waits is on, then report about the wait.
1568 */
1570 {
1572 lock_waiters_sbuf,
1573 lock_holders_sbuf;
1574 const char *modename;
1575 long secs;
1576 int usecs;
1577 long msecs;
1578 int lockHoldersNum = 0;
1579
1581 initStringInfo(&lock_waiters_sbuf);
1582 initStringInfo(&lock_holders_sbuf);
1583
1584 DescribeLockTag(&buf, &locallock->tag.lock);
1585 modename = GetLockmodeName(locallock->tag.lock.locktag_lockmethodid,
1586 lockmode);
1589 &secs, &usecs);
1590 msecs = secs * 1000 + usecs / 1000;
1591 usecs = usecs % 1000;
1592
1593 /* Gather a list of all lock holders and waiters */
1594 LWLockAcquire(partitionLock, LW_SHARED);
1595 GetLockHoldersAndWaiters(locallock, &lock_holders_sbuf,
1596 &lock_waiters_sbuf, &lockHoldersNum);
1597 LWLockRelease(partitionLock);
1598
1600 ereport(LOG,
1601 (errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
1602 MyProcPid, modename, buf.data, msecs, usecs),
1603 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1604 "Processes holding the lock: %s. Wait queue: %s.",
1605 lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1606 else if (deadlock_state == DS_HARD_DEADLOCK)
1607 {
1608 /*
1609 * This message is a bit redundant with the error that will be
1610 * reported subsequently, but in some cases the error report
1611 * might not make it to the log (eg, if it's caught by an
1612 * exception handler), and we want to ensure all long-wait
1613 * events get logged.
1614 */
1615 ereport(LOG,
1616 (errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
1617 MyProcPid, modename, buf.data, msecs, usecs),
1618 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1619 "Processes holding the lock: %s. Wait queue: %s.",
1620 lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1621 }
1622
1623 if (myWaitStatus == PROC_WAIT_STATUS_WAITING)
1624 ereport(LOG,
1625 (errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
1626 MyProcPid, modename, buf.data, msecs, usecs),
1627 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1628 "Processes holding the lock: %s. Wait queue: %s.",
1629 lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1630 else if (myWaitStatus == PROC_WAIT_STATUS_OK)
1631 ereport(LOG,
1632 (errmsg("process %d acquired %s on %s after %ld.%03d ms",
1633 MyProcPid, modename, buf.data, msecs, usecs)));
1634 else
1635 {
1636 Assert(myWaitStatus == PROC_WAIT_STATUS_ERROR);
1637
1638 /*
1639 * Currently, the deadlock checker always kicks its own
1640 * process, which means that we'll only see
1641 * PROC_WAIT_STATUS_ERROR when deadlock_state ==
1642 * DS_HARD_DEADLOCK, and there's no need to print redundant
1643 * messages. But for completeness and future-proofing, print
1644 * a message if it looks like someone else kicked us off the
1645 * lock.
1646 */
1648 ereport(LOG,
1649 (errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
1650 MyProcPid, modename, buf.data, msecs, usecs),
1651 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1652 "Processes holding the lock: %s. Wait queue: %s.",
1653 lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1654 }
1655
1656 /*
1657 * At this point we might still need to wait for the lock. Reset
1658 * state so we don't print the above messages again.
1659 */
1661
1662 pfree(buf.data);
1663 pfree(lock_holders_sbuf.data);
1664 pfree(lock_waiters_sbuf.data);
1665 }
1666 } while (myWaitStatus == PROC_WAIT_STATUS_WAITING);
1667
1668 /*
1669 * Disable the timers, if they are still running. As in LockErrorCleanup,
1670 * we must preserve the LOCK_TIMEOUT indicator flag: if a lock timeout has
1671 * already caused QueryCancelPending to become set, we want the cancel to
1672 * be reported as a lock timeout, not a user cancel.
1673 */
1674 if (!InHotStandby)
1675 {
1676 if (LockTimeout > 0)
1677 {
1678 DisableTimeoutParams timeouts[2];
1679
1680 timeouts[0].id = DEADLOCK_TIMEOUT;
1681 timeouts[0].keep_indicator = false;
1682 timeouts[1].id = LOCK_TIMEOUT;
1683 timeouts[1].keep_indicator = true;
1684 disable_timeouts(timeouts, 2);
1685 }
1686 else
1688 }
1689
1690 /*
1691 * Emit the log message if recovery conflict on lock was resolved but the
1692 * startup process waited longer than deadlock_timeout for it.
1693 */
1694 if (InHotStandby && logged_recovery_conflict)
1696 standbyWaitStart, GetCurrentTimestamp(),
1697 NULL, false);
1698
1699 /*
1700 * We don't have to do anything else, because the awaker did all the
1701 * necessary updates of the lock table and MyProc. (The caller is
1702 * responsible for updating the local lock table.)
1703 */
1704 return myWaitStatus;
1705}
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition: timestamp.c:1721
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
Definition: timestamp.c:1781
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1645
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1609
int64 TimestampTz
Definition: timestamp.h:39
PGPROC * GetBlockingAutoVacuumPgproc(void)
Definition: deadlock.c:290
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1170
bool message_level_is_interesting(int elevel)
Definition: elog.c:273
int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1285
int errdetail_log(const char *fmt,...)
Definition: elog.c:1264
#define LOG
Definition: elog.h:31
#define WARNING
Definition: elog.h:36
#define DEBUG1
Definition: elog.h:30
void ResetLatch(Latch *latch)
Definition: latch.c:374
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:172
void DescribeLockTag(StringInfo buf, const LOCKTAG *tag)
Definition: lmgr.c:1249
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
Definition: lock.c:3069
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
Definition: lock.c:4255
@ DS_BLOCKED_BY_AUTOVACUUM
Definition: lock.h:516
@ DS_NO_DEADLOCK
Definition: lock.h:513
@ DS_NOT_YET_CHECKED
Definition: lock.h:512
@ DS_SOFT_DEADLOCK
Definition: lock.h:514
#define AccessExclusiveLock
Definition: lockdefs.h:43
@ LW_SHARED
Definition: lwlock.h:113
void pfree(void *pointer)
Definition: mcxt.c:1594
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:123
static char * buf
Definition: pg_test_fsync.c:72
#define PROC_VACUUM_FOR_WRAPAROUND
Definition: proc.h:60
ProcWaitStatus
Definition: proc.h:140
@ PROCSIG_RECOVERY_CONFLICT_LOCK
Definition: procsignal.h:44
bool log_lock_waits
Definition: proc.c:64
void GetLockHoldersAndWaiters(LOCALLOCK *locallock, StringInfo lock_holders_sbuf, StringInfo lock_waiters_sbuf, int *lockHoldersNum)
Definition: proc.c:1910
int DeadlockTimeout
Definition: proc.c:58
static void CheckDeadLock(void)
Definition: proc.c:1797
int LockTimeout
Definition: proc.c:60
void CheckRecoveryConflictDeadlock(void)
Definition: standby.c:905
bool log_recovery_conflict_waits
Definition: standby.c:42
void LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
Definition: standby.c:274
void ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict)
Definition: standby.c:623
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
TimeoutType type
Definition: timeout.h:61
TimeoutId id
Definition: timeout.h:60
LOCKTAG lock
Definition: lock.h:412
Definition: lock.h:167
uint8 locktag_type
Definition: lock.h:172
uint8 locktag_lockmethodid
Definition: lock.h:173
int pgxactoff
Definition: proc.h:201
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:560
TimestampTz get_timeout_start_time(TimeoutId id)
Definition: timeout.c:813
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:685
void enable_timeouts(const EnableTimeoutParams *timeouts, int count)
Definition: timeout.c:630
@ TMPARAM_AFTER
Definition: timeout.h:53
#define PG_WAIT_LOCK
Definition: wait_classes.h:19
#define WL_EXIT_ON_PM_DEATH
Definition: waiteventset.h:39
#define WL_LATCH_SET
Definition: waiteventset.h:34
bool RecoveryInProgress(void)
Definition: xlog.c:6406
bool InRecovery
Definition: xlogutils.c:50
#define InHotStandby
Definition: xlogutils.h:60

References AccessExclusiveLock, appendStringInfo(), Assert(), buf, CHECK_FOR_INTERRUPTS, CheckDeadLock(), CheckRecoveryConflictDeadlock(), 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(), GetAwaitedLock(), GetBlockingAutoVacuumPgproc(), GetCurrentTimestamp(), GetLockConflicts(), GetLockHoldersAndWaiters(), GetLockmodeName(), got_deadlock_timeout, LOCALLOCK::hashcode, EnableTimeoutParams::id, DisableTimeoutParams::id, InHotStandby, initStringInfo(), InRecovery, DisableTimeoutParams::keep_indicator, kill, LOCALLOCKTAG::lock, LOCALLOCK::lock, LOCK_TIMEOUT, LockHashPartitionLock, LOCKTAG::locktag_lockmethodid, LOCKTAG::locktag_type, LockTimeout, LOG, log_lock_waits, log_recovery_conflict_waits, LogRecoveryConflict(), LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockHeldByMe(), LWLockRelease(), message_level_is_interesting(), LOCALLOCKTAG::mode, MyLatch, MyProc, MyProcPid, now(), 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, ProcGlobal, PROCSIG_RECOVERY_CONFLICT_LOCK, RecoveryInProgress(), ResetLatch(), ResolveRecoveryConflictWithLock(), PROC_HDR::statusFlags, LOCK::tag, LOCALLOCK::tag, TimestampDifference(), TimestampDifferenceExceeds(), TMPARAM_AFTER, EnableTimeoutParams::type, WaitLatch(), PGPROC::waitStart, PGPROC::waitStatus, WARNING, WL_EXIT_ON_PM_DEATH, and WL_LATCH_SET.

Referenced by WaitOnLock().

◆ ProcWaitForSignal()

void ProcWaitForSignal ( uint32  wait_event_info)

◆ ProcWakeup()

void ProcWakeup ( PGPROC proc,
ProcWaitStatus  waitStatus 
)

Definition at line 1721 of file proc.c.

1722{
1723 if (dlist_node_is_detached(&proc->links))
1724 return;
1725
1727
1728 /* Remove process from wait queue */
1730
1731 /* Clean up process' state and pass it the ok/fail signal */
1732 proc->waitLock = NULL;
1733 proc->waitProcLock = NULL;
1734 proc->waitStatus = waitStatus;
1736
1737 /* And awaken it */
1738 SetLatch(&proc->procLatch);
1739}
static void dclist_delete_from_thoroughly(dclist_head *head, dlist_node *node)
Definition: ilist.h:776

References Assert(), dclist_delete_from_thoroughly(), dlist_node_is_detached(), PGPROC::links, MyProc, pg_atomic_write_u64(), PROC_WAIT_STATUS_WAITING, PGPROC::procLatch, SetLatch(), PGPROC::waitLock, PGPROC::waitProcLock, LOCK::waitProcs, PGPROC::waitStart, and PGPROC::waitStatus.

Referenced by ProcLockWakeup().

◆ RemoveProcFromArray()

static void RemoveProcFromArray ( int  code,
Datum  arg 
)
static

Definition at line 913 of file proc.c.

914{
915 Assert(MyProc != NULL);
917}
void ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
Definition: procarray.c:565

References Assert(), InvalidTransactionId, MyProc, and ProcArrayRemove().

Referenced by InitProcessPhase2().

◆ SetStartupBufferPinWaitBufId()

void SetStartupBufferPinWaitBufId ( int  bufid)

Definition at line 759 of file proc.c.

760{
761 /* use volatile pointer to prevent code rearrangement */
762 volatile PROC_HDR *procglobal = ProcGlobal;
763
764 procglobal->startupBufferPinWaitBufId = bufid;
765}

References ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by LockBufferForCleanup().

Variable Documentation

◆ AuxiliaryProcs

NON_EXEC_STATIC PGPROC* AuxiliaryProcs = NULL

◆ deadlock_state

DeadLockState deadlock_state = DS_NOT_YET_CHECKED
static

Definition at line 83 of file proc.c.

Referenced by CheckDeadLock(), and ProcSleep().

◆ DeadlockTimeout

◆ got_deadlock_timeout

volatile sig_atomic_t got_deadlock_timeout
static

Definition at line 86 of file proc.c.

Referenced by CheckDeadLockAlert(), and ProcSleep().

◆ IdleInTransactionSessionTimeout

int IdleInTransactionSessionTimeout = 0

Definition at line 61 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

◆ IdleSessionTimeout

int IdleSessionTimeout = 0

Definition at line 63 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

◆ LockTimeout

int LockTimeout = 0

Definition at line 60 of file proc.c.

Referenced by ProcSleep().

◆ log_lock_waits

bool log_lock_waits = true

Definition at line 64 of file proc.c.

Referenced by ProcSleep().

◆ MyProc

PGPROC* MyProc = NULL

Definition at line 67 of file proc.c.

Referenced by _brin_parallel_build_main(), _bt_parallel_build_main(), _gin_parallel_build_main(), AbortTransaction(), AtEOSubXact_Namespace(), AtEOXact_Namespace(), AtEOXact_Snapshot(), attach_to_queues(), AutoVacWorkerMain(), AuxiliaryProcKill(), BaseInit(), BecomeLockGroupLeader(), BecomeLockGroupMember(), CheckDeadLock(), CommitTransaction(), ComputeXidHorizons(), ConditionVariableBroadcast(), consume_xids_common(), CountOtherDBBackends(), CreateReplicationSlot(), DefineIndex(), EndPrepare(), errdetail_abort(), exec_eval_simple_expr(), exec_simple_check_plan(), exec_stmt_call(), ExecParallelGetReceiver(), ExecParallelSetupTupleQueues(), ExecWaitStmt(), ExportSnapshot(), FastPathGetRelationLockEntry(), FastPathGrantRelationLock(), FastPathUnGrantRelationLock(), FindLockCycleRecurseMember(), get_cast_hashentry(), GetCurrentVirtualXIDs(), GetLockConflicts(), GetNewTransactionId(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), GetSnapshotDataReuse(), GetStableLatestTransactionId(), heap_inplace_update_and_unlock(), InitAuxiliaryProcess(), InitBufferManagerAccess(), InitializeParallelDSM(), InitPostgres(), InitProcess(), InitProcessPhase2(), InitRecoveryTransactionEnvironment(), InitTempTableNamespace(), InitWalSender(), JoinWaitQueue(), lock_and_open_sequence(), LockAcquireExtended(), LockCheckConflicts(), LockErrorCleanup(), LockRelease(), LockReleaseAll(), log_status_format(), logicalrep_worker_attach(), LWLockAcquire(), LWLockAcquireOrWait(), LWLockAttemptLock(), LWLockDequeueSelf(), LWLockQueueSelf(), LWLockWaitForVar(), MarkAsPreparingGuts(), MarkBufferDirtyHint(), MinimumActiveBackends(), pa_setup_dsm(), parallel_vacuum_main(), ParallelApplyWorkerMain(), ParallelWorkerMain(), pg_truncate_visibility_map(), pgaio_init_backend(), pgstat_report_activity(), PhysicalReplicationSlotNewXmin(), PostPrepare_Locks(), PrepareTransaction(), ProcArrayGroupClearXid(), ProcArrayInstallImportedXmin(), ProcArrayInstallRestoredXmin(), ProcessRecoveryConflictInterrupt(), ProcessStandbyHSFeedbackMessage(), ProcKill(), ProcReleaseLocks(), ProcSleep(), ProcWakeup(), RecordTransactionCommit(), RecordTransactionCommitPrepared(), ReinitializeParallelDSM(), RelationTruncate(), RemoveProcFromArray(), ReplicationSlotRelease(), ResolveRecoveryConflictWithLock(), set_indexsafe_procflags(), SetAuthenticatedUserId(), setup_dynamic_shared_memory(), shm_mq_attach(), shm_mq_detach_internal(), shm_mq_receive(), shm_mq_sendv(), shm_mq_wait_for_attach(), smgr_bulk_finish(), SnapBuildInitialSnapshot(), SnapshotResetXmin(), StartTransaction(), StartupDecodingContext(), SwitchBackToLocalLatch(), SwitchToSharedLatch(), SyncRepCancelWait(), SyncRepCleanupAtProcExit(), SyncRepQueueInsert(), SyncRepWaitForLSN(), TerminateOtherDBBackends(), TransactionGroupUpdateXidStatus(), TransactionIdIsInProgress(), TransactionIdSetPageStatus(), TruncateMultiXact(), vacuum_rel(), VirtualXactLockTableCleanup(), VirtualXactLockTableInsert(), WaitXLogInsertionsToFinish(), write_csvlog(), write_jsonlog(), XidCacheRemoveRunningXids(), and XLogSaveBufferForHint().

◆ PreparedXactProcs

PGPROC* PreparedXactProcs = NULL

Definition at line 81 of file proc.c.

Referenced by InitProcGlobal(), and TwoPhaseShmemInit().

◆ ProcGlobal

◆ ProcStructLock

NON_EXEC_STATIC slock_t* ProcStructLock = NULL

◆ StatementTimeout

int StatementTimeout = 0

Definition at line 59 of file proc.c.

Referenced by enable_statement_timeout().

◆ TransactionTimeout