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)
 
#define FIRST_PREPARED_XACT_PROC_NUMBER   (MaxBackends + NUM_AUXILIARY_PROCS)
 

Typedefs

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

◆ FIRST_PREPARED_XACT_PROC_NUMBER

#define FIRST_PREPARED_XACT_PROC_NUMBER   (MaxBackends + NUM_AUXILIARY_PROCS)

Definition at line 526 of file proc.h.

◆ 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 502 of file proc.h.

◆ GetPGProcByNumber

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

Definition at line 501 of file proc.h.

◆ MAX_IO_WORKERS

#define MAX_IO_WORKERS   32

Definition at line 523 of file proc.h.

◆ NUM_AUXILIARY_PROCS

#define NUM_AUXILIARY_PROCS   (6 + MAX_IO_WORKERS)

Definition at line 524 of file proc.h.

◆ NUM_SPECIAL_WORKER_PROCS

#define NUM_SPECIAL_WORKER_PROCS   2

Definition at line 511 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

◆ PGPROC

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

1086{
1087 PGPROC *result = NULL;
1088 int index;
1089
1090 if (pid == 0) /* never match dummy PGPROCs */
1091 return NULL;
1092
1093 for (index = 0; index < NUM_AUXILIARY_PROCS; index++)
1094 {
1095 PGPROC *proc = &AuxiliaryProcs[index];
1096
1097 if (proc->pid == pid)
1098 {
1099 result = proc;
1100 break;
1101 }
1102 }
1103 return result;
1104}
#define NUM_AUXILIARY_PROCS
Definition proc.h:524
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 2018 of file proc.c.

2019{
2021
2022 /* If we already did it, we don't need to do it again. */
2024 return;
2025
2026 /* We had better not be a follower. */
2028
2029 /* Create single-member group, containing only ourselves. */
2035}
#define Assert(condition)
Definition c.h:945
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition ilist.h:347
#define LockHashPartitionLockByProc(leader_pgproc)
Definition lock.h:372
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1177
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1794
@ LW_EXCLUSIVE
Definition lwlock.h:112
PGPROC * MyProc
Definition proc.c:68

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

2049{
2051 bool ok = false;
2052
2053 /* Group leader can't become member of group */
2054 Assert(MyProc != leader);
2055
2056 /* Can't already be a member of a group */
2058
2059 /* PID must be valid. */
2060 Assert(pid != 0);
2061
2062 /*
2063 * Get lock protecting the group fields. Note LockHashPartitionLockByProc
2064 * calculates the proc number based on the PGPROC slot without looking at
2065 * its contents, so we will acquire the correct lock even if the leader
2066 * PGPROC is in process of being recycled.
2067 */
2070
2071 /* Is this the leader we're looking for? */
2072 if (leader->pid == pid && leader->lockGroupLeader == leader)
2073 {
2074 /* OK, join the group */
2075 ok = true;
2076 MyProc->lockGroupLeader = leader;
2078 }
2080
2081 return ok;
2082}
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 1890 of file proc.c.

1891{
1892 int save_errno = errno;
1893
1894 got_deadlock_timeout = true;
1895
1896 /*
1897 * Have to set the latch again, even if handle_sig_alarm already did. Back
1898 * then got_deadlock_timeout wasn't yet set... It's unlikely that this
1899 * ever would be a problem, but setting a set latch again is cheap.
1900 *
1901 * Note that, when this function runs inside procsignal_sigusr1_handler(),
1902 * the handler function sets the latch again after the latch is set here.
1903 */
1905 errno = save_errno;
1906}
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:76

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

