Skip to content

Commit 80a8f95

Browse files
committed
Remove support for background workers without BGWORKER_SHMEM_ACCESS.
Background workers without shared memory access have been broken on EXEC_BACKEND / windows builds since shortly after background workers have been introduced, without that being reported. Clearly they are not commonly used. The problem is that bgworker startup requires to be attached to shared memory in EXEC_BACKEND child processes. StartBackgroundWorker() detaches from shared memory for unconnected workers, but at that point we already have initialized subsystems referencing shared memory. Fixing this problem is not entirely trivial, so removing the option to not be connected to shared memory seems the best way forward. In most use cases the advantages of being connected to shared memory far outweigh the disadvantages. As there have been no reports about this issue so far, we have decided that it is not worth trying to address the problem in the back branches. Per discussion with Alvaro Herrera, Robert Haas and Tom Lane. Author: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/20210802065116.j763tz3vz4egqy3w@alap3.anarazel.de
1 parent 1d5135f commit 80a8f95

File tree

4 files changed

+38
-63
lines changed

4 files changed

+38
-63
lines changed

doc/src/sgml/bgworker.sgml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
PostgreSQL can be extended to run user-supplied code in separate processes.
1212
Such processes are started, stopped and monitored by <command>postgres</command>,
1313
which permits them to have a lifetime closely linked to the server's status.
14-
These processes have the option to attach to <productname>PostgreSQL</productname>'s
15-
shared memory area and to connect to databases internally; they can also run
14+
These processes are attached to <productname>PostgreSQL</productname>'s
15+
shared memory area and have the option to connect to databases internally; they can also run
1616
multiple transactions serially, just like a regular client-connected server
1717
process. Also, by linking to <application>libpq</application> they can connect to the
1818
server and behave like a regular client application.
@@ -89,11 +89,7 @@ typedef struct BackgroundWorker
8989
<listitem>
9090
<para>
9191
<indexterm><primary>BGWORKER_SHMEM_ACCESS</primary></indexterm>
92-
Requests shared memory access. Workers without shared memory access
93-
cannot access any of <productname>PostgreSQL's</productname> shared
94-
data structures, such as heavyweight or lightweight locks, shared
95-
buffers, or any custom data structures which the worker itself may
96-
wish to create and use.
92+
Requests shared memory access. This flag is required.
9793
</para>
9894
</listitem>
9995
</varlistentry>

src/backend/postmaster/bgworker.c

Lines changed: 25 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -652,17 +652,24 @@ static bool
652652
SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel)
653653
{
654654
/* sanity check for flags */
655-
if (worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION)
655+
656+
/*
657+
* We used to support workers not connected to shared memory, but don't
658+
* anymore. Thus this is a required flag now. We're not removing the flag
659+
* for compatibility reasons and because the flag still provides some
660+
* signal when reading code.
661+
*/
662+
if (!(worker->bgw_flags & BGWORKER_SHMEM_ACCESS))
656663
{
657-
if (!(worker->bgw_flags & BGWORKER_SHMEM_ACCESS))
658-
{
659-
ereport(elevel,
660-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
661-
errmsg("background worker \"%s\": must attach to shared memory in order to request a database connection",
662-
worker->bgw_name)));
663-
return false;
664-
}
664+
ereport(elevel,
665+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
666+
errmsg("background worker \"%s\": background worker without shared memory access are not supported",
667+
worker->bgw_name)));
668+
return false;
669+
}
665670

