Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit090d0f2

Browse files
committed
Allow discovery of whether a dynamic background worker is running.
Using the infrastructure provided by this patch, it's possible eitherto wait for the startup of a dynamically-registered background worker,or to poll the status of such a worker without waiting. In eithercase, the current PID of the worker process can also be obtained.As usual, worker_spi is updated to demonstrate the new functionality.Patch by me. Review by Andres Freund.
1 parentc9e2e2d commit090d0f2

File tree

12 files changed

+368
-13
lines changed

12 files changed

+368
-13
lines changed

‎contrib/worker_spi/worker_spi--1.0.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
\echo Use"CREATE EXTENSION worker_spi" to load this file. \quit
55

66
CREATEFUNCTIONworker_spi_launch(pg_catalog.int4)
7-
RETURNSpg_catalog.bool STRICT
7+
RETURNSpg_catalog.int4 STRICT
88
AS'MODULE_PATHNAME'
99
LANGUAGE C;

‎contrib/worker_spi/worker_spi.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,9 @@ worker_spi_launch(PG_FUNCTION_ARGS)
365365
{
366366
int32i=PG_GETARG_INT32(0);
367367
BackgroundWorkerworker;
368+
BackgroundWorkerHandle*handle;
369+
BgwHandleStatusstatus;
370+
pid_tpid;
368371

369372
worker.bgw_flags=BGWORKER_SHMEM_ACCESS |
370373
BGWORKER_BACKEND_DATABASE_CONNECTION;
@@ -375,6 +378,25 @@ worker_spi_launch(PG_FUNCTION_ARGS)
375378
sprintf(worker.bgw_function_name,"worker_spi_main");
376379
snprintf(worker.bgw_name,BGW_MAXLEN,"worker %d",i);
377380
worker.bgw_main_arg=Int32GetDatum(i);
378-
379-
PG_RETURN_BOOL(RegisterDynamicBackgroundWorker(&worker));
381+
/* set bgw_notify_pid so that we can use WaitForBackgroundWorkerStartup */
382+
worker.bgw_notify_pid=MyProcPid;
383+
384+
if (!RegisterDynamicBackgroundWorker(&worker,&handle))
385+
PG_RETURN_NULL();
386+
387+
status=WaitForBackgroundWorkerStartup(handle,&pid);
388+
389+
if (status==BGWH_STOPPED)
390+
ereport(ERROR,
391+
(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
392+
errmsg("could not start background process"),
393+
errhint("More details may be available in the server log.")));
394+
if (status==BGWH_POSTMASTER_DIED)
395+
ereport(ERROR,
396+
(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
397+
errmsg("cannot start background processes without postmaster"),
398+
errhint("Kill all remaining database processes and restart the database.")));
399+
Assert(status==BGWH_STARTED);
400+
401+
PG_RETURN_INT32(pid);
380402
}

‎doc/src/sgml/bgworker.sgml

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@
3737
<function>RegisterBackgroundWorker(<type>BackgroundWorker *worker</type>)</function>
3838
from its <function>_PG_init()</>. Background workers can also be started
3939
after the system is up and running by calling the function
40-
<function>RegisterDynamicBackgroundWorker</function>(<type>BackgroundWorker
41-
*worker</type>). Unlike <function>RegisterBackgroundWorker</>, which can
42-
only be called from within the postmaster,
43-
<function>RegisterDynamicBackgroundWorker</function> must be called from
44-
a regular backend.
40+
<function>RegisterDynamicBackgroundWorker(<type>BackgroundWorker
41+
*worker, BackgroundWorkerHandle **handle</type>)</function>. Unlike
42+
<function>RegisterBackgroundWorker</>, which canonly be called from within
43+
the postmaster,<function>RegisterDynamicBackgroundWorker</function> must be
44+
called froma regular backend.
4545
</para>
4646

