00001 /*------------------------------------------------------------------------- 00002 * 00003 * proc.h 00004 * per-process shared memory data structures 00005 * 00006 * 00007 * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group 00008 * Portions Copyright (c) 1994, Regents of the University of California 00009 * 00010 * src/include/storage/proc.h 00011 * 00012 *------------------------------------------------------------------------- 00013 */ 00014 #ifndef _PROC_H_ 00015 #define _PROC_H_ 00016 00017 #include "access/xlogdefs.h" 00018 #include "storage/latch.h" 00019 #include "storage/lock.h" 00020 #include "storage/pg_sema.h" 00021 00022 /* 00023 * Each backend advertises up to PGPROC_MAX_CACHED_SUBXIDS TransactionIds 00024 * for non-aborted subtransactions of its current top transaction. These 00025 * have to be treated as running XIDs by other backends. 00026 * 00027 * We also keep track of whether the cache overflowed (ie, the transaction has 00028 * generated at least one subtransaction that didn't fit in the cache). 00029 * If none of the caches have overflowed, we can assume that an XID that's not 00030 * listed anywhere in the PGPROC array is not a running transaction. Else we 00031 * have to look at pg_subtrans. 00032 */ 00033 #define PGPROC_MAX_CACHED_SUBXIDS 64 /* XXX guessed-at value */ 00034 00035 struct XidCache 00036 { 00037 TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]; 00038 }; 00039 00040 /* Flags for PGXACT->vacuumFlags */ 00041 #define PROC_IS_AUTOVACUUM 0x01 /* is it an autovac worker? */ 00042 #define PROC_IN_VACUUM 0x02 /* currently running lazy vacuum */ 00043 #define PROC_IN_ANALYZE 0x04 /* currently running analyze */ 00044 #define PROC_VACUUM_FOR_WRAPAROUND 0x08 /* set by autovac only */ 00045 00046 /* flags reset at EOXact */ 00047 #define PROC_VACUUM_STATE_MASK (0x0E) 00048 00049 /* 00050 * We allow a small number of "weak" relation locks (AccesShareLock, 00051 * RowShareLock, RowExclusiveLock) to be recorded in the PGPROC structure 00052 * rather than the main lock table. This eases contention on the lock 00053 * manager LWLocks. See storage/lmgr/README for additional details. 00054 */ 00055 #define FP_LOCK_SLOTS_PER_BACKEND 16 00056 00057 /* 00058 * Each backend has a PGPROC struct in shared memory. There is also a list of 00059 * currently-unused PGPROC structs that will be reallocated to new backends. 00060 * 00061 * links: list link for any list the PGPROC is in. When waiting for a lock, 00062 * the PGPROC is linked into that lock's waitProcs queue. A recycled PGPROC 00063 * is linked into ProcGlobal's freeProcs list. 00064 * 00065 * Note: twophase.c also sets up a dummy PGPROC struct for each currently 00066 * prepared transaction. These PGPROCs appear in the ProcArray data structure 00067 * so that the prepared transactions appear to be still running and are 00068 * correctly shown as holding locks. A prepared transaction PGPROC can be 00069 * distinguished from a real one at need by the fact that it has pid == 0. 00070 * The semaphore and lock-activity fields in a prepared-xact PGPROC are unused, 00071 * but its myProcLocks[] lists are valid. 00072 */ 00073 struct PGPROC 00074 { 00075 /* proc->links MUST BE FIRST IN STRUCT (see ProcSleep,ProcWakeup,etc) */ 00076 SHM_QUEUE links; /* list link if process is in a list */ 00077 00078 PGSemaphoreData sem; /* ONE semaphore to sleep on */ 00079 int waitStatus; /* STATUS_WAITING, STATUS_OK or STATUS_ERROR */ 00080 00081 Latch procLatch; /* generic latch for process */ 00082 00083 LocalTransactionId lxid; /* local id of top-level transaction currently 00084 * being executed by this proc, if running; 00085 * else InvalidLocalTransactionId */ 00086 int pid; /* Backend's process ID; 0 if prepared xact */ 00087 int pgprocno; 00088 00089 /* These fields are zero while a backend is still starting up: */ 00090 BackendId backendId; /* This backend's backend ID (if assigned) */ 00091 Oid databaseId; /* OID of database this backend is using */ 00092 Oid roleId; /* OID of role using this backend */ 00093 00094 /* 00095 * While in hot standby mode, shows that a conflict signal has been sent 00096 * for the current transaction. Set/cleared while holding ProcArrayLock, 00097 * though not required. Accessed without lock, if needed. 00098 */ 00099 bool recoveryConflictPending; 00100 00101 /* Info about LWLock the process is currently waiting for, if any. */ 00102 bool lwWaiting; /* true if waiting for an LW lock */ 00103 uint8 lwWaitMode; /* lwlock mode being waited for */ 00104 struct PGPROC *lwWaitLink; /* next waiter for same LW lock */ 00105 00106 /* Info about lock the process is currently waiting for, if any. */ 00107 /* waitLock and waitProcLock are NULL if not currently waiting. */ 00108 LOCK *waitLock; /* Lock object we're sleeping on ... */ 00109 PROCLOCK *waitProcLock; /* Per-holder info for awaited lock */ 00110 LOCKMODE waitLockMode; /* type of lock we're waiting for */ 00111 LOCKMASK heldLocks; /* bitmask for lock types already held on this 00112 * lock object by this backend */ 00113 00114 /* 00115 * Info to allow us to wait for synchronous replication, if needed. 00116 * waitLSN is InvalidXLogRecPtr if not waiting; set only by user backend. 00117 * syncRepState must not be touched except by owning process or WALSender. 00118 * syncRepLinks used only while holding SyncRepLock. 00119 */ 00120 XLogRecPtr waitLSN; /* waiting for this LSN or higher */ 00121 int syncRepState; /* wait state for sync rep */ 00122 SHM_QUEUE syncRepLinks; /* list link if process is in syncrep queue */ 00123 00124 /* 00125 * All PROCLOCK objects for locks held or awaited by this backend are 00126 * linked into one of these lists, according to the partition number of 00127 * their lock. 00128 */ 00129 SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]; 00130 00131 struct XidCache subxids; /* cache for subtransaction XIDs */ 00132 00133 /* Per-backend LWLock. Protects fields below. */ 00134 LWLockId backendLock; /* protects the fields below */ 00135 00136 /* Lock manager data, recording fast-path locks taken by this backend. */ 00137 uint64 fpLockBits; /* lock modes held for each fast-path slot */ 00138 Oid fpRelId[FP_LOCK_SLOTS_PER_BACKEND]; /* slots for rel oids */ 00139 bool fpVXIDLock; /* are we holding a fast-path VXID lock? */ 00140 LocalTransactionId fpLocalTransactionId; /* lxid for fast-path VXID 00141 * lock */ 00142 }; 00143 00144 /* NOTE: "typedef struct PGPROC PGPROC" appears in storage/lock.h. */ 00145 00146 00147 extern PGDLLIMPORT PGPROC *MyProc; 00148 extern PGDLLIMPORT struct PGXACT *MyPgXact; 00149 00150 /* 00151 * Prior to PostgreSQL 9.2, the fields below were stored as part of the 00152 * PGPROC. However, benchmarking revealed that packing these particular 00153 * members into a separate array as tightly as possible sped up GetSnapshotData 00154 * considerably on systems with many CPU cores, by reducing the number of 00155 * cache lines needing to be fetched. Thus, think very carefully before adding 00156 * anything else here. 00157 */ 00158 typedef struct PGXACT 00159 { 00160 TransactionId xid; /* id of top-level transaction currently being 00161 * executed by this proc, if running and XID 00162 * is assigned; else InvalidTransactionId */ 00163 00164 TransactionId xmin; /* minimal running XID as it was when we were 00165 * starting our xact, excluding LAZY VACUUM: 00166 * vacuum must not remove tuples deleted by 00167 * xid >= xmin ! */ 00168 00169 uint8 vacuumFlags; /* vacuum-related flags, see above */ 00170 bool overflowed; 00171 bool delayChkpt; /* true if this proc delays checkpoint start; 00172 * previously called InCommit */ 00173 00174 uint8 nxids; 00175 } PGXACT; 00176 00177 /* 00178 * There is one ProcGlobal struct for the whole database cluster. 00179 */ 00180 typedef struct PROC_HDR 00181 { 00182 /* Array of PGPROC structures (not including dummies for prepared txns) */ 00183 PGPROC *allProcs; 00184 /* Array of PGXACT structures (not including dummies for prepared txns) */ 00185 PGXACT *allPgXact; 00186 /* Length of allProcs array */ 00187 uint32 allProcCount; 00188 /* Head of list of free PGPROC structures */ 00189 PGPROC *freeProcs; 00190 /* Head of list of autovacuum's free PGPROC structures */ 00191 PGPROC *autovacFreeProcs; 00192 /* Head of list of bgworker free PGPROC structures */ 00193 PGPROC *bgworkerFreeProcs; 00194 /* WALWriter process's latch */ 00195 Latch *walwriterLatch; 00196 /* Checkpointer process's latch */ 00197 Latch *checkpointerLatch; 00198 /* Current shared estimate of appropriate spins_per_delay value */ 00199 int spins_per_delay; 00200 /* The proc of the Startup process, since not in ProcArray */ 00201 PGPROC *startupProc; 00202 int startupProcPid; 00203 /* Buffer id of the buffer that Startup process waits for pin on, or -1 */ 00204 int startupBufferPinWaitBufId; 00205 } PROC_HDR; 00206 00207 extern PROC_HDR *ProcGlobal; 00208 00209 extern PGPROC *PreparedXactProcs; 00210 00211 /* 00212 * We set aside some extra PGPROC structures for auxiliary processes, 00213 * ie things that aren't full-fledged backends but need shmem access. 00214 * 00215 * Background writer, checkpointer and WAL writer run during normal operation. 00216 * Startup process and WAL receiver also consume 2 slots, but WAL writer is 00217 * launched only after startup has exited, so we only need 4 slots. 00218 */ 00219 #define NUM_AUXILIARY_PROCS 4 00220 00221 00222 /* configurable options */ 00223 extern int DeadlockTimeout; 00224 extern int StatementTimeout; 00225 extern int LockTimeout; 00226 extern bool log_lock_waits; 00227 00228 00229 /* 00230 * Function Prototypes 00231 */ 00232 extern int ProcGlobalSemas(void); 00233 extern Size ProcGlobalShmemSize(void); 00234 extern void InitProcGlobal(void); 00235 extern void InitProcess(void); 00236 extern void InitProcessPhase2(void); 00237 extern void InitAuxiliaryProcess(void); 00238 00239 extern void PublishStartupProcessInformation(void); 00240 extern void SetStartupBufferPinWaitBufId(int bufid); 00241 extern int GetStartupBufferPinWaitBufId(void); 00242 00243 extern bool HaveNFreeProcs(int n); 00244 extern void ProcReleaseLocks(bool isCommit); 00245 00246 extern void ProcQueueInit(PROC_QUEUE *queue); 00247 extern int ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable); 00248 extern PGPROC *ProcWakeup(PGPROC *proc, int waitStatus); 00249 extern void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock); 00250 extern void CheckDeadLock(void); 00251 extern bool IsWaitingForLock(void); 00252 extern void LockErrorCleanup(void); 00253 00254 extern void ProcWaitForSignal(void); 00255 extern void ProcSendSignal(int pid); 00256 00257 #endif /* PROC_H */