@@ -409,7 +409,7 @@ static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options);
409
409
static void processCancelRequest (Port * port , void * pkt );
410
410
static int initMasks (fd_set * rmask );
411
411
static void report_fork_failure_to_client (Port * port , int errnum );
412
- static CAC_state canAcceptConnections (void );
412
+ static CAC_state canAcceptConnections (int backend_type );
413
413
static bool RandomCancelKey (int32 * cancel_key );
414
414
static void signal_child (pid_t pid , int signal );
415
415
static bool SignalSomeChildren (int signal , int targets );
@@ -2384,24 +2384,30 @@ processCancelRequest(Port *port, void *pkt)
2384
2384
}
2385
2385
2386
2386
/*
2387
- * canAcceptConnections --- check to see if database state allows connections.
2387
+ * canAcceptConnections --- check to see if database state allows connections
2388
+ * of the specified type. backend_type can be BACKEND_TYPE_NORMAL,
2389
+ * BACKEND_TYPE_AUTOVAC, or BACKEND_TYPE_BGWORKER. (Note that we don't yet
2390
+ * know whether a NORMAL connection might turn into a walsender.)
2388
2391
*/
2389
2392
static CAC_state
2390
- canAcceptConnections (void )
2393
+ canAcceptConnections (int backend_type )
2391
2394
{
2392
2395
CAC_state result = CAC_OK ;
2393
2396
2394
2397
/*
2395
2398
* Can't start backends when in startup/shutdown/inconsistent recovery
2396
- * state.
2399
+ * state. We treat autovac workers the same as user backends for this
2400
+ * purpose. However, bgworkers are excluded from this test; we expect
2401
+ * bgworker_should_start_now() decided whether the DB state allows them.
2397
2402
*
2398
2403
* In state PM_WAIT_BACKUP only superusers can connect (this must be
2399
2404
* allowed so that a superuser can end online backup mode); we return
2400
2405
* CAC_WAITBACKUP code to indicate that this must be checked later. Note
2401
2406
* that neither CAC_OK nor CAC_WAITBACKUP can safely be returned until we
2402
2407
* have checked for too many children.
2403
2408
*/
2404
- if (pmState != PM_RUN )
2409
+ if (pmState != PM_RUN &&
2410
+ backend_type != BACKEND_TYPE_BGWORKER )
2405
2411
{
2406
2412
if (pmState == PM_WAIT_BACKUP )
2407
2413
result = CAC_WAITBACKUP ; /* allow superusers only */
@@ -2421,9 +2427,9 @@ canAcceptConnections(void)
2421
2427
/*
2422
2428
* Don't start too many children.
2423
2429
*
2424
- * We allow more connections than we can have backends here because some
2430
+ * We allow more connections here than we can have backends because some
2425
2431
* might still be authenticating; they might fail auth, or some existing
2426
- * backend might exit before the auth cycle is completed. The exact
2432
+ * backend might exit before the auth cycle is completed. The exact
2427
2433
* MaxBackends limit is enforced when a new backend tries to join the
2428
2434
* shared-inval backend array.
2429
2435
*
@@ -4086,7 +4092,7 @@ BackendStartup(Port *port)
4086
4092
bn -> cancel_key = MyCancelKey ;
4087
4093
4088
4094
/* Pass down canAcceptConnections state */
4089
- port -> canAcceptConnections = canAcceptConnections ();
4095
+ port -> canAcceptConnections = canAcceptConnections (BACKEND_TYPE_NORMAL );
4090
4096
bn -> dead_end = (port -> canAcceptConnections != CAC_OK &&
4091
4097
port -> canAcceptConnections != CAC_WAITBACKUP );
4092
4098
@@ -5458,7 +5464,7 @@ StartAutovacuumWorker(void)
5458
5464
* we have to check to avoid race-condition problems during DB state
5459
5465
* changes.
5460
5466
*/
5461
- if (canAcceptConnections () == CAC_OK )
5467
+ if (canAcceptConnections (BACKEND_TYPE_AUTOVAC ) == CAC_OK )
5462
5468
{
5463
5469
/*
5464
5470
* Compute the cancel key that will be assigned to this session. We
@@ -5703,12 +5709,13 @@ do_start_bgworker(RegisteredBgWorker *rw)
5703
5709
5704
5710
/*
5705
5711
* Allocate and assign the Backend element. Note we must do this before
5706
- * forking, so that we can handle out of memory properly.
5712
+ * forking, so that we can handle failures (out of memory or child-process
5713
+ * slots) cleanly.
5707
5714
*
5708
5715
* Treat failure as though the worker had crashed. That way, the
5709
- * postmaster will wait a bit before attempting to start it again; if it
5710
- * tried again right away, most likely it 'd find itself repeating the
5711
- * out-of-memory or fork failure condition.
5716
+ * postmaster will wait a bit before attempting to start it again; if we
5717
+ * tried again right away, most likely we 'd find ourselves hitting the
5718
+ * same resource-exhaustion condition.
5712
5719
*/
5713
5720
if (!assign_backendlist_entry (rw ))
5714
5721
{
@@ -5834,6 +5841,19 @@ assign_backendlist_entry(RegisteredBgWorker *rw)
5834
5841
{
5835
5842
Backend * bn ;
5836
5843
5844
+ /*
5845
+ * Check that database state allows another connection. Currently the
5846
+ * only possible failure is CAC_TOOMANY, so we just log an error message
5847
+ * based on that rather than checking the error code precisely.
5848
+ */
5849
+ if (canAcceptConnections (BACKEND_TYPE_BGWORKER ) != CAC_OK )
5850
+ {
5851
+ ereport (LOG ,
5852
+ (errcode (ERRCODE_CONFIGURATION_LIMIT_EXCEEDED ),
5853
+ errmsg ("no slot available for new worker process" )));
5854
+ return false;
5855
+ }
5856
+
5837
5857
/*
5838
5858
* Compute the cancel key that will be assigned to this session. We
5839
5859
* probably don't need cancel keys for background workers, but we'd better
0 commit comments