4747
<para>
@@ -58,6 +58,7 @@ typedef struct BackgroundWorker
5858
char bgw_library_name[BGW_MAXLEN]; /* only if bgw_main is NULL */
5959
char bgw_function_name[BGW_MAXLEN]; /* only if bgw_main is NULL */
6060
Datum bgw_main_arg;
61+
int bgw_notify_pid;
6162
} BackgroundWorker;
6263
</programlisting>
6364
</para>
@@ -135,6 +136,15 @@ typedef struct BackgroundWorker
135136
<structfield>bgw_main</structfield> is NULL.
136137
</para>
137138

139+
<para>
140+
<structfield>bgw_notify_pid</structfield> is the PID of a PostgreSQL
141+
backend process to which the postmaster should send <literal>SIGUSR1</>
142+
when the process is started or exits. It should be 0 for workers registered
143+
at postmaster startup time, or when the backend registering the worker does
144+
not wish to wait for the worker to start up. Otherwise, it should be
145+
initialized to <literal>MyProcPid</>.
146+
</para>
147+
138148
<para>Once running, the process can connect to a database by calling
139149
<function>BackgroundWorkerInitializeConnection(<parameter>char *dbname</parameter>, <parameter>char *username</parameter>)</function>.
140150
This allows the process to run transactions and queries using the
@@ -165,6 +175,40 @@ typedef struct BackgroundWorker
165175
<command>postgres</> itself has terminated.
166176
</para>
167177

178+
<para>
179+
When a background worker is registered using the
180+
<function>RegisterDynamicBackgroundWorker</function> function, it is
181+
possible for the backend performing the registration to obtain information
182+
the status of the worker. Backends wishing to do this should pass the
183+
address of a <type>BackgroundWorkerHandle *</type> as the second argument
184+
to <function>RegisterDynamicBackgroundWorker</function>. If the worker
185+
is successfully registered, this pointer will be initialized with an
186+
opaque handle that can subsequently be passed to
187+
<function>GetBackgroundWorkerPid(<parameter>BackgroundWorkerHandle *</parameter>, <parameter>pid_t *</parameter>)</function>.
188+
This function can be used to poll the status of the worker: a return
189+
value of <literal>BGWH_NOT_YET_STARTED</> indicates that the worker has not
190+
yet been started by the postmaster; <literal>BGWH_STOPPED</literal>
191+
indicates that it has been started but is no longer running; and
192+
<literal>BGWH_STARTED</literal> indicates that it is currently running.
193+
In this last case, the PID will also be returned via the second argument.
194+
</para>
195+
196+
<para>
197+
In some cases, a process which registers a background worker may wish to
198+
wait for the worker to start up. This can be accomplished by initializing
199+
<structfield>bgw_notify_pid</structfield> to <literal>MyProcPid</> and
200+
then passing the <type>BackgroundWorkerHandle *</type> obtained at
201+
registration time to
202+
<function>WaitForBackgroundWorkerStartup(<parameter>BackgroundWorkerHandle
203+
*handle</parameter>, <parameter>pid_t *</parameter>)</function> function.
204+
This function will block until the postmaster has attempted to start the
205+
background worker, or until the postmaster dies. If the background runner
206+
is running, the return value will <literal>BGWH_STARTED</>, and
207+
the PID will be written to the provided address. Otherwise, the return
208+
value will be <literal>BGWH_STOPPED</literal> or
209+
<literal>BGWH_POSTMASTER_DIED</literal>.
210+
</para>
211+
168212
<para>
169213
The <filename>worker_spi</> contrib module contains a working example,
170214
which demonstrates some useful techniques.

‎src/backend/commands/async.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,6 @@ typedef struct QueueBackendStatus
207207
QueuePositionpos;/* backend has read queue up to here */
208208
}QueueBackendStatus;
209209

210-
#defineInvalidPid(-1)
211-
212210
/*
213211
* Shared memory state for LISTEN/NOTIFY (excluding its SLRU stuff)
214212
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp