YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/postgres/src/include/storage/proc.h
Line
Count
Source (jump to first uncovered line)
1
/*-------------------------------------------------------------------------
2
 *
3
 * proc.h
4
 *    per-process shared memory data structures
5
 *
6
 *
7
 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
8
 * Portions Copyright (c) 1994, Regents of the University of California
9
 *
10
 * src/include/storage/proc.h
11
 *
12
 *-------------------------------------------------------------------------
13
 */
14
#ifndef _PROC_H_
15
#define _PROC_H_
16
17
#include "access/clog.h"
18
#include "access/xlogdefs.h"
19
#include "lib/ilist.h"
20
#include "storage/latch.h"
21
#include "storage/lock.h"
22
#include "storage/pg_sema.h"
23
#include "storage/proclist_types.h"
24
25
/*
26
 * Each backend advertises up to PGPROC_MAX_CACHED_SUBXIDS TransactionIds
27
 * for non-aborted subtransactions of its current top transaction.  These
28
 * have to be treated as running XIDs by other backends.
29
 *
30
 * We also keep track of whether the cache overflowed (ie, the transaction has
31
 * generated at least one subtransaction that didn't fit in the cache).
32
 * If none of the caches have overflowed, we can assume that an XID that's not
33
 * listed anywhere in the PGPROC array is not a running transaction.  Else we
34
 * have to look at pg_subtrans.
35
 */
36
21.4k
#define PGPROC_MAX_CACHED_SUBXIDS 64  /* XXX guessed-at value */
37
38
struct XidCache
39
{
40
  TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS];
41
};
42
43
/*
44
 * Flags for PGXACT->vacuumFlags
45
 *
46
 * Note: If you modify these flags, you need to modify PROCARRAY_XXX flags
47
 * in src/include/storage/procarray.h.
48
 *
49
 * PROC_RESERVED may later be assigned for use in vacuumFlags, but its value is
50
 * used for PROCARRAY_SLOTS_XMIN in procarray.h, so GetOldestXmin won't be able
51
 * to match and ignore processes with this flag set.
52
 */
53
0
#define   PROC_IS_AUTOVACUUM  0x01  /* is it an autovac worker? */
54
862k
#define   PROC_IN_VACUUM    0x02  /* currently running lazy vacuum */
55
154k
#define   PROC_IN_ANALYZE   0x04  /* currently running analyze */
56
154k
#define   PROC_VACUUM_FOR_WRAPAROUND  0x08  /* set by autovac only */
57
707k
#define   PROC_IN_LOGICAL_DECODING  0x10  /* currently doing logical
58
                         * decoding outside xact */
59
#define   PROC_RESERVED       0x20  /* reserved for procarray */
60
61
/* flags reset at EOXact */
62
#define   PROC_VACUUM_STATE_MASK \
63
154k
  (PROC_IN_VACUUM | PROC_IN_ANALYZE | PROC_VACUUM_FOR_WRAPAROUND)
64
65
/*
66
 * We allow a small number of "weak" relation locks (AccesShareLock,
67
 * RowShareLock, RowExclusiveLock) to be recorded in the PGPROC structure
68
 * rather than the main lock table.  This eases contention on the lock
69
 * manager LWLocks.  See storage/lmgr/README for additional details.
70
 */
71
0
#define   FP_LOCK_SLOTS_PER_BACKEND 16
72
73
/*
74
 * An invalid pgprocno.  Must be larger than the maximum number of PGPROC
75
 * structures we could possibly have.  See comments for MAX_BACKENDS.
76
 */