1919{
1922 LOCK *lock = locallock->lock;
1923 bool first_holder = true,
1924 first_waiter = true;
1925
1926#ifdef USE_ASSERT_CHECKING
1927 {
1928 uint32 hashcode = locallock->hashcode;
1930
1932 }
1933#endif
1934
1935 *lockHoldersNum = 0;
1936
1937 /*
1938 * Loop over the lock's procLocks to gather a list of all holders and
1939 * waiters. Thus we will be able to provide more detailed information for
1940 * lock debugging purposes.
1941 *
1942 * lock->procLocks contains all processes which hold or wait for this
1943 * lock.
1944 */
1946 {
1947 curproclock =
1948 dlist_container(PROCLOCK, lockLink, proc_iter.cur);
1949
1950 /*
1951 * We are a waiter if myProc->waitProcLock == curproclock; we are a
1952 * holder if it is NULL or something different.
1953 */
1954 if (curproclock->tag.myProc->waitProcLock == curproclock)
1955 {
1956 if (first_waiter)
1957 {
1959 curproclock->tag.myProc->pid);
1960 first_waiter = false;
1961 }
1962 else
1964 curproclock->tag.myProc->pid);
1965 }
1966 else
1967 {
1968 if (first_holder)
1969 {
1971 curproclock->tag.myProc->pid);
1972 first_holder = false;
1973 }
1974 else
1976 curproclock->tag.myProc->pid);
1977
1978 (*lockHoldersNum)++;
1979 }
1980 }
1981}
#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:357
bool LWLockHeldByMe(LWLock *lock)
Definition lwlock.c:1912
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
dlist_head procLocks
Definition lock.h:147

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

760{
761 /* use volatile pointer to prevent code rearrangement */
762 volatile PROC_HDR *procglobal = ProcGlobal;
763
765}
PROC_HDR * ProcGlobal
Definition proc.c:71

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

Referenced by HoldingBufferPinThatDelaysRecovery().

◆ HaveNFreeProcs()

bool HaveNFreeProcs ( int  n,
int nfree 
)
extern

Definition at line 775 of file proc.c.

776{
777 dlist_iter iter;
778
779 Assert(n > 0);
780 Assert(nfree);
781
783
784 *nfree = 0;
786 {
787 (*nfree)++;
788 if (*nfree == n)
789 break;
790 }
791
793
794 return (*nfree == n);
795}
static void SpinLockRelease(volatile slock_t *lock)
Definition spin.h:62
static void SpinLockAcquire(volatile slock_t *lock)
Definition spin.h:56

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

607{
609 int proctype;
610
611 /*
612 * ProcGlobal should be set up already (if we are a backend, we inherit
613 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
614 */
615 if (ProcGlobal == NULL || AuxiliaryProcs == NULL)
616 elog(PANIC, "proc header uninitialized");
617
618 if (MyProc != NULL)
619 elog(ERROR, "you already exist");
620
623
624 /*
625 * We use the freeProcsLock to protect assignment and releasing of
626 * AuxiliaryProcs entries.
627 *
628 * While we are holding the spinlock, also copy the current shared
629 * estimate of spins_per_delay to local storage.
630 */
632
634
635 /*
636 * Find a free auxproc ... *big* trouble if there isn't one ...
637 */
639 {
641 if (auxproc->pid == 0)
642 break;
643 }
645 {
647 elog(FATAL, "all AuxiliaryProcs are in use");
648 }
649
650 /* Mark auxiliary proc as in use by me */
651 /* use volatile pointer to prevent code rearrangement */
652 ((volatile PGPROC *) auxproc)->pid = MyProcPid;
653
655
656 MyProc = auxproc;
658
659 /*
660 * Initialize all fields of MyProc, except for those previously
661 * initialized by InitProcGlobal.
662 */
665 MyProc->fpVXIDLock = false;
676 MyProc->statusFlags = 0;
678 MyProc->lwWaitMode = 0;
683#ifdef USE_ASSERT_CHECKING
684 {
685 int i;
686
687 /* Last process should have released all locks. */
688 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
690 }
691#endif
693
694 /*
695 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
696 * on it. That allows us to repoint the process latch, which so far
697 * points to process local one, to the shared one.
698 */
701
702 /* now that we have a proc, report wait events to shared memory */
704
705 /* Check that group locking fields are in a proper initial state. */
708
709 /*
710 * We might be reusing a semaphore that belonged to a failed process. So
711 * be careful and reinitialize its value here. (This is not strictly
712 * necessary anymore, but seems like a good idea for cleanliness.)
713 */
715
716 /*
717 * Arrange to clean up at process exit.
718 */
720
721 /*
722 * Now that we have a PGPROC, we could try to acquire lightweight locks.
723 * Initialize local state needed for them. (Heavyweight locks cannot be
724 * acquired in aux processes.)
725 */
727
728#ifdef EXEC_BACKEND
729
730 /*
731 * Initialize backend-local pointers to all the shared data structures.
732 * (We couldn't do this until now because it needs LWLocks.)
733 */
736#endif
737}
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:485
static void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition atomics.h:274
#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:68
void InitLWLockAccess(void)
Definition lwlock.c:551
@ LW_WS_NOT_WAITING
Definition lwlock.h:30
void SwitchToSharedLatch(void)
Definition miscinit.c:216
BackendType MyBackendType
Definition miscinit.c:65
void RegisterPostmasterChildActive(void)
Definition pmsignal.c:290
void PGSemaphoreReset(PGSemaphore sema)
Definition posix_sema.c:290
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
#define InvalidOid
#define GetNumberFromPGProc(proc)
Definition proc.h:502
#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:1034
#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, PGPROC::freeProcsLink, PROC_HDR::freeProcsLock, GetNumberFromPGProc, i, InitLWLockAccess(), Int32GetDatum(), INVALID_PROC_NUMBER, InvalidLocalTransactionId, InvalidOid, InvalidTransactionId, IsUnderPostmaster, 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, PGPROC::pendingRecoveryConflicts, pg_atomic_write_u32(), 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::waitLink, PGPROC::waitLock, PGPROC::waitProcLock, PGPROC::waitStart, PGPROC::waitStatus, PGPROC::xid, and PGPROC::xmin.

Referenced by AuxiliaryProcessMainCommon().

◆ InitProcess()

void InitProcess ( void  )
extern

Definition at line 380 of file proc.c.

381{
382 dlist_head *procgloballist;
383
384 /*
385 * ProcGlobal should be set up already (if we are a backend, we inherit
386 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
387 */
388 if (ProcGlobal == NULL)
389 elog(PANIC, "proc header uninitialized");
390
391 if (MyProc != NULL)
392 elog(ERROR, "you already exist");
393
394 /*
395 * Before we start accessing the shared memory in a serious way, mark
396 * ourselves as an active postmaster child; this is so that the postmaster
397 * can detect it if we exit without cleaning up.
398 */
401
402 /*
403 * Decide which list should supply our PGPROC. This logic must match the
404 * way the freelists were constructed in InitProcGlobal().
405 */
407 procgloballist = &ProcGlobal->autovacFreeProcs;
408 else if (AmBackgroundWorkerProcess())
409 procgloballist = &ProcGlobal->bgworkerFreeProcs;
410 else if (AmWalSenderProcess())
411 procgloballist = &ProcGlobal->walsenderFreeProcs;
412 else
413 procgloballist = &ProcGlobal->freeProcs;
414
415 /*
416 * Try to get a proc struct from the appropriate free list. If this
417 * fails, we must be out of PGPROC structures (not to mention semaphores).
418 *
419 * While we are holding the spinlock, also copy the current shared
420 * estimate of spins_per_delay to local storage.
421 */
423
425
426 if (!dlist_is_empty(procgloballist))
427 {
428 MyProc = dlist_container(PGPROC, freeProcsLink, dlist_pop_head_node(procgloballist));
430 }
431 else
432 {
433 /*
434 * If we reach here, all the PGPROCs are in use. This is one of the
435 * possible places to detect "too many backends", so give the standard
436 * error message. XXX do we need to give a different failure message
437 * in the autovacuum case?
438 */
440 if (AmWalSenderProcess())
443 errmsg("number of requested standby connections exceeds \"max_wal_senders\" (currently %d)",
447 errmsg("sorry, too many clients already")));
448 }
450
451 /*
452 * Cross-check that the PGPROC is of the type we expect; if this were not
453 * the case, it would get returned to the wrong list.
454 */
455 Assert(MyProc->procgloballist == procgloballist);
456
457 /*
458 * Initialize all fields of MyProc, except for those previously
459 * initialized by InitProcGlobal.
460 */
463 MyProc->fpVXIDLock = false;
470 /* databaseId and roleId will be filled in later */
476 MyProc->statusFlags = 0;
477 /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
481 MyProc->lwWaitMode = 0;
486#ifdef USE_ASSERT_CHECKING
487 {
488 int i;
489
490 /* Last process should have released all locks. */
491 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
493 }
494#endif
496
497 /* Initialize fields for sync rep */
501
502 /* Initialize fields for group XID clearing. */
506
507 /* Check that group locking fields are in a proper initial state. */
510
511 /* Initialize wait event information. */
513
514 /* Initialize fields for group transaction status update. */
515 MyProc->clogGroupMember = false;
521
522 /*
523 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
524 * on it. That allows us to repoint the process latch, which so far
525 * points to process local one, to the shared one.
526 */
529
530 /* now that we have a proc, report wait events to shared memory */
532
533 /*
534 * We might be reusing a semaphore that belonged to a failed process. So
535 * be careful and reinitialize its value here. (This is not strictly
536 * necessary anymore, but seems like a good idea for cleanliness.)
537 */
539
540 /*
541 * Arrange to clean up at backend exit.
542 */
544
545 /*
546 * Now that we have a PGPROC, we could try to acquire locks, so initialize
547 * local state needed for LWLocks, and the deadlock checker.
548 */
551
552#ifdef EXEC_BACKEND
553
554 /*
555 * Initialize backend-local pointers to all the shared data structures.
556 * (We couldn't do this until now because it needs LWLocks.)
557 */
560#endif
561}
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:874
#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
static char * errmsg
#define PROC_IS_AUTOVACUUM
Definition proc.h:58
static void ProcKill(int code, Datum arg)
Definition proc.c:912
#define SYNC_REP_NOT_WAITING
Definition syncrep.h:30
int max_wal_senders
Definition walsender.c:130
#define InvalidXLogRecPtr
Definition xlogdefs.h:28

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, PGPROC::freeProcsLink, PROC_HDR::freeProcsLock, GetNumberFromPGProc, i, InitDeadLockChecking(), InitLWLockAccess(), INVALID_PROC_NUMBER, InvalidLocalTransactionId, InvalidOid, InvalidTransactionId, InvalidXLogRecPtr, IsUnderPostmaster, 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::waitLink, 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 571 of file proc.c.

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

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

