1 /*-------------------------------------------------------------------------
2  *
3  * proc.h
4  *	  per-process shared memory data structures
5  *
6  *
7  * Portions Copyright (c) 1996-2020, 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 #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 #define		PROC_IS_AUTOVACUUM	0x01	/* is it an autovac worker? */
54 #define		PROC_IN_VACUUM		0x02	/* currently running lazy vacuum */
55 #define		PROC_IN_ANALYZE		0x04	/* currently running analyze */
56 #define		PROC_VACUUM_FOR_WRAPAROUND	0x08	/* set by autovac only */
57 #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 	(PROC_IN_VACUUM | PROC_IN_ANALYZE | PROC_VACUUM_FOR_WRAPAROUND)
64 
65 /*
66  * We allow a small number of "weak" relation locks (AccessShareLock,
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 #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 #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 	bool		delayChkpt;		/* true if this proc delays checkpoint start */
146 
147 	/*
148 	 * Info to allow us to wait for synchronous replication, if needed.
149 	 * waitLSN is InvalidXLogRecPtr if not waiting; set only by user backend.
150 	 * syncRepState must not be touched except by owning process or WALSender.
151 	 * syncRepLinks used only while holding SyncRepLock.
152 	 */
153 	XLogRecPtr	waitLSN;		/* waiting for this LSN or higher */
154 	int			syncRepState;	/* wait state for sync rep */
155 	SHM_QUEUE	syncRepLinks;	/* list link if process is in syncrep queue */
156 
157 	/*
158 	 * All PROCLOCK objects for locks held or awaited by this backend are
159 	 * linked into one of these lists, according to the partition number of
160 	 * their lock.
161 	 */
162 	SHM_QUEUE	myProcLocks[NUM_LOCK_PARTITIONS];
163 
164 	struct XidCache subxids;	/* cache for subtransaction XIDs */
165 
166 	/* Support for group XID clearing. */
167 	/* true, if member of ProcArray group waiting for XID clear */
168 	bool		procArrayGroupMember;
169 	/* next ProcArray group member waiting for XID clear */
170 	pg_atomic_uint32 procArrayGroupNext;
171 
172 	/*
173 	 * latest transaction id among the transaction's main XID and
174 	 * subtransactions
175 	 */
176 	TransactionId procArrayGroupMemberXid;
177 
178 	uint32		wait_event_info;	/* proc's wait information */
179 
180 	/* Support for group transaction status update. */
181 	bool		clogGroupMember;	/* true, if member of clog group */
182 	pg_atomic_uint32 clogGroupNext; /* next clog group member */
183 	TransactionId clogGroupMemberXid;	/* transaction id of clog group member */
184 	XidStatus	clogGroupMemberXidStatus;	/* transaction status of clog
185 											 * group member */
186 	int			clogGroupMemberPage;	/* clog page corresponding to
187 										 * transaction id of clog group member */
188 	XLogRecPtr	clogGroupMemberLsn; /* WAL location of commit record for clog
189 									 * group member */
190 
191 	/* Lock manager data, recording fast-path locks taken by this backend. */
192 	LWLock		fpInfoLock;		/* protects per-backend fast-path state */
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 
236 	uint8		nxids;
237 } PGXACT;
238 
239 /*
240  * There is one ProcGlobal struct for the whole database cluster.
241  */
242 typedef struct PROC_HDR
243 {
244 	/* Array of PGPROC structures (not including dummies for prepared txns) */
245 	PGPROC	   *allProcs;
246 	/* Array of PGXACT structures (not including dummies for prepared txns) */
247 	PGXACT	   *allPgXact;
248 	/* Length of allProcs array */
249 	uint32		allProcCount;
250 	/* Head of list of free PGPROC structures */
251 	PGPROC	   *freeProcs;
252 	/* Head of list of autovacuum's free PGPROC structures */
253 	PGPROC	   *autovacFreeProcs;
254 	/* Head of list of bgworker free PGPROC structures */
255 	PGPROC	   *bgworkerFreeProcs;
256 	/* Head of list of walsender free PGPROC structures */
257 	PGPROC	   *walsenderFreeProcs;
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 #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 #define NUM_AUXILIARY_PROCS		4
291 
292 /* configurable options */
293 extern PGDLLIMPORT int DeadlockTimeout;
294 extern PGDLLIMPORT int StatementTimeout;
295 extern PGDLLIMPORT int LockTimeout;
296 extern PGDLLIMPORT int IdleInTransactionSessionTimeout;
297 extern bool log_lock_waits;
298 
299 
300 /*
301  * Function Prototypes
302  */
303 extern int	ProcGlobalSemas(void);
304 extern Size ProcGlobalShmemSize(void);
305 extern void InitProcGlobal(void);
306 extern void InitProcess(void);
307 extern void InitProcessPhase2(void);
308 extern void InitAuxiliaryProcess(void);
309 
310 extern void PublishStartupProcessInformation(void);
311 extern void SetStartupBufferPinWaitBufId(int bufid);
312 extern int	GetStartupBufferPinWaitBufId(void);
313 
314 extern bool HaveNFreeProcs(int n);
315 extern void ProcReleaseLocks(bool isCommit);
316 
317 extern void ProcQueueInit(PROC_QUEUE *queue);
318 extern int	ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable);
319 extern PGPROC *ProcWakeup(PGPROC *proc, int waitStatus);
320 extern void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock);
321 extern void CheckDeadLockAlert(void);
322 extern bool IsWaitingForLock(void);
323 extern void LockErrorCleanup(void);
324 
325 extern void ProcWaitForSignal(uint32 wait_event_info);
326 extern void ProcSendSignal(int pid);
327 
328 extern PGPROC *AuxiliaryPidGetProc(int pid);
329 
330 extern void BecomeLockGroupLeader(void);
331 extern bool BecomeLockGroupMember(PGPROC *leader, int pid);
332 
333 #endif							/* _PROC_H_ */
334