@@ -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 );
@@ -2398,24 +2398,30 @@ processCancelRequest(Port *port, void *pkt)
2398
2398
}
2399
2399
2400
2400
/*
2401
- * canAcceptConnections --- check to see if database state allows connections.
2401
+ * canAcceptConnections --- check to see if database state allows connections
2402
+ * of the specified type. backend_type can be BACKEND_TYPE_NORMAL,
2403
+ * BACKEND_TYPE_AUTOVAC, or BACKEND_TYPE_BGWORKER. (Note that we don't yet
2404
+ * know whether a NORMAL connection might turn into a walsender.)
2402
2405
*/
2403
2406
static CAC_state
2404
- canAcceptConnections (void )
2407
+ canAcceptConnections (int backend_type )
2405
2408
{
2406
2409
CAC_state result = CAC_OK ;
2407
2410
2408
2411
/*
2409
2412
* Can't start backends when in startup/shutdown/inconsistent recovery
2410
- * state.
2413
+ * state. We treat autovac workers the same as user backends for this
2414
+ * purpose. However, bgworkers are excluded from this test; we expect
2415
+ * bgworker_should_start_now() decided whether the DB state allows them.
2411
2416
*
2412
2417
* In state PM_WAIT_BACKUP only superusers can connect (this must be
2413
2418
* allowed so that a superuser can end online backup mode); we return
2414
2419
* CAC_WAITBACKUP code to indicate that this must be checked later. Note
2415
2420
* that neither CAC_OK nor CAC_WAITBACKUP can safely be returned until we
2416
2421
* have checked for too many children.
2417
2422
*/
2418
- if (pmState != PM_RUN )
2423
+ if (pmState != PM_RUN &&
2424
+ backend_type != BACKEND_TYPE_BGWORKER )
2419
2425
{
2420
2426
if (pmState == PM_WAIT_BACKUP )
2421
2427
result = CAC_WAITBACKUP ; /* allow superusers only */
@@ -2435,9 +2441,9 @@ canAcceptConnections(void)
2435
2441
/*
2436
2442
* Don't start too many children.
2437
2443
*
2438
- * We allow more connections than we can have backends here because some
2444
+ * We allow more connections here than we can have backends because some
2439
2445
* might still be authenticating; they might fail auth, or some existing
2440
- * backend might exit before the auth cycle is completed. The exact
2446
+ * backend might exit before the auth cycle is completed. The exact
2441
2447
* MaxBackends limit is enforced when a new backend tries to join the
2442
2448
* shared-inval backend array.
2443
2449
*
@@ -4114,7 +4120,7 @@ BackendStartup(Port *port)
4114
4120
bn -> cancel_key = MyCancelKey ;
4115
4121
4116
4122
/* Pass down canAcceptConnections state */
4117
- port -> canAcceptConnections = canAcceptConnections ();
4123
+ port -> canAcceptConnections = canAcceptConnections (BACKEND_TYPE_NORMAL );
4118
4124
bn -> dead_end = (port -> canAcceptConnections != CAC_OK &&
4119
4125
port -> canAcceptConnections != CAC_WAITBACKUP );
4120
4126
@@ -5486,7 +5492,7 @@ StartAutovacuumWorker(void)
5486
5492
* we have to check to avoid race-condition problems during DB state
5487
5493
* changes.
5488
5494
*/
5489
- if (canAcceptConnections () == CAC_OK )
5495
+ if (canAcceptConnections (BACKEND_TYPE_AUTOVAC ) == CAC_OK )
5490
5496
{
5491
5497
/*
5492
5498
* Compute the cancel key that will be assigned to this session. We
@@ -5731,12 +5737,13 @@ do_start_bgworker(RegisteredBgWorker *rw)
5731
5737
5732
5738
/*
5733
5739
* Allocate and assign the Backend element. Note we must do this before
5734
- * forking, so that we can handle out of memory properly.
5740
+ * forking, so that we can handle failures (out of memory or child-process
5741
+ * slots) cleanly.
5735
5742
*
5736
5743
* Treat failure as though the worker had crashed. That way, the
5737
- * postmaster will wait a bit before attempting to start it again; if it
5738
- * tried again right away, most likely it 'd find itself repeating the
5739
- * out-of-memory or fork failure condition.
5744
+ * postmaster will wait a bit before attempting to start it again; if we
5745
+ * tried again right away, most likely we 'd find ourselves hitting the
5746
+ * same resource-exhaustion condition.
5740
5747
*/
5741
5748
if (!assign_backendlist_entry (rw ))
5742
5749
{
@@ -5862,6 +5869,19 @@ assign_backendlist_entry(RegisteredBgWorker *rw)
5862
5869
{
5863
5870
Backend * bn ;
5864
5871
5872
+ /*
5873
+ * Check that database state allows another connection. Currently the
5874
+ * only possible failure is CAC_TOOMANY, so we just log an error message
5875
+ * based on that rather than checking the error code precisely.
5876
+ */
5877
+ if (canAcceptConnections (BACKEND_TYPE_BGWORKER ) != CAC_OK )
5878
+ {
5879
+ ereport (LOG ,
5880
+ (errcode (ERRCODE_CONFIGURATION_LIMIT_EXCEEDED ),
5881
+ errmsg ("no slot available for new worker process" )));
5882
+ return false;
5883
+ }
5884
+
5865
5885
/*
5866
5886
* Compute the cancel key that will be assigned to this session. We
5867
5887
* probably don't need cancel keys for background workers, but we'd better
0 commit comments