Referenced by InitPostgres().

◆ InitProcGlobal()

void InitProcGlobal ( void  )
extern

Definition at line 184 of file proc.c.

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

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(), FIRST_PREPARED_XACT_PROC_NUMBER, PGPROC::fpInfoLock, PGPROC::fpLockBits, PGPROC::fpRelId, PROC_HDR::freeProcs, PGPROC::freeProcsLink, PROC_HDR::freeProcsLock, i, InitSharedLatch(), INVALID_PROC_NUMBER, j, 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 1134 of file proc.c.

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

Referenced by LockAcquireExtended().

◆ LockErrorCleanup()

void LockErrorCleanup ( void  )
extern

Definition at line 806 of file proc.c.

807{
811
813
815
816 /* Nothing to do if we weren't waiting for a lock */
818 if (lockAwaited == NULL)
819 {
821 return;
822 }
823
824 /*
825 * Turn off the deadlock and lock timeout timers, if they are still
826 * running (see ProcSleep). Note we must preserve the LOCK_TIMEOUT
827 * indicator flag, since this function is executed before
828 * ProcessInterrupts when responding to SIGINT; else we'd lose the
829 * knowledge that the SIGINT came from a lock timeout and not an external
830 * source.
831 */
833 timeouts[0].keep_indicator = false;
834 timeouts[1].id = LOCK_TIMEOUT;
835 timeouts[1].keep_indicator = true;
837
838 /* Unlink myself from the wait queue, if on it (might not be anymore!) */
841
843 {
844 /* We could not have been granted the lock yet */
846 }
847 else
848 {
849 /*
850 * Somebody kicked us off the lock queue already. Perhaps they
851 * granted us the lock, or perhaps they detected a deadlock. If they
852 * did grant us the lock, we'd better remember it in our local lock
853 * table.
854 */
857 }
858
860
862
864}
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, LOCK_TIMEOUT, LockHashPartitionLock, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MyProc, PROC_WAIT_STATUS_OK, RemoveFromWaitQueue(), ResetAwaitedLock(), RESUME_INTERRUPTS, PGPROC::waitLink, and PGPROC::waitStatus.

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

◆ ProcGlobalSemas()

int ProcGlobalSemas ( void  )
extern

Definition at line 149 of file proc.c.

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

References MaxBackends, and NUM_AUXILIARY_PROCS.

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

◆ ProcGlobalShmemSize()

