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 "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)
 
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 = false
 
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 1040 of file proc.c.

1041{
1042 PGPROC *result = NULL;
1043 int index;
1044
1045 if (pid == 0) /* never match dummy PGPROCs */
1046 return NULL;
1047
1048 for (index = 0; index < NUM_AUXILIARY_PROCS; index++)
1049 {
1050 PGPROC *proc = &AuxiliaryProcs[index];
1051
1052 if (proc->pid == pid)
1053 {
1054 result = proc;
1055 break;
1056 }
1057 }
1058 return result;
1059}
#define NUM_AUXILIARY_PROCS
Definition: proc.h:447
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:79
Definition: proc.h:163
int pid
Definition: proc.h:183
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 989 of file proc.c.

990{
991 int proctype = DatumGetInt32(arg);
993 PGPROC *proc;
994
995 Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS);
996
997 /* not safe if forked by system(), etc. */
998 if (MyProc->pid != (int) getpid())
999 elog(PANIC, "AuxiliaryProcKill() called in child process");
1000
1001 auxproc = &AuxiliaryProcs[proctype];
1002
1003 Assert(MyProc == auxproc);
1004
1005 /* Release any LW locks I am holding (see notes above) */
1007
1008 /* Cancel any pending condition variable sleep, too */
1010
1011 /* look at the equivalent ProcKill() code for comments */
1014
1015 proc = MyProc;
1016 MyProc = NULL;
1018 DisownLatch(&proc->procLatch);
1019
1021
1022 /* Mark auxiliary proc no longer in use */
1023 proc->pid = 0;
1026
1027 /* Update shared estimate of spins_per_delay */
1029
1031}
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:224
bool ConditionVariableCancelSleep(void)
#define PANIC
Definition: elog.h:42
#define elog(elevel,...)
Definition: elog.h:225
ProcNumber MyProcNumber
Definition: globals.c:89
Assert(PointerIsAligned(start, uint64))
void DisownLatch(Latch *latch)
Definition: latch.c:144
void LWLockReleaseAll(void)
Definition: lwlock.c:1950
void SwitchBackToLocalLatch(void)
Definition: miscinit.c:242
void * arg
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:207
#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:66
PROC_HDR * ProcGlobal
Definition: proc.c:78
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:75
struct PGPROC::@127 vxid
LocalTransactionId lxid
Definition: proc.h:201
ProcNumber procNumber
Definition: proc.h:196
Latch procLatch
Definition: proc.h:170
int spins_per_delay
Definition: proc.h:412
#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 1950 of file proc.c.

1951{
1952 LWLock *leader_lwlock;
1953
1954 /* If we already did it, we don't need to do it again. */
1956 return;
1957
1958 /* We had better not be a follower. */
1959 Assert(MyProc->lockGroupLeader == NULL);
1960
1961 /* Create single-member group, containing only ourselves. */
1962 leader_lwlock = LockHashPartitionLockByProc(MyProc);
1963 LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
1966 LWLockRelease(leader_lwlock);
1967}
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:347
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:542
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1179
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1899
@ LW_EXCLUSIVE
Definition: lwlock.h:114
Definition: lwlock.h:42
dlist_head lockGroupMembers
Definition: proc.h:306
dlist_node lockGroupLink
Definition: proc.h:307
PGPROC * lockGroupLeader
Definition: proc.h:305

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 1980 of file proc.c.

1981{
1982 LWLock *leader_lwlock;
1983 bool ok = false;
1984
1985 /* Group leader can't become member of group */
1986 Assert(MyProc != leader);
1987
1988 /* Can't already be a member of a group */
1989 Assert(MyProc->lockGroupLeader == NULL);
1990
1991 /* PID must be valid. */
1992 Assert(pid != 0);
1993
1994 /*
1995 * Get lock protecting the group fields. Note LockHashPartitionLockByProc
1996 * calculates the proc number based on the PGPROC slot without looking at
1997 * its contents, so we will acquire the correct lock even if the leader
1998 * PGPROC is in process of being recycled.
1999 */
2000 leader_lwlock = LockHashPartitionLockByProc(leader);
2001 LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
2002
2003 /* Is this the leader we're looking for? */
2004 if (leader->pid == pid && leader->lockGroupLeader == leader)
2005 {
2006 /* OK, join the group */
2007 ok = true;
2008 MyProc->lockGroupLeader = leader;
2010 }
2011 LWLockRelease(leader_lwlock);
2012
2013 return ok;
2014}
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 1736 of file proc.c.

1737{
1738 int i;
1739
1740 /*
1741 * Acquire exclusive lock on the entire shared lock data structures. Must
1742 * grab LWLocks in partition-number order to avoid LWLock deadlock.
1743 *
1744 * Note that the deadlock check interrupt had better not be enabled
1745 * anywhere that this process itself holds lock partition locks, else this
1746 * will wait forever. Also note that LWLockAcquire creates a critical
1747 * section, so that this routine cannot be interrupted by cancel/die
1748 * interrupts.
1749 */
1750 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
1752
1753 /*
1754 * Check to see if we've been awoken by anyone in the interim.
1755 *
1756 * If we have, we can return and resume our transaction -- happy day.
1757 * Before we are awoken the process releasing the lock grants it to us so
1758 * we know that we don't have to wait anymore.
1759 *
1760 * We check by looking to see if we've been unlinked from the wait queue.
1761 * This is safe because we hold the lock partition lock.
1762 */
1763 if (MyProc->links.prev == NULL ||
1764 MyProc->links.next == NULL)
1765 goto check_done;
1766
1767#ifdef LOCK_DEBUG
1768 if (Debug_deadlocks)
1769 DumpAllLocks();
1770#endif
1771
1772 /* Run the deadlock check, and set deadlock_state for use by ProcSleep */
1774
1776 {
1777 /*
1778 * Oops. We have a deadlock.
1779 *
1780 * Get this process out of wait state. (Note: we could do this more
1781 * efficiently by relying on lockAwaited, but use this coding to
1782 * preserve the flexibility to kill some other transaction than the
1783 * one detecting the deadlock.)
1784 *
1785 * RemoveFromWaitQueue sets MyProc->waitStatus to
1786 * PROC_WAIT_STATUS_ERROR, so ProcSleep will report an error after we
1787 * return from the signal handler.
1788 */
1789 Assert(MyProc->waitLock != NULL);
1791
1792 /*
1793 * We're done here. Transaction abort caused by the error that
1794 * ProcSleep will raise will cause any other locks we hold to be
1795 * released, thus allowing other processes to wake up; we don't need
1796 * to do that here. NOTE: an exception is that releasing locks we
1797 * hold doesn't consider the possibility of waiters that were blocked
1798 * behind us on the lock we just failed to get, and might now be
1799 * wakable because we're not in front of them anymore. However,
1800 * RemoveFromWaitQueue took care of waking up any such processes.
1801 */
1802 }
1803
1804 /*
1805 * And release locks. We do this in reverse order for two reasons: (1)
1806 * Anyone else who needs more than one of the locks will be trying to lock
1807 * them in increasing order; we don't want to release the other process
1808 * until it can get all the locks it needs. (2) This avoids O(N^2)
1809 * behavior inside LWLockRelease.
1810 */
1811check_done:
1812 for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
1814}
DeadLockState DeadLockCheck(PGPROC *proc)
Definition: deadlock.c:220
int i
Definition: isn.c:74
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition: lock.c:2002
uint32 LockTagHashCode(const LOCKTAG *locktag)
Definition: lock.c:553
@ DS_HARD_DEADLOCK
Definition: lock.h:514
#define LockHashPartitionLockByIndex(i)
Definition: lock.h:530
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:97
static DeadLockState deadlock_state
Definition: proc.c:82
LOCKTAG tag
Definition: lock.h:312
LOCK * waitLock
Definition: proc.h:233
dlist_node links
Definition: proc.h:164
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 1822 of file proc.c.

1823{
1824 int save_errno = errno;
1825
1826 got_deadlock_timeout = true;
1827
1828 /*
1829 * Have to set the latch again, even if handle_sig_alarm already did. Back
1830 * then got_deadlock_timeout wasn't yet set... It's unlikely that this
1831 * ever would be a problem, but setting a set latch again is cheap.
1832 *
1833 * Note that, when this function runs inside procsignal_sigusr1_handler(),
1834 * the handler function sets the latch again after the latch is set here.
1835 */
1837 errno = save_errno;
1838}
struct Latch * MyLatch
Definition: globals.c:62
void SetLatch(Latch *latch)
Definition: latch.c:288
static volatile sig_atomic_t got_deadlock_timeout
Definition: proc.c:85

References got_deadlock_timeout, MyLatch, and SetLatch().

Referenced by InitPostgres(), and ProcessRecoveryConflictInterrupt().

◆ GetLockHoldersAndWaiters()

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

Definition at line 1849 of file proc.c.

1851{
1852 dlist_iter proc_iter;
1853 PROCLOCK *curproclock;
1854 LOCK *lock = locallock->lock;
1855 bool first_holder = true,
1856 first_waiter = true;
1857
1858#ifdef USE_ASSERT_CHECKING
1859 {
1860 uint32 hashcode = locallock->hashcode;
1861 LWLock *partitionLock = LockHashPartitionLock(hashcode);
1862
1863 Assert(LWLockHeldByMe(partitionLock));
1864 }
1865#endif
1866
1867 *lockHoldersNum = 0;
1868
1869 /*
1870 * Loop over the lock's procLocks to gather a list of all holders and
1871 * waiters. Thus we will be able to provide more detailed information for
1872 * lock debugging purposes.
1873 *
1874 * lock->procLocks contains all processes which hold or wait for this
1875 * lock.
1876 */
1877 dlist_foreach(proc_iter, &lock->procLocks)
1878 {
1879 curproclock =
1880 dlist_container(PROCLOCK, lockLink, proc_iter.cur);
1881
1882 /*
1883 * We are a waiter if myProc->waitProcLock == curproclock; we are a
1884 * holder if it is NULL or something different.
1885 */
1886 if (curproclock->tag.myProc->waitProcLock == curproclock)
1887 {
1888 if (first_waiter)
1889 {
1890 appendStringInfo(lock_waiters_sbuf, "%d",
1891 curproclock->tag.myProc->pid);
1892 first_waiter = false;
1893 }
1894 else
1895 appendStringInfo(lock_waiters_sbuf, ", %d",
1896 curproclock->tag.myProc->pid);
1897 }
1898 else
1899 {
1900 if (first_holder)
1901 {
1902 appendStringInfo(lock_holders_sbuf, "%d",
1903 curproclock->tag.myProc->pid);
1904 first_holder = false;
1905 }
1906 else
1907 appendStringInfo(lock_holders_sbuf, ", %d",
1908 curproclock->tag.myProc->pid);
1909
1910 (*lockHoldersNum)++;
1911 }
1912 }
1913}
uint32_t uint32
Definition: c.h:502
#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:527
bool LWLockHeldByMe(LWLock *lock)
Definition: lwlock.c:1967
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
uint32 hashcode
Definition: lock.h:433
LOCK * lock
Definition: lock.h:434
Definition: lock.h:310
dlist_head procLocks
Definition: lock.h:317
PROCLOCK * waitProcLock
Definition: proc.h:234
PGPROC * myProc
Definition: lock.h:367
Definition: lock.h:371
PROCLOCKTAG tag
Definition: lock.h:373
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 717 of file proc.c.

718{
719 /* use volatile pointer to prevent code rearrangement */
720 volatile PROC_HDR *procglobal = ProcGlobal;
721
722 return procglobal->startupBufferPinWaitBufId;
723}
Definition: proc.h:370
int startupBufferPinWaitBufId
Definition: proc.h:414

References ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by HoldingBufferPinThatDelaysRecovery(), and ProcessRecoveryConflictInterrupt().

◆ HaveNFreeProcs()

bool HaveNFreeProcs ( int  n,
int *  nfree 
)

Definition at line 733 of file proc.c.

734{
735 dlist_iter iter;
736
737 Assert(n > 0);
738 Assert(nfree);
739
741
742 *nfree = 0;
744 {
745 (*nfree)++;
746 if (*nfree == n)
747 break;
748 }
749
751
752 return (*nfree == n);
753}
dlist_head freeProcs
Definition: proc.h:392

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

Referenced by InitPostgres().

◆ InitAuxiliaryProcess()

void InitAuxiliaryProcess ( void  )

Definition at line 566 of file proc.c.

567{
568 PGPROC *auxproc;
569 int proctype;
570
571 /*
572 * ProcGlobal should be set up already (if we are a backend, we inherit
573 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
574 */
575 if (ProcGlobal == NULL || AuxiliaryProcs == NULL)
576 elog(PANIC, "proc header uninitialized");
577
578 if (MyProc != NULL)
579 elog(ERROR, "you already exist");
580
583
584 /*
585 * We use the ProcStructLock to protect assignment and releasing of
586 * AuxiliaryProcs entries.
587 *
588 * While we are holding the ProcStructLock, also copy the current shared
589 * estimate of spins_per_delay to local storage.
590 */
592
594
595 /*
596 * Find a free auxproc ... *big* trouble if there isn't one ...
597 */
598 for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++)
599 {
600 auxproc = &AuxiliaryProcs[proctype];
601 if (auxproc->pid == 0)
602 break;
603 }
604 if (proctype >= NUM_AUXILIARY_PROCS)
605 {
607 elog(FATAL, "all AuxiliaryProcs are in use");
608 }
609
610 /* Mark auxiliary proc as in use by me */
611 /* use volatile pointer to prevent code rearrangement */
612 ((volatile PGPROC *) auxproc)->pid = MyProcPid;
613
615
616 MyProc = auxproc;
618
619 /*
620 * Initialize all fields of MyProc, except for those previously
621 * initialized by InitProcGlobal.
622 */
625 MyProc->fpVXIDLock = false;
634 MyProc->isRegularBackend = false;
636 MyProc->statusFlags = 0;
638 MyProc->lwWaitMode = 0;
639 MyProc->waitLock = NULL;
640 MyProc->waitProcLock = NULL;
642#ifdef USE_ASSERT_CHECKING
643 {
644 int i;
645
646 /* Last process should have released all locks. */
647 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
649 }
650#endif
651
652 /*
653 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
654 * on it. That allows us to repoint the process latch, which so far
655 * points to process local one, to the shared one.
656 */
659
660 /* now that we have a proc, report wait events to shared memory */
662
663 /* Check that group locking fields are in a proper initial state. */
664 Assert(MyProc->lockGroupLeader == NULL);
666
667 /*
668 * We might be reusing a semaphore that belonged to a failed process. So
669 * be careful and reinitialize its value here. (This is not strictly
670 * necessary anymore, but seems like a good idea for cleanliness.)
671 */
673
674 /*
675 * Arrange to clean up at process exit.
676 */
678
679 /*
680 * Now that we have a PGPROC, we could try to acquire lightweight locks.
681 * Initialize local state needed for them. (Heavyweight locks cannot be
682 * acquired in aux processes.)
683 */
685
686#ifdef EXEC_BACKEND
687
688 /*
689 * Initialize backend-local pointers to all the shared data structures.
690 * (We couldn't do this until now because it needs LWLocks.)
691 */
693 AttachSharedMemoryStructs();
694#endif
695}
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:485
#define FATAL
Definition: elog.h:41
#define ERROR
Definition: elog.h:39
int MyProcPid
Definition: globals.c:46
bool IsUnderPostmaster
Definition: globals.c:119
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:66
void InitLWLockAccess(void)
Definition: lwlock.c:568
@ 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:294
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:217
#define InvalidOid
Definition: postgres_ext.h:37
#define GetNumberFromPGProc(proc)
Definition: proc.h:425
@ PROC_WAIT_STATUS_OK
Definition: proc.h:125
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:989
bool isRegularBackend
Definition: proc.h:214
TransactionId xmin
Definition: proc.h:178
uint8 lwWaitMode
Definition: proc.h:225
uint32 wait_event_info
Definition: proc.h:280
uint8 statusFlags
Definition: proc.h:243
Oid databaseId
Definition: proc.h:208
pg_atomic_uint64 waitStart
Definition: proc.h:238
bool fpVXIDLock
Definition: proc.h:297
TransactionId xid
Definition: proc.h:173
int delayChkptFlags
Definition: proc.h:241
LocalTransactionId fpLocalTransactionId
Definition: proc.h:298
PGSemaphore sem
Definition: proc.h:167
dlist_head myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:262
Oid roleId
Definition: proc.h:209
ProcWaitStatus waitStatus
Definition: proc.h:168
Oid tempNamespaceId
Definition: proc.h:211
uint8 lwWaiting
Definition: proc.h:224
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 341 of file proc.c.