77
99.0M
#define INVALID_PGPROCNO    PG_INT32_MAX
78
79
/*
80
 * Each backend has a PGPROC struct in shared memory.  There is also a list of
81
 * currently-unused PGPROC structs that will be reallocated to new backends.
82
 *
83
 * links: list link for any list the PGPROC is in.  When waiting for a lock,
84
 * the PGPROC is linked into that lock's waitProcs queue.  A recycled PGPROC
85
 * is linked into ProcGlobal's freeProcs list.
86
 *
87
 * Note: twophase.c also sets up a dummy PGPROC struct for each currently
88
 * prepared transaction.  These PGPROCs appear in the ProcArray data structure
89
 * so that the prepared transactions appear to be still running and are
90
 * correctly shown as holding locks.  A prepared transaction PGPROC can be
91
 * distinguished from a real one at need by the fact that it has pid == 0.
92
 * The semaphore and lock-activity fields in a prepared-xact PGPROC are unused,
93
 * but its myProcLocks[] lists are valid.
94
 */
95
struct PGPROC
96
{
97
  /* proc->links MUST BE FIRST IN STRUCT (see ProcSleep,ProcWakeup,etc) */
98
  SHM_QUEUE links;      /* list link if process is in a list */
99
  PGPROC    **procgloballist; /* procglobal list that owns this PGPROC */
100
101
  PGSemaphore sem;      /* ONE semaphore to sleep on */
102
  int     waitStatus;   /* STATUS_WAITING, STATUS_OK or STATUS_ERROR */
103
104
  Latch   procLatch;    /* generic latch for process */
105
106
  LocalTransactionId lxid;  /* local id of top-level transaction currently
107
                 * being executed by this proc, if running;
108
                 * else InvalidLocalTransactionId */
109
  int     pid;      /* Backend's process ID; 0 if prepared xact */
110
  int     pgprocno;
111
112
  /* These fields are zero while a backend is still starting up: */
113
  BackendId backendId;    /* This backend's backend ID (if assigned) */
114
  Oid     databaseId;   /* OID of database this backend is using */
115
  Oid     roleId;     /* OID of role using this backend */
116
117
  Oid     tempNamespaceId;  /* OID of temp schema this backend is
118
                   * using */
119
120
  bool    isBackgroundWorker; /* true if background worker. */
121
122
  /*
123
   * While in hot standby mode, shows that a conflict signal has been sent
124
   * for the current transaction. Set/cleared while holding ProcArrayLock,
125
   * though not required. Accessed without lock, if needed.
126
   */
127
  bool    recoveryConflictPending;
128
129
  /* Info about LWLock the process is currently waiting for, if any. */
130
  bool    lwWaiting;    /* true if waiting for an LW lock */
131
  uint8   lwWaitMode;   /* lwlock mode being waited for */
132
  proclist_node lwWaitLink; /* position in LW lock wait list */
133
134
  /* Support for condition variables. */
135
  proclist_node cvWaitLink; /* position in CV wait list */
136
137
  /* Info about lock the process is currently waiting for, if any. */
138
  /* waitLock and waitProcLock are NULL if not currently waiting. */
139
  LOCK     *waitLock;   /* Lock object we're sleeping on ... */
140
  PROCLOCK   *waitProcLock; /* Per-holder info for awaited lock */
141
  LOCKMODE  waitLockMode; /* type of lock we're waiting for */
142
  LOCKMASK  heldLocks;    /* bitmask for lock types already held on this
143
                 * lock object by this backend */
144
145
  /*
146
   * Info to allow us to wait for synchronous replication, if needed.
147
   * waitLSN is InvalidXLogRecPtr if not waiting; set only by user backend.
148
   * syncRepState must not be touched except by owning process or WALSender.
149
   * syncRepLinks used only while holding SyncRepLock.
150
   */
151
  XLogRecPtr  waitLSN;    /* waiting for this LSN or higher */
152
  int     syncRepState; /* wait state for sync rep */
153
  SHM_QUEUE syncRepLinks; /* list link if process is in syncrep queue */
154
155
  /*
156
   * All PROCLOCK objects for locks held or awaited by this backend are
157
   * linked into one of these lists, according to the partition number of
158
   * their lock.
159
   */
160
  SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS];
