From 9045b64086e685c6f9e5d42c5b85478b44abe11e Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Wed, 2 May 2007 15:47:14 +0000 Subject: [PATCH] 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. --- src/backend/postmaster/autovacuum.c | 43 ++++++++++++++++++----------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a9f6146f30..069dbff5eb 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -1407,25 +1407,36 @@ AutoVacWorkerMain(int argc, char *argv[]) * Get the info about the database we're going to work on. */ 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 - * worker if required + * beware of startingWorker being INVALID; this could happen if the + * launcher thinks we've taking too long to start. */ - AutoVacuumShmem->av_startingWorker = INVALID_OFFSET; - LWLockRelease(AutovacuumLock); + if (AutoVacuumShmem->av_startingWorker != INVALID_OFFSET) + { + 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 + * worker if required + */ + AutoVacuumShmem->av_startingWorker = INVALID_OFFSET; + LWLockRelease(AutovacuumLock); - on_shmem_exit(FreeWorkerInfo, 0); + on_shmem_exit(FreeWorkerInfo, 0); - /* wake up the launcher */ - 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)) { @@ -1466,8 +1477,8 @@ AutoVacWorkerMain(int argc, char *argv[]) } /* - * FIXME -- we need to notify the launcher when we are gone. But this - * should be done after our PGPROC is released, in ProcKill. + * The launcher will be notified of my death in ProcKill, *if* we managed + * to get a worker slot at all */ /* All done, go away */ -- 2.39.5