342{
343 dlist_head *procgloballist;
344
345 /*
346 * ProcGlobal should be set up already (if we are a backend, we inherit
347 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
348 */
349 if (ProcGlobal == NULL)
350 elog(PANIC, "proc header uninitialized");
351
352 if (MyProc != NULL)
353 elog(ERROR, "you already exist");
354
355 /*
356 * Before we start accessing the shared memory in a serious way, mark
357 * ourselves as an active postmaster child; this is so that the postmaster
358 * can detect it if we exit without cleaning up.
359 */
362
363 /*
364 * Decide which list should supply our PGPROC. This logic must match the
365 * way the freelists were constructed in InitProcGlobal().
366 */
368 procgloballist = &ProcGlobal->autovacFreeProcs;
369 else if (AmBackgroundWorkerProcess())
370 procgloballist = &ProcGlobal->bgworkerFreeProcs;
371 else if (AmWalSenderProcess())
372 procgloballist = &ProcGlobal->walsenderFreeProcs;
373 else
374 procgloballist = &ProcGlobal->freeProcs;
375
376 /*
377 * Try to get a proc struct from the appropriate free list. If this
378 * fails, we must be out of PGPROC structures (not to mention semaphores).
379 *
380 * While we are holding the ProcStructLock, also copy the current shared
381 * estimate of spins_per_delay to local storage.
382 */
384
386
387 if (!dlist_is_empty(procgloballist))
388 {
391 }
392 else
393 {
394 /*
395 * If we reach here, all the PGPROCs are in use. This is one of the
396 * possible places to detect "too many backends", so give the standard
397 * error message. XXX do we need to give a different failure message
398 * in the autovacuum case?
399 */
401 if (AmWalSenderProcess())
403 (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
404 errmsg("number of requested standby connections exceeds \"max_wal_senders\" (currently %d)",
407 (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
408 errmsg("sorry, too many clients already")));
409 }
411
412 /*
413 * Cross-check that the PGPROC is of the type we expect; if this were not
414 * the case, it would get returned to the wrong list.
415 */
416 Assert(MyProc->procgloballist == procgloballist);
417
418 /*
419 * Initialize all fields of MyProc, except for those previously
420 * initialized by InitProcGlobal.
421 */
424 MyProc->fpVXIDLock = false;
431 /* databaseId and roleId will be filled in later */
437 MyProc->statusFlags = 0;
438 /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
442 MyProc->lwWaitMode = 0;
443 MyProc->waitLock = NULL;
444 MyProc->waitProcLock = NULL;
446#ifdef USE_ASSERT_CHECKING
447 {
448 int i;
449
450 /* Last process should have released all locks. */
451 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
453 }
454#endif
456
457 /* Initialize fields for sync rep */
458 MyProc->waitLSN = 0;
461
462 /* Initialize fields for group XID clearing. */
466
467 /* Check that group locking fields are in a proper initial state. */
468 Assert(MyProc->lockGroupLeader == NULL);
470
471 /* Initialize wait event information. */
473
474 /* Initialize fields for group transaction status update. */
475 MyProc->clogGroupMember = false;
481
482 /*
483 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
484 * on it. That allows us to repoint the process latch, which so far
485 * points to process local one, to the shared one.
486 */
489
490 /* now that we have a proc, report wait events to shared memory */
492
493 /*
494 * We might be reusing a semaphore that belonged to a failed process. So
495 * be careful and reinitialize its value here. (This is not strictly
496 * necessary anymore, but seems like a good idea for cleanliness.)
497 */
499
500 /*
501 * Arrange to clean up at backend exit.
502 */
504
505 /*
506 * Now that we have a PGPROC, we could try to acquire locks, so initialize
507 * local state needed for LWLocks, and the deadlock checker.
508 */
511
512#ifdef EXEC_BACKEND
513
514 /*
515 * Initialize backend-local pointers to all the shared data structures.
516 * (We couldn't do this until now because it needs LWLocks.)
517 */
519 AttachSharedMemoryStructs();
520#endif
521}
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:239
#define TRANSACTION_STATUS_IN_PROGRESS
Definition: clog.h:27
void InitDeadLockChecking(void)
Definition: deadlock.c:144
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereport(elevel,...)
Definition: elog.h:149
static dlist_node * dlist_pop_head_node(dlist_head *head)
Definition: ilist.h:450
#define AmAutoVacuumWorkerProcess()
Definition: miscadmin.h:382
#define AmBackgroundWorkerProcess()
Definition: miscadmin.h:383
#define AmWalSenderProcess()
Definition: miscadmin.h:384
#define AmSpecialWorkerProcess()
Definition: miscadmin.h:395
#define AmRegularBackendProcess()
Definition: miscadmin.h:380
#define PROC_IS_AUTOVACUUM
Definition: proc.h:57
static void ProcKill(int code, Datum arg)
Definition: proc.c:868
bool procArrayGroupMember
Definition: proc.h:270
XLogRecPtr clogGroupMemberLsn
Definition: proc.h:290
pg_atomic_uint32 procArrayGroupNext
Definition: proc.h:272
dlist_head * procgloballist
Definition: proc.h:165
bool recoveryConflictPending
Definition: proc.h:221
TransactionId clogGroupMemberXid
Definition: proc.h:285
int64 clogGroupMemberPage
Definition: proc.h:288
bool clogGroupMember
Definition: proc.h:283
XLogRecPtr waitLSN
Definition: proc.h:253
dlist_node syncRepLinks
Definition: proc.h:255
int syncRepState
Definition: proc.h:254
pg_atomic_uint32 clogGroupNext
Definition: proc.h:284
XidStatus clogGroupMemberXidStatus
Definition: proc.h:286
TransactionId procArrayGroupMemberXid
Definition: proc.h:278
dlist_head autovacFreeProcs
Definition: proc.h:394
dlist_head walsenderFreeProcs
Definition: proc.h:398
dlist_head bgworkerFreeProcs
Definition: proc.h:396
#define SYNC_REP_NOT_WAITING
Definition: syncrep.h:30
int max_wal_senders
Definition: walsender.c:122
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
static struct link * links
Definition: zic.c:299

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 531 of file proc.c.

532{
533 Assert(MyProc != NULL);
534
535 /*
536 * Add our PGPROC to the PGPROC array in shared memory.
537 */
539
540 /*
541 * Arrange to clean that up at backend exit.
542 */
544}
void ProcArrayAdd(PGPROC *proc)
Definition: procarray.c:468
static void RemoveProcFromArray(int code, Datum arg)
Definition: proc.c:857

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

Referenced by InitPostgres().

◆ InitProcGlobal()

void InitProcGlobal ( void  )

Definition at line 165 of file proc.c.

166{
167 PGPROC *procs;
168 int i,
169 j;
170 bool found;
172
173 /* Used for setup of per-backend fast-path slots. */
174 char *fpPtr,
175 *fpEndPtr PG_USED_FOR_ASSERTS_ONLY;
176 Size fpLockBitsSize,
177 fpRelIdSize;
178
179 /* Create the ProcGlobal shared structure */
180 ProcGlobal = (PROC_HDR *)
181 ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
182 Assert(!found);
183
184 /*
185 * Initialize the data structures.
186 */
197
198 /*
199 * Create and initialize all the PGPROC structures we'll need. There are
200 * six separate consumers: (1) normal backends, (2) autovacuum workers and
201 * special workers, (3) background workers, (4) walsenders, (5) auxiliary
202 * processes, and (6) prepared transactions. (For largely-historical
203 * reasons, we combine autovacuum and special workers into one category
204 * with a single freelist.) Each PGPROC structure is dedicated to exactly
205 * one of these purposes, and they do not move between groups.
206 */
207 procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC));
208 MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
209 ProcGlobal->allProcs = procs;
210 /* XXX allProcCount isn't really all of them; it excludes prepared xacts */
212
213 /*
214 * Allocate arrays mirroring PGPROC fields in a dense manner. See
215 * PROC_HDR.
216 *
217 * XXX: It might make sense to increase padding for these arrays, given
218 * how hotly they are accessed.
219 */
221 (TransactionId *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->xids));
222 MemSet(ProcGlobal->xids, 0, TotalProcs * sizeof(*ProcGlobal->xids));
224 MemSet(ProcGlobal->subxidStates, 0, TotalProcs * sizeof(*ProcGlobal->subxidStates));
225 ProcGlobal->statusFlags = (uint8 *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->statusFlags));
226 MemSet(ProcGlobal->statusFlags, 0, TotalProcs * sizeof(*ProcGlobal->statusFlags));
227
228 /*
229 * Allocate arrays for fast-path locks. Those are variable-length, so
230 * can't be included in PGPROC directly. We allocate a separate piece of
231 * shared memory and then divide that between backends.
232 */
233 fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
234 fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
235
236 fpPtr = ShmemAlloc(TotalProcs * (fpLockBitsSize + fpRelIdSize));
237 MemSet(fpPtr, 0, TotalProcs * (fpLockBitsSize + fpRelIdSize));
238
239 /* For asserts checking we did not overflow. */
240 fpEndPtr = fpPtr + (TotalProcs * (fpLockBitsSize + fpRelIdSize));
241
242 for (i = 0; i < TotalProcs; i++)
243 {
244 PGPROC *proc = &procs[i];
245
246 /* Common initialization for all PGPROCs, regardless of type. */
247
248 /*
249 * Set the fast-path lock arrays, and move the pointer. We interleave
250 * the two arrays, to (hopefully) get some locality for each backend.
251 */
252 proc->fpLockBits = (uint64 *) fpPtr;
253 fpPtr += fpLockBitsSize;
254
255 proc->fpRelId = (Oid *) fpPtr;
256 fpPtr += fpRelIdSize;
257
258 Assert(fpPtr <= fpEndPtr);
259
260 /*
261 * Set up per-PGPROC semaphore, latch, and fpInfoLock. Prepared xact
262 * dummy PGPROCs don't need these though - they're never associated
263 * with a real process
264 */
266 {
267 proc->sem = PGSemaphoreCreate();
268 InitSharedLatch(&(proc->procLatch));
270 }
271
272 /*
273 * Newly created PGPROCs for normal backends, autovacuum workers,
274 * special workers, bgworkers, and walsenders must be queued up on the
275 * appropriate free list. Because there can only ever be a small,
276 * fixed number of auxiliary processes, no free list is used in that
277 * case; InitAuxiliaryProcess() instead uses a linear search. PGPROCs
278 * for prepared transactions are added to a free list by
279 * TwoPhaseShmemInit().
280 */
281 if (i < MaxConnections)
282 {
283 /* PGPROC for normal backend, add to freeProcs list */
286 }
288 {
289 /* PGPROC for AV or special worker, add to autovacFreeProcs list */
292 }
294 {
295 /* PGPROC for bgworker, add to bgworkerFreeProcs list */
298 }
299 else if (i < MaxBackends)
300 {
301 /* PGPROC for walsender, add to walsenderFreeProcs list */
304 }
305
306 /* Initialize myProcLocks[] shared memory queues. */
307 for (j = 0; j < NUM_LOCK_PARTITIONS; j++)
308 dlist_init(&(proc->myProcLocks[j]));
309
310 /* Initialize lockGroupMembers list. */
312
313 /*
314 * Initialize the atomic variables, otherwise, it won't be safe to
315 * access them for backends that aren't currently in use.
316 */
319 pg_atomic_init_u64(&(proc->waitStart), 0);
320 }
321
322 /* Should have consumed exactly the expected amount of fast-path memory. */
323 Assert(fpPtr == fpEndPtr);
324
325 /*
326 * Save pointers to the blocks of PGPROC structures reserved for auxiliary
327 * processes and prepared transactions.
328 */
329 AuxiliaryProcs = &procs[MaxBackends];
331
332 /* Create ProcStructLock spinlock, too */
333 ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t));
335}
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:221
static void pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:453
int autovacuum_worker_slots
Definition: autovacuum.c:119
#define MAXALIGN(LEN)
Definition: c.h:782
uint8_t uint8
Definition: c.h:500
uint64_t uint64
Definition: c.h:503
#define MemSet(start, val, len)
Definition: c.h:991
uint32 TransactionId
Definition: c.h:623
size_t Size
Definition: c.h:576
int MaxConnections
Definition: globals.c:142
int MaxBackends
Definition: globals.c:145
int max_worker_processes
Definition: globals.c:143
static void dlist_init(dlist_head *head)
Definition: ilist.h:314
int j
Definition: isn.c:75
void InitSharedLatch(Latch *latch)
Definition: latch.c:93
int FastPathLockGroupsPerBackend
Definition: lock.c:202
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:718
@ LWTRANCHE_LOCK_FASTPATH
Definition: lwlock.h:192
PGSemaphore PGSemaphoreCreate(void)
Definition: posix_sema.c:261
unsigned int Oid
Definition: postgres_ext.h:32
#define FastPathLockSlotsPerBackend()
Definition: proc.h:85
#define NUM_SPECIAL_WORKER_PROCS
Definition: proc.h:434
#define DEFAULT_SPINS_PER_DELAY
Definition: s_lock.h:720
void * ShmemAlloc(Size size)
Definition: shmem.c:147
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:382
#define SpinLockInit(lock)
Definition: spin.h:57
PGPROC * PreparedXactProcs
Definition: proc.c:80
LWLock fpInfoLock
Definition: proc.h:294
Oid * fpRelId
Definition: proc.h:296
uint64 * fpLockBits
Definition: proc.h:295
uint8 * statusFlags
Definition: proc.h:387
XidCacheStatus * subxidStates
Definition: proc.h:381
ProcNumber checkpointerProc
Definition: proc.h:409
PGPROC * allProcs
Definition: proc.h:372
pg_atomic_uint32 clogGroupFirst
Definition: proc.h:402
TransactionId * xids
Definition: proc.h:375
ProcNumber walwriterProc
Definition: proc.h:408
pg_atomic_uint32 procArrayGroupFirst
Definition: proc.h:400
uint32 allProcCount
Definition: proc.h:390
int max_prepared_xacts
Definition: twophase.c:115

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, FastPathLockSlotsPerBackend, PGPROC::fpInfoLock, PGPROC::fpLockBits, PGPROC::fpRelId, PROC_HDR::freeProcs, i, InitSharedLatch(), INVALID_PROC_NUMBER, j, PGPROC::links, PGPROC::lockGroupMembers, LWLockInitialize(), LWTRANCHE_LOCK_FASTPATH, 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, PGSemaphoreCreate(), PreparedXactProcs, PROC_HDR::procArrayGroupFirst, PGPROC::procArrayGroupNext, ProcGlobal, PGPROC::procgloballist, PGPROC::procLatch, ProcStructLock, PGPROC::sem, ShmemAlloc(), 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 1089 of file proc.c.

