fix_worker_startup_failures_v1.patch
application/octet-stream
Filename: fix_worker_startup_failures_v1.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v1
| File | + | − |
|---|---|---|
| src/backend/access/transam/parallel.c | 10 | 1 |
| src/backend/postmaster/bgworker.c | 4 | 2 |
| src/backend/postmaster/postmaster.c | 8 | 0 |
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;
}