161
162
  struct XidCache subxids;  /* cache for subtransaction XIDs */
163
164
  /* Support for group XID clearing. */
165
  /* true, if member of ProcArray group waiting for XID clear */
166
  bool    procArrayGroupMember;
167
  /* next ProcArray group member waiting for XID clear */
168
  pg_atomic_uint32 procArrayGroupNext;
169
170
  /*
171
   * latest transaction id among the transaction's main XID and
172
   * subtransactions
173
   */
174
  TransactionId procArrayGroupMemberXid;
175
176
  uint32    wait_event_info;  /* proc's wait information */
177
178
  /* Support for group transaction status update. */
179
  bool    clogGroupMember;  /* true, if member of clog group */
180
  pg_atomic_uint32 clogGroupNext; /* next clog group member */
181
  TransactionId clogGroupMemberXid; /* transaction id of clog group member */
182
  XidStatus clogGroupMemberXidStatus; /* transaction status of clog
183
                       * group member */
184
  int     clogGroupMemberPage;  /* clog page corresponding to
185
                     * transaction id of clog group member */
186
  XLogRecPtr  clogGroupMemberLsn; /* WAL location of commit record for clog
187
                   * group member */
188
189
  /* Per-backend LWLock.  Protects fields below (but not group fields). */
190
  LWLock    backendLock;
191
192
  /* Lock manager data, recording fast-path locks taken by this backend. */
193
  uint64    fpLockBits;   /* lock modes held for each fast-path slot */
194
  Oid     fpRelId[FP_LOCK_SLOTS_PER_BACKEND]; /* slots for rel oids */
195
  bool    fpVXIDLock;   /* are we holding a fast-path VXID lock? */
196
  LocalTransactionId fpLocalTransactionId;  /* lxid for fast-path VXID
197
                         * lock */
198
199
  /*
200
   * Support for lock groups.  Use LockHashPartitionLockByProc on the group
201
   * leader to get the LWLock protecting these fields.
202
   */
203
  PGPROC     *lockGroupLeader;  /* lock group leader, if I'm a member */
204
  dlist_head  lockGroupMembers; /* list of members, if I'm a leader */
205
  dlist_node  lockGroupLink;  /* my member link, if I'm a member */
206
};
207
208
/* NOTE: "typedef struct PGPROC PGPROC" appears in storage/lock.h. */
209
210
211
extern PGDLLIMPORT PGPROC *MyProc;
212
extern PGDLLIMPORT struct PGXACT *MyPgXact;
213
214
/*
215
 * Prior to PostgreSQL 9.2, the fields below were stored as part of the
216
 * PGPROC.  However, benchmarking revealed that packing these particular
217
 * members into a separate array as tightly as possible sped up GetSnapshotData
218
 * considerably on systems with many CPU cores, by reducing the number of
219
 * cache lines needing to be fetched.  Thus, think very carefully before adding
220
 * anything else here.
221
 */
222
typedef struct PGXACT
223
{
224
  TransactionId xid;      /* id of top-level transaction currently being
225
                 * executed by this proc, if running and XID
226
                 * is assigned; else InvalidTransactionId */
227
228
  TransactionId xmin;     /* minimal running XID as it was when we were
229
                 * starting our xact, excluding LAZY VACUUM:
230
                 * vacuum must not remove tuples deleted by
231
                 * xid >= xmin ! */
232
233
  uint8   vacuumFlags;  /* vacuum-related flags, see above */
234
  bool    overflowed;
235
  bool    delayChkpt;   /* true if this proc delays checkpoint start;
236
                 * previously called InCommit */
237
238
  uint8   nxids;
239
} PGXACT;
240
241
/*
242
 * There is one ProcGlobal struct for the whole database cluster.
243
 */
