Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit021065a

Browse files
committed
Check for too many postmaster children before spawning a bgworker.
The postmaster's code path for spawning a bgworker neglected to checkwhether we already have the max number of live child processes. That'sa bit hard to hit, since it would necessarily be a transient condition;but if we do, AssignPostmasterChildSlot() fails causing a postmastercrash, as seen in a report from Bhargav Kamineni.To fix, invoke canAcceptConnections() in the bgworker code path, as wedo in the other code paths that spawn children. Since we don't wantthe same pmState tests in this case, add a child-process-type parameterto canAcceptConnections() so that it can know what to do.Back-patch to 9.5. In principle the same hazard exists in 9.4, but thecode is enough different that this patch wouldn't quite fix it there.Given the tiny usage of bgworkers in that branch it doesn't seem worthcreating a variant patch for it.Discussion:https://postgr.es/m/18733.1570382257@sss.pgh.pa.us
1 parenteb74022 commit021065a

File tree

1 file changed

+33
-13
lines changed

1 file changed

+33
-13
lines changed

‎src/backend/postmaster/postmaster.c

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options);
418418
staticvoidprocessCancelRequest(Port*port,void*pkt);
419419
staticintinitMasks(fd_set*rmask);
420420
staticvoidreport_fork_failure_to_client(Port*port,interrnum);
421-
staticCAC_statecanAcceptConnections(void);
421+
staticCAC_statecanAcceptConnections(intbackend_type);
422422
staticboolRandomCancelKey(int32*cancel_key);
423423
staticvoidsignal_child(pid_tpid,intsignal);
424424
staticboolSignalSomeChildren(intsignal,inttargets);
@@ -2321,24 +2321,30 @@ processCancelRequest(Port *port, void *pkt)
23212321
}
23222322

23232323
/*
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.)
23252328
*/
23262329
staticCAC_state
2327-
canAcceptConnections(void)
2330+
canAcceptConnections(intbackend_type)
23282331
{
23292332
CAC_stateresult=CAC_OK;
23302333

23312334
/*
23322335
* 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.
23342339
*
23352340
* In state PM_WAIT_BACKUP only superusers can connect (this must be
23362341
* allowed so that a superuser can end online backup mode); we return
23372342
* CAC_WAITBACKUP code to indicate that this must be checked later. Note
23382343
* that neither CAC_OK nor CAC_WAITBACKUP can safely be returned until we
23392344
* have checked for too many children.
23402345
*/
2341-
if (pmState!=PM_RUN)
2346+
if (pmState!=PM_RUN&&
2347+
backend_type!=BACKEND_TYPE_BGWORKER)
23422348
{
23432349
if (pmState==PM_WAIT_BACKUP)
23442350
result=CAC_WAITBACKUP;/* allow superusers only */
@@ -2358,9 +2364,9 @@ canAcceptConnections(void)
23582364
/*
23592365
* Don't start too many children.
23602366
*
2361-
* We allow more connections than we can have backends here because some
2367+
* We allow more connectionsherethan we can have backends because some
23622368
* 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
23642370
* MaxBackends limit is enforced when a new backend tries to join the
23652371
* shared-inval backend array.
23662372
*
@@ -3994,7 +4000,7 @@ BackendStartup(Port *port)
39944000
bn->cancel_key=MyCancelKey;
39954001

39964002
/* Pass down canAcceptConnections state */
3997-
port->canAcceptConnections=canAcceptConnections();
4003+
port->canAcceptConnections=canAcceptConnections(BACKEND_TYPE_NORMAL);
39984004
bn->dead_end= (port->canAcceptConnections!=CAC_OK&&
39994005
port->canAcceptConnections!=CAC_WAITBACKUP);
40004006

@@ -5409,7 +5415,7 @@ StartAutovacuumWorker(void)
54095415
* we have to check to avoid race-condition problems during DB state
54105416
* changes.
54115417
*/
5412-
if (canAcceptConnections()==CAC_OK)
5418+
if (canAcceptConnections(BACKEND_TYPE_AUTOVAC)==CAC_OK)
54135419
{
54145420
/*
54155421
* Compute the cancel key that will be assigned to this session. We
@@ -5654,12 +5660,13 @@ do_start_bgworker(RegisteredBgWorker *rw)
56545660

56555661
/*
56565662
* 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.
56585665
*
56595666
* 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.
56635670
*/
56645671
if (!assign_backendlist_entry(rw))
56655672
{
@@ -5785,6 +5792,19 @@ assign_backendlist_entry(RegisteredBgWorker *rw)
57855792
{
57865793
Backend*bn;
57875794

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+
57885808
/*
57895809
* Compute the cancel key that will be assigned to this session. We
57905810
* probably don't need cancel keys for background workers, but we'd better

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp