| 1 | /*-------------------------------------------------------------------- |
| 2 | * bgworker.h |
| 3 | * POSTGRES pluggable background workers interface |
| 4 | * |
| 5 | * A background worker is a process able to run arbitrary, user-supplied code, |
| 6 | * including normal transactions. |
| 7 | * |
| 8 | * Any external module loaded via shared_preload_libraries can register a |
| 9 | * worker. Workers can also be registered dynamically at runtime. In either |
| 10 | * case, the worker process is forked from the postmaster and runs the |
| 11 | * user-supplied "main" function. This code may connect to a database and |
| 12 | * run transactions. Workers can remain active indefinitely, but will be |
| 13 | * terminated if a shutdown or crash occurs. |
| 14 | * |
| 15 | * If the fork() call fails in the postmaster, it will try again later. Note |
| 16 | * that the failure can only be transient (fork failure due to high load, |
| 17 | * memory pressure, too many processes, etc); more permanent problems, like |
| 18 | * failure to connect to a database, are detected later in the worker and dealt |
| 19 | * with just by having the worker exit normally. A worker which exits with |
| 20 | * a return code of 0 will never be restarted and will be removed from worker |
| 21 | * list. A worker which exits with a return code of 1 will be restarted after |
| 22 | * the configured restart interval (unless that interval is BGW_NEVER_RESTART). |
| 23 | * The TerminateBackgroundWorker() function can be used to terminate a |
| 24 | * dynamically registered background worker; the worker will be sent a SIGTERM |
| 25 | * and will not be restarted after it exits. Whenever the postmaster knows |
| 26 | * that a worker will not be restarted, it unregisters the worker, freeing up |
| 27 | * that worker's slot for use by a new worker. |
| 28 | * |
| 29 | * Note that there might be more than one worker in a database concurrently, |
| 30 | * and the same module may request more than one worker running the same (or |
| 31 | * different) code. |
| 32 | * |
| 33 | * |
| 34 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 35 | * Portions Copyright (c) 1994, Regents of the University of California |
| 36 | * |
| 37 | * IDENTIFICATION |
| 38 | * src/include/postmaster/bgworker.h |
| 39 | *-------------------------------------------------------------------- |
| 40 | */ |
| 41 | #ifndef BGWORKER_H |
| 42 | #define BGWORKER_H |
| 43 | |
| 44 | /*--------------------------------------------------------------------- |
| 45 | * External module API. |
| 46 | *--------------------------------------------------------------------- |
| 47 | */ |
| 48 | |
| 49 | /* |
| 50 | * Pass this flag to have your worker be able to connect to shared memory. |
| 51 | */ |
| 52 | #define BGWORKER_SHMEM_ACCESS 0x0001 |
| 53 | |
| 54 | /* |
| 55 | * This flag means the bgworker requires a database connection. The connection |
| 56 | * is not established automatically; the worker must establish it later. |
| 57 | * It requires that BGWORKER_SHMEM_ACCESS was passed too. |
| 58 | */ |
| 59 | #define BGWORKER_BACKEND_DATABASE_CONNECTION 0x0002 |
| 60 | |
| 61 | /* |
| 62 | * This class is used internally for parallel queries, to keep track of the |
| 63 | * number of active parallel workers and make sure we never launch more than |
| 64 | * max_parallel_workers parallel workers at the same time. Third party |
| 65 | * background workers should not use this class. |
| 66 | */ |
| 67 | #define BGWORKER_CLASS_PARALLEL 0x0010 |
| 68 | /* add additional bgworker classes here */ |
| 69 | |
| 70 | |
| 71 | typedef void (*bgworker_main_type) (Datum main_arg); |
| 72 | |
| 73 | /* |
| 74 | * Points in time at which a bgworker can request to be started |
| 75 | */ |
| 76 | typedef enum |
| 77 | { |
| 78 | BgWorkerStart_PostmasterStart, |
| 79 | BgWorkerStart_ConsistentState, |
| 80 | BgWorkerStart_RecoveryFinished |
| 81 | } BgWorkerStartTime; |
| 82 | |
| 83 | #define BGW_DEFAULT_RESTART_INTERVAL 60 |
| 84 | #define BGW_NEVER_RESTART -1 |
| 85 | #define BGW_MAXLEN 96 |
| 86 | #define 128 |
| 87 | |
| 88 | typedef struct BackgroundWorker |
| 89 | { |
| 90 | char bgw_name[BGW_MAXLEN]; |
| 91 | char bgw_type[BGW_MAXLEN]; |
| 92 | int bgw_flags; |
| 93 | BgWorkerStartTime bgw_start_time; |
| 94 | int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */ |
| 95 | char bgw_library_name[BGW_MAXLEN]; |
| 96 | char bgw_function_name[BGW_MAXLEN]; |
| 97 | Datum bgw_main_arg; |
| 98 | char [BGW_EXTRALEN]; |
| 99 | pid_t bgw_notify_pid; /* SIGUSR1 this backend on start/stop */ |
| 100 | } BackgroundWorker; |
| 101 | |
| 102 | typedef enum BgwHandleStatus |
| 103 | { |
| 104 | BGWH_STARTED, /* worker is running */ |
| 105 | BGWH_NOT_YET_STARTED, /* worker hasn't been started yet */ |
| 106 | BGWH_STOPPED, /* worker has exited */ |
| 107 | BGWH_POSTMASTER_DIED /* postmaster died; worker status unclear */ |
| 108 | } BgwHandleStatus; |
| 109 | |
| 110 | struct BackgroundWorkerHandle; |
| 111 | typedef struct BackgroundWorkerHandle BackgroundWorkerHandle; |
| 112 | |
| 113 | /* Register a new bgworker during shared_preload_libraries */ |
| 114 | extern void RegisterBackgroundWorker(BackgroundWorker *worker); |
| 115 | |
| 116 | /* Register a new bgworker from a regular backend */ |
| 117 | extern bool RegisterDynamicBackgroundWorker(BackgroundWorker *worker, |
| 118 | BackgroundWorkerHandle **handle); |
| 119 | |
| 120 | /* Query the status of a bgworker */ |
| 121 | extern BgwHandleStatus GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, |
| 122 | pid_t *pidp); |
| 123 | extern BgwHandleStatus WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pid); |
| 124 | extern BgwHandleStatus |
| 125 | WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *); |
| 126 | extern const char *GetBackgroundWorkerTypeByPid(pid_t pid); |
| 127 | |
| 128 | /* Terminate a bgworker */ |
| 129 | extern void TerminateBackgroundWorker(BackgroundWorkerHandle *handle); |
| 130 | |
| 131 | /* This is valid in a running worker */ |
| 132 | extern PGDLLIMPORT BackgroundWorker *MyBgworkerEntry; |
| 133 | |
| 134 | /* |
| 135 | * Connect to the specified database, as the specified user. Only a worker |
| 136 | * that passed BGWORKER_BACKEND_DATABASE_CONNECTION during registration may |
| 137 | * call this. |
| 138 | * |
| 139 | * If username is NULL, bootstrapping superuser is used. |
| 140 | * If dbname is NULL, connection is made to no specific database; |
| 141 | * only shared catalogs can be accessed. |
| 142 | */ |
| 143 | extern void BackgroundWorkerInitializeConnection(const char *dbname, const char *username, uint32 flags); |
| 144 | |
| 145 | /* Just like the above, but specifying database and user by OID. */ |
| 146 | extern void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags); |
| 147 | |
| 148 | /* |
| 149 | * Flags to BackgroundWorkerInitializeConnection et al |
| 150 | * |
| 151 | * |
| 152 | * Allow bypassing datallowconn restrictions when connecting to database |
| 153 | */ |
| 154 | #define BGWORKER_BYPASS_ALLOWCONN 1 |
| 155 | |
| 156 | |
| 157 | /* Block/unblock signals in a background worker process */ |
| 158 | extern void BackgroundWorkerBlockSignals(void); |
| 159 | extern void BackgroundWorkerUnblockSignals(void); |
| 160 | |
| 161 | #endif /* BGWORKER_H */ |
| 162 | |