1090{
1091 LOCKMODE lockmode = locallock->tag.mode;
1092 LOCK *lock = locallock->lock;
1093 PROCLOCK *proclock = locallock->proclock;
1094 uint32 hashcode = locallock->hashcode;
1095 LWLock *partitionLock PG_USED_FOR_ASSERTS_ONLY = LockHashPartitionLock(hashcode);
1096 dclist_head *waitQueue = &lock->waitProcs;
1097 PGPROC *insert_before = NULL;
1098 LOCKMASK myProcHeldLocks;
1099 LOCKMASK myHeldLocks;
1100 bool early_deadlock = false;
1101 PGPROC *leader = MyProc->lockGroupLeader;
1102
1103 Assert(LWLockHeldByMeInMode(partitionLock, LW_EXCLUSIVE));
1104
1105 /*
1106 * Set bitmask of locks this process already holds on this object.
1107 */
1108 myHeldLocks = MyProc->heldLocks = proclock->holdMask;
1109
1110 /*
1111 * Determine which locks we're already holding.
1112 *
1113 * If group locking is in use, locks held by members of my locking group
1114 * need to be included in myHeldLocks. This is not required for relation
1115 * extension lock which conflict among group members. However, including
1116 * them in myHeldLocks will give group members the priority to get those
1117 * locks as compared to other backends which are also trying to acquire
1118 * those locks. OTOH, we can avoid giving priority to group members for
1119 * that kind of locks, but there doesn't appear to be a clear advantage of
1120 * the same.
1121 */
1122 myProcHeldLocks = proclock->holdMask;
1123 myHeldLocks = myProcHeldLocks;
1124 if (leader != NULL)
1125 {
1126 dlist_iter iter;
1127
1128 dlist_foreach(iter, &lock->procLocks)
1129 {
1130 PROCLOCK *otherproclock;
1131
1132 otherproclock = dlist_container(PROCLOCK, lockLink, iter.cur);
1133
1134 if (otherproclock->groupLeader == leader)
1135 myHeldLocks |= otherproclock->holdMask;
1136 }
1137 }
1138
1139 /*
1140 * Determine where to add myself in the wait queue.
1141 *
1142 * Normally I should go at the end of the queue. However, if I already
1143 * hold locks that conflict with the request of any previous waiter, put
1144 * myself in the queue just in front of the first such waiter. This is not
1145 * a necessary step, since deadlock detection would move me to before that
1146 * waiter anyway; but it's relatively cheap to detect such a conflict
1147 * immediately, and avoid delaying till deadlock timeout.
1148 *
1149 * Special case: if I find I should go in front of some waiter, check to
1150 * see if I conflict with already-held locks or the requests before that
1151 * waiter. If not, then just grant myself the requested lock immediately.
1152 * This is the same as the test for immediate grant in LockAcquire, except
1153 * we are only considering the part of the wait queue before my insertion
1154 * point.
1155 */
1156 if (myHeldLocks != 0 && !dclist_is_empty(waitQueue))
1157 {
1158 LOCKMASK aheadRequests = 0;
1159 dlist_iter iter;
1160
1161 dclist_foreach(iter, waitQueue)
1162 {
1163 PGPROC *proc = dlist_container(PGPROC, links, iter.cur);
1164
1165 /*
1166 * If we're part of the same locking group as this waiter, its
1167 * locks neither conflict with ours nor contribute to
1168 * aheadRequests.
1169 */
1170 if (leader != NULL && leader == proc->lockGroupLeader)
1171 continue;
1172
1173 /* Must he wait for me? */
1174 if (lockMethodTable->conflictTab[proc->waitLockMode] & myHeldLocks)
1175 {
1176 /* Must I wait for him ? */
1177 if (lockMethodTable->conflictTab[lockmode] & proc->heldLocks)
1178 {
1179 /*
1180 * Yes, so we have a deadlock. Easiest way to clean up
1181 * correctly is to call RemoveFromWaitQueue(), but we
1182 * can't do that until we are *on* the wait queue. So, set
1183 * a flag to check below, and break out of loop. Also,
1184 * record deadlock info for later message.
1185 */
1186 RememberSimpleDeadLock(MyProc, lockmode, lock, proc);
1187 early_deadlock = true;
1188 break;
1189 }
1190 /* I must go before this waiter. Check special case. */
1191 if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1192 !LockCheckConflicts(lockMethodTable, lockmode, lock,
1193 proclock))
1194 {
1195 /* Skip the wait and just grant myself the lock. */
1196 GrantLock(lock, proclock, lockmode);
1197 return PROC_WAIT_STATUS_OK;
1198 }
1199
1200 /* Put myself into wait queue before conflicting process */
1201 insert_before = proc;
1202 break;
1203 }
1204 /* Nope, so advance to next waiter */
1205 aheadRequests |= LOCKBIT_ON(proc->waitLockMode);
1206 }
1207 }
1208
1209 /*
1210 * If we detected deadlock, give up without waiting. This must agree with
1211 * CheckDeadLock's recovery code.
1212 */
1213 if (early_deadlock)
1215
1216 /*
1217 * At this point we know that we'd really need to sleep. If we've been
1218 * commanded not to do that, bail out.
1219 */
1220 if (dontWait)
1222
1223 /*
1224 * Insert self into queue, at the position determined above.
1225 */
1226 if (insert_before)
1227 dclist_insert_before(waitQueue, &insert_before->links, &MyProc->links);
1228 else
1229 dclist_push_tail(waitQueue, &MyProc->links);
1230
1231 lock->waitMask |= LOCKBIT_ON(lockmode);
1232
1233 /* Set up wait information in PGPROC object, too */
1234 MyProc->heldLocks = myProcHeldLocks;
1235 MyProc->waitLock = lock;
1236 MyProc->waitProcLock = proclock;
1237 MyProc->waitLockMode = lockmode;
1238
1240
1242}
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:1654
bool LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
Definition: lock.c:1525
#define LOCKBIT_ON(lockmode)
Definition: lock.h:85
int LOCKMODE
Definition: lockdefs.h:26
int LOCKMASK
Definition: lockdefs.h:25
bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:2011
@ PROC_WAIT_STATUS_WAITING
Definition: proc.h:126
@ PROC_WAIT_STATUS_ERROR
Definition: proc.h:127
LOCKMODE mode
Definition: lock.h:412
PROCLOCK * proclock
Definition: lock.h:435
LOCALLOCKTAG tag
Definition: lock.h:430
dclist_head waitProcs
Definition: lock.h:318
LOCKMASK waitMask
Definition: lock.h:316
const LOCKMASK * conflictTab
Definition: lock.h:112
LOCKMODE waitLockMode
Definition: proc.h:235
LOCKMASK heldLocks
Definition: proc.h:236
LOCKMASK holdMask
Definition: lock.h:377
PGPROC * groupLeader
Definition: lock.h:376

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 764 of file proc.c.

