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 | |