diff --git a/doc/src/sgml/bgworker.sgml b/doc/src/sgml/bgworker.sgml
index ef28f725114..33ff5269516 100644
--- a/doc/src/sgml/bgworker.sgml
+++ b/doc/src/sgml/bgworker.sgml
@@ -58,6 +58,7 @@ typedef struct BackgroundWorker
char bgw_library_name[BGW_MAXLEN]; /* only if bgw_main is NULL */
char bgw_function_name[BGW_MAXLEN]; /* only if bgw_main is NULL */
Datum bgw_main_arg;
+ char bgw_extra[BGW_EXTRALEN];
int bgw_notify_pid;
} BackgroundWorker;
@@ -136,6 +137,13 @@ typedef struct BackgroundWorker
bgw_main is NULL.
+
+ bgw_extra can contain extra data to be passed
+ to the background worker. Unlike bgw_main_arg>, this data
+ is not passed as an argument to the worker's main function, but it can be
+ accessed via MyBgworkerEntry, as discussed above.
+
+
bgw_notify_pid is the PID of a PostgreSQL
backend process to which the postmaster should send SIGUSR1>
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index 9c7428f5d6c..38a4d65b1f5 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -77,10 +77,6 @@ typedef struct FixedParallelState
/* Mutex protects remaining fields. */
slock_t mutex;
- /* Track whether workers have attached. */
- int workers_expected;
- int workers_attached;
-
/* Maximum XactLastRecEnd of any worker. */
XLogRecPtr last_xlog_end;
} FixedParallelState;
@@ -286,8 +282,6 @@ InitializeParallelDSM(ParallelContext *pcxt)
fps->parallel_master_backend_id = MyBackendId;
fps->entrypoint = pcxt->entrypoint;
SpinLockInit(&fps->mutex);
- fps->workers_expected = pcxt->nworkers;
- fps->workers_attached = 0;
fps->last_xlog_end = 0;
shm_toc_insert(pcxt->toc, PARALLEL_KEY_FIXED, fps);
@@ -406,6 +400,7 @@ LaunchParallelWorkers(ParallelContext *pcxt)
worker.bgw_main = ParallelWorkerMain;
worker.bgw_main_arg = UInt32GetDatum(dsm_segment_handle(pcxt->seg));
worker.bgw_notify_pid = MyProcPid;
+ memset(&worker.bgw_extra, 0, BGW_EXTRALEN);
/*
* Start workers.
@@ -417,6 +412,7 @@ LaunchParallelWorkers(ParallelContext *pcxt)
*/
for (i = 0; i < pcxt->nworkers; ++i)
{
+ memcpy(worker.bgw_extra, &i, sizeof(int));
if (!any_registrations_failed &&
RegisterDynamicBackgroundWorker(&worker,
&pcxt->worker[i].bgwhandle))
@@ -825,6 +821,10 @@ ParallelWorkerMain(Datum main_arg)
pqsignal(SIGTERM, die);
BackgroundWorkerUnblockSignals();
+ /* Determine and set our parallel worker number. */
+ Assert(ParallelWorkerNumber == -1);
+ memcpy(&ParallelWorkerNumber, MyBgworkerEntry->bgw_extra, sizeof(int));
+
/* Set up a memory context and resource owner. */
Assert(CurrentResourceOwner == NULL);
CurrentResourceOwner = ResourceOwnerCreate(NULL, "parallel toplevel");
@@ -849,18 +849,9 @@ ParallelWorkerMain(Datum main_arg)
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("bad magic number in dynamic shared memory segment")));
- /* Determine and set our worker number. */
+ /* Look up fixed parallel state. */
fps = shm_toc_lookup(toc, PARALLEL_KEY_FIXED);
Assert(fps != NULL);
- Assert(ParallelWorkerNumber == -1);
- SpinLockAcquire(&fps->mutex);
- if (fps->workers_attached < fps->workers_expected)
- ParallelWorkerNumber = fps->workers_attached++;
- SpinLockRelease(&fps->mutex);
- if (ParallelWorkerNumber < 0)
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("too many parallel workers already attached")));
MyFixedParallelState = fps;
/*
diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c
index 220e599cca2..76619e9517c 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -314,6 +314,7 @@ BackgroundWorkerStateChange(void)
rw->rw_worker.bgw_restart_time = slot->worker.bgw_restart_time;
rw->rw_worker.bgw_main = slot->worker.bgw_main;
rw->rw_worker.bgw_main_arg = slot->worker.bgw_main_arg;
+ memcpy(rw->rw_worker.bgw_extra, slot->worker.bgw_extra, BGW_EXTRALEN);
/*
* Copy the PID to be notified about state changes, but only if the
diff --git a/src/include/postmaster/bgworker.h b/src/include/postmaster/bgworker.h
index f0a95306545..6e0b5cd9fc8 100644
--- a/src/include/postmaster/bgworker.h
+++ b/src/include/postmaster/bgworker.h
@@ -74,6 +74,7 @@ typedef enum
#define BGW_DEFAULT_RESTART_INTERVAL 60
#define BGW_NEVER_RESTART -1
#define BGW_MAXLEN 64
+#define BGW_EXTRALEN 128
typedef struct BackgroundWorker
{
@@ -85,6 +86,7 @@ typedef struct BackgroundWorker
char bgw_library_name[BGW_MAXLEN]; /* only if bgw_main is NULL */
char bgw_function_name[BGW_MAXLEN]; /* only if bgw_main is NULL */
Datum bgw_main_arg;
+ char bgw_extra[BGW_EXTRALEN];
pid_t bgw_notify_pid; /* SIGUSR1 this backend on start/stop */
} BackgroundWorker;