765{
766 LOCALLOCK *lockAwaited;
767 LWLock *partitionLock;
768 DisableTimeoutParams timeouts[2];
769
771
773
774 /* Nothing to do if we weren't waiting for a lock */
775 lockAwaited = GetAwaitedLock();
776 if (lockAwaited == NULL)
777 {
779 return;
780 }
781
782 /*
783 * Turn off the deadlock and lock timeout timers, if they are still
784 * running (see ProcSleep). Note we must preserve the LOCK_TIMEOUT
785 * indicator flag, since this function is executed before
786 * ProcessInterrupts when responding to SIGINT; else we'd lose the
787 * knowledge that the SIGINT came from a lock timeout and not an external
788 * source.
789 */
790 timeouts[0].id = DEADLOCK_TIMEOUT;
791 timeouts[0].keep_indicator = false;
792 timeouts[1].id = LOCK_TIMEOUT;
793 timeouts[1].keep_indicator = true;
794 disable_timeouts(timeouts, 2);
795
796 /* Unlink myself from the wait queue, if on it (might not be anymore!) */
797 partitionLock = LockHashPartitionLock(lockAwaited->hashcode);
798 LWLockAcquire(partitionLock, LW_EXCLUSIVE);
799
801 {
802 /* We could not have been granted the lock yet */
803 RemoveFromWaitQueue(MyProc, lockAwaited->hashcode);
804 }
805 else
806 {
807 /*
808 * Somebody kicked us off the lock queue already. Perhaps they
809 * granted us the lock, or perhaps they detected a deadlock. If they
810 * did grant us the lock, we'd better remember it in our local lock
811 * table.
812 */
815 }
816
817 LWLockRelease(partitionLock);
818
820}
static bool dlist_node_is_detached(const dlist_node *node)
Definition: ilist.h:525
void GrantAwaitedLock(void)
Definition: lock.c:1885
void AbortStrongLockAcquire(void)
Definition: lock.c:1856
LOCALLOCK * GetAwaitedLock(void)
Definition: lock.c:1894
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:135
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:133
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(), RESUME_INTERRUPTS, and PGPROC::waitStatus.

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

◆ ProcGlobalSemas()

int ProcGlobalSemas ( void  )

Definition at line 130 of file proc.c.

131{
132 /*
133 * We need a sema per backend (including autovacuum), plus one for each
134 * auxiliary process.
135 */
137}

References MaxBackends, and NUM_AUXILIARY_PROCS.

Referenced by CalculateShmemSize().

◆ ProcGlobalShmemSize()

Size ProcGlobalShmemSize ( void  )

Definition at line 97 of file proc.c.

98{
99 Size size = 0;
100 Size TotalProcs =
102 Size fpLockBitsSize,
103 fpRelIdSize;
104
105 /* ProcGlobal */
106 size = add_size(size, sizeof(PROC_HDR));
107 size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC)));
108 size = add_size(size, sizeof(slock_t));
109
110 size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids)));
111 size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates)));
112 size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags)));
113
114 /*
115 * Memory needed for PGPROC fast-path lock arrays. Make sure the sizes are
116 * nicely aligned in each backend.
117 */
118 fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
119 fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
120
121 size = add_size(size, mul_size(TotalProcs, (fpLockBitsSize + fpRelIdSize)));
122
123 return size;
124}
Size add_size(Size s1, Size s2)
Definition: shmem.c:488
Size mul_size(Size s1, Size s2)
Definition: shmem.c:505

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

