Fix failure to check for INVALID worker entry in the new autovacuum code, which

could happen when a worker took to long to start and was thus "aborted" by the
launcher.  Noticed by lionfish buildfarm member.
This commit is contained in:
Alvaro Herrera 2007-05-02 15:47:14 +00:00
parent 88f1fd2989
commit a115bfe3b9
1 changed files with 28 additions and 17 deletions

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.42 2007/04/18 16:44:18 alvherre Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.43 2007/05/02 15:47:14 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1407,25 +1407,36 @@ AutoVacWorkerMain(int argc, char *argv[])
* Get the info about the database we're going to work on. * Get the info about the database we're going to work on.
*/ */
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE); LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
MyWorkerInfo = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker);
dbid = MyWorkerInfo->wi_dboid;
MyWorkerInfo->wi_workerpid = MyProcPid;
/* insert into the running list */
SHMQueueInsertBefore(&AutoVacuumShmem->av_runningWorkers,
&MyWorkerInfo->wi_links);
/* /*
* remove from the "starting" pointer, so that the launcher can start a new * beware of startingWorker being INVALID; this could happen if the
* worker if required * launcher thinks we've taking too long to start.
*/ */
AutoVacuumShmem->av_startingWorker = INVALID_OFFSET; if (AutoVacuumShmem->av_startingWorker != INVALID_OFFSET)
LWLockRelease(AutovacuumLock); {
MyWorkerInfo = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker);
dbid = MyWorkerInfo->wi_dboid;
MyWorkerInfo->wi_workerpid = MyProcPid;
on_shmem_exit(FreeWorkerInfo, 0); /* insert into the running list */
SHMQueueInsertBefore(&AutoVacuumShmem->av_runningWorkers,
&MyWorkerInfo->wi_links);
/*
* remove from the "starting" pointer, so that the launcher can start a new
* worker if required
*/
AutoVacuumShmem->av_startingWorker = INVALID_OFFSET;
LWLockRelease(AutovacuumLock);
/* wake up the launcher */ on_shmem_exit(FreeWorkerInfo, 0);
if (AutoVacuumShmem->av_launcherpid != 0)
kill(AutoVacuumShmem->av_launcherpid, SIGUSR1); /* wake up the launcher */
if (AutoVacuumShmem->av_launcherpid != 0)
kill(AutoVacuumShmem->av_launcherpid, SIGUSR1);
}
else
/* no worker entry for me, go away */
LWLockRelease(AutovacuumLock);
if (OidIsValid(dbid)) if (OidIsValid(dbid))
{ {
@ -1466,8 +1477,8 @@ AutoVacWorkerMain(int argc, char *argv[])
} }
/* /*
* FIXME -- we need to notify the launcher when we are gone. But this * The launcher will be notified of my death in ProcKill, *if* we managed
* should be done after our PGPROC is released, in ProcKill. * to get a worker slot at all
*/ */
/* All done, go away */ /* All done, go away */