1 /*------------------------------------------------------------------------- 2 * 3 * miscadmin.h 4 * This file contains general postgres administration and initialization 5 * stuff that used to be spread out between the following files: 6 * globals.h global variables 7 * pdir.h directory path crud 8 * pinit.h postgres initialization 9 * pmod.h processing modes 10 * Over time, this has also become the preferred place for widely known 11 * resource-limitation stuff, such as work_mem and check_stack_depth(). 12 * 13 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group 14 * Portions Copyright (c) 1994, Regents of the University of California 15 * 16 * src/include/miscadmin.h 17 * 18 * NOTES 19 * some of the information in this file should be moved to other files. 20 * 21 *------------------------------------------------------------------------- 22 */ 23 #ifndef MISCADMIN_H 24 #define MISCADMIN_H 25 26 #include <signal.h> 27 28 #include "datatype/timestamp.h" /* for TimestampTz */ 29 #include "pgtime.h" /* for pg_time_t */ 30 31 32 #define InvalidPid (-1) 33 34 35 /***************************************************************************** 36 * System interrupt and critical section handling 37 * 38 * There are two types of interrupts that a running backend needs to accept 39 * without messing up its state: QueryCancel (SIGINT) and ProcDie (SIGTERM). 40 * In both cases, we need to be able to clean up the current transaction 41 * gracefully, so we can't respond to the interrupt instantaneously --- 42 * there's no guarantee that internal data structures would be self-consistent 43 * if the code is interrupted at an arbitrary instant. Instead, the signal 44 * handlers set flags that are checked periodically during execution. 45 * 46 * The CHECK_FOR_INTERRUPTS() macro is called at strategically located spots 47 * where it is normally safe to accept a cancel or die interrupt. In some 48 * cases, we invoke CHECK_FOR_INTERRUPTS() inside low-level subroutines that 49 * might sometimes be called in contexts that do *not* want to allow a cancel 50 * or die interrupt. The HOLD_INTERRUPTS() and RESUME_INTERRUPTS() macros 51 * allow code to ensure that no cancel or die interrupt will be accepted, 52 * even if CHECK_FOR_INTERRUPTS() gets called in a subroutine. The interrupt 53 * will be held off until CHECK_FOR_INTERRUPTS() is done outside any 54 * HOLD_INTERRUPTS() ... RESUME_INTERRUPTS() section. 55 * 56 * There is also a mechanism to prevent query cancel interrupts, while still 57 * allowing die interrupts: HOLD_CANCEL_INTERRUPTS() and 58 * RESUME_CANCEL_INTERRUPTS(). 59 * 60 * Note that ProcessInterrupts() has also acquired a number of tasks that 61 * do not necessarily cause a query-cancel-or-die response. Hence, it's 62 * possible that it will just clear InterruptPending and return. 63 * 64 * INTERRUPTS_PENDING_CONDITION() can be checked to see whether an 65 * interrupt needs to be serviced, without trying to do so immediately. 66 * Some callers are also interested in INTERRUPTS_CAN_BE_PROCESSED(), 67 * which tells whether ProcessInterrupts is sure to clear the interrupt. 68 * 69 * Special mechanisms are used to let an interrupt be accepted when we are 70 * waiting for a lock or when we are waiting for command input (but, of 71 * course, only if the interrupt holdoff counter is zero). See the 72 * related code for details. 73 * 74 * A lost connection is handled similarly, although the loss of connection 75 * does not raise a signal, but is detected when we fail to write to the 76 * socket. If there was a signal for a broken connection, we could make use of 77 * it by setting ClientConnectionLost in the signal handler. 78 * 79 * A related, but conceptually distinct, mechanism is the "critical section" 80 * mechanism. A critical section not only holds off cancel/die interrupts, 81 * but causes any ereport(ERROR) or ereport(FATAL) to become ereport(PANIC) 82 * --- that is, a system-wide reset is forced. Needless to say, only really 83 * *critical* code should be marked as a critical section! Currently, this 84 * mechanism is only used for XLOG-related code. 85 * 86 *****************************************************************************/ 87 88 /* in globals.c */ 89 /* these are marked volatile because they are set by signal handlers: */ 90 extern PGDLLIMPORT volatile sig_atomic_t InterruptPending; 91 extern PGDLLIMPORT volatile sig_atomic_t QueryCancelPending; 92 extern PGDLLIMPORT volatile sig_atomic_t ProcDiePending; 93 extern PGDLLIMPORT volatile sig_atomic_t IdleInTransactionSessionTimeoutPending; 94 extern PGDLLIMPORT volatile sig_atomic_t IdleSessionTimeoutPending; 95 extern PGDLLIMPORT volatile sig_atomic_t ProcSignalBarrierPending; 96 extern PGDLLIMPORT volatile sig_atomic_t LogMemoryContextPending; 97 98 extern PGDLLIMPORT volatile sig_atomic_t CheckClientConnectionPending; 99 extern PGDLLIMPORT volatile sig_atomic_t ClientConnectionLost; 100 101 /* these are marked volatile because they are examined by signal handlers: */ 102 extern PGDLLIMPORT volatile uint32 InterruptHoldoffCount; 103 extern PGDLLIMPORT volatile uint32 QueryCancelHoldoffCount; 104 extern PGDLLIMPORT volatile uint32 CritSectionCount; 105 106 /* in tcop/postgres.c */ 107 extern void ProcessInterrupts(void); 108 109 /* Test whether an interrupt is pending */ 110 #ifndef WIN32 111 #define INTERRUPTS_PENDING_CONDITION() \ 112 (unlikely(InterruptPending)) 113 #else 114 #define INTERRUPTS_PENDING_CONDITION() \ 115 (unlikely(UNBLOCKED_SIGNAL_QUEUE()) ? pgwin32_dispatch_queued_signals() : 0, \ 116 unlikely(InterruptPending)) 117 #endif 118 119 /* Service interrupt, if one is pending and it's safe to service it now */ 120 #define CHECK_FOR_INTERRUPTS() \ 121 do { \ 122 if (INTERRUPTS_PENDING_CONDITION()) \ 123 ProcessInterrupts(); \ 124 } while(0) 125 126 /* Is ProcessInterrupts() guaranteed to clear InterruptPending? */ 127 #define INTERRUPTS_CAN_BE_PROCESSED() \ 128 (InterruptHoldoffCount == 0 && CritSectionCount == 0 && \ 129 QueryCancelHoldoffCount == 0) 130 131 #define HOLD_INTERRUPTS() (InterruptHoldoffCount++) 132 133 #define RESUME_INTERRUPTS() \ 134 do { \ 135 Assert(InterruptHoldoffCount > 0); \ 136 InterruptHoldoffCount--; \ 137 } while(0) 138 139 #define HOLD_CANCEL_INTERRUPTS() (QueryCancelHoldoffCount++) 140 141 #define RESUME_CANCEL_INTERRUPTS() \ 142 do { \ 143 Assert(QueryCancelHoldoffCount > 0); \ 144 QueryCancelHoldoffCount--; \ 145 } while(0) 146 147 #define START_CRIT_SECTION() (CritSectionCount++) 148 149 #define END_CRIT_SECTION() \ 150 do { \ 151 Assert(CritSectionCount > 0); \ 152 CritSectionCount--; \ 153 } while(0) 154 155 156 /***************************************************************************** 157 * globals.h -- * 158 *****************************************************************************/ 159 160 /* 161 * from utils/init/globals.c 162 */ 163 extern PGDLLIMPORT pid_t PostmasterPid; 164 extern PGDLLIMPORT bool IsPostmasterEnvironment; 165 extern PGDLLIMPORT bool IsUnderPostmaster; 166 extern PGDLLIMPORT bool IsBackgroundWorker; 167 extern PGDLLIMPORT bool IsBinaryUpgrade; 168 169 extern PGDLLIMPORT bool ExitOnAnyError; 170 171 extern PGDLLIMPORT char *DataDir; 172 extern PGDLLIMPORT int data_directory_mode; 173 174 extern PGDLLIMPORT int NBuffers; 175 extern PGDLLIMPORT int MaxBackends; 176 extern PGDLLIMPORT int MaxConnections; 177 extern PGDLLIMPORT int max_worker_processes; 178 extern PGDLLIMPORT int max_parallel_workers; 179 180 extern PGDLLIMPORT int MyProcPid; 181 extern PGDLLIMPORT pg_time_t MyStartTime; 182 extern PGDLLIMPORT TimestampTz MyStartTimestamp; 183 extern PGDLLIMPORT struct Port *MyProcPort; 184 extern PGDLLIMPORT struct Latch *MyLatch; 185 extern int32 MyCancelKey; 186 extern int MyPMChildSlot; 187 188 extern char OutputFileName[]; 189 extern PGDLLIMPORT char my_exec_path[]; 190 extern char pkglib_path[]; 191 192 #ifdef EXEC_BACKEND 193 extern char postgres_exec_path[]; 194 #endif 195 196 /* 197 * done in storage/backendid.h for now. 198 * 199 * extern BackendId MyBackendId; 200 */ 201 extern PGDLLIMPORT Oid MyDatabaseId; 202 203 extern PGDLLIMPORT Oid MyDatabaseTableSpace; 204 205 /* 206 * Date/Time Configuration 207 * 208 * DateStyle defines the output formatting choice for date/time types: 209 * USE_POSTGRES_DATES specifies traditional Postgres format 210 * USE_ISO_DATES specifies ISO-compliant format 211 * USE_SQL_DATES specifies Oracle/Ingres-compliant format 212 * USE_GERMAN_DATES specifies German-style dd.mm/yyyy 213 * 214 * DateOrder defines the field order to be assumed when reading an 215 * ambiguous date (anything not in YYYY-MM-DD format, with a four-digit 216 * year field first, is taken to be ambiguous): 217 * DATEORDER_YMD specifies field order yy-mm-dd 218 * DATEORDER_DMY specifies field order dd-mm-yy ("European" convention) 219 * DATEORDER_MDY specifies field order mm-dd-yy ("US" convention) 220 * 221 * In the Postgres and SQL DateStyles, DateOrder also selects output field 222 * order: day comes before month in DMY style, else month comes before day. 223 * 224 * The user-visible "DateStyle" run-time parameter subsumes both of these. 225 */ 226 227 /* valid DateStyle values */ 228 #define USE_POSTGRES_DATES 0 229 #define USE_ISO_DATES 1 230 #define USE_SQL_DATES 2 231 #define USE_GERMAN_DATES 3 232 #define USE_XSD_DATES 4 233 234 /* valid DateOrder values */ 235 #define DATEORDER_YMD 0 236 #define DATEORDER_DMY 1 237 #define DATEORDER_MDY 2 238 239 extern PGDLLIMPORT int DateStyle; 240 extern PGDLLIMPORT int DateOrder; 241 242 /* 243 * IntervalStyles 244 * INTSTYLE_POSTGRES Like Postgres < 8.4 when DateStyle = 'iso' 245 * INTSTYLE_POSTGRES_VERBOSE Like Postgres < 8.4 when DateStyle != 'iso' 246 * INTSTYLE_SQL_STANDARD SQL standard interval literals 247 * INTSTYLE_ISO_8601 ISO-8601-basic formatted intervals 248 */ 249 #define INTSTYLE_POSTGRES 0 250 #define INTSTYLE_POSTGRES_VERBOSE 1 251 #define INTSTYLE_SQL_STANDARD 2 252 #define INTSTYLE_ISO_8601 3 253 254 extern PGDLLIMPORT int IntervalStyle; 255 256 #define MAXTZLEN 10 /* max TZ name len, not counting tr. null */ 257 258 extern bool enableFsync; 259 extern PGDLLIMPORT bool allowSystemTableMods; 260 extern PGDLLIMPORT int work_mem; 261 extern PGDLLIMPORT double hash_mem_multiplier; 262 extern PGDLLIMPORT int maintenance_work_mem; 263 extern PGDLLIMPORT int max_parallel_maintenance_workers; 264 265 extern int VacuumCostPageHit; 266 extern int VacuumCostPageMiss; 267 extern int VacuumCostPageDirty; 268 extern int VacuumCostLimit; 269 extern double VacuumCostDelay; 270 271 extern int64 VacuumPageHit; 272 extern int64 VacuumPageMiss; 273 extern int64 VacuumPageDirty; 274 275 extern int VacuumCostBalance; 276 extern bool VacuumCostActive; 277 278 279 /* in tcop/postgres.c */ 280 281 #if defined(__ia64__) || defined(__ia64) 282 typedef struct 283 { 284 char *stack_base_ptr; 285 char *register_stack_base_ptr; 286 } pg_stack_base_t; 287 #else 288 typedef char *pg_stack_base_t; 289 #endif 290 291 extern pg_stack_base_t set_stack_base(void); 292 extern void restore_stack_base(pg_stack_base_t base); 293 extern void check_stack_depth(void); 294 extern bool stack_is_too_deep(void); 295 296 /* in tcop/utility.c */ 297 extern void PreventCommandIfReadOnly(const char *cmdname); 298 extern void PreventCommandIfParallelMode(const char *cmdname); 299 extern void PreventCommandDuringRecovery(const char *cmdname); 300 301 /* in utils/misc/guc.c */ 302 extern int trace_recovery_messages; 303 extern int trace_recovery(int trace_level); 304 305 /***************************************************************************** 306 * pdir.h -- * 307 * POSTGRES directory path definitions. * 308 *****************************************************************************/ 309 310 /* flags to be OR'd to form sec_context */ 311 #define SECURITY_LOCAL_USERID_CHANGE 0x0001 312 #define SECURITY_RESTRICTED_OPERATION 0x0002 313 #define SECURITY_NOFORCE_RLS 0x0004 314 315 extern char *DatabasePath; 316 317 /* now in utils/init/miscinit.c */ 318 extern void InitPostmasterChild(void); 319 extern void InitStandaloneProcess(const char *argv0); 320 extern void SwitchToSharedLatch(void); 321 extern void SwitchBackToLocalLatch(void); 322 323 typedef enum BackendType 324 { 325 B_INVALID = 0, 326 B_AUTOVAC_LAUNCHER, 327 B_AUTOVAC_WORKER, 328 B_BACKEND, 329 B_BG_WORKER, 330 B_BG_WRITER, 331 B_CHECKPOINTER, 332 B_STARTUP, 333 B_WAL_RECEIVER, 334 B_WAL_SENDER, 335 B_WAL_WRITER, 336 B_ARCHIVER, 337 B_STATS_COLLECTOR, 338 B_LOGGER, 339 } BackendType; 340 341 extern BackendType MyBackendType; 342 343 extern const char *GetBackendTypeDesc(BackendType backendType); 344 345 extern void SetDatabasePath(const char *path); 346 extern void checkDataDir(void); 347 extern void SetDataDir(const char *dir); 348 extern void ChangeToDataDir(void); 349 350 extern char *GetUserNameFromId(Oid roleid, bool noerr); 351 extern Oid GetUserId(void); 352 extern Oid GetOuterUserId(void); 353 extern Oid GetSessionUserId(void); 354 extern Oid GetAuthenticatedUserId(void); 355 extern void GetUserIdAndSecContext(Oid *userid, int *sec_context); 356 extern void SetUserIdAndSecContext(Oid userid, int sec_context); 357 extern bool InLocalUserIdChange(void); 358 extern bool InSecurityRestrictedOperation(void); 359 extern bool InNoForceRLSOperation(void); 360 extern void GetUserIdAndContext(Oid *userid, bool *sec_def_context); 361 extern void SetUserIdAndContext(Oid userid, bool sec_def_context); 362 extern void InitializeSessionUserId(const char *rolename, Oid useroid); 363 extern void InitializeSessionUserIdStandalone(void); 364 extern void SetSessionAuthorization(Oid userid, bool is_superuser); 365 extern Oid GetCurrentRoleId(void); 366 extern void SetCurrentRoleId(Oid roleid, bool is_superuser); 367 368 /* in utils/misc/superuser.c */ 369 extern bool superuser(void); /* current user is superuser */ 370 extern bool superuser_arg(Oid roleid); /* given user is superuser */ 371 372 373 /***************************************************************************** 374 * pmod.h -- * 375 * POSTGRES processing mode definitions. * 376 *****************************************************************************/ 377 378 /* 379 * Description: 380 * There are three processing modes in POSTGRES. They are 381 * BootstrapProcessing or "bootstrap," InitProcessing or 382 * "initialization," and NormalProcessing or "normal." 383 * 384 * The first two processing modes are used during special times. When the 385 * system state indicates bootstrap processing, transactions are all given 386 * transaction id "one" and are consequently guaranteed to commit. This mode 387 * is used during the initial generation of template databases. 388 * 389 * Initialization mode: used while starting a backend, until all normal 390 * initialization is complete. Some code behaves differently when executed 391 * in this mode to enable system bootstrapping. 392 * 393 * If a POSTGRES backend process is in normal mode, then all code may be 394 * executed normally. 395 */ 396 397 typedef enum ProcessingMode 398 { 399 BootstrapProcessing, /* bootstrap creation of template database */ 400 InitProcessing, /* initializing system */ 401 NormalProcessing /* normal processing */ 402 } ProcessingMode; 403 404 extern ProcessingMode Mode; 405 406 #define IsBootstrapProcessingMode() (Mode == BootstrapProcessing) 407 #define IsInitProcessingMode() (Mode == InitProcessing) 408 #define IsNormalProcessingMode() (Mode == NormalProcessing) 409 410 #define GetProcessingMode() Mode 411 412 #define SetProcessingMode(mode) \ 413 do { \ 414 AssertArg((mode) == BootstrapProcessing || \ 415 (mode) == InitProcessing || \ 416 (mode) == NormalProcessing); \ 417 Mode = (mode); \ 418 } while(0) 419 420 421 /* 422 * Auxiliary-process type identifiers. These used to be in bootstrap.h 423 * but it seems saner to have them here, with the ProcessingMode stuff. 424 * The MyAuxProcType global is defined and set in bootstrap.c. 425 */ 426 427 typedef enum 428 { 429 NotAnAuxProcess = -1, 430 CheckerProcess = 0, 431 BootstrapProcess, 432 StartupProcess, 433 BgWriterProcess, 434 ArchiverProcess, 435 CheckpointerProcess, 436 WalWriterProcess, 437 WalReceiverProcess, 438 439 NUM_AUXPROCTYPES /* Must be last! */ 440 } AuxProcType; 441 442 extern AuxProcType MyAuxProcType; 443 444 #define AmBootstrapProcess() (MyAuxProcType == BootstrapProcess) 445 #define AmStartupProcess() (MyAuxProcType == StartupProcess) 446 #define AmBackgroundWriterProcess() (MyAuxProcType == BgWriterProcess) 447 #define AmArchiverProcess() (MyAuxProcType == ArchiverProcess) 448 #define AmCheckpointerProcess() (MyAuxProcType == CheckpointerProcess) 449 #define AmWalWriterProcess() (MyAuxProcType == WalWriterProcess) 450 #define AmWalReceiverProcess() (MyAuxProcType == WalReceiverProcess) 451 452 453 /***************************************************************************** 454 * pinit.h -- * 455 * POSTGRES initialization and cleanup definitions. * 456 *****************************************************************************/ 457 458 /* in utils/init/postinit.c */ 459 extern void pg_split_opts(char **argv, int *argcp, const char *optstr); 460 extern void InitializeMaxBackends(void); 461 extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username, 462 Oid useroid, char *out_dbname, bool override_allow_connections); 463 extern void BaseInit(void); 464 465 /* in utils/init/miscinit.c */ 466 extern bool IgnoreSystemIndexes; 467 extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress; 468 extern char *session_preload_libraries_string; 469 extern char *shared_preload_libraries_string; 470 extern char *local_preload_libraries_string; 471 472 extern void CreateDataDirLockFile(bool amPostmaster); 473 extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster, 474 const char *socketDir); 475 extern void TouchSocketLockFiles(void); 476 extern void AddToDataDirLockFile(int target_line, const char *str); 477 extern bool RecheckDataDirLockFile(void); 478 extern void ValidatePgVersion(const char *path); 479 extern void process_shared_preload_libraries(void); 480 extern void process_session_preload_libraries(void); 481 extern void pg_bindtextdomain(const char *domain); 482 extern bool has_rolreplication(Oid roleid); 483 484 /* in access/transam/xlog.c */ 485 extern bool BackupInProgress(void); 486 extern void CancelBackup(void); 487 488 /* in executor/nodeHash.c */ 489 extern size_t get_hash_memory_limit(void); 490 extern int get_hash_mem(void); 491 492 #endif /* MISCADMIN_H */ 493