Referenced by CalculateShmemSize().

◆ ProcKill()

static void ProcKill ( int  code,
Datum  arg 
)
static

Definition at line 868 of file proc.c.

869{
870 PGPROC *proc;
871 dlist_head *procgloballist;
872
873 Assert(MyProc != NULL);
874
875 /* not safe if forked by system(), etc. */
876 if (MyProc->pid != (int) getpid())
877 elog(PANIC, "ProcKill() called in child process");
878
879 /* Make sure we're out of the sync rep lists */
881
882#ifdef USE_ASSERT_CHECKING
883 {
884 int i;
885
886 /* Last process should have released all locks. */
887 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
889 }
890#endif
891
892 /*
893 * Release any LW locks I am holding. There really shouldn't be any, but
894 * it's cheap to check again before we cut the knees off the LWLock
895 * facility by releasing our PGPROC ...
896 */
898
899 /* Cancel any pending condition variable sleep, too */
901
902 /*
903 * Detach from any lock group of which we are a member. If the leader
904 * exits before all other group members, its PGPROC will remain allocated
905 * until the last group process exits; that process must return the
906 * leader's PGPROC to the appropriate list.
907 */
908 if (MyProc->lockGroupLeader != NULL)
909 {
910 PGPROC *leader = MyProc->lockGroupLeader;
911 LWLock *leader_lwlock = LockHashPartitionLockByProc(leader);
912
913 LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
916 if (dlist_is_empty(&leader->lockGroupMembers))
917 {
918 leader->lockGroupLeader = NULL;
919 if (leader != MyProc)
920 {
921 procgloballist = leader->procgloballist;
922
923 /* Leader exited first; return its PGPROC. */
925 dlist_push_head(procgloballist, &leader->links);
927 }
928 }
929 else if (leader != MyProc)
930 MyProc->lockGroupLeader = NULL;
931 LWLockRelease(leader_lwlock);
932 }
933
934 /*
935 * Reset MyLatch to the process local one. This is so that signal
936 * handlers et al can continue using the latch after the shared latch
937 * isn't ours anymore.
938 *
939 * Similarly, stop reporting wait events to MyProc->wait_event_info.
940 *
941 * After that clear MyProc and disown the shared latch.
942 */
945
946 proc = MyProc;
947 MyProc = NULL;
949 DisownLatch(&proc->procLatch);
950
951 /* Mark the proc no longer in use */
952 proc->pid = 0;
955
956 procgloballist = proc->procgloballist;
958
959 /*
960 * If we're still a member of a locking group, that means we're a leader
961 * which has somehow exited before its children. The last remaining child
962 * will release our PGPROC. Otherwise, release it now.
963 */
964 if (proc->lockGroupLeader == NULL)
965 {
966 /* Since lockGroupLeader is NULL, lockGroupMembers should be empty. */
968
969 /* Return PGPROC structure (and semaphore) to appropriate freelist */
970 dlist_push_tail(procgloballist, &proc->links);
971 }
972
973 /* Update shared estimate of spins_per_delay */
975
977
978 /* wake autovac launcher if needed -- see comments in FreeWorkerInfo */
979 if (AutovacuumLauncherPid != 0)
981}
int AutovacuumLauncherPid
Definition: autovacuum.c:317
static void dlist_delete(dlist_node *node)
Definition: ilist.h:405
void SyncRepCleanupAtProcExit(void)
Definition: syncrep.c:373
#define kill(pid, sig)
Definition: win32_port.h:493
#define SIGUSR2
Definition: win32_port.h:171

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(), and PGPROC::vxid.

Referenced by InitProcess().

◆ ProcLockWakeup()

void ProcLockWakeup ( LockMethod  lockMethodTable,
LOCK lock 
)

Definition at line 1688 of file proc.c.

1689{
1690 dclist_head *waitQueue = &lock->waitProcs;
1691 LOCKMASK aheadRequests = 0;
1692 dlist_mutable_iter miter;
1693
1694 if (dclist_is_empty(waitQueue))
1695 return;
1696
1697 dclist_foreach_modify(miter, waitQueue)
1698 {
1699 PGPROC *proc = dlist_container(PGPROC, links, miter.cur);
1700 LOCKMODE lockmode = proc->waitLockMode;
1701
1702 /*
1703 * Waken if (a) doesn't conflict with requests of earlier waiters, and
1704 * (b) doesn't conflict with already-held locks.
1705 */
1706 if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1707 !LockCheckConflicts(lockMethodTable, lockmode, lock,
1708 proc->waitProcLock))
1709 {
1710 /* OK to waken */
1711 GrantLock(lock, proc->waitProcLock, lockmode);
1712 /* removes proc from the lock's waiting process queue */
1714 }
1715 else
1716 {
1717 /*
1718 * Lock conflicts: Don't wake, but remember requested mode for
1719 * later checks.
1720 */
1721 aheadRequests |= LOCKBIT_ON(lockmode);
1722 }
1723 }
1724}
#define dclist_foreach_modify(iter, lhead)
Definition: ilist.h:973
void ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus)
Definition: proc.c:1660
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 840 of file proc.c.

841{
842 if (!MyProc)
843 return;
844 /* If waiting, get off wait queue (should only be needed after error) */
846 /* Release standard locks, including session-level if aborting */
848 /* Release transaction-level advisory locks */
850}
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition: lock.c:2263
#define DEFAULT_LOCKMETHOD
Definition: lock.h:126
#define USER_LOCKMETHOD
Definition: lock.h:127
void LockErrorCleanup(void)
Definition: proc.c:764

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

Referenced by ResourceOwnerReleaseInternal().

◆ ProcSendSignal()

void ProcSendSignal ( ProcNumber  procNumber)

Definition at line 1935 of file proc.c.

1936{
1937 if (procNumber < 0 || procNumber >= ProcGlobal->allProcCount)
1938 elog(ERROR, "procNumber out of range");
1939
1940 SetLatch(&ProcGlobal->allProcs[procNumber].procLatch);
1941}

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

Referenced by ReleasePredicateLocks(), and UnpinBufferNoOwner().

◆ ProcSleep()

ProcWaitStatus ProcSleep ( LOCALLOCK locallock)

Definition at line 1258 of file proc.c.

1259{
1260 LOCKMODE lockmode = locallock->tag.mode;
1261 LOCK *lock = locallock->lock;
1262 uint32 hashcode = locallock->hashcode;
1263 LWLock *partitionLock = LockHashPartitionLock(hashcode);
1264 TimestampTz standbyWaitStart = 0;
1265 bool allow_autovacuum_cancel = true;
1266 bool logged_recovery_conflict = false;
1267 ProcWaitStatus myWaitStatus;
1268
1269 /* The caller must've armed the on-error cleanup mechanism */
1270 Assert(GetAwaitedLock() == locallock);
1271 Assert(!LWLockHeldByMe(partitionLock));
1272
1273 /*
1274 * Now that we will successfully clean up after an ereport, it's safe to
1275 * check to see if there's a buffer pin deadlock against the Startup
1276 * process. Of course, that's only necessary if we're doing Hot Standby
1277 * and are not the Startup process ourselves.
1278 */
1281
1282 /* Reset deadlock_state before enabling the timeout handler */
1284 got_deadlock_timeout = false;
1285
1286 /*
1287 * Set timer so we can wake up after awhile and check for a deadlock. If a
1288 * deadlock is detected, the handler sets MyProc->waitStatus =
1289 * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure
1290 * rather than success.
1291 *
1292 * By delaying the check until we've waited for a bit, we can avoid
1293 * running the rather expensive deadlock-check code in most cases.
1294 *
1295 * If LockTimeout is set, also enable the timeout for that. We can save a
1296 * few cycles by enabling both timeout sources in one call.
1297 *
1298 * If InHotStandby we set lock waits slightly later for clarity with other
1299 * code.
1300 */
1301 if (!InHotStandby)
1302 {
1303 if (LockTimeout > 0)
1304 {
1305 EnableTimeoutParams timeouts[2];
1306
1307 timeouts[0].id = DEADLOCK_TIMEOUT;
1308 timeouts[0].type = TMPARAM_AFTER;
1309 timeouts[0].delay_ms = DeadlockTimeout;
1310 timeouts[1].id = LOCK_TIMEOUT;
1311 timeouts[1].type = TMPARAM_AFTER;
1312 timeouts[1].delay_ms = LockTimeout;
1313 enable_timeouts(timeouts, 2);
1314 }
1315 else
1317
1318 /*
1319 * Use the current time obtained for the deadlock timeout timer as
1320 * waitStart (i.e., the time when this process started waiting for the
1321 * lock). Since getting the current time newly can cause overhead, we
1322 * reuse the already-obtained time to avoid that overhead.
1323 *
1324 * Note that waitStart is updated without holding the lock table's
1325 * partition lock, to avoid the overhead by additional lock
1326 * acquisition. This can cause "waitstart" in pg_locks to become NULL
1327 * for a very short period of time after the wait started even though
1328 * "granted" is false. This is OK in practice because we can assume
1329 * that users are likely to look at "waitstart" when waiting for the
1330 * lock for a long time.
1331 */
1334 }
1336 {
1337 /*
1338 * Set the wait start timestamp if logging is enabled and in hot
1339 * standby.
1340 */
1341 standbyWaitStart = GetCurrentTimestamp();
1342 }
1343
1344 /*
1345 * If somebody wakes us between LWLockRelease and WaitLatch, the latch
1346 * will not wait. But a set latch does not necessarily mean that the lock
1347 * is free now, as there are many other sources for latch sets than
1348 * somebody releasing the lock.
1349 *
1350 * We process interrupts whenever the latch has been set, so cancel/die
1351 * interrupts are processed quickly. This means we must not mind losing
1352 * control to a cancel/die interrupt here. We don't, because we have no
1353 * shared-state-change work to do after being granted the lock (the
1354 * grantor did it all). We do have to worry about canceling the deadlock
1355 * timeout and updating the locallock table, but if we lose control to an
1356 * error, LockErrorCleanup will fix that up.
1357 */
1358 do
1359 {
1360 if (InHotStandby)
1361 {
1362 bool maybe_log_conflict =
1363 (standbyWaitStart != 0 && !logged_recovery_conflict);
1364
1365 /* Set a timer and wait for that or for the lock to be granted */
1367 maybe_log_conflict);
1368
1369 /*
1370 * Emit the log message if the startup process is waiting longer
1371 * than deadlock_timeout for recovery conflict on lock.
1372 */
1373 if (maybe_log_conflict)
1374 {
1376
1377 if (TimestampDifferenceExceeds(standbyWaitStart, now,
1379 {
1380 VirtualTransactionId *vxids;
1381 int cnt;
1382
1383 vxids = GetLockConflicts(&locallock->tag.lock,
1384 AccessExclusiveLock, &cnt);
1385
1386 /*
1387 * Log the recovery conflict and the list of PIDs of
1388 * backends holding the conflicting lock. Note that we do
1389 * logging even if there are no such backends right now
1390 * because the startup process here has already waited
1391 * longer than deadlock_timeout.
1392 */
1394 standbyWaitStart, now,
1395 cnt > 0 ? vxids : NULL, true);
1396 logged_recovery_conflict = true;
1397 }
1398 }
1399 }
1400 else
1401 {
1403 PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
1405 /* check for deadlocks first, as that's probably log-worthy */
1407 {
1408 CheckDeadLock();
1409 got_deadlock_timeout = false;
1410 }
1412 }
1413
1414 /*
1415 * waitStatus could change from PROC_WAIT_STATUS_WAITING to something
1416 * else asynchronously. Read it just once per loop to prevent
1417 * surprising behavior (such as missing log messages).
1418 */
1419 myWaitStatus = *((volatile ProcWaitStatus *) &MyProc->waitStatus);
1420
1421 /*
1422 * If we are not deadlocked, but are waiting on an autovacuum-induced
1423 * task, send a signal to interrupt it.
1424 */
1425 if (deadlock_state == DS_BLOCKED_BY_AUTOVACUUM && allow_autovacuum_cancel)
1426 {
1428 uint8 statusFlags;
1429 uint8 lockmethod_copy;
1430 LOCKTAG locktag_copy;
1431
1432 /*
1433 * Grab info we need, then release lock immediately. Note this
1434 * coding means that there is a tiny chance that the process
1435 * terminates its current transaction and starts a different one
1436 * before we have a change to send the signal; the worst possible
1437 * consequence is that a for-wraparound vacuum is canceled. But
1438 * that could happen in any case unless we were to do kill() with
1439 * the lock held, which is much more undesirable.
1440 */
1441 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1442 statusFlags = ProcGlobal->statusFlags[autovac->pgxactoff];
1443 lockmethod_copy = lock->tag.locktag_lockmethodid;
1444 locktag_copy = lock->tag;
1445 LWLockRelease(ProcArrayLock);
1446
1447 /*
1448 * Only do it if the worker is not working to protect against Xid
1449 * wraparound.
1450 */
1451 if ((statusFlags & PROC_IS_AUTOVACUUM) &&
1452 !(statusFlags & PROC_VACUUM_FOR_WRAPAROUND))
1453 {
1454 int pid = autovac->pid;
1455
1456 /* report the case, if configured to do so */
1458 {
1459 StringInfoData locktagbuf;
1460 StringInfoData logbuf; /* errdetail for server log */
1461
1462 initStringInfo(&locktagbuf);
1463 initStringInfo(&logbuf);
1464 DescribeLockTag(&locktagbuf, &locktag_copy);
1465 appendStringInfo(&logbuf,
1466 "Process %d waits for %s on %s.",
1467 MyProcPid,
1468 GetLockmodeName(lockmethod_copy, lockmode),
1469 locktagbuf.data);
1470
1472 (errmsg_internal("sending cancel to blocking autovacuum PID %d",
1473 pid),
1474 errdetail_log("%s", logbuf.data)));
1475
1476 pfree(locktagbuf.data);
1477 pfree(logbuf.data);
1478 }
1479
1480 /* send the autovacuum worker Back to Old Kent Road */
1481 if (kill(pid, SIGINT) < 0)
1482 {
1483 /*
1484 * There's a race condition here: once we release the
1485 * ProcArrayLock, it's possible for the autovac worker to
1486 * close up shop and exit before we can do the kill().
1487 * Therefore, we do not whinge about no-such-process.
1488 * Other errors such as EPERM could conceivably happen if
1489 * the kernel recycles the PID fast enough, but such cases
1490 * seem improbable enough that it's probably best to issue
1491 * a warning if we see some other errno.
1492 */
1493 if (errno != ESRCH)
1495 (errmsg("could not send signal to process %d: %m",
1496 pid)));
1497 }
1498 }
1499
1500 /* prevent signal from being sent again more than once */
1501 allow_autovacuum_cancel = false;
1502 }
1503
1504 /*
1505 * If awoken after the deadlock check interrupt has run, and
1506 * log_lock_waits is on, then report about the wait.
1507 */
1509 {
1511 lock_waiters_sbuf,
1512 lock_holders_sbuf;
1513 const char *modename;
1514 long secs;
1515 int usecs;
1516 long msecs;
1517 int lockHoldersNum = 0;
1518
1520 initStringInfo(&lock_waiters_sbuf);
1521 initStringInfo(&lock_holders_sbuf);
1522
1523 DescribeLockTag(&buf, &locallock->tag.lock);
1524 modename = GetLockmodeName(locallock->tag.lock.locktag_lockmethodid,
1525 lockmode);
1528 &secs, &usecs);
1529 msecs = secs * 1000 + usecs / 1000;
1530 usecs = usecs % 1000;
1531
1532 /* Gather a list of all lock holders and waiters */
1533 LWLockAcquire(partitionLock, LW_SHARED);
1534 GetLockHoldersAndWaiters(locallock, &lock_holders_sbuf,
1535 &lock_waiters_sbuf, &lockHoldersNum);
1536 LWLockRelease(partitionLock);
1537
1539 ereport(LOG,
1540 (errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
1541 MyProcPid, modename, buf.data, msecs, usecs),
1542 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1543 "Processes holding the lock: %s. Wait queue: %s.",
1544 lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1545 else if (deadlock_state == DS_HARD_DEADLOCK)
1546 {
1547 /*
1548 * This message is a bit redundant with the error that will be
1549 * reported subsequently, but in some cases the error report
1550 * might not make it to the log (eg, if it's caught by an
1551 * exception handler), and we want to ensure all long-wait
1552 * events get logged.
1553 */
1554 ereport(LOG,
1555 (errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
1556 MyProcPid, modename, buf.data, msecs, usecs),
1557 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1558 "Processes holding the lock: %s. Wait queue: %s.",
1559 lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1560 }
1561
1562 if (myWaitStatus == PROC_WAIT_STATUS_WAITING)
1563 ereport(LOG,
1564 (errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
1565 MyProcPid, modename, buf.data, msecs, usecs),
1566 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1567 "Processes holding the lock: %s. Wait queue: %s.",
1568 lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1569 else if (myWaitStatus == PROC_WAIT_STATUS_OK)
1570 ereport(LOG,
1571 (errmsg("process %d acquired %s on %s after %ld.%03d ms",
1572 MyProcPid, modename, buf.data, msecs, usecs)));
1573 else
1574 {
1575 Assert(myWaitStatus == PROC_WAIT_STATUS_ERROR);
1576
1577 /*
1578 * Currently, the deadlock checker always kicks its own
1579 * process, which means that we'll only see
1580 * PROC_WAIT_STATUS_ERROR when deadlock_state ==
1581 * DS_HARD_DEADLOCK, and there's no need to print redundant
1582 * messages. But for completeness and future-proofing, print
1583 * a message if it looks like someone else kicked us off the
1584 * lock.
1585 */
1587 ereport(LOG,
1588 (errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
1589 MyProcPid, modename, buf.data, msecs, usecs),
1590 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1591 "Processes holding the lock: %s. Wait queue: %s.",
1592 lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1593 }
1594
1595 /*
1596 * At this point we might still need to wait for the lock. Reset
1597 * state so we don't print the above messages again.
1598 */
1600
1601 pfree(buf.data);
1602 pfree(lock_holders_sbuf.data);
1603 pfree(lock_waiters_sbuf.data);
1604 }
1605 } while (myWaitStatus == PROC_WAIT_STATUS_WAITING);
1606
1607 /*
1608 * Disable the timers, if they are still running. As in LockErrorCleanup,
1609 * we must preserve the LOCK_TIMEOUT indicator flag: if a lock timeout has
1610 * already caused QueryCancelPending to become set, we want the cancel to
1611 * be reported as a lock timeout, not a user cancel.
1612 */
1613 if (!InHotStandby)
1614 {
1615 if (LockTimeout > 0)
1616 {
1617 DisableTimeoutParams timeouts[2];
1618
1619 timeouts[0].id = DEADLOCK_TIMEOUT;
1620 timeouts[0].keep_indicator = false;
1621 timeouts[1].id = LOCK_TIMEOUT;
1622 timeouts[1].keep_indicator = true;
1623 disable_timeouts(timeouts, 2);
1624 }
1625 else
1627 }
1628
1629 /*
1630 * Emit the log message if recovery conflict on lock was resolved but the
1631 * startup process waited longer than deadlock_timeout for it.
1632 */
1633 if (InHotStandby && logged_recovery_conflict)
1635 standbyWaitStart, GetCurrentTimestamp(),
1636 NULL, false);
1637
1638 /*
1639 * We don't have to do anything else, because the awaker did all the
1640 * necessary updates of the lock table and MyProc. (The caller is
1641 * responsible for updating the local lock table.)
1642 */
1643 return myWaitStatus;
1644}
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition: timestamp.c:1720
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
Definition: timestamp.c:1780
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1644
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1608
int64 TimestampTz
Definition: timestamp.h:39
PGPROC * GetBlockingAutoVacuumPgproc(void)
Definition: deadlock.c:290
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
bool message_level_is_interesting(int elevel)
Definition: elog.c:272
int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1272
int errdetail_log(const char *fmt,...)
Definition: elog.c:1251
#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:372
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:1243
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
Definition: lock.c:3025
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
Definition: lock.c:4211
@ DS_BLOCKED_BY_AUTOVACUUM
Definition: lock.h:515
@ DS_NO_DEADLOCK
Definition: lock.h:512
@ DS_NOT_YET_CHECKED
Definition: lock.h:511
@ DS_SOFT_DEADLOCK
Definition: lock.h:513
#define AccessExclusiveLock
Definition: lockdefs.h:43
@ LW_SHARED
Definition: lwlock.h:115
void pfree(void *pointer)
Definition: mcxt.c:1524
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
static char * buf
Definition: pg_test_fsync.c:72
#define PROC_VACUUM_FOR_WRAPAROUND
Definition: proc.h:60
ProcWaitStatus
Definition: proc.h:124
@ PROCSIG_RECOVERY_CONFLICT_LOCK
Definition: procsignal.h:44
bool log_lock_waits
Definition: proc.c:63
void GetLockHoldersAndWaiters(LOCALLOCK *locallock, StringInfo lock_holders_sbuf, StringInfo lock_waiters_sbuf, int *lockHoldersNum)
Definition: proc.c:1849
int DeadlockTimeout
Definition: proc.c:57
static void CheckDeadLock(void)
Definition: proc.c:1736
int LockTimeout
Definition: proc.c:59
void CheckRecoveryConflictDeadlock(void)
Definition: standby.c:904
bool log_recovery_conflict_waits
Definition: standby.c:41
void LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
Definition: standby.c:273
void ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict)
Definition: standby.c:622
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:411
Definition: lock.h:166
uint8 locktag_type
Definition: lock.h:171
uint8 locktag_lockmethodid
Definition: lock.h:172
int pgxactoff
Definition: proc.h:185
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_event.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:6380
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 1660 of file proc.c.

