diff --git a/doc/src/sgml/bgworker.sgml b/doc/src/sgml/bgworker.sgml
index 7fd673ab54e..d34acfc220d 100644
--- a/doc/src/sgml/bgworker.sgml
+++ b/doc/src/sgml/bgworker.sgml
@@ -11,8 +11,8 @@
PostgreSQL can be extended to run user-supplied code in separate processes.
Such processes are started, stopped and monitored by postgres,
which permits them to have a lifetime closely linked to the server's status.
- These processes have the option to attach to PostgreSQL's
- shared memory area and to connect to databases internally; they can also run
+ These processes are attached to PostgreSQL's
+ shared memory area and have the option to connect to databases internally; they can also run
multiple transactions serially, just like a regular client-connected server
process. Also, by linking to libpq they can connect to the
server and behave like a regular client application.
@@ -89,11 +89,7 @@ typedef struct BackgroundWorker
BGWORKER_SHMEM_ACCESS
- Requests shared memory access. Workers without shared memory access
- cannot access any of PostgreSQL's 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.
+ Requests shared memory access. This flag is required.
diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c
index 11c4ceddbf6..c05f5006393 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -652,17 +652,24 @@ static bool
SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel)
{
/* sanity check for flags */
+
+ /*
+ * We used to support workers not connected to shared memory, but don't
+ * anymore. Thus this is a required flag now. We're not removing the flag
+ * for compatibility reasons and because the flag still provides some
+ * signal when reading code.
+ */
+ if (!(worker->bgw_flags & BGWORKER_SHMEM_ACCESS))
+ {
+ ereport(elevel,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("background worker \"%s\": background worker without shared memory access are not supported",
+ worker->bgw_name)));
+ return false;
+ }
+
if (worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION)
{
- if (!(worker->bgw_flags & BGWORKER_SHMEM_ACCESS))
- {
- ereport(elevel,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("background worker \"%s\": must attach to shared memory in order to request a database connection",
- worker->bgw_name)));
- return false;
- }
-
if (worker->bgw_start_time == BgWorkerStart_PostmasterStart)
{
ereport(elevel,
@@ -745,20 +752,6 @@ StartBackgroundWorker(void)
MyBackendType = B_BG_WORKER;
init_ps_display(worker->bgw_name);
- /*
- * If we're not supposed to have shared memory access, then detach from
- * shared memory. If we didn't request shared memory access, the
- * postmaster won't force a cluster-wide restart if we exit unexpectedly,
- * so we'd better make sure that we don't mess anything up that would
- * require that sort of cleanup.
- */
- if ((worker->bgw_flags & BGWORKER_SHMEM_ACCESS) == 0)
- {
- ShutdownLatchSupport();
- dsm_detach_all();
- PGSharedMemoryDetach();
- }
-
SetProcessingMode(InitProcessing);
/* Apply PostAuthDelay */
@@ -832,29 +825,19 @@ StartBackgroundWorker(void)
PG_exception_stack = &local_sigjmp_buf;
/*
- * If the background worker request shared memory access, set that up now;
- * else, detach all shared memory segments.
+ * Create a per-backend PGPROC struct in shared memory, except in the
+ * EXEC_BACKEND case where this was done in SubPostmasterMain. We must
+ * do this before we can use LWLocks (and in the EXEC_BACKEND case we
+ * already had to do some stuff with LWLocks).
*/
- if (worker->bgw_flags & BGWORKER_SHMEM_ACCESS)
- {
- /*
- * Create a per-backend PGPROC struct in shared memory, except in the
- * EXEC_BACKEND case where this was done in SubPostmasterMain. We must
- * do this before we can use LWLocks (and in the EXEC_BACKEND case we
- * already had to do some stuff with LWLocks).
- */
#ifndef EXEC_BACKEND
- InitProcess();
+ InitProcess();
#endif
- /*
- * Early initialization. Some of this could be useful even for
- * background workers that aren't using shared memory, but they can
- * call the individual startup routines for those subsystems if
- * needed.
- */
- BaseInit();
- }
+ /*
+ * Early initialization.
+ */
+ BaseInit();
/*
* Look up the entry point function, loading its library if necessary.
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index fc0bc8d99ee..9c2c98614aa 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -3302,26 +3302,21 @@ CleanupBackgroundWorker(int pid,
}
/*
- * Additionally, for shared-memory-connected workers, just like a
- * backend, any exit status other than 0 or 1 is considered a crash
- * and causes a system-wide restart.
+ * Additionally, just like a backend, any exit status other than 0 or
+ * 1 is considered a crash and causes a system-wide restart.
*/
- if ((rw->rw_worker.bgw_flags & BGWORKER_SHMEM_ACCESS) != 0)
+ if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
{
- if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
- {
- HandleChildCrash(pid, exitstatus, namebuf);
- return true;
- }
+ HandleChildCrash(pid, exitstatus, namebuf);
+ return true;
}
/*
- * We must release the postmaster child slot whether this worker is
- * connected to shared memory or not, but we only treat it as a crash
- * if it is in fact connected.
+ * We must release the postmaster child slot. If the worker failed to
+ * do so, it did not clean up after itself, requiring a crash-restart
+ * cycle.
*/
- if (!ReleasePostmasterChildSlot(rw->rw_child_slot) &&
- (rw->rw_worker.bgw_flags & BGWORKER_SHMEM_ACCESS) != 0)
+ if (!ReleasePostmasterChildSlot(rw->rw_child_slot))
{
HandleChildCrash(pid, exitstatus, namebuf);
return true;
diff --git a/src/include/postmaster/bgworker.h b/src/include/postmaster/bgworker.h
index 8e9ef7c7bfa..6d4122b4c7e 100644
--- a/src/include/postmaster/bgworker.h
+++ b/src/include/postmaster/bgworker.h
@@ -48,6 +48,7 @@
/*
* Pass this flag to have your worker be able to connect to shared memory.
+ * This flag is required.
*/
#define BGWORKER_SHMEM_ACCESS 0x0001