Size ProcGlobalShmemSize ( void  )
extern

Definition at line 130 of file proc.c.

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

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

Referenced by CalculateShmemSize().

◆ ProcLockWakeup()

void ProcLockWakeup ( LockMethod  lockMethodTable,
LOCK lock 
)
extern

Definition at line 1752 of file proc.c.

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

References dclist_foreach_modify, dclist_is_empty(), dlist_container, fb(), GrantLock(), 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 884 of file proc.c.

885{
886 if (!MyProc)
887 return;
888 /* If waiting, get off wait queue (should only be needed after error) */
890 /* Release standard locks, including session-level if aborting */
892 /* Release transaction-level advisory locks */
894}
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition lock.c:2307
#define DEFAULT_LOCKMETHOD
Definition locktag.h:25
#define USER_LOCKMETHOD
Definition locktag.h:26
void LockErrorCleanup(void)
Definition proc.c:806

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

Referenced by ResourceOwnerReleaseInternal().

◆ ProcSendSignal()

void ProcSendSignal ( ProcNumber  procNumber)
extern

Definition at line 2003 of file proc.c.

2004{
2006 elog(ERROR, "procNumber out of range");
2007
2008 SetLatch(&GetPGProcByNumber(procNumber)->procLatch);
2009}
#define GetPGProcByNumber(n)
Definition proc.h:501

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

