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

Commitc98605c

Browse files
committed
Pass extra data to bgworkers, and use this to fix parallel contexts.
Up until now, the total amount of data that could be passed to abackground worker at startup was one datum, which can be a small as4 bytes on some systems. That's enough to pass a dsm_handle or anarray index, but not much else. Add a bgw_extra flag to theBackgroundWorker struct, allowing up to 128 bytes to be passed toa new worker on any platform.Use this to fix a problem I recently discovered with the parallelcontext machinery added in 9.5: the master assigns each worker anarray index, and each worker subsequently assigns itself an arrayindex, and there's nothing to guarantee that the two sets of indexesmatch, leading to chaos.Normally, I would not back-patch the change to add bgw_extra, since itis basically a feature addition. However, since 9.5 is still in betaand there seems to be no other sensible way to repair the brokenparallel context machinery, back-patch to 9.5. Existing backgroundworker code can ignore the bgw_extra field without a problem, butmight need to be recompiled since the structure size has changed.Report and patch by me. Review by Amit Kapila.
1 parent1d97b25 commitc98605c

File tree

4 files changed

+18
-16
lines changed

4 files changed

+18
-16
lines changed

‎doc/src/sgml/bgworker.sgml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
char bgw_extra[BGW_EXTRALEN];
6162
int bgw_notify_pid;
6263
} BackgroundWorker;
6364
</programlisting>
@@ -136,6 +137,13 @@ typedef struct BackgroundWorker
136137
<structfield>bgw_main</structfield> is NULL.
137138
</para>
138139

140+
<para>
141+
<structfield>bgw_extra</structfield> can contain extra data to be passed
142+
to the background worker. Unlike <structfield>bgw_main_arg</>, this data
143+
is not passed as an argument to the worker's main function, but it can be
144+
accessed via <literal>MyBgworkerEntry</literal>, as discussed above.
145+
</para>
146+
139147
<para>
140148
<structfield>bgw_notify_pid</structfield> is the PID of a PostgreSQL
141149
backend process to which the postmaster should send <literal>SIGUSR1</>

‎src/backend/access/transam/parallel.c

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,6 @@ typedef struct FixedParallelState
7777
/* Mutex protects remaining fields. */
7878
slock_tmutex;
7979

80-
/* Track whether workers have attached. */
81-
intworkers_expected;
82-
intworkers_attached;
83-
8480
/* Maximum XactLastRecEnd of any worker. */
8581
XLogRecPtrlast_xlog_end;
8682
}FixedParallelState;
@@ -286,8 +282,6 @@ InitializeParallelDSM(ParallelContext *pcxt)
286282
fps->parallel_master_backend_id=MyBackendId;
287283
fps->entrypoint=pcxt->entrypoint;
288284
SpinLockInit(&fps->mutex);
289-
fps->workers_expected=pcxt->nworkers;
290-
fps->workers_attached=0;
291285
fps->last_xlog_end=0;
292286
shm_toc_insert(pcxt->toc,PARALLEL_KEY_FIXED,fps);
293287

@@ -406,6 +400,7 @@ LaunchParallelWorkers(ParallelContext *pcxt)
406400
worker.bgw_main=ParallelWorkerMain;
407401
worker.bgw_main_arg=UInt32GetDatum(dsm_segment_handle(pcxt->seg));
408402
worker.bgw_notify_pid=MyProcPid;
403+
memset(&worker.bgw_extra,0,BGW_EXTRALEN);
409404

410405
/*
411406
* Start workers.
@@ -417,6 +412,7 @@ LaunchParallelWorkers(ParallelContext *pcxt)
417412
*/
418413
for (i=0;i<pcxt->nworkers;++i)
419414
{
415+
memcpy(worker.bgw_extra,&i,sizeof(int));
420416
if (!any_registrations_failed&&
421417
RegisterDynamicBackgroundWorker(&worker,
422418
&pcxt->worker[i].bgwhandle))
@@ -825,6 +821,10 @@ ParallelWorkerMain(Datum main_arg)
825821
pqsignal(SIGTERM,die);
826822
BackgroundWorkerUnblockSignals();
827823

824+
/* Determine and set our parallel worker number. */
825+
Assert(ParallelWorkerNumber==-1);
826+
memcpy(&ParallelWorkerNumber,MyBgworkerEntry->bgw_extra,sizeof(int));
827+
828828
/* Set up a memory context and resource owner. */
829829
Assert(CurrentResourceOwner==NULL);
830830
CurrentResourceOwner=ResourceOwnerCreate(NULL,"parallel toplevel");
@@ -849,18 +849,9 @@ ParallelWorkerMain(Datum main_arg)
849849
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
850850
errmsg("bad magic number in dynamic shared memory segment")));
851851

852-
/*Determine and set our worker number. */
852+
/*Look up fixed parallel state. */
853853
fps=shm_toc_lookup(toc,PARALLEL_KEY_FIXED);
854854
Assert(fps!=NULL);
855-
Assert(ParallelWorkerNumber==-1);
856-
SpinLockAcquire(&fps->mutex);
857-
if (fps->workers_attached<fps->workers_expected)
858-
ParallelWorkerNumber=fps->workers_attached++;
859-
SpinLockRelease(&fps->mutex);
860-
if (ParallelWorkerNumber<0)
861-
ereport(ERROR,
862-
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
863-
errmsg("too many parallel workers already attached")));
864855
MyFixedParallelState=fps;
865856

866857
/*

‎src/backend/postmaster/bgworker.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ BackgroundWorkerStateChange(void)
314314
rw->rw_worker.bgw_restart_time=slot->worker.bgw_restart_time;
315315
rw->rw_worker.bgw_main=slot->worker.bgw_main;
316316
rw->rw_worker.bgw_main_arg=slot->worker.bgw_main_arg;
317+
memcpy(rw->rw_worker.bgw_extra,slot->worker.bgw_extra,BGW_EXTRALEN);
317318

318319
/*
319320
* Copy the PID to be notified about state changes, but only if the

‎src/include/postmaster/bgworker.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ typedef enum
7474
#defineBGW_DEFAULT_RESTART_INTERVAL60
7575
#defineBGW_NEVER_RESTART-1
7676
#defineBGW_MAXLEN64
77+
#defineBGW_EXTRALEN128
7778

7879
typedefstructBackgroundWorker
7980
{
@@ -85,6 +86,7 @@ typedef struct BackgroundWorker
8586
charbgw_library_name[BGW_MAXLEN];/* only if bgw_main is NULL */
8687
charbgw_function_name[BGW_MAXLEN];/* only if bgw_main is NULL */
8788
Datumbgw_main_arg;
89+
charbgw_extra[BGW_EXTRALEN];
8890
pid_tbgw_notify_pid;/* SIGUSR1 this backend on start/stop */
8991
}BackgroundWorker;
9092

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp