|
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 47. Background Worker Processes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets V1.79.1" /><link rel="prev" href="spi-spi-start-transaction.html" title="SPI_start_transaction" /><link rel="next" href="logicaldecoding.html" title="Chapter 48. Logical Decoding" /></head><body><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 47. Background Worker Processes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-start-transaction.html" title="SPI_start_transaction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 12.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding.html" title="Chapter 48. Logical Decoding">Next</a></td></tr></table><hr></hr></div><div class="chapter" id="BGWORKER"><div class="titlepage"><div><div><h2 class="title">Chapter 47. Background Worker Processes</h2></div></div></div><a id="id-1.8.13.2" class="indexterm"></a><p>
- PostgreSQL can be extended to run user-supplied code in separate processes.
- Such processes are started, stopped and monitored by <code class="command">postgres</code>,
- which permits them to have a lifetime closely linked to the server's status.
- These processes have the option to attach to <span class="productname">PostgreSQL</span>'s
- shared memory area and to connect to databases internally; they can also run
- multiple transactions serially, just like a regular client-connected server
- process. Also, by linking to <span class="application">libpq</span> they can connect to the
- server and behave like a regular client application.
- </p><div class="warning"><h3 class="title">Warning</h3><p>
- There are considerable robustness and security risks in using background
- worker processes because, being written in the <code class="literal">C</code> language,
- they have unrestricted access to data. Administrators wishing to enable
- modules that include background worker processes should exercise extreme
- caution. Only carefully audited modules should be permitted to run
- background worker processes.
- </p></div><p>
- Background workers can be initialized at the time that
- <span class="productname">PostgreSQL</span> is started by including the module name in
- <code class="varname">shared_preload_libraries</code>. A module wishing to run a background
- worker can register it by calling
- <code class="function">RegisterBackgroundWorker(<code class="type">BackgroundWorker *worker</code>)</code>
- from its <code class="function">_PG_init()</code>. Background workers can also be started
- after the system is up and running by calling the function
- <code class="function">RegisterDynamicBackgroundWorker(<code class="type">BackgroundWorker
- *worker, BackgroundWorkerHandle **handle</code>)</code>. Unlike
- <code class="function">RegisterBackgroundWorker</code>, which can only be called from within
- the postmaster, <code class="function">RegisterDynamicBackgroundWorker</code> must be
- called from a regular backend or another background worker.
- </p><p>
- The structure <code class="structname">BackgroundWorker</code> is defined thus:
- </p><pre class="programlisting">
- typedef void (*bgworker_main_type)(Datum main_arg);
- typedef struct BackgroundWorker
- {
- char bgw_name[BGW_MAXLEN];
- char bgw_type[BGW_MAXLEN];
- int bgw_flags;
- BgWorkerStartTime bgw_start_time;
- int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */
- char bgw_library_name[BGW_MAXLEN];
- char bgw_function_name[BGW_MAXLEN];
- Datum bgw_main_arg;
- char bgw_extra[BGW_EXTRALEN];
- int bgw_notify_pid;
- } BackgroundWorker;
- </pre><p>
- </p><p>
- <code class="structfield">bgw_name</code> and <code class="structfield">bgw_type</code> are
- strings to be used in log messages, process listings and similar contexts.
- <code class="structfield">bgw_type</code> should be the same for all background
- workers of the same type, so that it is possible to group such workers in a
- process listing, for example. <code class="structfield">bgw_name</code> on the
- other hand can contain additional information about the specific process.
- (Typically, the string for <code class="structfield">bgw_name</code> will contain
- the type somehow, but that is not strictly required.)
- </p><p>
- <code class="structfield">bgw_flags</code> is a bitwise-or'd bit mask indicating the
- capabilities that the module wants. Possible values are:
- </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">BGWORKER_SHMEM_ACCESS</code></span></dt><dd><p>
- <a id="id-1.8.13.8.2.1.2.1.1" class="indexterm"></a>
- Requests shared memory access. Workers without shared memory access
- cannot access any of <span class="productname">PostgreSQL's</span> shared
- data structures, such as heavyweight or lightweight locks, shared
- buffers, or any custom data structures which the worker itself may
- wish to create and use.
- </p></dd><dt><span class="term"><code class="literal">BGWORKER_BACKEND_DATABASE_CONNECTION</code></span></dt><dd><p>
- <a id="id-1.8.13.8.2.2.2.1.1" class="indexterm"></a>
- Requests the ability to establish a database connection through which it
- can later run transactions and queries. A background worker using
- <code class="literal">BGWORKER_BACKEND_DATABASE_CONNECTION</code> to connect to a
- database must also attach shared memory using
- <code class="literal">BGWORKER_SHMEM_ACCESS</code>, or worker start-up will fail.
- </p></dd></dl></div><p>
-
- </p><p>
- <code class="structfield">bgw_start_time</code> is the server state during which
- <code class="command">postgres</code> should start the process; it can be one of
- <code class="literal">BgWorkerStart_PostmasterStart</code> (start as soon as
- <code class="command">postgres</code> itself has finished its own initialization; processes
- requesting this are not eligible for database connections),
- <code class="literal">BgWorkerStart_ConsistentState</code> (start as soon as a consistent state
- has been reached in a hot standby, allowing processes to connect to
- databases and run read-only queries), and
- <code class="literal">BgWorkerStart_RecoveryFinished</code> (start as soon as the system has
- entered normal read-write state). Note the last two values are equivalent
- in a server that's not a hot standby. Note that this setting only indicates
- when the processes are to be started; they do not stop when a different state
- is reached.
- </p><p>
- <code class="structfield">bgw_restart_time</code> is the interval, in seconds, that
- <code class="command">postgres</code> should wait before restarting the process, in
- case it crashes. It can be any positive value,
- or <code class="literal">BGW_NEVER_RESTART</code>, indicating not to restart the
- process in case of a crash.
- </p><p>
- <code class="structfield">bgw_library_name</code> is the name of a library in
- which the initial entry point for the background worker should be sought.
- The named library will be dynamically loaded by the worker process and
- <code class="structfield">bgw_function_name</code> will be used to identify the
- function to be called. If loading a function from the core code, this must
- be set to "postgres".
- </p><p>
- <code class="structfield">bgw_function_name</code> is the name of a function in
- a dynamically loaded library which should be used as the initial entry point
- for a new background worker.
- </p><p>
- <code class="structfield">bgw_main_arg</code> is the <code class="type">Datum</code> argument
- to the background worker main function. This main function should take a
- single argument of type <code class="type">Datum</code> and return <code class="type">void</code>.
- <code class="structfield">bgw_main_arg</code> will be passed as the argument.
- In addition, the global variable <code class="literal">MyBgworkerEntry</code>
- points to a copy of the <code class="structname">BackgroundWorker</code> structure
- passed at registration time; the worker may find it helpful to examine
- this structure.
- </p><p>
- On Windows (and anywhere else where <code class="literal">EXEC_BACKEND</code> is
- defined) or in dynamic background workers it is not safe to pass a
- <code class="type">Datum</code> by reference, only by value. If an argument is required, it
- is safest to pass an int32 or other small value and use that as an index
- into an array allocated in shared memory. If a value like a <code class="type">cstring</code>
- or <code class="type">text</code> is passed then the pointer won't be valid from the
- new background worker process.
- </p><p>
- <code class="structfield">bgw_extra</code> can contain extra data to be passed
- to the background worker. Unlike <code class="structfield">bgw_main_arg</code>, this data
- is not passed as an argument to the worker's main function, but it can be
- accessed via <code class="literal">MyBgworkerEntry</code>, as discussed above.
- </p><p>
- <code class="structfield">bgw_notify_pid</code> is the PID of a PostgreSQL
- backend process to which the postmaster should send <code class="literal">SIGUSR1</code>
- when the process is started or exits. It should be 0 for workers registered
- at postmaster startup time, or when the backend registering the worker does
- not wish to wait for the worker to start up. Otherwise, it should be
- initialized to <code class="literal">MyProcPid</code>.
- </p><p>Once running, the process can connect to a database by calling
- <code class="function">BackgroundWorkerInitializeConnection(<em class="parameter"><code>char *dbname</code></em>, <em class="parameter"><code>char *username</code></em>, <em class="parameter"><code>uint32 flags</code></em>)</code> or
- <code class="function">BackgroundWorkerInitializeConnectionByOid(<em class="parameter"><code>Oid dboid</code></em>, <em class="parameter"><code>Oid useroid</code></em>, <em class="parameter"><code>uint32 flags</code></em>)</code>.
- This allows the process to run transactions and queries using the
- <code class="literal">SPI</code> interface. If <code class="varname">dbname</code> is NULL or
- <code class="varname">dboid</code> is <code class="literal">InvalidOid</code>, the session is not connected
- to any particular database, but shared catalogs can be accessed.
- If <code class="varname">username</code> is NULL or <code class="varname">useroid</code> is
- <code class="literal">InvalidOid</code>, the process will run as the superuser created
- during <code class="command">initdb</code>. If <code class="literal">BGWORKER_BYPASS_ALLOWCONN</code>
- is specified as <code class="varname">flags</code> it is possible to bypass the restriction
- to connect to databases not allowing user connections.
- A background worker can only call one of these two functions, and only
- once. It is not possible to switch databases.
- </p><p>
- Signals are initially blocked when control reaches the
- background worker's main function, and must be unblocked by it; this is to
- allow the process to customize its signal handlers, if necessary.
- Signals can be unblocked in the new process by calling
- <code class="function">BackgroundWorkerUnblockSignals</code> and blocked by calling
- <code class="function">BackgroundWorkerBlockSignals</code>.
- </p><p>
- If <code class="structfield">bgw_restart_time</code> for a background worker is
- configured as <code class="literal">BGW_NEVER_RESTART</code>, or if it exits with an exit
- code of 0 or is terminated by <code class="function">TerminateBackgroundWorker</code>,
- it will be automatically unregistered by the postmaster on exit.
- Otherwise, it will be restarted after the time period configured via
- <code class="structfield">bgw_restart_time</code>, or immediately if the postmaster
- reinitializes the cluster due to a backend failure. Backends which need
- to suspend execution only temporarily should use an interruptible sleep
- rather than exiting; this can be achieved by calling
- <code class="function">WaitLatch()</code>. Make sure the
- <code class="literal">WL_POSTMASTER_DEATH</code> flag is set when calling that function, and
- verify the return code for a prompt exit in the emergency case that
- <code class="command">postgres</code> itself has terminated.
- </p><p>
- When a background worker is registered using the
- <code class="function">RegisterDynamicBackgroundWorker</code> function, it is
- possible for the backend performing the registration to obtain information
- regarding the status of the worker. Backends wishing to do this should
- pass the address of a <code class="type">BackgroundWorkerHandle *</code> as the second
- argument to <code class="function">RegisterDynamicBackgroundWorker</code>. If the
- worker is successfully registered, this pointer will be initialized with an
- opaque handle that can subsequently be passed to
- <code class="function">GetBackgroundWorkerPid(<em class="parameter"><code>BackgroundWorkerHandle *</code></em>, <em class="parameter"><code>pid_t *</code></em>)</code> or
- <code class="function">TerminateBackgroundWorker(<em class="parameter"><code>BackgroundWorkerHandle *</code></em>)</code>.
- <code class="function">GetBackgroundWorkerPid</code> can be used to poll the status of the
- worker: a return value of <code class="literal">BGWH_NOT_YET_STARTED</code> indicates that
- the worker has not yet been started by the postmaster;
- <code class="literal">BGWH_STOPPED</code> indicates that it has been started but is
- no longer running; and <code class="literal">BGWH_STARTED</code> indicates that it is
- currently running. In this last case, the PID will also be returned via the
- second argument.
- <code class="function">TerminateBackgroundWorker</code> causes the postmaster to send
- <code class="literal">SIGTERM</code> to the worker if it is running, and to unregister it
- as soon as it is not.
- </p><p>
- In some cases, a process which registers a background worker may wish to
- wait for the worker to start up. This can be accomplished by initializing
- <code class="structfield">bgw_notify_pid</code> to <code class="literal">MyProcPid</code> and
- then passing the <code class="type">BackgroundWorkerHandle *</code> obtained at
- registration time to
- <code class="function">WaitForBackgroundWorkerStartup(<em class="parameter"><code>BackgroundWorkerHandle
- *handle</code></em>, <em class="parameter"><code>pid_t *</code></em>)</code> function.
- This function will block until the postmaster has attempted to start the
- background worker, or until the postmaster dies. If the background worker
- is running, the return value will be <code class="literal">BGWH_STARTED</code>, and
- the PID will be written to the provided address. Otherwise, the return
- value will be <code class="literal">BGWH_STOPPED</code> or
- <code class="literal">BGWH_POSTMASTER_DIED</code>.
- </p><p>
- A process can also wait for a background worker to shut down, by using the
- <code class="function">WaitForBackgroundWorkerShutdown(<em class="parameter"><code>BackgroundWorkerHandle
- *handle</code></em>)</code> function and passing the
- <code class="type">BackgroundWorkerHandle *</code> obtained at registration. This
- function will block until the background worker exits, or postmaster dies.
- When the background worker exits, the return value is
- <code class="literal">BGWH_STOPPED</code>, if postmaster dies it will return
- <code class="literal">BGWH_POSTMASTER_DIED</code>.
- </p><p>
- If a background worker sends asynchronous notifications with the
- <code class="command">NOTIFY</code> command via the Server Programming Interface
- (<acronym class="acronym">SPI</acronym>), it should call
- <code class="function">ProcessCompletedNotifies</code> explicitly after committing
- the enclosing transaction so that any notifications can be delivered. If a
- background worker registers to receive asynchronous notifications with
- the <code class="command">LISTEN</code> through <acronym class="acronym">SPI</acronym>, the worker
- will log those notifications, but there is no programmatic way for the
- worker to intercept and respond to those notifications.
- </p><p>
- The <code class="filename">src/test/modules/worker_spi</code> module
- contains a working example,
- which demonstrates some useful techniques.
- </p><p>
- The maximum number of registered background workers is limited by
- <a class="xref" href="runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES">max_worker_processes</a>.
- </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-start-transaction.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_start_transaction </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 48. Logical Decoding</td></tr></table></div></body></html>
|