@@ -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 );
@@ -2370,24 +2370,30 @@ processCancelRequest(Port *port, void *pkt)
2370
2370
}
2371
2371
2372
2372
/*
2373
- * canAcceptConnections --- check to see if database state allows connections.
2373
+ * canAcceptConnections --- check to see if database state allows connections
2374
+ * of the specified type. backend_type can be BACKEND_TYPE_NORMAL,
2375
+ * BACKEND_TYPE_AUTOVAC, or BACKEND_TYPE_BGWORKER. (Note that we don't yet
2376
+ * know whether a NORMAL connection might turn into a walsender.)
2374
2377
*/
2375
2378
static CAC_state
2376
- canAcceptConnections (void )
2379
+ canAcceptConnections (int backend_type )
2377
2380
{
2378
2381
CAC_state result = CAC_OK ;
2379
2382
2380
2383
/*
2381
2384
* Can't start backends when in startup/shutdown/inconsistent recovery
2382
- * state.
2385
+ * state. We treat autovac workers the same as user backends for this
2386
+ * purpose. However, bgworkers are excluded from this test; we expect
2387
+ * bgworker_should_start_now() decided whether the DB state allows them.
2383
2388
*
2384
2389
* In state PM_WAIT_BACKUP only superusers can connect (this must be
2385
2390
* allowed so that a superuser can end online backup mode); we return
2386
2391
* CAC_WAITBACKUP code to indicate that this must be checked later. Note
2387
2392
* that neither CAC_OK nor CAC_WAITBACKUP can safely be returned until we
2388
2393
* have checked for too many children.
2389
2394
*/
2390
- if (pmState != PM_RUN )
2395
+ if (pmState != PM_RUN &&
2396
+ backend_type != BACKEND_TYPE_BGWORKER )
2391
2397
{
2392
2398
if (pmState == PM_WAIT_BACKUP )
2393
2399
result = CAC_WAITBACKUP ; /* allow superusers only */
@@ -2407,9 +2413,9 @@ canAcceptConnections(void)
2407
2413
/*
2408
2414
* Don't start too many children.
2409
2415
*
2410
- * We allow more connections than we can have backends here because some
2416
+ * We allow more connections here than we can have backends because some
2411
2417
* might still be authenticating; they might fail auth, or some existing
2412
- * backend might exit before the auth cycle is completed. The exact
2418
+ * backend might exit before the auth cycle is completed. The exact
2413
2419
* MaxBackends limit is enforced when a new backend tries to join the
2414
2420
* shared-inval backend array.
2415
2421
*
@@ -4038,7 +4044,7 @@ BackendStartup(Port *port)
4038
4044
bn -> cancel_key = MyCancelKey ;
4039
4045
4040
4046
/* Pass down canAcceptConnections state */
4041
- port -> canAcceptConnections = canAcceptConnections ();
4047
+ port -> canAcceptConnections = canAcceptConnections (BACKEND_TYPE_NORMAL );
4042
4048
bn -> dead_end = (port -> canAcceptConnections != CAC_OK &&
4043
4049
port -> canAcceptConnections != CAC_WAITBACKUP );
4044
4050
@@ -5439,7 +5445,7 @@ StartAutovacuumWorker(void)
5439
5445
* we have to check to avoid race-condition problems during DB state
5440
5446
* changes.
5441
5447
*/
5442
- if (canAcceptConnections () == CAC_OK )
5448
+ if (canAcceptConnections (BACKEND_TYPE_AUTOVAC ) == CAC_OK )
5443
5449
{
5444
5450
/*
5445
5451
* Compute the cancel key that will be assigned to this session. We
@@ -5684,12 +5690,13 @@ do_start_bgworker(RegisteredBgWorker *rw)
5684
5690
5685
5691
/*
5686
5692
* Allocate and assign the Backend element. Note we must do this before
5687
- * forking, so that we can handle out of memory properly.
5693
+ * forking, so that we can handle failures (out of memory or child-process
5694
+ * slots) cleanly.
5688
5695
*
5689
5696
* Treat failure as though the worker had crashed. That way, the
5690
- * postmaster will wait a bit before attempting to start it again; if it
5691
- * tried again right away, most likely it 'd find itself repeating the
5692
- * out-of-memory or fork failure condition.
5697
+ * postmaster will wait a bit before attempting to start it again; if we
5698
+ * tried again right away, most likely we 'd find ourselves hitting the
5699
+ * same resource-exhaustion condition.
5693
5700
*/
5694
5701
if (!assign_backendlist_entry (rw ))
5695
5702
{
@@ -5815,6 +5822,19 @@ assign_backendlist_entry(RegisteredBgWorker *rw)
5815
5822
{
5816
5823
Backend * bn ;
5817
5824
5825
+ /*
5826
+ * Check that database state allows another connection. Currently the
5827
+ * only possible failure is CAC_TOOMANY, so we just log an error message
5828
+ * based on that rather than checking the error code precisely.
5829
+ */
5830
+ if (canAcceptConnections (BACKEND_TYPE_BGWORKER ) != CAC_OK )
5831
+ {
5832
+ ereport (LOG ,
5833
+ (errcode (ERRCODE_CONFIGURATION_LIMIT_EXCEEDED ),
5834
+ errmsg ("no slot available for new worker process" )));
5835
+ return false;
5836
+ }
5837
+
5818
5838
/*
5819
5839
* Compute the cancel key that will be assigned to this session. We
5820
5840
* probably don't need cancel keys for background workers, but we'd better
0 commit comments