1661{
1662 if (dlist_node_is_detached(&proc->links))
1663 return;
1664
1666
1667 /* Remove process from wait queue */
1669
1670 /* Clean up process' state and pass it the ok/fail signal */
1671 proc->waitLock = NULL;
1672 proc->waitProcLock = NULL;
1673 proc->waitStatus = waitStatus;
1675
1676 /* And awaken it */
1677 SetLatch(&proc->procLatch);
1678}
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 857 of file proc.c.

858{
859 Assert(MyProc != NULL);
861}
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 705 of file proc.c.

706{
707 /* use volatile pointer to prevent code rearrangement */
708 volatile PROC_HDR *procglobal = ProcGlobal;
709
710 procglobal->startupBufferPinWaitBufId = bufid;
711}

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 82 of file proc.c.

Referenced by CheckDeadLock(), and ProcSleep().

◆ DeadlockTimeout

◆ got_deadlock_timeout

volatile sig_atomic_t got_deadlock_timeout
static

Definition at line 85 of file proc.c.

Referenced by CheckDeadLockAlert(), and ProcSleep().

◆ IdleInTransactionSessionTimeout

int IdleInTransactionSessionTimeout = 0

Definition at line 60 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

◆ IdleSessionTimeout

int IdleSessionTimeout = 0

Definition at line 62 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

◆ LockTimeout

int LockTimeout = 0

Definition at line 59 of file proc.c.

Referenced by ProcSleep().

◆ log_lock_waits

bool log_lock_waits = false

Definition at line 63 of file proc.c.

Referenced by ProcSleep().

◆ MyProc

PGPROC* MyProc = NULL

Definition at line 66 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(), ExportSnapshot(), FastPathGetRelationLockEntry(), FastPathGrantRelationLock(), FastPathUnGrantRelationLock(), FindLockCycleRecurseMember(), fmgr_sql(), get_cast_hashentry(), GetCurrentVirtualXIDs(), GetLockConflicts(), GetNewTransactionId(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), GetSnapshotDataReuse(), GetStableLatestTransactionId(), heap_inplace_update_and_unlock(), init_sql_fcache(), 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(), validate_sync_standby_slots(), VirtualXactLockTableCleanup(), VirtualXactLockTableInsert(), WaitXLogInsertionsToFinish(), write_csvlog(), write_jsonlog(), XidCacheRemoveRunningXids(), and XLogSaveBufferForHint().

◆ PreparedXactProcs

PGPROC* PreparedXactProcs = NULL

Definition at line 80 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 58 of file proc.c.

Referenced by enable_statement_timeout().

◆ TransactionTimeout