Commit 0cb117eb authored by Tom Lane's avatar Tom Lane

Repair some problems in bgwriter start/stop logic. In particular, don't

allow the bgwriter to start before the startup subprocess has finished
... it tends to crash otherwise.  (The same problem may have existed for
the checkpointer, I'm not entirely sure.)  Remove some code that was
redundant because the bgwriter is handled as a member of the backend list.
parent 3b6bf0c0
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.365 2004/02/08 22:28:56 neilc Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.366 2004/02/11 22:25:02 tgl Exp $
* *
* NOTES * NOTES
* *
...@@ -1079,7 +1079,8 @@ ServerLoop(void) ...@@ -1079,7 +1079,8 @@ ServerLoop(void)
timeout.tv_usec = 0; timeout.tv_usec = 0;
if (CheckPointPID == 0 && checkpointed && if (CheckPointPID == 0 && checkpointed &&
Shutdown == NoShutdown && !FatalError && random_seed != 0) StartupPID == 0 && Shutdown == NoShutdown &&
!FatalError && random_seed != 0)
{ {
time_t now = time(NULL); time_t now = time(NULL);
...@@ -1113,7 +1114,8 @@ ServerLoop(void) ...@@ -1113,7 +1114,8 @@ ServerLoop(void)
* this fails, we'll just try again later. * this fails, we'll just try again later.
*/ */
if (BgWriterPID == 0 && BgWriterPercent > 0 && if (BgWriterPID == 0 && BgWriterPercent > 0 &&
Shutdown == NoShutdown && !FatalError && random_seed != 0) StartupPID == 0 && Shutdown == NoShutdown &&
!FatalError && random_seed != 0)
{ {
BgWriterPID = StartBackgroundWriter(); BgWriterPID = StartBackgroundWriter();
} }
...@@ -1772,13 +1774,16 @@ pmdie(SIGNAL_ARGS) ...@@ -1772,13 +1774,16 @@ pmdie(SIGNAL_ARGS)
* *
* Wait for children to end their work and ShutdownDataBase. * Wait for children to end their work and ShutdownDataBase.
*/ */
if (BgWriterPID != 0)
kill(BgWriterPID, SIGTERM);
if (Shutdown >= SmartShutdown) if (Shutdown >= SmartShutdown)
break; break;
Shutdown = SmartShutdown; Shutdown = SmartShutdown;
ereport(LOG, ereport(LOG,
(errmsg("received smart shutdown request"))); (errmsg("received smart shutdown request")));
/* Must tell bgwriter to quit, or it never will... */
if (BgWriterPID != 0)
kill(BgWriterPID, SIGTERM);
if (DLGetHead(BackendList)) /* let reaper() handle this */ if (DLGetHead(BackendList)) /* let reaper() handle this */
break; break;
...@@ -1803,46 +1808,38 @@ pmdie(SIGNAL_ARGS) ...@@ -1803,46 +1808,38 @@ pmdie(SIGNAL_ARGS)
/* /*
* Fast Shutdown: * Fast Shutdown:
* *
* abort all children with SIGTERM (rollback active transactions * Abort all children with SIGTERM (rollback active transactions
* and exit) and ShutdownDataBase when they are gone. * and exit) and ShutdownDataBase when they are gone.
*/ */
if (BgWriterPID != 0)
kill(BgWriterPID, SIGTERM);
if (Shutdown >= FastShutdown) if (Shutdown >= FastShutdown)
break; break;
Shutdown = FastShutdown;
ereport(LOG, ereport(LOG,
(errmsg("received fast shutdown request"))); (errmsg("received fast shutdown request")));
if (DLGetHead(BackendList)) /* let reaper() handle this */
if (DLGetHead(BackendList))
{ {
Shutdown = FastShutdown;
if (!FatalError) if (!FatalError)
{ {
ereport(LOG, ereport(LOG,
(errmsg("aborting any active transactions"))); (errmsg("aborting any active transactions")));
SignalChildren(SIGTERM); SignalChildren(SIGTERM);
/* reaper() does the rest */
} }
break; break;
} }
if (Shutdown > NoShutdown)
{
Shutdown = FastShutdown;
break;
}
Shutdown = FastShutdown;
/* /*
* No children left. Shutdown data base system. * No children left. Shutdown data base system.
*
* Unlike the previous case, it is not an error for the shutdown
* process to be running already (we could get SIGTERM followed
* shortly later by SIGINT).
*/ */
if (StartupPID > 0 || FatalError) /* let reaper() handle if (StartupPID > 0 || FatalError) /* let reaper() handle
* this */ * this */
break; break;
if (ShutdownPID > 0) if (ShutdownPID == 0)
{
elog(PANIC, "shutdown process %d already running",
(int) ShutdownPID);
abort();
}
ShutdownPID = ShutdownDataBase(); ShutdownPID = ShutdownDataBase();
break; break;
...@@ -1854,8 +1851,6 @@ pmdie(SIGNAL_ARGS) ...@@ -1854,8 +1851,6 @@ pmdie(SIGNAL_ARGS)
* abort all children with SIGQUIT and exit without attempt to * abort all children with SIGQUIT and exit without attempt to
* properly shutdown data base system. * properly shutdown data base system.
*/ */
if (BgWriterPID != 0)
kill(BgWriterPID, SIGQUIT);
ereport(LOG, ereport(LOG,
(errmsg("received immediate shutdown request"))); (errmsg("received immediate shutdown request")));
if (ShutdownPID > 0) if (ShutdownPID > 0)
...@@ -1973,12 +1968,6 @@ reaper(SIGNAL_ARGS) ...@@ -1973,12 +1968,6 @@ reaper(SIGNAL_ARGS)
CheckPointPID = 0; CheckPointPID = 0;
checkpointed = time(NULL); checkpointed = time(NULL);
if (BgWriterPID == 0 && BgWriterPercent > 0 &&
Shutdown == NoShutdown && !FatalError && random_seed != 0)
{
BgWriterPID = StartBackgroundWriter();
}
/* /*
* Go to shutdown mode if a shutdown request was pending. * Go to shutdown mode if a shutdown request was pending.
*/ */
...@@ -2844,7 +2833,8 @@ sigusr1_handler(SIGNAL_ARGS) ...@@ -2844,7 +2833,8 @@ sigusr1_handler(SIGNAL_ARGS)
* is currently disabled * is currently disabled
*/ */
if (CheckPointPID == 0 && checkpointed && if (CheckPointPID == 0 && checkpointed &&
Shutdown == NoShutdown && !FatalError && random_seed != 0) StartupPID == 0 && Shutdown == NoShutdown &&
!FatalError && random_seed != 0)
{ {
CheckPointPID = CheckPointDataBase(); CheckPointPID = CheckPointDataBase();
/* note: if fork fails, CheckPointPID stays 0; nothing happens */ /* note: if fork fails, CheckPointPID stays 0; nothing happens */
...@@ -2975,6 +2965,7 @@ CountChildren(void) ...@@ -2975,6 +2965,7 @@ CountChildren(void)
if (bp->pid != MyProcPid) if (bp->pid != MyProcPid)
cnt++; cnt++;
} }
/* Checkpoint and bgwriter will be in the list, discount them */
if (CheckPointPID != 0) if (CheckPointPID != 0)
cnt--; cnt--;
if (BgWriterPID != 0) if (BgWriterPID != 0)
...@@ -2983,10 +2974,10 @@ CountChildren(void) ...@@ -2983,10 +2974,10 @@ CountChildren(void)
} }
/* /*
* Fire off a subprocess for startup/shutdown/checkpoint. * Fire off a subprocess for startup/shutdown/checkpoint/bgwriter.
* *
* Return value of SSDataBase is subprocess' PID, or 0 if failed to start subprocess * Return value of SSDataBase is subprocess' PID, or 0 if failed to start subprocess
* (0 is returned only for checkpoint case). * (0 is returned only for checkpoint/bgwriter cases).
* *
* note: in the EXEC_BACKEND case, we delay the fork until argument list has been * note: in the EXEC_BACKEND case, we delay the fork until argument list has been
* established * established
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment