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

Go to the source code of this file.

Data Structures

struct  XidCacheStatus
 
struct  XidCache
 
struct  PGPROC
 
struct  PROC_HDR
 

Macros

#define PGPROC_MAX_CACHED_SUBXIDS   64 /* XXX guessed-at value */
 
#define PROC_IS_AUTOVACUUM   0x01 /* is it an autovac worker? */
 
#define PROC_IN_VACUUM   0x02 /* currently running lazy vacuum */
 
#define PROC_IN_SAFE_IC
 
#define PROC_VACUUM_FOR_WRAPAROUND   0x08 /* set by autovac only */
 
#define PROC_IN_LOGICAL_DECODING
 
#define PROC_AFFECTS_ALL_HORIZONS
 
#define PROC_VACUUM_STATE_MASK    (PROC_IN_VACUUM | PROC_IN_SAFE_IC | PROC_VACUUM_FOR_WRAPAROUND)
 
#define PROC_XMIN_FLAGS   (PROC_IN_VACUUM | PROC_IN_SAFE_IC)
 
#define FP_LOCK_GROUPS_PER_BACKEND_MAX   1024
 
#define FP_LOCK_SLOTS_PER_GROUP   16 /* don't change */
 
#define FastPathLockSlotsPerBackend()    (FP_LOCK_SLOTS_PER_GROUP * FastPathLockGroupsPerBackend)
 
#define DELAY_CHKPT_START   (1<<0)
 
#define DELAY_CHKPT_COMPLETE   (1<<1)
 
#define DELAY_CHKPT_IN_COMMIT   (DELAY_CHKPT_START | 1<<2)
 
#define GetPGProcByNumber(n)   (&ProcGlobal->allProcs[(n)])
 
#define GetNumberFromPGProc(proc)   ((proc) - &ProcGlobal->allProcs[0])
 
#define NUM_SPECIAL_WORKER_PROCS   2
 
#define MAX_IO_WORKERS   32
 
#define NUM_AUXILIARY_PROCS   (6 + MAX_IO_WORKERS)
 

Typedefs

typedef struct XidCacheStatus XidCacheStatus
 
typedef struct PROC_HDR PROC_HDR
 

Enumerations

enum  ProcWaitStatus { PROC_WAIT_STATUS_OK , PROC_WAIT_STATUS_WAITING , PROC_WAIT_STATUS_ERROR }
 

Functions

int ProcGlobalSemas (void)
 
Size ProcGlobalShmemSize (void)
 
void InitProcGlobal (void)
 
void InitProcess (void)
 
void InitProcessPhase2 (void)
 
void InitAuxiliaryProcess (void)
 
void SetStartupBufferPinWaitBufId (int bufid)
 
int GetStartupBufferPinWaitBufId (void)
 
bool HaveNFreeProcs (int n, int *nfree)
 
void ProcReleaseLocks (bool isCommit)
 
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 LockErrorCleanup (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)
 
PGPROCAuxiliaryPidGetProc (int pid)
 
void BecomeLockGroupLeader (void)
 
bool BecomeLockGroupMember (PGPROC *leader, int pid)
 

Variables

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

Macro Definition Documentation

◆ DELAY_CHKPT_COMPLETE

#define DELAY_CHKPT_COMPLETE   (1<<1)

Definition at line 137 of file proc.h.

◆ DELAY_CHKPT_IN_COMMIT

#define DELAY_CHKPT_IN_COMMIT   (DELAY_CHKPT_START | 1<<2)

Definition at line 138 of file proc.h.

◆ DELAY_CHKPT_START

#define DELAY_CHKPT_START   (1<<0)

Definition at line 136 of file proc.h.

◆ FastPathLockSlotsPerBackend

#define FastPathLockSlotsPerBackend ( )     (FP_LOCK_SLOTS_PER_GROUP * FastPathLockGroupsPerBackend)

Definition at line 94 of file proc.h.