1304{
1305 LOCKMODE lockmode = locallock->tag.mode;
1306 LOCK *lock = locallock->lock;
1307 uint32 hashcode = locallock->hashcode;
1310 bool allow_autovacuum_cancel = true;
1311 bool logged_recovery_conflict = false;
1312 bool logged_lock_wait = false;
1315
1316 /* The caller must've armed the on-error cleanup mechanism */
1319
1320 /*
1321 * Now that we will successfully clean up after an ereport, it's safe to
1322 * check to see if there's a buffer pin deadlock against the Startup
1323 * process. Of course, that's only necessary if we're doing Hot Standby
1324 * and are not the Startup process ourselves.
1325 */
1328
1329 /* Reset deadlock_state before enabling the timeout handler */
1331 got_deadlock_timeout = false;
1332
1333 /*
1334 * Set timer so we can wake up after awhile and check for a deadlock. If a
1335 * deadlock is detected, the handler sets MyProc->waitStatus =
1336 * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure
1337 * rather than success.
1338 *
1339 * By delaying the check until we've waited for a bit, we can avoid
1340 * running the rather expensive deadlock-check code in most cases.
1341 *
1342 * If LockTimeout is set, also enable the timeout for that. We can save a
1343 * few cycles by enabling both timeout sources in one call.
1344 *
1345 * If InHotStandby we set lock waits slightly later for clarity with other
1346 * code.
1347 */
1348 if (!InHotStandby)
1349 {
1350 if (LockTimeout > 0)
1351 {
1353
1355 timeouts[0].type = TMPARAM_AFTER;
1356 timeouts[0].delay_ms = DeadlockTimeout;
1357 timeouts[1].id = LOCK_TIMEOUT;
1358 timeouts[1].type = TMPARAM_AFTER;
1359 timeouts[1].delay_ms = LockTimeout;
1361 }
1362 else
1364
1365 /*
1366 * Use the current time obtained for the deadlock timeout timer as
1367 * waitStart (i.e., the time when this process started waiting for the
1368 * lock). Since getting the current time newly can cause overhead, we
1369 * reuse the already-obtained time to avoid that overhead.
1370 *
1371 * Note that waitStart is updated without holding the lock table's
1372 * partition lock, to avoid the overhead by additional lock
1373 * acquisition. This can cause "waitstart" in pg_locks to become NULL
1374 * for a very short period of time after the wait started even though
1375 * "granted" is false. This is OK in practice because we can assume
1376 * that users are likely to look at "waitstart" when waiting for the
1377 * lock for a long time.
1378 */
1381 }
1383 {
1384 /*
1385 * Set the wait start timestamp if logging is enabled and in hot
1386 * standby.
1387 */
1389 }
1390
1391 /*
1392 * If somebody wakes us between LWLockRelease and WaitLatch, the latch
1393 * will not wait. But a set latch does not necessarily mean that the lock
1394 * is free now, as there are many other sources for latch sets than
1395 * somebody releasing the lock.
1396 *
1397 * We process interrupts whenever the latch has been set, so cancel/die
1398 * interrupts are processed quickly. This means we must not mind losing
1399 * control to a cancel/die interrupt here. We don't, because we have no
1400 * shared-state-change work to do after being granted the lock (the
1401 * grantor did it all). We do have to worry about canceling the deadlock
1402 * timeout and updating the locallock table, but if we lose control to an
1403 * error, LockErrorCleanup will fix that up.
1404 */
1405 do
1406 {
1407 if (InHotStandby)
1408 {
1409 bool maybe_log_conflict =
1411
1412 /* Set a timer and wait for that or for the lock to be granted */
1415
1416 /*
1417 * Emit the log message if the startup process is waiting longer
1418 * than deadlock_timeout for recovery conflict on lock.
1419 */
1421 {
1423
1426 {
1428 int cnt;
1429
1430 vxids = GetLockConflicts(&locallock->tag.lock,
1431 AccessExclusiveLock, &cnt);
1432
1433 /*
1434 * Log the recovery conflict and the list of PIDs of
1435 * backends holding the conflicting lock. Note that we do
1436 * logging even if there are no such backends right now
1437 * because the startup process here has already waited
1438 * longer than deadlock_timeout.
1439 */
1442 cnt > 0 ? vxids : NULL, true);
1444 }
1445 }
1446 }
1447 else
1448 {
1450 PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
1452 /* check for deadlocks first, as that's probably log-worthy */
1454 {
1456 got_deadlock_timeout = false;
1457 }
1459 }
1460
1461 /*
1462 * waitStatus could change from PROC_WAIT_STATUS_WAITING to something
1463 * else asynchronously. Read it just once per loop to prevent
1464 * surprising behavior (such as missing log messages).
1465 */
1466 myWaitStatus = *((volatile ProcWaitStatus *) &MyProc->waitStatus);
1467
1468 /*
1469 * If we are not deadlocked, but are waiting on an autovacuum-induced
1470 * task, send a signal to interrupt it.
1471 */
1473 {
1475 uint8 statusFlags;
1478
1479 /*
1480 * Grab info we need, then release lock immediately. Note this
1481 * coding means that there is a tiny chance that the process
1482 * terminates its current transaction and starts a different one
1483 * before we have a change to send the signal; the worst possible
1484 * consequence is that a for-wraparound vacuum is canceled. But
1485 * that could happen in any case unless we were to do kill() with
1486 * the lock held, which is much more undesirable.
1487 */
1489 statusFlags = ProcGlobal->statusFlags[autovac->pgxactoff];
1491 locktag_copy = lock->tag;
1493
1494 /*
1495 * Only do it if the worker is not working to protect against Xid
1496 * wraparound.
1497 */
1498 if ((statusFlags & PROC_IS_AUTOVACUUM) &&
1499 !(statusFlags & PROC_VACUUM_FOR_WRAPAROUND))
1500 {
1501 int pid = autovac->pid;
1502
1503 /* report the case, if configured to do so */
1505 {
1507 StringInfoData logbuf; /* errdetail for server log */
1508
1513 "Process %d waits for %s on %s.",
1514 MyProcPid,
1516 locktagbuf.data);
1517
1519 (errmsg_internal("sending cancel to blocking autovacuum PID %d",
1520 pid),
1521 errdetail_log("%s", logbuf.data)));
1522
1523 pfree(locktagbuf.data);
1524 pfree(logbuf.data);
1525 }
1526
1527 /* send the autovacuum worker Back to Old Kent Road */
1528 if (kill(pid, SIGINT) < 0)
1529 {
1530 /*
1531 * There's a race condition here: once we release the
1532 * ProcArrayLock, it's possible for the autovac worker to
1533 * close up shop and exit before we can do the kill().
1534 * Therefore, we do not whinge about no-such-process.
1535 * Other errors such as EPERM could conceivably happen if
1536 * the kernel recycles the PID fast enough, but such cases
1537 * seem improbable enough that it's probably best to issue
1538 * a warning if we see some other errno.
1539 */
1540 if (errno != ESRCH)
1542 (errmsg("could not send signal to process %d: %m",
1543 pid)));
1544 }
1545 }
1546
1547 /* prevent signal from being sent again more than once */
1549 }
1550
1551 /*
1552 * If awoken after the deadlock check interrupt has run, and
1553 * log_lock_waits is on, then report about the wait.
1554 */
1556 {
1560 const char *modename;
1561 long secs;
1562 int usecs;
1563 long msecs;
1564 int lockHoldersNum = 0;
1565
1569
1570 DescribeLockTag(&buf, &locallock->tag.lock);
1571 modename = GetLockmodeName(locallock->tag.lock.locktag_lockmethodid,
1572 lockmode);
1575 &secs, &usecs);
1576 msecs = secs * 1000 + usecs / 1000;
1577 usecs = usecs % 1000;
1578
1579 /* Gather a list of all lock holders and waiters */
1584
1586 ereport(LOG,
1587 (errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
1588 MyProcPid, modename, buf.data, msecs, usecs),
1589 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1590 "Processes holding the lock: %s. Wait queue: %s.",
1592 else if (deadlock_state == DS_HARD_DEADLOCK)
1593 {
1594 /*
1595 * This message is a bit redundant with the error that will be
1596 * reported subsequently, but in some cases the error report
1597 * might not make it to the log (eg, if it's caught by an
1598 * exception handler), and we want to ensure all long-wait
1599 * events get logged.
1600 */
1601 ereport(LOG,
1602 (errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
1603 MyProcPid, modename, buf.data, msecs, usecs),
1604 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1605 "Processes holding the lock: %s. Wait queue: %s.",
1607 }
1608
1610 {
1611 /*
1612 * Guard the "still waiting on lock" log message so it is
1613 * reported at most once while waiting for the lock.
1614 *
1615 * Without this guard, the message can be emitted whenever the
1616 * lock-wait sleep is interrupted (for example by SIGHUP for
1617 * config reload or by client_connection_check_interval). For
1618 * example, if client_connection_check_interval is set very
1619 * low (e.g., 100 ms), the message could be logged repeatedly,
1620 * flooding the log and making it difficult to use.
1621 */
1622 if (!logged_lock_wait)
1623 {
1624 ereport(LOG,
1625 (errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
1626 MyProcPid, modename, buf.data, msecs, usecs),
1627 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1628 "Processes holding the lock: %s. Wait queue: %s.",
1630 logged_lock_wait = true;
1631 }
1632 }
1634 ereport(LOG,
1635 (errmsg("process %d acquired %s on %s after %ld.%03d ms",
1636 MyProcPid, modename, buf.data, msecs, usecs)));
1637 else
1638 {
1640
1641 /*
1642 * Currently, the deadlock checker always kicks its own
1643 * process, which means that we'll only see
1644 * PROC_WAIT_STATUS_ERROR when deadlock_state ==
1645 * DS_HARD_DEADLOCK, and there's no need to print redundant
1646 * messages. But for completeness and future-proofing, print
1647 * a message if it looks like someone else kicked us off the
1648 * lock.
1649 */
1651 ereport(LOG,
1652 (errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
1653 MyProcPid, modename, buf.data, msecs, usecs),
1654 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1655 "Processes holding the lock: %s. Wait queue: %s.",
1657 }
1658
1659 /*
1660 * At this point we might still need to wait for the lock. Reset
1661 * state so we don't print the above messages again.
1662 */
1664
1665 pfree(buf.data);
1668 }
1670
1671 /*
1672 * Disable the timers, if they are still running. As in LockErrorCleanup,
1673 * we must preserve the LOCK_TIMEOUT indicator flag: if a lock timeout has
1674 * already caused QueryCancelPending to become set, we want the cancel to
1675 * be reported as a lock timeout, not a user cancel.
1676 */
1677 if (!InHotStandby)
1678 {
1679 if (LockTimeout > 0)
1680 {
1682
1684 timeouts[0].keep_indicator = false;
1685 timeouts[1].id = LOCK_TIMEOUT;
1686 timeouts[1].keep_indicator = true;
1688 }
1689 else
1691 }
1692
1693 /*
1694 * Emit the log message if recovery conflict on lock was resolved but the
1695 * startup process waited longer than deadlock_timeout for it.
1696 */
1700 NULL, false);
1701
1702 /*
1703 * We don't have to do anything else, because the awaker did all the
1704 * necessary updates of the lock table and MyProc. (The caller is
1705 * responsible for updating the local lock table.)
1706 */
1707 return myWaitStatus;
1708}
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition timestamp.c:1712
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
Definition timestamp.c:1772
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1636
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1600
int64 TimestampTz
Definition timestamp.h:39
PGPROC * GetBlockingAutoVacuumPgproc(void)
Definition deadlock.c:290
bool message_level_is_interesting(int elevel)
Definition elog.c:284
#define LOG
Definition elog.h:31
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:36
#define DEBUG1
Definition elog.h:30
int int int errdetail_log(const char *fmt,...) pg_attribute_printf(1
int int int int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(1
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:340
@ DS_HARD_DEADLOCK
Definition lock.h:344
@ DS_BLOCKED_BY_AUTOVACUUM
Definition lock.h:345
@ DS_NO_DEADLOCK
Definition lock.h:342
@ DS_NOT_YET_CHECKED
Definition lock.h:341
@ DS_SOFT_DEADLOCK
Definition lock.h:343
#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:65
void GetLockHoldersAndWaiters(LOCALLOCK *locallock, StringInfo lock_holders_sbuf, StringInfo lock_waiters_sbuf, int *lockHoldersNum)
Definition proc.c:1917
int DeadlockTimeout
Definition proc.c:59
int LockTimeout
Definition proc.c:61
static DeadLockState CheckDeadLock(void)
Definition proc.c:1799
void CheckRecoveryConflictDeadlock(void)
Definition standby.c:906
bool log_recovery_conflict_waits
Definition standby.c:43
void LogRecoveryConflict(RecoveryConflictReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
Definition standby.c:275
void ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict)
Definition standby.c:625
@ RECOVERY_CONFLICT_LOCK
Definition standby.h:37
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
uint8 locktag_lockmethodid
Definition locktag.h:71
LOCKTAG tag
Definition lock.h:142
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:6444
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 1724 of file proc.c.

1725{
1726 if (dlist_node_is_detached(&proc->waitLink))
1727 return;
1728
1730
1731 /* Remove process from wait queue */
1733
1734 /* Clean up process' state and pass it the ok/fail signal */
1735 proc->waitLock = NULL;
1736 proc->waitProcLock = NULL;
1737 proc->waitStatus = waitStatus;
1738 pg_atomic_write_u64(&proc->waitStart, 0);
1739
1740 /* And awaken it */
1741 SetLatch(&proc->procLatch);
1742}
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(), pg_atomic_write_u64(), PROC_WAIT_STATUS_WAITING, PGPROC::procLatch, SetLatch(), PGPROC::waitLink, PGPROC::waitLock, PGPROC::waitProcLock, LOCK::waitProcs, PGPROC::waitStart, and PGPROC::waitStatus.

Referenced by ProcLockWakeup().

◆ SetStartupBufferPinWaitBufId()

void SetStartupBufferPinWaitBufId ( int  bufid)
extern

Definition at line 747 of file proc.c.

748{
749 /* use volatile pointer to prevent code rearrangement */
750 volatile PROC_HDR *procglobal = ProcGlobal;
751
753}

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

Referenced by PostgresMain(), and ProcessInterrupts().

◆ IdleSessionTimeout

PGDLLIMPORT int IdleSessionTimeout
extern

Definition at line 64 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

◆ LockTimeout

PGDLLIMPORT int LockTimeout
extern

Definition at line 61 of file proc.c.

Referenced by ProcSleep().

◆ log_lock_waits

PGDLLIMPORT bool log_lock_waits
extern

Definition at line 65 of file proc.c.

Referenced by ProcSleep().

◆ MyProc

PGDLLIMPORT PGPROC* MyProc
extern

Definition at line 68 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(), 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(), 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(), 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(), and XidCacheRemoveRunningXids().

◆ PreparedXactProcs

PGDLLIMPORT PGPROC* PreparedXactProcs
extern

Definition at line 73 of file proc.c.

Referenced by InitProcGlobal(), and TwoPhaseShmemInit().

◆ ProcGlobal

◆ StatementTimeout

PGDLLIMPORT int StatementTimeout
extern

Definition at line 60 of file proc.c.

Referenced by enable_statement_timeout().

◆ TransactionTimeout