244
typedef struct PROC_HDR
245
{
246
  /* Array of PGPROC structures (not including dummies for prepared txns) */
247
  PGPROC     *allProcs;
248
  /* Array of PGXACT structures (not including dummies for prepared txns) */
249
  PGXACT     *allPgXact;
250
  /* Length of allProcs array */
251
  uint32    allProcCount;
252
  /* Head of list of free PGPROC structures */
253
  PGPROC     *freeProcs;
254
  /* Head of list of autovacuum's free PGPROC structures */
255
  PGPROC     *autovacFreeProcs;
256
  /* Head of list of bgworker free PGPROC structures */
257
  PGPROC     *bgworkerFreeProcs;
258
  /* First pgproc waiting for group XID clear */
259
  pg_atomic_uint32 procArrayGroupFirst;
260
  /* First pgproc waiting for group transaction status update */
261
  pg_atomic_uint32 clogGroupFirst;
262
  /* WALWriter process's latch */
263
  Latch    *walwriterLatch;
264
  /* Checkpointer process's latch */
265
  Latch    *checkpointerLatch;
266
  /* Current shared estimate of appropriate spins_per_delay value */
267
  int     spins_per_delay;
268
  /* The proc of the Startup process, since not in ProcArray */
269
  PGPROC     *startupProc;
270
  int     startupProcPid;
271
  /* Buffer id of the buffer that Startup process waits for pin on, or -1 */
272
  int     startupBufferPinWaitBufId;
273
} PROC_HDR;
274
275
extern PGDLLIMPORT PROC_HDR *ProcGlobal;
276
277
extern PGPROC *PreparedXactProcs;
278
279
/* Accessor for PGPROC given a pgprocno. */
280
3.36k
#define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)])
281
282
/*
283
 * We set aside some extra PGPROC structures for auxiliary processes,
284
 * ie things that aren't full-fledged backends but need shmem access.
285
 *
286
 * Background writer, checkpointer and WAL writer run during normal operation.
287
 * Startup process and WAL receiver also consume 2 slots, but WAL writer is
288
 * launched only after startup has exited, so we only need 4 slots.
289
 */
290
1.16M
#define NUM_AUXILIARY_PROCS   4
291
292
/* configurable options */
293
extern PGDLLIMPORT int DeadlockTimeout;
294
extern int  StatementTimeout;
295
extern int  LockTimeout;
296
extern int  IdleInTransactionSessionTimeout;
297
extern bool log_lock_waits;
298
299
extern int  RetryMaxBackoffMsecs;
300
extern int  RetryMinBackoffMsecs;
301
extern double RetryBackoffMultiplier;
302
303
/*
304
 * Function Prototypes
305
 */
306
307
extern int  ProcGlobalSemas(void);
308
extern Size ProcGlobalShmemSize(void);
309
extern void InitProcGlobal(void);
310
extern void InitProcess(void);
311
extern void InitProcessPhase2(void);
312
extern void InitAuxiliaryProcess(void);
313
314
extern void PublishStartupProcessInformation(void);
315
extern void SetStartupBufferPinWaitBufId(int bufid);
316
extern int  GetStartupBufferPinWaitBufId(void);
317
318
extern bool HaveNFreeProcs(int n);
319
extern void ProcReleaseLocks(bool isCommit);
320
321
extern void ProcQueueInit(PROC_QUEUE *queue);
322
extern int  ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable);
323
extern PGPROC *ProcWakeup(PGPROC *proc, int waitStatus);
324
extern void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock);
325
extern void CheckDeadLockAlert(void);
326
extern bool IsWaitingForLock(void);
327
extern void LockErrorCleanup(void);
328
329
extern void ProcWaitForSignal(uint32 wait_event_info);
330
extern void ProcSendSignal(int pid);
331
332
extern PGPROC *AuxiliaryPidGetProc(int pid);
333
334
extern void BecomeLockGroupLeader(void);
335
extern bool BecomeLockGroupMember(PGPROC *leader, int pid);
336
337
#endif              /* PROC_H */