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