147{
152
153/*
154 * Each backend has a PGPROC struct in shared memory. There is also a list of
155 * currently-unused PGPROC structs that will be reallocated to new backends.
156 *
157 * links: list link for any list the PGPROC is in. When waiting for a lock,
158 * the PGPROC is linked into that lock's waitProcs queue. A recycled PGPROC
159 * is linked into ProcGlobal's freeProcs list.
160 *
161 * Note: twophase.c also sets up a dummy PGPROC struct for each currently
162 * prepared transaction. These PGPROCs appear in the ProcArray data structure
163 * so that the prepared transactions appear to be still running and are
164 * correctly shown as holding locks. A prepared transaction PGPROC can be
165 * distinguished from a real one at need by the fact that it has pid == 0.
166 * The semaphore and lock-activity fields in a prepared-xact PGPROC are unused,
167 * but its myProcLocks[] lists are valid.
168 *
169 * We allow many fields of this struct to be accessed without locks, such as
170 * delayChkptFlags and backendType. However, keep in mind that writing
171 * mirrored ones (see below) requires holding ProcArrayLock or XidGenLock in
172 * at least shared mode, so that pgxactoff does not change concurrently.
173 *
174 * Mirrored fields:
175 *
176 * Some fields in PGPROC (see "mirrored in ..." comment) are mirrored into an
177 * element of more densely packed ProcGlobal arrays. These arrays are indexed
178 * by PGPROC->pgxactoff. Both copies need to be maintained coherently.
179 *
180 * NB: The pgxactoff indexed value can *never* be accessed without holding
181 * locks.
182 *
183 * See PROC_HDR for details.
184 */
185struct PGPROC
186{
187 dlist_node links; /* list link if process is in a list */
188 dlist_head *procgloballist; /* procglobal list that owns this PGPROC */
189
190 PGSemaphore sem; /* ONE semaphore to sleep on */
192
193 Latch procLatch; /* generic latch for process */
194
195
196 TransactionId xid; /* id of top-level transaction currently being
197 * executed by this proc, if running and XID
198 * is assigned; else InvalidTransactionId.
199 * mirrored in ProcGlobal->xids[pgxactoff] */
200
201 TransactionId xmin; /* minimal running XID as it was when we were
202 * starting our xact, excluding LAZY VACUUM:
203 * vacuum must not remove tuples deleted by
204 * xid >= xmin ! */
205
206 int pid; /* Backend's process ID; 0 if prepared xact */
207
208 int pgxactoff; /* offset into various ProcGlobal->arrays with
209 * data mirrored from this PGPROC */
210
211 /*
212 * Currently running top-level transaction's virtual xid. Together these
213 * form a VirtualTransactionId, but we don't use that struct because this
214 * is not atomically assignable as whole, and we want to enforce code to
215 * consider both parts separately. See comments at VirtualTransactionId.
216 */
217 struct
218 {
219 ProcNumber procNumber; /* For regular backends, equal to
220 * GetNumberFromPGProc(proc). For prepared
221 * xacts, ID of the original backend that
222 * processed the transaction. For unused
223 * PGPROC entries, INVALID_PROC_NUMBER. */
224 LocalTransactionId lxid; /* local id of top-level transaction
225 * currently * being executed by this
226 * proc, if running; else
227 * InvalidLocalTransactionId */
228 } vxid;
229
230 /* These fields are zero while a backend is still starting up: */
231 Oid databaseId; /* OID of database this backend is using */
232 Oid roleId; /* OID of role using this backend */
233
234 Oid tempNamespaceId; /* OID of temp schema this backend is
235 * using */
236
237 BackendType backendType; /* what kind of process is this? */
238
239 /*
240 * While in hot standby mode, shows that a conflict signal has been sent
241 * for the current transaction. Set/cleared while holding ProcArrayLock,
242 * though not required. Accessed without lock, if needed.
243 *
244 * This is a bitmask; each bit corresponds to a RecoveryConflictReason
245 * enum value.
246 */
248
249 /*
250 * Info about LWLock the process is currently waiting for, if any.
251 *
252 * This is currently used both for lwlocks and buffer content locks, which
253 * is acceptable, although not pretty, because a backend can't wait for
254 * both types of locks at the same time.
255 */
256 uint8 lwWaiting; /* see LWLockWaitState */
257 uint8 lwWaitMode; /* lwlock mode being waited for */
258 proclist_node lwWaitLink; /* position in LW lock wait list */
259
260 /* Support for condition variables. */
261 proclist_node cvWaitLink; /* position in CV wait list */
262
263 /* Info about lock the process is currently waiting for, if any. */
264 /* waitLock and waitProcLock are NULL if not currently waiting. */
265 LOCK *waitLock; /* Lock object we're sleeping on ... */
266 PROCLOCK *waitProcLock; /* Per-holder info for awaited lock */
267 LOCKMODE waitLockMode; /* type of lock we're waiting for */
268 LOCKMASK heldLocks; /* bitmask for lock types already held on this
269 * lock object by this backend */
270 pg_atomic_uint64 waitStart; /* time at which wait for lock acquisition
271 * started */
272
273 int delayChkptFlags; /* for DELAY_CHKPT_* flags */
274
275 uint8 statusFlags; /* this backend's status flags, see PROC_*
276 * above. mirrored in
277 * ProcGlobal->statusFlags[pgxactoff] */
278
279 /*
280 * Info to allow us to wait for synchronous replication, if needed.
281 * waitLSN is InvalidXLogRecPtr if not waiting; set only by user backend.
282 * syncRepState must not be touched except by owning process or WALSender.
283 * syncRepLinks used only while holding SyncRepLock.
284 */
285 XLogRecPtr waitLSN; /* waiting for this LSN or higher */
286 int syncRepState; /* wait state for sync rep */
287 dlist_node syncRepLinks; /* list link if process is in syncrep queue */
288
289 /*
290 * All PROCLOCK objects for locks held or awaited by this backend are
291 * linked into one of these lists, according to the partition number of
292 * their lock.
293 */
295
296 XidCacheStatus subxidStatus; /* mirrored with
297 * ProcGlobal->subxidStates[i] */
298 struct XidCache subxids; /* cache for subtransaction XIDs */
299
300 /* Support for group XID clearing. */
301 /* true, if member of ProcArray group waiting for XID clear */
303 /* next ProcArray group member waiting for XID clear */
305
306 /*
307 * latest transaction id among the transaction's main XID and
308 * subtransactions
309 */
311
312 uint32 wait_event_info; /* proc's wait information */
313
314 /* Support for group transaction status update. */
315 bool clogGroupMember; /* true, if member of clog group */
316 pg_atomic_uint32 clogGroupNext; /* next clog group member */
317 TransactionId clogGroupMemberXid; /* transaction id of clog group member */
318 XidStatus clogGroupMemberXidStatus; /* transaction status of clog
319 * group member */
320 int64 clogGroupMemberPage; /* clog page corresponding to
321 * transaction id of clog group member */
322 XLogRecPtr clogGroupMemberLsn; /* WAL location of commit record for clog
323 * group member */
324
325 /* Lock manager data, recording fast-path locks taken by this backend. */
326 LWLock fpInfoLock; /* protects per-backend fast-path state */
327 uint64 *fpLockBits; /* lock modes held for each fast-path slot */
328 Oid *fpRelId; /* slots for rel oids */
329 bool fpVXIDLock; /* are we holding a fast-path VXID lock? */
330 LocalTransactionId fpLocalTransactionId; /* lxid for fast-path VXID
331 * lock */
332
333 /*
334 * Support for lock groups. Use LockHashPartitionLockByProc on the group
335 * leader to get the LWLock protecting these fields.
336 */
337 PGPROC *lockGroupLeader; /* lock group leader, if I'm a member */
338 dlist_head lockGroupMembers; /* list of members, if I'm a leader */
339 dlist_node lockGroupLink; /* my member link, if I'm a member */
340};
341
342/* NOTE: "typedef struct PGPROC PGPROC" appears in storage/lock.h. */
343
344
346
347/*
348 * There is one ProcGlobal struct for the whole database cluster.
349 *
350 * Adding/Removing an entry into the procarray requires holding *both*
351 * ProcArrayLock and XidGenLock in exclusive mode (in that order). Both are
352 * needed because the dense arrays (see below) are accessed from
353 * GetNewTransactionId() and GetSnapshotData(), and we don't want to add
354 * further contention by both using the same lock. Adding/Removing a procarray
355 * entry is much less frequent.
356 *
357 * Some fields in PGPROC are mirrored into more densely packed arrays (e.g.
358 * xids), with one entry for each backend. These arrays only contain entries
359 * for PGPROCs that have been added to the shared array with ProcArrayAdd()
360 * (in contrast to PGPROC array which has unused PGPROCs interspersed).
361 *
362 * The dense arrays are indexed by PGPROC->pgxactoff. Any concurrent
363 * ProcArrayAdd() / ProcArrayRemove() can lead to pgxactoff of a procarray
364 * member to change. Therefore it is only safe to use PGPROC->pgxactoff to
365 * access the dense array while holding either ProcArrayLock or XidGenLock.
366 *
367 * As long as a PGPROC is in the procarray, the mirrored values need to be
368 * maintained in both places in a coherent manner.
369 *
370 * The denser separate arrays are beneficial for three main reasons: First, to
371 * allow for as tight loops accessing the data as possible. Second, to prevent
372 * updates of frequently changing data (e.g. xmin) from invalidating
373 * cachelines also containing less frequently changing data (e.g. xid,
374 * statusFlags). Third to condense frequently accessed data into as few
375 * cachelines as possible.
376 *
377 * There are two main reasons to have the data mirrored between these dense
378 * arrays and PGPROC. First, as explained above, a PGPROC's array entries can
379 * only be accessed with either ProcArrayLock or XidGenLock held, whereas the
380 * PGPROC entries do not require that (obviously there may still be locking
381 * requirements around the individual field, separate from the concerns
382 * here). That is particularly important for a backend to efficiently checks
383 * it own values, which it often can safely do without locking. Second, the
384 * PGPROC fields allow to avoid unnecessary accesses and modification to the
385 * dense arrays. A backend's own PGPROC is more likely to be in a local cache,
386 * whereas the cachelines for the dense array will be modified by other
387 * backends (often removing it from the cache for other cores/sockets). At
388 * commit/abort time a check of the PGPROC value can avoid accessing/dirtying
389 * the corresponding array value.
390 *
391 * Basically it makes sense to access the PGPROC variable when checking a
392 * single backend's data, especially when already looking at the PGPROC for
393 * other reasons already. It makes sense to look at the "dense" arrays if we
394 * need to look at many / most entries, because we then benefit from the
395 * reduced indirection and better cross-process cache-ability.
396 *
397 * When entering a PGPROC for 2PC transactions with ProcArrayAdd(), the data
398 * in the dense arrays is initialized from the PGPROC while it already holds
399 * ProcArrayLock.
400 */
401typedef struct PROC_HDR
402{
403 /* Array of PGPROC structures (not including dummies for prepared txns) */
405
406 /* Array mirroring PGPROC.xid for each PGPROC currently in the procarray */
408
409 /*
410 * Array mirroring PGPROC.subxidStatus for each PGPROC currently in the
411 * procarray.
412 */
414
415 /*
416 * Array mirroring PGPROC.statusFlags for each PGPROC currently in the
417 * procarray.
418 */
420
421 /* Length of allProcs array */
423
424 /*
425 * This spinlock protects the below freelists of PGPROC structures. We
426 * cannot use an LWLock because the LWLock manager depends on already
427 * having a PGPROC and a wait semaphore! But these structures are touched
428 * relatively infrequently (only at backend startup or shutdown) and not
429 * for very long, so a spinlock is okay.
430 */
432
433 /* Head of list of free PGPROC structures */
435 /* Head of list of autovacuum & special worker free PGPROC structures */
437 /* Head of list of bgworker free PGPROC structures */
439 /* Head of list of walsender free PGPROC structures */
441
442 /* First pgproc waiting for group XID clear */
444 /* First pgproc waiting for group transaction status update */
446
447 /*
448 * Current slot numbers of some auxiliary processes. There can be only one
449 * of each of these running at a time.
450 */
453
454 /* Current shared estimate of appropriate spins_per_delay value */
455 int spins_per_delay;
456 /* Buffer id of the buffer that Startup process waits for pin on, or -1 */
458} PROC_HDR;
459
461
463
464/*
465 * Accessors for getting PGPROC given a ProcNumber and vice versa.
466 */
467#define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)])
468#define GetNumberFromPGProc(proc) ((proc) - &ProcGlobal->allProcs[0])
469
470/*
471 * We set aside some extra PGPROC structures for "special worker" processes,
472 * which are full-fledged backends (they can run transactions)
473 * but are unique animals that there's never more than one of.
474 * Currently there are two such processes: the autovacuum launcher
475 * and the slotsync worker.
476 */
477#define NUM_SPECIAL_WORKER_PROCS 2
478
479/*
480 * We set aside some extra PGPROC structures for auxiliary processes,
481 * ie things that aren't full-fledged backends (they cannot run transactions
482 * or take heavyweight locks) but need shmem access.
483 *
484 * Background writer, checkpointer, WAL writer, WAL summarizer, and archiver
485 * run during normal operation. Startup process and WAL receiver also consume
486 * 2 slots, but WAL writer is launched only after startup has exited, so we
487 * only need 6 slots.
488 */
489#define MAX_IO_WORKERS 32
490#define NUM_AUXILIARY_PROCS (6 + MAX_IO_WORKERS)
491
492
493/* configurable options */
496extern PGDLLIMPORT int LockTimeout;
500extern PGDLLIMPORT bool log_lock_waits;
501
502#ifdef EXEC_BACKEND
504#endif
505
506
507/*
508 * Function Prototypes
509 */
510extern int ProcGlobalSemas(void);
511extern Size ProcGlobalShmemSize(void);
512extern void InitProcGlobal(void);
513extern void InitProcess(void);
514extern void InitProcessPhase2(void);
515extern void InitAuxiliaryProcess(void);
516
517extern void SetStartupBufferPinWaitBufId(int bufid);
518extern int GetStartupBufferPinWaitBufId(void);
519
520extern bool HaveNFreeProcs(int n, int *nfree);
521extern void ProcReleaseLocks(bool isCommit);
522
526extern void ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus);
528extern void CheckDeadLockAlert(void);
529extern void LockErrorCleanup(void);
533 int *lockHoldersNum);
534
535extern void ProcWaitForSignal(uint32 wait_event_info);
536extern void ProcSendSignal(ProcNumber procNumber);
537
538extern PGPROC *AuxiliaryPidGetProc(int pid);
539
540extern void BecomeLockGroupLeader(void);
541extern bool BecomeLockGroupMember(PGPROC *leader, int pid);
542
543#endif /* _PROC_H_ */
#define PGDLLIMPORT
Definition c.h:1334
uint8_t uint8
Definition c.h:544
int64_t int64
Definition c.h:543
uint64_t uint64
Definition c.h:547
uint32_t uint32
Definition c.h:546
uint32 LocalTransactionId
Definition c.h:668
uint32 TransactionId
Definition c.h:666
size_t Size
Definition c.h:619
int XidStatus
Definition clog.h:25
int LOCKMODE
Definition lockdefs.h:26
int LOCKMASK
Definition lockdefs.h:25
#define NUM_LOCK_PARTITIONS
Definition lwlock.h:95
BackendType
Definition miscadmin.h:338
unsigned int Oid
static int fb(int x)
ProcWaitStatus JoinWaitQueue(LOCALLOCK *locallock, LockMethod lockMethodTable, bool dontWait)
Definition proc.c:1130
void ProcSendSignal(ProcNumber procNumber)
Definition proc.c:1982
PGDLLIMPORT int IdleInTransactionSessionTimeout
Definition proc.c:61
Size ProcGlobalShmemSize(void)
Definition proc.c:129
void ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus)
Definition proc.c:1702
PGDLLIMPORT int IdleSessionTimeout
Definition proc.c:63
bool HaveNFreeProcs(int n, int *nfree)
Definition proc.c:771
void InitAuxiliaryProcess(void)
Definition proc.c:604
void GetLockHoldersAndWaiters(LOCALLOCK *locallock, StringInfo lock_holders_sbuf, StringInfo lock_waiters_sbuf, int *lockHoldersNum)
Definition proc.c:1896
PGDLLIMPORT PROC_HDR * ProcGlobal
Definition proc.c:70
int GetStartupBufferPinWaitBufId(void)
Definition proc.c:755
ProcWaitStatus ProcSleep(LOCALLOCK *locallock)
Definition proc.c:1299
PGDLLIMPORT PGPROC * MyProc
Definition proc.c:67
void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
Definition proc.c:1730
int ProcGlobalSemas(void)
Definition proc.c:148
void ProcReleaseLocks(bool isCommit)
Definition proc.c:880
void LockErrorCleanup(void)
Definition proc.c:802
bool BecomeLockGroupMember(PGPROC *leader, int pid)
Definition proc.c:2027
PGDLLIMPORT int StatementTimeout
Definition proc.c:59
void BecomeLockGroupLeader(void)
Definition proc.c:1997
PGDLLIMPORT int DeadlockTimeout
Definition proc.c:58
PGDLLIMPORT int LockTimeout
Definition proc.c:60
void InitProcess(void)
Definition proc.c:379
void CheckDeadLockAlert(void)
Definition proc.c:1869
void InitProcessPhase2(void)
Definition proc.c:569
void InitProcGlobal(void)
Definition proc.c:183
PGDLLIMPORT bool log_lock_waits
Definition proc.c:64
ProcWaitStatus
Definition proc.h:141
@ PROC_WAIT_STATUS_OK
Definition proc.h:142
@ PROC_WAIT_STATUS_WAITING
Definition proc.h:143
@ PROC_WAIT_STATUS_ERROR
Definition proc.h:144
PGDLLIMPORT PGPROC * PreparedXactProcs
Definition proc.c:72
PGDLLIMPORT int TransactionTimeout
Definition proc.c:62
PGPROC * AuxiliaryPidGetProc(int pid)
Definition proc.c:1081
void SetStartupBufferPinWaitBufId(int bufid)
Definition proc.c:743
void ProcWaitForSignal(uint32 wait_event_info)
Definition proc.c:1970
int ProcNumber
Definition procnumber.h:24
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition proc.c:71
Definition lock.h:311
Definition latch.h:114
Definition proc.h:180
LWLock fpInfoLock
Definition proc.h:320
TransactionId xmin
Definition proc.h:195
bool procArrayGroupMember
Definition proc.h:296
LocalTransactionId lxid
Definition proc.h:218
PROCLOCK * waitProcLock
Definition proc.h:260
XLogRecPtr clogGroupMemberLsn
Definition proc.h:316
pg_atomic_uint32 procArrayGroupNext
Definition proc.h:298
uint8 lwWaitMode
Definition proc.h:251
dlist_head lockGroupMembers
Definition proc.h:332
uint32 wait_event_info
Definition proc.h:306
dlist_head * procgloballist
Definition proc.h:182
Oid * fpRelId
Definition proc.h:322
BackendType backendType
Definition proc.h:231
uint8 statusFlags
Definition proc.h:269
TransactionId clogGroupMemberXid
Definition proc.h:311
Oid databaseId
Definition proc.h:225
int64 clogGroupMemberPage
Definition proc.h:314
bool clogGroupMember
Definition proc.h:309
uint64 * fpLockBits
Definition proc.h:321
pg_atomic_uint64 waitStart
Definition proc.h:264
bool fpVXIDLock
Definition proc.h:323
ProcNumber procNumber
Definition proc.h:213
int pid
Definition proc.h:200
XLogRecPtr waitLSN
Definition proc.h:279
dlist_node syncRepLinks
Definition proc.h:281
struct PGPROC::@131 vxid
int syncRepState
Definition proc.h:280
pg_atomic_uint32 clogGroupNext
Definition proc.h:310
dlist_node lockGroupLink
Definition proc.h:333
XidStatus clogGroupMemberXidStatus
Definition proc.h:312
int pgxactoff
Definition proc.h:202
XidCacheStatus subxidStatus
Definition proc.h:290
LOCK * waitLock
Definition proc.h:259
proclist_node lwWaitLink
Definition proc.h:252
TransactionId xid
Definition proc.h:190
LOCKMODE waitLockMode
Definition proc.h:261
struct XidCache subxids
Definition proc.h:292
int delayChkptFlags
Definition proc.h:267
PGPROC * lockGroupLeader
Definition proc.h:331
pg_atomic_uint32 pendingRecoveryConflicts
Definition proc.h:241
LocalTransactionId fpLocalTransactionId
Definition proc.h:324
TransactionId procArrayGroupMemberXid
Definition proc.h:304
LOCKMASK heldLocks
Definition proc.h:262
PGSemaphore sem
Definition proc.h:184
dlist_head myProcLocks[NUM_LOCK_PARTITIONS]
Definition proc.h:288
Oid roleId
Definition proc.h:226
ProcWaitStatus waitStatus
Definition proc.h:185
proclist_node cvWaitLink
Definition proc.h:255
Oid tempNamespaceId
Definition proc.h:228
dlist_node links
Definition proc.h:181
uint8 lwWaiting
Definition proc.h:250
Latch procLatch
Definition proc.h:187
uint8 * statusFlags
Definition proc.h:413
XidCacheStatus * subxidStates
Definition proc.h:407
dlist_head autovacFreeProcs
Definition proc.h:430
dlist_head freeProcs
Definition proc.h:428
ProcNumber checkpointerProc
Definition proc.h:446
slock_t freeProcsLock
Definition proc.h:425
int startupBufferPinWaitBufId
Definition proc.h:451
PGPROC * allProcs
Definition proc.h:398
pg_atomic_uint32 clogGroupFirst
Definition proc.h:439
int spins_per_delay
Definition proc.h:449
TransactionId * xids
Definition proc.h:401
dlist_head walsenderFreeProcs
Definition proc.h:434
dlist_head bgworkerFreeProcs
Definition proc.h:432
ProcNumber walwriterProc
Definition proc.h:445
pg_atomic_uint32 procArrayGroupFirst
Definition proc.h:437
uint32 allProcCount
Definition proc.h:416
uint64 XLogRecPtr
Definition xlogdefs.h:21

◆ FP_LOCK_GROUPS_PER_BACKEND_MAX

#define FP_LOCK_GROUPS_PER_BACKEND_MAX   1024

Definition at line 92 of file proc.h.

◆ FP_LOCK_SLOTS_PER_GROUP

#define FP_LOCK_SLOTS_PER_GROUP   16 /* don't change */

Definition at line 93 of file proc.h.

◆ GetNumberFromPGProc

#define GetNumberFromPGProc (   proc)    ((proc) - &ProcGlobal->allProcs[0])

Definition at line 462 of file proc.h.

◆ GetPGProcByNumber

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

Definition at line 461 of file proc.h.

◆ MAX_IO_WORKERS

#define MAX_IO_WORKERS   32

Definition at line 483 of file proc.h.

◆ NUM_AUXILIARY_PROCS

#define NUM_AUXILIARY_PROCS   (6 + MAX_IO_WORKERS)

Definition at line 484 of file proc.h.

◆ NUM_SPECIAL_WORKER_PROCS

#define NUM_SPECIAL_WORKER_PROCS   2

Definition at line 471 of file proc.h.

◆ PGPROC_MAX_CACHED_SUBXIDS

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

Definition at line 40 of file proc.h.

◆ PROC_AFFECTS_ALL_HORIZONS

#define PROC_AFFECTS_ALL_HORIZONS
Value:
0x20 /* this proc's xmin must be
* included in vacuum horizons
* in all databases */

Definition at line 63 of file proc.h.

◆ PROC_IN_LOGICAL_DECODING

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

Definition at line 62 of file proc.h.

◆ PROC_IN_SAFE_IC

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

