@@ -418,7 +418,7 @@ static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options);
418
418
static void processCancelRequest (Port * port ,void * pkt );
419
419
static int initMasks (fd_set * rmask );
420
420
static void report_fork_failure_to_client (Port * port ,int errnum );
421
- static CAC_state canAcceptConnections (void );
421
+ static CAC_state canAcceptConnections (int backend_type );
422
422
static bool RandomCancelKey (int32 * cancel_key );
423
423
static void signal_child (pid_t pid ,int signal );
424
424
static bool SignalSomeChildren (int signal ,int targets );
@@ -2321,24 +2321,30 @@ processCancelRequest(Port *port, void *pkt)
2321
2321
}
2322
2322
2323
2323
/*
2324
- * canAcceptConnections --- check to see if database state allows connections.
2324
+ * canAcceptConnections --- check to see if database state allows connections
2325
+ * of the specified type. backend_type can be BACKEND_TYPE_NORMAL,
2326
+ * BACKEND_TYPE_AUTOVAC, or BACKEND_TYPE_BGWORKER. (Note that we don't yet
2327
+ * know whether a NORMAL connection might turn into a walsender.)
2325
2328
*/
2326
2329
static CAC_state
2327
- canAcceptConnections (void )
2330
+ canAcceptConnections (int backend_type )
2328
2331
{
2329
2332
CAC_state result = CAC_OK ;
2330
2333
2331
2334
/*
2332
2335
* Can't start backends when in startup/shutdown/inconsistent recovery
2333
- * state.
2336
+ * state. We treat autovac workers the same as user backends for this
2337
+ * purpose. However, bgworkers are excluded from this test; we expect
2338
+ * bgworker_should_start_now() decided whether the DB state allows them.
2334
2339
*
2335
2340
* In state PM_WAIT_BACKUP only superusers can connect (this must be
2336
2341
* allowed so that a superuser can end online backup mode); we return
2337
2342
* CAC_WAITBACKUP code to indicate that this must be checked later. Note
2338
2343
* that neither CAC_OK nor CAC_WAITBACKUP can safely be returned until we
2339
2344
* have checked for too many children.
2340
2345
*/
2341
- if (pmState != PM_RUN )
2346
+ if (pmState != PM_RUN &&
2347
+ backend_type != BACKEND_TYPE_BGWORKER )
2342
2348
{
2343
2349
if (pmState == PM_WAIT_BACKUP )
2344
2350
result = CAC_WAITBACKUP ;/* allow superusers only */
@@ -2358,9 +2364,9 @@ canAcceptConnections(void)
2358
2364
/*
2359
2365
* Don't start too many children.
2360
2366
*
2361
- * We allow more connections than we can have backends here because some
2367
+ * We allow more connectionshere than we can have backends because some
2362
2368
* might still be authenticating; they might fail auth, or some existing
2363
- * backend might exit before the auth cycle is completed. The exact
2369
+ * backend might exit before the auth cycle is completed. The exact
2364
2370
* MaxBackends limit is enforced when a new backend tries to join the
2365
2371
* shared-inval backend array.
2366
2372
*
@@ -3994,7 +4000,7 @@ BackendStartup(Port *port)
3994
4000
bn -> cancel_key = MyCancelKey ;
3995
4001
3996
4002
/* Pass down canAcceptConnections state */
3997
- port -> canAcceptConnections = canAcceptConnections ();
4003
+ port -> canAcceptConnections = canAcceptConnections (BACKEND_TYPE_NORMAL );
3998
4004
bn -> dead_end = (port -> canAcceptConnections != CAC_OK &&
3999
4005
port -> canAcceptConnections != CAC_WAITBACKUP );
4000
4006
@@ -5409,7 +5415,7 @@ StartAutovacuumWorker(void)
5409
5415
* we have to check to avoid race-condition problems during DB state
5410
5416
* changes.
5411
5417
*/
5412
- if (canAcceptConnections ()== CAC_OK )
5418
+ if (canAcceptConnections (BACKEND_TYPE_AUTOVAC )== CAC_OK )
5413
5419
{
5414
5420
/*
5415
5421
* Compute the cancel key that will be assigned to this session. We
@@ -5654,12 +5660,13 @@ do_start_bgworker(RegisteredBgWorker *rw)
5654
5660
5655
5661
/*
5656
5662
* Allocate and assign the Backend element. Note we must do this before
5657
- * forking, so that we can handle out of memory properly.
5663
+ * forking, so that we can handle failures (out of memory or child-process
5664
+ * slots) cleanly.
5658
5665
*
5659
5666
* Treat failure as though the worker had crashed. That way, the
5660
- * postmaster will wait a bit before attempting to start it again; ifit
5661
- * tried again right away, most likelyit 'd finditself repeating the
5662
- *out-of-memory or fork failure condition.
5667
+ * postmaster will wait a bit before attempting to start it again; ifwe
5668
+ * tried again right away, most likelywe 'd findourselves hitting the
5669
+ *same resource-exhaustion condition.
5663
5670
*/
5664
5671
if (!assign_backendlist_entry (rw ))
5665
5672
{
@@ -5785,6 +5792,19 @@ assign_backendlist_entry(RegisteredBgWorker *rw)
5785
5792
{
5786
5793
Backend * bn ;
5787
5794
5795
+ /*
5796
+ * Check that database state allows another connection. Currently the
5797
+ * only possible failure is CAC_TOOMANY, so we just log an error message
5798
+ * based on that rather than checking the error code precisely.
5799
+ */
5800
+ if (canAcceptConnections (BACKEND_TYPE_BGWORKER )!= CAC_OK )
5801
+ {
5802
+ ereport (LOG ,
5803
+ (errcode (ERRCODE_CONFIGURATION_LIMIT_EXCEEDED ),
5804
+ errmsg ("no slot available for new worker process" )));
5805
+ return false;
5806
+ }
5807
+
5788
5808
/*
5789
5809
* Compute the cancel key that will be assigned to this session. We
5790
5810
* probably don't need cancel keys for background workers, but we'd better