Skip to content

Commit c350b01

Browse files
committed
Fix canAcceptConnections() bugs introduced by replication-related patches.
We must not return any "okay to proceed" result code without having checked for too many children, else we might fail later on when trying to add the new child to one of the per-child state arrays. It's not clear whether this oversight explains Stefan Kaltenbrunner's recent report, but it could certainly produce a similar symptom. Back-patch to 8.4; the logic was not broken before that.
1 parent 9f65a87 commit c350b01

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

src/backend/postmaster/postmaster.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ static int ProcessStartupPacket(Port *port, bool SSLdone);
349349
static void processCancelRequest(Port *port, void *pkt);
350350
static int initMasks(fd_set *rmask);
351351
static void report_fork_failure_to_client(Port *port, int errnum);
352-
static enum CAC_state canAcceptConnections(void);
352+
static CAC_state canAcceptConnections(void);
353353
static long PostmasterRandom(void);
354354
static void RandomSalt(char *md5Salt);
355355
static void signal_child(pid_t pid, int signal);
@@ -1907,31 +1907,36 @@ processCancelRequest(Port *port, void *pkt)
19071907
/*
19081908
* canAcceptConnections --- check to see if database state allows connections.
19091909
*/
1910-
static enum CAC_state
1910+
static CAC_state
19111911
canAcceptConnections(void)
19121912
{
1913+
CAC_state result = CAC_OK;
1914+
19131915
/*
19141916
* Can't start backends when in startup/shutdown/inconsistent recovery
19151917
* state.
19161918
*
19171919
* In state PM_WAIT_BACKUP only superusers can connect (this must be
19181920
* allowed so that a superuser can end online backup mode); we return
19191921
* CAC_WAITBACKUP code to indicate that this must be checked later.
1922+
* Note that neither CAC_OK nor CAC_WAITBACKUP can safely be returned
1923+
* until we have checked for too many children.
19201924
*/
19211925
if (pmState != PM_RUN)
19221926
{
19231927
if (pmState == PM_WAIT_BACKUP)
1924-
return CAC_WAITBACKUP; /* allow superusers only */
1925-
if (Shutdown > NoShutdown)
1928+
result = CAC_WAITBACKUP; /* allow superusers only */
1929+
else if (Shutdown > NoShutdown)
19261930
return CAC_SHUTDOWN; /* shutdown is pending */
1927-
if (!FatalError &&
1928-
(pmState == PM_STARTUP ||
1929-
pmState == PM_RECOVERY))
1930-
return CAC_STARTUP; /* normal startup */
1931-
if (!FatalError &&
1932-
pmState == PM_HOT_STANDBY)
1933-
return CAC_OK; /* connection OK during hot standby */
1934-
return CAC_RECOVERY; /* else must be crash recovery */
1931+
else if (!FatalError &&
1932+
(pmState == PM_STARTUP ||
1933+
pmState == PM_RECOVERY))
1934+
return CAC_STARTUP; /* normal startup */
1935+
else if (!FatalError &&
1936+
pmState == PM_HOT_STANDBY)
1937+
result = CAC_OK; /* connection OK during hot standby */
1938+
else
1939+
return CAC_RECOVERY; /* else must be crash recovery */
19351940
}
19361941

19371942
/*
@@ -1947,9 +1952,9 @@ canAcceptConnections(void)
19471952
* see comments for MaxLivePostmasterChildren().
19481953
*/
19491954
if (CountChildren(BACKEND_TYPE_ALL) >= MaxLivePostmasterChildren())
1950-
return CAC_TOOMANY;
1955+
result = CAC_TOOMANY;
19511956

1952-
return CAC_OK;
1957+
return result;
19531958
}
19541959

19551960

0 commit comments

Comments
 (0)