Definition at line 60 of file proc.h.

◆ PROC_IN_VACUUM

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

Definition at line 59 of file proc.h.

◆ PROC_IS_AUTOVACUUM

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

Definition at line 58 of file proc.h.

◆ PROC_VACUUM_FOR_WRAPAROUND

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

Definition at line 61 of file proc.h.

◆ PROC_VACUUM_STATE_MASK

#define PROC_VACUUM_STATE_MASK    (PROC_IN_VACUUM | PROC_IN_SAFE_IC | PROC_VACUUM_FOR_WRAPAROUND)

Definition at line 66 of file proc.h.

◆ PROC_XMIN_FLAGS

#define PROC_XMIN_FLAGS   (PROC_IN_VACUUM | PROC_IN_SAFE_IC)

Definition at line 73 of file proc.h.

Typedef Documentation

◆ PROC_HDR

◆ XidCacheStatus

Enumeration Type Documentation

◆ ProcWaitStatus

Enumerator
PROC_WAIT_STATUS_OK 
PROC_WAIT_STATUS_WAITING 
PROC_WAIT_STATUS_ERROR 

Definition at line 140 of file proc.h.

Function Documentation

◆ AuxiliaryPidGetProc()

PGPROC * AuxiliaryPidGetProc ( int  pid)
extern

Definition at line 1081 of file proc.c.

1082{
1083 PGPROC *result = NULL;
1084 int index;
1085
1086 if (pid == 0) /* never match dummy PGPROCs */
1087 return NULL;
1088
1089 for (index = 0; index < NUM_AUXILIARY_PROCS; index++)
1090 {
1091 PGPROC *proc = &AuxiliaryProcs[index];
1092
1093 if (proc->pid == pid)
1094 {
1095 result = proc;
1096 break;
1097 }
1098 }
1099 return result;
1100}
#define NUM_AUXILIARY_PROCS
Definition proc.h:484
Definition type.h:96

References AuxiliaryProcs, fb(), NUM_AUXILIARY_PROCS, and PGPROC::pid.

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

◆ BecomeLockGroupLeader()

void BecomeLockGroupLeader ( void  )
extern

Definition at line 1997 of file proc.c.

1998{
2000
2001 /* If we already did it, we don't need to do it again. */
2003 return;
2004
2005 /* We had better not be a follower. */
2007
2008 /* Create single-member group, containing only ourselves. */
2014}
#define Assert(condition)
Definition c.h:873
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:1176
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1793
@ LW_EXCLUSIVE
Definition lwlock.h:112
PGPROC * MyProc
Definition proc.c:67

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

Referenced by LaunchParallelWorkers().

◆ BecomeLockGroupMember()

bool BecomeLockGroupMember ( PGPROC leader,
int  pid 
)
extern

Definition at line 2027 of file proc.c.

2028{
2030 bool ok = false;
2031
2032 /* Group leader can't become member of group */
2033 Assert(MyProc != leader);
2034
2035 /* Can't already be a member of a group */
2037
2038 /* PID must be valid. */
2039 Assert(pid != 0);
2040
2041 /*
2042 * Get lock protecting the group fields. Note LockHashPartitionLockByProc
2043 * calculates the proc number based on the PGPROC slot without looking at
2044 * its contents, so we will acquire the correct lock even if the leader
2045 * PGPROC is in process of being recycled.
2046 */
2049
2050 /* Is this the leader we're looking for? */
2051 if (leader->pid == pid && leader->lockGroupLeader == leader)
2052 {
2053 /* OK, join the group */
2054 ok = true;
2055 MyProc->lockGroupLeader = leader;
2057 }
2059
2060 return ok;
2061}
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition ilist.h:364

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

Referenced by ParallelWorkerMain().

◆ CheckDeadLockAlert()

void CheckDeadLockAlert ( void  )
extern

Definition at line 1869 of file proc.c.

1870{
1871 int save_errno = errno;
1872
1873 got_deadlock_timeout = true;
1874
1875 /*
1876 * Have to set the latch again, even if handle_sig_alarm already did. Back
1877 * then got_deadlock_timeout wasn't yet set... It's unlikely that this
1878 * ever would be a problem, but setting a set latch again is cheap.
1879 *
1880 * Note that, when this function runs inside procsignal_sigusr1_handler(),
1881 * the handler function sets the latch again after the latch is set here.
1882 */
1884 errno = save_errno;
1885}
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:75

References fb(), 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 
)
extern

Definition at line 1896 of file proc.c.

1898{
1901 LOCK *lock = locallock->lock;
1902 bool first_holder = true,
1903 first_waiter = true;
1904
1905#ifdef USE_ASSERT_CHECKING
1906 {
1907 uint32 hashcode = locallock->hashcode;
1909
1911 }
1912#endif
1913
1914 *lockHoldersNum = 0;
1915
1916 /*
1917 * Loop over the lock's procLocks to gather a list of all holders and
1918 * waiters. Thus we will be able to provide more detailed information for
1919 * lock debugging purposes.
1920 *
1921 * lock->procLocks contains all processes which hold or wait for this
1922 * lock.
1923 */
1925 {
1926 curproclock =
1927 dlist_container(PROCLOCK, lockLink, proc_iter.cur);
1928
1929 /*
1930 * We are a waiter if myProc->waitProcLock == curproclock; we are a
1931 * holder if it is NULL or something different.
1932 */
1933 if (curproclock->tag.myProc->waitProcLock == curproclock)
1934 {
1935 if (first_waiter)
1936 {
1938 curproclock->tag.myProc->pid);
1939 first_waiter = false;
1940 }
1941 else
1943 curproclock->tag.myProc->pid);
1944 }
1945 else
1946 {
1947 if (first_holder)
1948 {
1950 curproclock->tag.myProc->pid);
1951 first_holder = false;
1952 }
1953 else
1955 curproclock->tag.myProc->pid);
1956
1957 (*lockHoldersNum)++;
1958 }
1959 }
1960}
#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:1911
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
dlist_head procLocks
Definition lock.h:318

References appendStringInfo(), Assert, dlist_container, dlist_foreach, fb(), LockHashPartitionLock, LWLockHeldByMe(), and LOCK::procLocks.

Referenced by LockAcquireExtended(), and ProcSleep().

◆ GetStartupBufferPinWaitBufId()

int GetStartupBufferPinWaitBufId ( void  )
extern

Definition at line 755 of file proc.c.

756{
757 /* use volatile pointer to prevent code rearrangement */
758 volatile PROC_HDR *procglobal = ProcGlobal;
759
761}
PROC_HDR * ProcGlobal
Definition proc.c:70

References fb(), ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by HoldingBufferPinThatDelaysRecovery().

◆ HaveNFreeProcs()

bool HaveNFreeProcs ( int  n,
int nfree 
)
extern

Definition at line 771 of file proc.c.

772{
773 dlist_iter iter;
774
775 Assert(n > 0);
776 Assert(nfree);
777
779
780 *nfree = 0;
782 {
783 (*nfree)++;
784 if (*nfree == n)
785 break;
786 }
787
789
790 return (*nfree == n);
791}
#define SpinLockRelease(lock)
Definition spin.h:61
#define SpinLockAcquire(lock)
Definition spin.h:59

References Assert, dlist_foreach, PROC_HDR::freeProcs, PROC_HDR::freeProcsLock, ProcGlobal, SpinLockAcquire, and SpinLockRelease.

Referenced by InitPostgres().

◆ InitAuxiliaryProcess()

void InitAuxiliaryProcess ( void  )
extern

Definition at line 604 of file proc.c.

605{
607 int proctype;
608
609 /*
610 * ProcGlobal should be set up already (if we are a backend, we inherit
611 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
612 */
613 if (ProcGlobal == NULL || AuxiliaryProcs == NULL)
614 elog(PANIC, "proc header uninitialized");
615
616 if (MyProc != NULL)
617 elog(ERROR, "you already exist");
618
621
622 /*
623 * We use the freeProcsLock to protect assignment and releasing of
624 * AuxiliaryProcs entries.
625 *
626 * While we are holding the spinlock, also copy the current shared
627 * estimate of spins_per_delay to local storage.
628 */
630
632
633 /*
634 * Find a free auxproc ... *big* trouble if there isn't one ...
635 */
637 {
639 if (auxproc->pid == 0)
640 break;
641 }
643 {
645 elog(FATAL, "all AuxiliaryProcs are in use");
646 }
647
648 /* Mark auxiliary proc as in use by me */
649 /* use volatile pointer to prevent code rearrangement */
650 ((volatile PGPROC *) auxproc)->pid = MyProcPid;
651
653
654 MyProc = auxproc;
656
657 /*
658 * Initialize all fields of MyProc, except for those previously
659 * initialized by InitProcGlobal.
660 */
663 MyProc->fpVXIDLock = false;
674 MyProc->statusFlags = 0;
676 MyProc->lwWaitMode = 0;
680#ifdef USE_ASSERT_CHECKING
681 {
682 int i;
683
684 /* Last process should have released all locks. */
685 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
687 }
688#endif
689
690 /*
691 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
692 * on it. That allows us to repoint the process latch, which so far
693 * points to process local one, to the shared one.
694 */
697
698 /* now that we have a proc, report wait events to shared memory */
700
701 /* Check that group locking fields are in a proper initial state. */
704
705 /*
706 * We might be reusing a semaphore that belonged to a failed process. So
707 * be careful and reinitialize its value here. (This is not strictly
708 * necessary anymore, but seems like a good idea for cleanliness.)
709 */
711
712 /*
713 * Arrange to clean up at process exit.
714 */
716
717 /*
718 * Now that we have a PGPROC, we could try to acquire lightweight locks.
719 * Initialize local state needed for them. (Heavyweight locks cannot be
720 * acquired in aux processes.)
721 */
723
724#ifdef EXEC_BACKEND
725
726 /*
727 * Initialize backend-local pointers to all the shared data structures.
728 * (We couldn't do this until now because it needs LWLocks.)
729 */
732#endif
733}
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:485
#define FATAL
Definition elog.h:41
#define PANIC
Definition elog.h:42
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
int MyProcPid
Definition globals.c:47
ProcNumber MyProcNumber
Definition globals.c:90
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:372
int i
Definition isn.c:77
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
BackendType MyBackendType
Definition miscinit.c:64
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
#define GetNumberFromPGProc(proc)
Definition proc.h:462
#define INVALID_PROC_NUMBER
Definition procnumber.h:26
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:1030
#define InvalidTransactionId
Definition transam.h:31
void pgstat_set_wait_event_storage(uint32 *wait_event_info)
Definition wait_event.c:349

References Assert, AuxiliaryProcKill(), AuxiliaryProcs, PGPROC::backendType, PGPROC::databaseId, PGPROC::delayChkptFlags, dlist_is_empty(), dlist_node_init(), elog, ERROR, FATAL, fb(), PGPROC::fpLocalTransactionId, PGPROC::fpVXIDLock, PROC_HDR::freeProcsLock, GetNumberFromPGProc, i, InitLWLockAccess(), Int32GetDatum(), INVALID_PROC_NUMBER, InvalidLocalTransactionId, InvalidOid, InvalidTransactionId, IsUnderPostmaster, PGPROC::links, PGPROC::lockGroupLeader, PGPROC::lockGroupMembers, LW_WS_NOT_WAITING, PGPROC::lwWaiting, PGPROC::lwWaitMode, PGPROC::lxid, MyBackendType, 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(), PROC_WAIT_STATUS_OK, ProcGlobal, PGPROC::procLatch, PGPROC::procNumber, 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  )
extern

Definition at line 379 of file proc.c.

380{
381 dlist_head *procgloballist;
382
383 /*
384 * ProcGlobal should be set up already (if we are a backend, we inherit
385 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
386 */
387 if (ProcGlobal == NULL)
388 elog(PANIC, "proc header uninitialized");
389
390 if (MyProc != NULL)
391 elog(ERROR, "you already exist");
392
393 /*
394 * Before we start accessing the shared memory in a serious way, mark
395 * ourselves as an active postmaster child; this is so that the postmaster
396 * can detect it if we exit without cleaning up.
397 */
400
401 /*
402 * Decide which list should supply our PGPROC. This logic must match the
403 * way the freelists were constructed in InitProcGlobal().
404 */
406 procgloballist = &ProcGlobal->autovacFreeProcs;
407 else if (AmBackgroundWorkerProcess())
408 procgloballist = &ProcGlobal->bgworkerFreeProcs;
409 else if (AmWalSenderProcess())
410 procgloballist = &ProcGlobal->walsenderFreeProcs;
411 else
412 procgloballist = &ProcGlobal->freeProcs;
413
414 /*
415 * Try to get a proc struct from the appropriate free list. If this
416 * fails, we must be out of PGPROC structures (not to mention semaphores).
417 *
418 * While we are holding the spinlock, also copy the current shared
419 * estimate of spins_per_delay to local storage.
420 */
422
424
425 if (!dlist_is_empty(procgloballist))
426 {
429 }
430 else
431 {
432 /*
433 * If we reach here, all the PGPROCs are in use. This is one of the
434 * possible places to detect "too many backends", so give the standard
435 * error message. XXX do we need to give a different failure message
436 * in the autovacuum case?
437 */
439 if (AmWalSenderProcess())
442 errmsg("number of requested standby connections exceeds \"max_wal_senders\" (currently %d)",
446 errmsg("sorry, too many clients already")));
447 }
449
450 /*
451 * Cross-check that the PGPROC is of the type we expect; if this were not
452 * the case, it would get returned to the wrong list.
453 */
454 Assert(MyProc->procgloballist == procgloballist);
455
456 /*
457 * Initialize all fields of MyProc, except for those previously
458 * initialized by InitProcGlobal.
459 */
462 MyProc->fpVXIDLock = false;
469 /* databaseId and roleId will be filled in later */
475 MyProc->statusFlags = 0;
476 /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
480 MyProc->lwWaitMode = 0;
484#ifdef USE_ASSERT_CHECKING
485 {
486 int i;
487
488 /* Last process should have released all locks. */
489 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
491 }
492#endif
494
495 /* Initialize fields for sync rep */
499
500 /* Initialize fields for group XID clearing. */
504
505 /* Check that group locking fields are in a proper initial state. */
508
509 /* Initialize wait event information. */
511
512 /* Initialize fields for group transaction status update. */
513 MyProc->clogGroupMember = false;
519
520 /*
521 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
522 * on it. That allows us to repoint the process latch, which so far
523 * points to process local one, to the shared one.
524 */
527
528 /* now that we have a proc, report wait events to shared memory */
530
531 /*
532 * We might be reusing a semaphore that belonged to a failed process. So
533 * be careful and reinitialize its value here. (This is not strictly
534 * necessary anymore, but seems like a good idea for cleanliness.)
535 */
537
538 /*
539 * Arrange to clean up at backend exit.
540 */
542
543 /*
544 * Now that we have a PGPROC, we could try to acquire locks, so initialize
545 * local state needed for LWLocks, and the deadlock checker.
546 */
549
550#ifdef EXEC_BACKEND
551
552 /*
553 * Initialize backend-local pointers to all the shared data structures.
554 * (We couldn't do this until now because it needs LWLocks.)
555 */
558#endif
559}
static void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition atomics.h:274
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:143
int errcode(int sqlerrcode)
Definition elog.c:864
int errmsg(const char *fmt,...)
Definition elog.c:1081
#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 PROC_IS_AUTOVACUUM
Definition proc.h:58
static void ProcKill(int code, Datum arg)
Definition proc.c:908
#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, AmSpecialWorkerProcess, AmWalSenderProcess, Assert, PROC_HDR::autovacFreeProcs, PGPROC::backendType, 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, fb(), PGPROC::fpLocalTransactionId, PGPROC::fpVXIDLock, PROC_HDR::freeProcs, PROC_HDR::freeProcsLock, GetNumberFromPGProc, i, InitDeadLockChecking(), InitLWLockAccess(), INVALID_PROC_NUMBER, InvalidLocalTransactionId, InvalidOid, InvalidTransactionId, InvalidXLogRecPtr, IsUnderPostmaster, PGPROC::links, links, PGPROC::lockGroupLeader, PGPROC::lockGroupMembers, LW_WS_NOT_WAITING, PGPROC::lwWaiting, PGPROC::lwWaitMode, PGPROC::lxid, max_wal_senders, MyBackendType, MyProc, PGPROC::myProcLocks, MyProcNumber, MyProcPid, NUM_LOCK_PARTITIONS, on_shmem_exit(), OwnLatch(), PANIC, PGPROC::pendingRecoveryConflicts, pg_atomic_read_u32(), pg_atomic_write_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, 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  )
extern

Definition at line 569 of file proc.c.

570{
571 Assert(MyProc != NULL);
572
573 /*
574 * Add our PGPROC to the PGPROC array in shared memory.
575 */
577
578 /*
579 * Arrange to clean that up at backend exit.
580 */
582}
void ProcArrayAdd(PGPROC *proc)
Definition procarray.c:471
static void RemoveProcFromArray(int code, Datum arg)
Definition proc.c:897

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

Referenced by InitPostgres().

◆ InitProcGlobal()

void InitProcGlobal ( void  )
extern

Definition at line 183 of file proc.c.

184{
185 PGPROC *procs;
186 int i,
187 j;
188 bool found;
190
191 /* Used for setup of per-backend fast-path slots. */
192 char *fpPtr,
197 char *ptr;
198
199 /* Create the ProcGlobal shared structure */
200 ProcGlobal = (PROC_HDR *)
201 ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
202 Assert(!found);
203
204 /*
205 * Initialize the data structures.
206 */
218
219 /*
220 * Create and initialize all the PGPROC structures we'll need. There are
221 * six separate consumers: (1) normal backends, (2) autovacuum workers and
222 * special workers, (3) background workers, (4) walsenders, (5) auxiliary
223 * processes, and (6) prepared transactions. (For largely-historical
224 * reasons, we combine autovacuum and special workers into one category
225 * with a single freelist.) Each PGPROC structure is dedicated to exactly
226 * one of these purposes, and they do not move between groups.
227 */
229
230 ptr = ShmemInitStruct("PGPROC structures",
232 &found);
233
234 MemSet(ptr, 0, requestSize);
235
236 procs = (PGPROC *) ptr;
237 ptr = ptr + TotalProcs * sizeof(PGPROC);
238
239 ProcGlobal->allProcs = procs;
240 /* XXX allProcCount isn't really all of them; it excludes prepared xacts */
242
243 /*
244 * Allocate arrays mirroring PGPROC fields in a dense manner. See
245 * PROC_HDR.
246 *
247 * XXX: It might make sense to increase padding for these arrays, given
248 * how hotly they are accessed.
249 */
250 ProcGlobal->xids = (TransactionId *) ptr;
251 ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->xids));
252
254 ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->subxidStates));
255
256 ProcGlobal->statusFlags = (uint8 *) ptr;
257 ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->statusFlags));
258
259 /* make sure wer didn't overflow */
260 Assert((ptr > (char *) procs) && (ptr <= (char *) procs + requestSize));
261
262 /*
263 * Allocate arrays for fast-path locks. Those are variable-length, so
264 * can't be included in PGPROC directly. We allocate a separate piece of
265 * shared memory and then divide that between backends.
266 */
269
271
272 fpPtr = ShmemInitStruct("Fast-Path Lock Array",
274 &found);
275
277
278 /* For asserts checking we did not overflow. */
280
281 /* Reserve space for semaphores. */
283
284 for (i = 0; i < TotalProcs; i++)
285 {
286 PGPROC *proc = &procs[i];
287
288 /* Common initialization for all PGPROCs, regardless of type. */
289
290 /*
291 * Set the fast-path lock arrays, and move the pointer. We interleave
292 * the two arrays, to (hopefully) get some locality for each backend.
293 */
294 proc->fpLockBits = (uint64 *) fpPtr;
296
297 proc->fpRelId = (Oid *) fpPtr;
299
301
302 /*
303 * Set up per-PGPROC semaphore, latch, and fpInfoLock. Prepared xact
304 * dummy PGPROCs don't need these though - they're never associated
305 * with a real process
306 */
308 {
309 proc->sem = PGSemaphoreCreate();
310 InitSharedLatch(&(proc->procLatch));
312 }
313
314 /*
315 * Newly created PGPROCs for normal backends, autovacuum workers,
316 * special workers, bgworkers, and walsenders must be queued up on the
317 * appropriate free list. Because there can only ever be a small,
318 * fixed number of auxiliary processes, no free list is used in that
319 * case; InitAuxiliaryProcess() instead uses a linear search. PGPROCs
320 * for prepared transactions are added to a free list by
321 * TwoPhaseShmemInit().
322 */
323 if (i < MaxConnections)
324 {
325 /* PGPROC for normal backend, add to freeProcs list */
328 }
330 {
331 /* PGPROC for AV or special worker, add to autovacFreeProcs list */
334 }
336 {
337 /* PGPROC for bgworker, add to bgworkerFreeProcs list */
340 }
341 else if (i < MaxBackends)
342 {
343 /* PGPROC for walsender, add to walsenderFreeProcs list */
346 }
347
348 /* Initialize myProcLocks[] shared memory queues. */
349 for (j = 0; j < NUM_LOCK_PARTITIONS; j++)
350 dlist_init(&(proc->myProcLocks[j]));
351
352 /* Initialize lockGroupMembers list. */
354
355 /*
356 * Initialize the atomic variables, otherwise, it won't be safe to
357 * access them for backends that aren't currently in use.
358 */
361 pg_atomic_init_u64(&(proc->waitStart), 0);
362 }
363
364 /* Should have consumed exactly the expected amount of fast-path memory. */
366
367 /*
368 * Save pointers to the blocks of PGPROC structures reserved for auxiliary
369 * processes and prepared transactions.
370 */
371 AuxiliaryProcs = &procs[MaxBackends];
373}
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:453
int autovacuum_worker_slots
Definition autovacuum.c:118
#define MAXALIGN(LEN)
Definition c.h:826
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:223
#define MemSet(start, val, len)
Definition c.h:1013
int MaxConnections
Definition globals.c:143
int MaxBackends
Definition globals.c:146
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
int FastPathLockGroupsPerBackend
Definition lock.c:202
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 FastPathLockSlotsPerBackend()
Definition proc.h:94
#define NUM_SPECIAL_WORKER_PROCS
Definition proc.h:471
#define DEFAULT_SPINS_PER_DELAY
Definition s_lock.h:726
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition shmem.c:378
#define SpinLockInit(lock)
Definition spin.h:57
PGPROC * PreparedXactProcs
Definition proc.c:72
static Size PGProcShmemSize(void)
Definition proc.c:87
static Size FastPathLockShmemSize(void)
Definition proc.c:105
int ProcGlobalSemas(void)
Definition proc.c:148
int max_prepared_xacts
Definition twophase.c:116

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, fb(), PGPROC::fpInfoLock, PGPROC::fpLockBits, PGPROC::fpRelId, PROC_HDR::freeProcs, PROC_HDR::freeProcsLock, 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, 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 
)
extern

Definition at line 1130 of file proc.c.

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

References Assert, dlist_iter::cur, dclist_foreach, dclist_insert_before(), dclist_is_empty(), dclist_push_tail(), dlist_container, dlist_foreach, fb(), GrantLock(), PGPROC::heldLocks, PROCLOCK::holdMask, PGPROC::links, links, LOCKBIT_ON, LockCheckConflicts(), PGPROC::lockGroupLeader, LockHashPartitionLock, LW_EXCLUSIVE, LWLockHeldByMeInMode(), MyProc, PG_USED_FOR_ASSERTS_ONLY, PROC_WAIT_STATUS_ERROR, PROC_WAIT_STATUS_OK, PROC_WAIT_STATUS_WAITING, LOCK::procLocks, RememberSimpleDeadLock(), PGPROC::waitLock, PGPROC::waitLockMode, LOCK::waitMask, PGPROC::waitProcLock, LOCK::waitProcs, and PGPROC::waitStatus.

Referenced by LockAcquireExtended().

◆ LockErrorCleanup()

void LockErrorCleanup ( void  )
extern

Definition at line 802 of file proc.c.

803{
807
809
811
812 /* Nothing to do if we weren't waiting for a lock */
814 if (lockAwaited == NULL)
815 {
817 return;
818 }
819
820 /*
821 * Turn off the deadlock and lock timeout timers, if they are still
822 * running (see ProcSleep). Note we must preserve the LOCK_TIMEOUT
823 * indicator flag, since this function is executed before
824 * ProcessInterrupts when responding to SIGINT; else we'd lose the
825 * knowledge that the SIGINT came from a lock timeout and not an external
826 * source.
827 */
829 timeouts[0].keep_indicator = false;
830 timeouts[1].id = LOCK_TIMEOUT;
831 timeouts[1].keep_indicator = true;
833
834 /* Unlink myself from the wait queue, if on it (might not be anymore!) */
837
839 {
840 /* We could not have been granted the lock yet */
842 }
843 else
844 {
845 /*
846 * Somebody kicked us off the lock queue already. Perhaps they
847 * granted us the lock, or perhaps they detected a deadlock. If they
848 * did grant us the lock, we'd better remember it in our local lock
849 * table.
850 */
853 }
854
856
858
860}
static bool dlist_node_is_detached(const dlist_node *node)
Definition ilist.h:525
void GrantAwaitedLock(void)
Definition lock.c:1889
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition lock.c:2046
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
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(), fb(), GetAwaitedLock(), GrantAwaitedLock(), HOLD_INTERRUPTS, 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(), ProcReleaseLocks(), and report_recovery_conflict().

◆ ProcGlobalSemas()

int ProcGlobalSemas ( void  )
extern

Definition at line 148 of file proc.c.

149{
150 /*
151 * We need a sema per backend (including autovacuum), plus one for each
152 * auxiliary process.
153 */
155}

References MaxBackends, and NUM_AUXILIARY_PROCS.

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

◆ ProcGlobalShmemSize()

Size ProcGlobalShmemSize ( void  )
extern

Definition at line 129 of file proc.c.

130{
131 Size size = 0;
132
133 /* ProcGlobal */
134 size = add_size(size, sizeof(PROC_HDR));
135 size = add_size(size, sizeof(slock_t));
136
138 size = add_size(size, PGProcShmemSize());
139 size = add_size(size, FastPathLockShmemSize());
140
141 return size;
142}
Size PGSemaphoreShmemSize(int maxSemas)
Definition posix_sema.c:165
Size add_size(Size s1, Size s2)
Definition shmem.c:482

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

Referenced by CalculateShmemSize().

◆ ProcLockWakeup()

void ProcLockWakeup ( LockMethod  lockMethodTable,
LOCK lock 
)
extern

Definition at line 1730 of file proc.c.

1731{
1735
1737 return;
1738
1740 {
1741 PGPROC *proc = dlist_container(PGPROC, links, miter.cur);
1742 LOCKMODE lockmode = proc->waitLockMode;
1743
1744 /*
1745 * Waken if (a) doesn't conflict with requests of earlier waiters, and
1746 * (b) doesn't conflict with already-held locks.
1747 */
1748 if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1749 !LockCheckConflicts(lockMethodTable, lockmode, lock,
1750 proc->waitProcLock))
1751 {
1752 /* OK to waken */
1753 GrantLock(lock, proc->waitProcLock, lockmode);
1754 /* removes proc from the lock's waiting process queue */
1756 }
1757 else
1758 {
1759 /*
1760 * Lock conflicts: Don't wake, but remember requested mode for
1761 * later checks.
1762 */
1763 aheadRequests |= LOCKBIT_ON(lockmode);
1764 }
1765 }
1766}
#define dclist_foreach_modify(iter, lhead)
Definition ilist.h:973
void ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus)
Definition proc.c:1702

References dclist_foreach_modify, dclist_is_empty(), dlist_container, fb(), 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)
extern

Definition at line 880 of file proc.c.

881{
882 if (!MyProc)
883 return;
884 /* If waiting, get off wait queue (should only be needed after error) */
886 /* Release standard locks, including session-level if aborting */
888 /* Release transaction-level advisory locks */
890}
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:802

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

Referenced by ResourceOwnerReleaseInternal().

◆ ProcSendSignal()

void ProcSendSignal ( ProcNumber  procNumber)
extern

Definition at line 1982 of file proc.c.

1983{
1985 elog(ERROR, "procNumber out of range");
1986
1987 SetLatch(&GetPGProcByNumber(procNumber)->procLatch);
1988}
#define GetPGProcByNumber(n)
Definition proc.h:461

References PROC_HDR::allProcCount, elog, ERROR, fb(), GetPGProcByNumber, ProcGlobal, and SetLatch().

Referenced by ReleasePredicateLocks(), and WakePinCountWaiter().

◆ ProcSleep()

ProcWaitStatus ProcSleep ( LOCALLOCK locallock)
extern

Definition at line 1299 of file proc.c.

1300{
1301 LOCKMODE lockmode = locallock->tag.mode;
1302 LOCK *lock = locallock->lock;
1303 uint32 hashcode = locallock->hashcode;
1306 bool allow_autovacuum_cancel = true;
1307 bool logged_recovery_conflict = false;
1310
1311 /* The caller must've armed the on-error cleanup mechanism */
1314
1315 /*
1316 * Now that we will successfully clean up after an ereport, it's safe to
1317 * check to see if there's a buffer pin deadlock against the Startup
1318 * process. Of course, that's only necessary if we're doing Hot Standby
1319 * and are not the Startup process ourselves.
1320 */
1323
1324 /* Reset deadlock_state before enabling the timeout handler */
1326 got_deadlock_timeout = false;
1327
1328 /*
1329 * Set timer so we can wake up after awhile and check for a deadlock. If a
1330 * deadlock is detected, the handler sets MyProc->waitStatus =
1331 * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure
1332 * rather than success.
1333 *
1334 * By delaying the check until we've waited for a bit, we can avoid
1335 * running the rather expensive deadlock-check code in most cases.
1336 *
1337 * If LockTimeout is set, also enable the timeout for that. We can save a
1338 * few cycles by enabling both timeout sources in one call.
1339 *
1340 * If InHotStandby we set lock waits slightly later for clarity with other
1341 * code.
1342 */
1343 if (!InHotStandby)
1344 {
1345 if (LockTimeout > 0)
1346 {
1348
1350 timeouts[0].type = TMPARAM_AFTER;
1351 timeouts[0].delay_ms = DeadlockTimeout;
1352 timeouts[1].id = LOCK_TIMEOUT;
1353 timeouts[1].type = TMPARAM_AFTER;
1354 timeouts[1].delay_ms = LockTimeout;
1356 }
1357 else
1359
1360 /*
1361 * Use the current time obtained for the deadlock timeout timer as
1362 * waitStart (i.e., the time when this process started waiting for the
1363 * lock). Since getting the current time newly can cause overhead, we
1364 * reuse the already-obtained time to avoid that overhead.
1365 *
1366 * Note that waitStart is updated without holding the lock table's
1367 * partition lock, to avoid the overhead by additional lock
1368 * acquisition. This can cause "waitstart" in pg_locks to become NULL
1369 * for a very short period of time after the wait started even though
1370 * "granted" is false. This is OK in practice because we can assume
1371 * that users are likely to look at "waitstart" when waiting for the
1372 * lock for a long time.
1373 */
1376 }
1378 {
1379 /*
1380 * Set the wait start timestamp if logging is enabled and in hot
1381 * standby.
1382 */
1384 }
1385
1386 /*
1387 * If somebody wakes us between LWLockRelease and WaitLatch, the latch
1388 * will not wait. But a set latch does not necessarily mean that the lock
1389 * is free now, as there are many other sources for latch sets than
1390 * somebody releasing the lock.
1391 *
1392 * We process interrupts whenever the latch has been set, so cancel/die
1393 * interrupts are processed quickly. This means we must not mind losing
1394 * control to a cancel/die interrupt here. We don't, because we have no
1395 * shared-state-change work to do after being granted the lock (the
1396 * grantor did it all). We do have to worry about canceling the deadlock
1397 * timeout and updating the locallock table, but if we lose control to an
1398 * error, LockErrorCleanup will fix that up.
1399 */
1400 do
1401 {
1402 if (InHotStandby)
1403 {
1404 bool maybe_log_conflict =
1406
1407 /* Set a timer and wait for that or for the lock to be granted */
1410
1411 /*
1412 * Emit the log message if the startup process is waiting longer
1413 * than deadlock_timeout for recovery conflict on lock.
1414 */
1416 {
1418
1421 {
1423 int cnt;
1424
1425 vxids = GetLockConflicts(&locallock->tag.lock,
1426 AccessExclusiveLock, &cnt);
1427
1428 /*
1429 * Log the recovery conflict and the list of PIDs of
1430 * backends holding the conflicting lock. Note that we do
1431 * logging even if there are no such backends right now
1432 * because the startup process here has already waited
1433 * longer than deadlock_timeout.
1434 */
1437 cnt > 0 ? vxids : NULL, true);
1439 }
1440 }
1441 }
1442 else
1443 {
1445 PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
1447 /* check for deadlocks first, as that's probably log-worthy */
1449 {
1451 got_deadlock_timeout = false;
1452 }
1454 }
1455
1456 /*
1457 * waitStatus could change from PROC_WAIT_STATUS_WAITING to something
1458 * else asynchronously. Read it just once per loop to prevent
1459 * surprising behavior (such as missing log messages).
1460 */
1461 myWaitStatus = *((volatile ProcWaitStatus *) &MyProc->waitStatus);
1462
1463 /*
1464 * If we are not deadlocked, but are waiting on an autovacuum-induced
1465 * task, send a signal to interrupt it.
1466 */
1468 {
1470 uint8 statusFlags;
1473
1474 /*
1475 * Grab info we need, then release lock immediately. Note this
1476 * coding means that there is a tiny chance that the process
1477 * terminates its current transaction and starts a different one
1478 * before we have a change to send the signal; the worst possible
1479 * consequence is that a for-wraparound vacuum is canceled. But
1480 * that could happen in any case unless we were to do kill() with
1481 * the lock held, which is much more undesirable.
1482 */
1484 statusFlags = ProcGlobal->statusFlags[autovac->pgxactoff];
1486 locktag_copy = lock->tag;
1488
1489 /*
1490 * Only do it if the worker is not working to protect against Xid
1491 * wraparound.
1492 */
1493 if ((statusFlags & PROC_IS_AUTOVACUUM) &&
1494 !(statusFlags & PROC_VACUUM_FOR_WRAPAROUND))
1495 {
1496 int pid = autovac->pid;
1497
1498 /* report the case, if configured to do so */
1500 {
1502 StringInfoData logbuf; /* errdetail for server log */
1503
1508 "Process %d waits for %s on %s.",
1509 MyProcPid,
1511 locktagbuf.data);
1512
1514 (errmsg_internal("sending cancel to blocking autovacuum PID %d",
1515 pid),
1516 errdetail_log("%s", logbuf.data)));
1517
1518 pfree(locktagbuf.data);
1519 pfree(logbuf.data);
1520 }
1521
1522 /* send the autovacuum worker Back to Old Kent Road */
1523 if (kill(pid, SIGINT) < 0)
1524 {
1525 /*
1526 * There's a race condition here: once we release the
1527 * ProcArrayLock, it's possible for the autovac worker to
1528 * close up shop and exit before we can do the kill().
1529 * Therefore, we do not whinge about no-such-process.
1530 * Other errors such as EPERM could conceivably happen if
1531 * the kernel recycles the PID fast enough, but such cases
1532 * seem improbable enough that it's probably best to issue
1533 * a warning if we see some other errno.
1534 */
1535 if (errno != ESRCH)
1537 (errmsg("could not send signal to process %d: %m",
1538 pid)));
1539 }
1540 }
1541
1542 /* prevent signal from being sent again more than once */
1544 }
1545
1546 /*
1547 * If awoken after the deadlock check interrupt has run, and
1548 * log_lock_waits is on, then report about the wait.
1549 */
1551 {
1555 const char *modename;
1556 long secs;
1557 int usecs;
1558 long msecs;
1559 int lockHoldersNum = 0;
1560
1564
1565 DescribeLockTag(&buf, &locallock->tag.lock);
1566 modename = GetLockmodeName(locallock->tag.lock.locktag_lockmethodid,
1567 lockmode);
1570 &secs, &usecs);
1571 msecs = secs * 1000 + usecs / 1000;
1572 usecs = usecs % 1000;
1573
1574 /* Gather a list of all lock holders and waiters */
1579
1581 ereport(LOG,
1582 (errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
1583 MyProcPid, modename, buf.data, msecs, usecs),
1584 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1585 "Processes holding the lock: %s. Wait queue: %s.",
1587 else if (deadlock_state == DS_HARD_DEADLOCK)
1588 {
1589 /*
1590 * This message is a bit redundant with the error that will be
1591 * reported subsequently, but in some cases the error report
1592 * might not make it to the log (eg, if it's caught by an
1593 * exception handler), and we want to ensure all long-wait
1594 * events get logged.
1595 */
1596 ereport(LOG,
1597 (errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
1598 MyProcPid, modename, buf.data, msecs, usecs),
1599 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1600 "Processes holding the lock: %s. Wait queue: %s.",
1602 }
1603
1605 ereport(LOG,
1606 (errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
1607 MyProcPid, modename, buf.data, msecs, usecs),
1608 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1609 "Processes holding the lock: %s. Wait queue: %s.",
1612 ereport(LOG,
1613 (errmsg("process %d acquired %s on %s after %ld.%03d ms",
1614 MyProcPid, modename, buf.data, msecs, usecs)));
1615 else
1616 {
1618
1619 /*
1620 * Currently, the deadlock checker always kicks its own
1621 * process, which means that we'll only see
1622 * PROC_WAIT_STATUS_ERROR when deadlock_state ==
1623 * DS_HARD_DEADLOCK, and there's no need to print redundant
1624 * messages. But for completeness and future-proofing, print
1625 * a message if it looks like someone else kicked us off the
1626 * lock.
1627 */
1629 ereport(LOG,
1630 (errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
1631 MyProcPid, modename, buf.data, msecs, usecs),
1632 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1633 "Processes holding the lock: %s. Wait queue: %s.",
1635 }
1636
1637 /*
1638 * At this point we might still need to wait for the lock. Reset
1639 * state so we don't print the above messages again.
1640 */
1642
1643 pfree(buf.data);
1646 }
1648
1649 /*
1650 * Disable the timers, if they are still running. As in LockErrorCleanup,
1651 * we must preserve the LOCK_TIMEOUT indicator flag: if a lock timeout has
1652 * already caused QueryCancelPending to become set, we want the cancel to
1653 * be reported as a lock timeout, not a user cancel.
1654 */
1655 if (!InHotStandby)
1656 {
1657 if (LockTimeout > 0)
1658 {
1660
1662 timeouts[0].keep_indicator = false;
1663 timeouts[1].id = LOCK_TIMEOUT;
1664 timeouts[1].keep_indicator = true;
1666 }
1667 else
1669 }
1670
1671 /*
1672 * Emit the log message if recovery conflict on lock was resolved but the
1673 * startup process waited longer than deadlock_timeout for it.
1674 */
1678 NULL, false);
1679
1680 /*
1681 * We don't have to do anything else, because the awaker did all the
1682 * necessary updates of the lock table and MyProc. (The caller is
1683 * responsible for updating the local lock table.)
1684 */
1685 return myWaitStatus;
1686}
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:288
int errmsg_internal(const char *fmt,...)
Definition elog.c:1171
bool message_level_is_interesting(int elevel)
Definition elog.c:274
int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition elog.c:1286
int errdetail_log(const char *fmt,...)
Definition elog.c:1265
#define LOG
Definition elog.h:31
#define WARNING
Definition elog.h:36
#define DEBUG1
Definition elog.h:30
return true
Definition isn.c:130
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:4252
DeadLockState
Definition lock.h:511
@ DS_HARD_DEADLOCK
Definition lock.h:515
@ 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:1616
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define PROC_VACUUM_FOR_WRAPAROUND
Definition proc.h:61
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:1896
int DeadlockTimeout
Definition proc.c:58
int LockTimeout
Definition proc.c:60
static DeadLockState CheckDeadLock(void)
Definition proc.c:1777
void CheckRecoveryConflictDeadlock(void)
Definition standby.c:905
bool log_recovery_conflict_waits
Definition standby.c:42
void LogRecoveryConflict(RecoveryConflictReason 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:624
@ RECOVERY_CONFLICT_LOCK
Definition standby.h:37
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
uint8 locktag_lockmethodid
Definition lock.h:173
LOCKTAG tag
Definition lock.h:313
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
#define WL_EXIT_ON_PM_DEATH
#define WL_LATCH_SET
#define kill(pid, sig)
Definition win32_port.h:490
bool RecoveryInProgress(void)
Definition xlog.c:6460
bool InRecovery
Definition xlogutils.c:50
#define InHotStandby
Definition xlogutils.h:60

References AccessExclusiveLock, appendStringInfo(), Assert, buf, CHECK_FOR_INTERRUPTS, CheckDeadLock(), CheckRecoveryConflictDeadlock(), DEADLOCK_TIMEOUT, DeadlockTimeout, DEBUG1, 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(), fb(), get_timeout_start_time(), GetAwaitedLock(), GetBlockingAutoVacuumPgproc(), GetCurrentTimestamp(), GetLockConflicts(), GetLockHoldersAndWaiters(), GetLockmodeName(), got_deadlock_timeout, EnableTimeoutParams::id, DisableTimeoutParams::id, InHotStandby, initStringInfo(), InRecovery, kill, LOCK_TIMEOUT, LockHashPartitionLock, LOCKTAG::locktag_lockmethodid, LockTimeout, LOG, log_lock_waits, log_recovery_conflict_waits, LogRecoveryConflict(), LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockHeldByMe(), LWLockRelease(), message_level_is_interesting(), MyLatch, MyProc, MyProcPid, now(), pfree(), pg_atomic_write_u64(), PG_WAIT_LOCK, PROC_IS_AUTOVACUUM, PROC_VACUUM_FOR_WRAPAROUND, PROC_WAIT_STATUS_ERROR, PROC_WAIT_STATUS_OK, PROC_WAIT_STATUS_WAITING, ProcGlobal, RECOVERY_CONFLICT_LOCK, RecoveryInProgress(), ResetLatch(), ResolveRecoveryConflictWithLock(), PROC_HDR::statusFlags, LOCK::tag, TimestampDifference(), TimestampDifferenceExceeds(), TMPARAM_AFTER, 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)
extern

◆ ProcWakeup()

void ProcWakeup ( PGPROC proc,
ProcWaitStatus  waitStatus 
)
extern

Definition at line 1702 of file proc.c.

1703{
1704 if (dlist_node_is_detached(&proc->links))
1705 return;
1706
1708
1709 /* Remove process from wait queue */
1711
1712 /* Clean up process' state and pass it the ok/fail signal */
1713 proc->waitLock = NULL;
1714 proc->waitProcLock = NULL;
1715 proc->waitStatus = waitStatus;
1717
1718 /* And awaken it */
1719 SetLatch(&proc->procLatch);
1720}
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(), fb(), 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().

◆ SetStartupBufferPinWaitBufId()

void SetStartupBufferPinWaitBufId ( int  bufid)
extern

Definition at line 743 of file proc.c.

744{
745 /* use volatile pointer to prevent code rearrangement */
746 volatile PROC_HDR *procglobal = ProcGlobal;
747
749}

References fb(), ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by LockBufferForCleanup().

Variable Documentation

◆ DeadlockTimeout

◆ FastPathLockGroupsPerBackend

PGDLLIMPORT int FastPathLockGroupsPerBackend
extern

◆ IdleInTransactionSessionTimeout

PGDLLIMPORT int IdleInTransactionSessionTimeout
extern

Definition at line 61 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

◆ IdleSessionTimeout

PGDLLIMPORT int IdleSessionTimeout
extern

Definition at line 63 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

◆ LockTimeout

PGDLLIMPORT int LockTimeout
extern

Definition at line 60 of file proc.c.

Referenced by ProcSleep().

◆ log_lock_waits

PGDLLIMPORT bool log_lock_waits
extern

Definition at line 64 of file proc.c.

Referenced by ProcSleep().

◆ MyProc

PGDLLIMPORT PGPROC* MyProc
extern

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(), BufferLockAcquire(), BufferLockDequeueSelf(), BufferLockQueueSelf(), CheckDeadLock(), CommitTransaction(), ComputeXidHorizons(), ConditionVariableBroadcast(), consume_xids_common(), CountOtherDBBackends(), CreateReplicationSlot(), DefineIndex(), EndPrepare(), 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(), HandleRecoveryConflictInterrupt(), heap_inplace_update_and_unlock(), InitAuxiliaryProcess(), InitBufferManagerAccess(), InitializeParallelDSM(), InitPostgres(), InitProcess(), InitProcessPhase2(), InitRecoveryTransactionEnvironment(), InitTempTableNamespace(), InitWalSender(), JoinWaitQueue(), lock_and_open_sequence(), LockAcquireExtended(), LockBufferInternal(), 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(), ProcessInterrupts(), ProcessRecoveryConflictInterrupts(), ProcessStandbyHSFeedbackMessage(), ProcKill(), ProcReleaseLocks(), ProcSleep(), ProcWakeup(), RecordTransactionCommit(), RecordTransactionCommitPrepared(), ReinitializeParallelDSM(), RelationTruncate(), RemoveProcFromArray(), ReplicationSlotRelease(), report_recovery_conflict(), 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

PGDLLIMPORT PGPROC* PreparedXactProcs
extern

Definition at line 72 of file proc.c.

Referenced by InitProcGlobal(), and TwoPhaseShmemInit().

◆ ProcGlobal

◆ StatementTimeout

PGDLLIMPORT int StatementTimeout
extern

Definition at line 59 of file proc.c.

Referenced by enable_statement_timeout().

◆ TransactionTimeout