diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index 13c8ba3..189d790 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -546,7 +546,16 @@ WaitForParallelWorkersToFinish(ParallelContext *pcxt) for (i = 0; i < pcxt->nworkers_launched; ++i) { - if (pcxt->worker[i].error_mqh != NULL) + pid_t pid; + + /* + * Check for unexpected worker death. This will ensure that if + * the postmaster failed to start the worker, then we don't wait + * for it indefinitely. + */ + if (pcxt->worker[i].error_mqh != NULL && + pcxt->worker[i].bgwhandle != NULL && + GetBackgroundWorkerPid(pcxt->worker[i].bgwhandle, &pid) != BGWH_STOPPED) { anyone_alive = true; break; diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 28af6f0..83a390c 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -1031,7 +1031,8 @@ RegisterDynamicBackgroundWorker(BackgroundWorker *worker, * BGWH_STARTED and *pidp will get the PID of the worker process. * Otherwise, the return value will be BGWH_NOT_YET_STARTED if the worker * hasn't been started yet, and BGWH_STOPPED if the worker was previously - * running but is no longer. + * running but is no longer or postmaster has failed to start the worker due + * to fork failure or such conditions. * * In the latter case, the worker may be stopped temporarily (if it is * configured for automatic restart and exited non-zero) or gone for @@ -1061,7 +1062,8 @@ GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, pid_t *pidp) * won't be garbage, but it might be out of date by the time the caller * examines it (but that's unavoidable anyway). */ - if (handle->generation != slot->generation) + if (handle->generation != slot->generation || + !slot->in_use) pid = 0; else pid = slot->pid; diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index e4f8f59..7119359 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -5854,7 +5854,15 @@ maybe_start_bgworkers(void) { if (rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART) { + int notify_pid; + + notify_pid = rw->rw_worker.bgw_notify_pid; + ForgetBackgroundWorker(&iter); + + /* Report worker is gone now. */ + if (notify_pid != 0) + kill(notify_pid, SIGUSR1); continue; }