671+
if (worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION)
672+
{
666673
if (worker->bgw_start_time == BgWorkerStart_PostmasterStart)
667674
{
668675
ereport(elevel,
@@ -745,20 +752,6 @@ StartBackgroundWorker(void)
745752
MyBackendType = B_BG_WORKER;
746753
init_ps_display(worker->bgw_name);
747754

748-
/*
749-
* If we're not supposed to have shared memory access, then detach from
750-
* shared memory. If we didn't request shared memory access, the
751-
* postmaster won't force a cluster-wide restart if we exit unexpectedly,
752-
* so we'd better make sure that we don't mess anything up that would
753-
* require that sort of cleanup.
754-
*/
755-
if ((worker->bgw_flags & BGWORKER_SHMEM_ACCESS) == 0)
756-
{
757-
ShutdownLatchSupport();
758-
dsm_detach_all();
759-
PGSharedMemoryDetach();
760-
}
761-
762755
SetProcessingMode(InitProcessing);
763756

764757
/* Apply PostAuthDelay */
@@ -832,29 +825,19 @@ StartBackgroundWorker(void)
832825
PG_exception_stack = &local_sigjmp_buf;
833826

834827
/*
835-
* If the background worker request shared memory access, set that up now;
836-
* else, detach all shared memory segments.
828+
* Create a per-backend PGPROC struct in shared memory, except in the
829+
* EXEC_BACKEND case where this was done in SubPostmasterMain. We must
830+
* do this before we can use LWLocks (and in the EXEC_BACKEND case we
831+
* already had to do some stuff with LWLocks).
837832
*/
838-
if (worker->bgw_flags & BGWORKER_SHMEM_ACCESS)
839-
{
840-
/*
841-
* Create a per-backend PGPROC struct in shared memory, except in the
842-
* EXEC_BACKEND case where this was done in SubPostmasterMain. We must
843-
* do this before we can use LWLocks (and in the EXEC_BACKEND case we
844-
* already had to do some stuff with LWLocks).
845-
*/
846833
#ifndef EXEC_BACKEND
847-
InitProcess();
834+
InitProcess();
848835
#endif
849836

850-
/*
851-
* Early initialization. Some of this could be useful even for
852-
* background workers that aren't using shared memory, but they can
853-
* call the individual startup routines for those subsystems if
854-
* needed.
855-
*/
856-
BaseInit();
857-
}
837+
/*
838+
* Early initialization.
839+
*/
840+
BaseInit();
858841

859842
/*
860843
* Look up the entry point function, loading its library if necessary.

src/backend/postmaster/postmaster.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3302,26 +3302,21 @@ CleanupBackgroundWorker(int pid,
33023302
}
33033303

33043304
/*
3305-
* Additionally, for shared-memory-connected workers, just like a
3306-
* backend, any exit status other than 0 or 1 is considered a crash
3307-
* and causes a system-wide restart.
3305+
* Additionally, just like a backend, any exit status other than 0 or
3306+
* 1 is considered a crash and causes a system-wide restart.
33083307
*/
3309-
if ((rw->rw_worker.bgw_flags & BGWORKER_SHMEM_ACCESS) != 0)
3308+
if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
33103309
{
3311-
if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
3312-
{
3313-
HandleChildCrash(pid, exitstatus, namebuf);
3314-
return true;
3315-
}
3310+
HandleChildCrash(pid, exitstatus, namebuf);
3311+
return true;
33163312
}
33173313

33183314
/*
3319-
* We must release the postmaster child slot whether this worker is
3320-
* connected to shared memory or not, but we only treat it as a crash
3321-
* if it is in fact connected.
3315+
* We must release the postmaster child slot. If the worker failed to
3316+
* do so, it did not clean up after itself, requiring a crash-restart
3317+
* cycle.
33223318
*/
3323-
if (!ReleasePostmasterChildSlot(rw->rw_child_slot) &&
3324-
(rw->rw_worker.bgw_flags & BGWORKER_SHMEM_ACCESS) != 0)
3319+
if (!ReleasePostmasterChildSlot(rw->rw_child_slot))
33253320
{
33263321
HandleChildCrash(pid, exitstatus, namebuf);
33273322
return true;

src/include/postmaster/bgworker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
/*
5050
* Pass this flag to have your worker be able to connect to shared memory.
51+
* This flag is required.
5152
*/
5253
#define BGWORKER_SHMEM_ACCESS 0x0001
5354

0 commit comments

Comments
 (0)