*** pgsql/src/backend/postmaster/autovacuum.c 2008/08/13 00:07:50 1.84 --- pgsql/src/backend/postmaster/autovacuum.c 2008/11/02 21:24:52 1.85 *************** *** 55,61 **** * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.83 2008/07/23 20:20:10 alvherre Exp $ * *------------------------------------------------------------------------- */ --- 55,61 ---- * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.84 2008/08/13 00:07:50 alvherre Exp $ * *------------------------------------------------------------------------- */ *************** typedef struct *** 244,252 **** { sig_atomic_t av_signal[AutoVacNumSignals]; pid_t av_launcherpid; ! SHMEM_OFFSET av_freeWorkers; SHM_QUEUE av_runningWorkers; ! SHMEM_OFFSET av_startingWorker; } AutoVacuumShmemStruct; static AutoVacuumShmemStruct *AutoVacuumShmem; --- 244,252 ---- { sig_atomic_t av_signal[AutoVacNumSignals]; pid_t av_launcherpid; ! WorkerInfo av_freeWorkers; SHM_QUEUE av_runningWorkers; ! WorkerInfo av_startingWorker; } AutoVacuumShmemStruct; static AutoVacuumShmemStruct *AutoVacuumShmem; *************** AutoVacLauncherMain(int argc, char *argv *** 556,563 **** if (!PostmasterIsAlive(true)) exit(1); ! launcher_determine_sleep(AutoVacuumShmem->av_freeWorkers != ! INVALID_OFFSET, false, &nap); /* * Sleep for a while according to schedule. --- 556,563 ---- if (!PostmasterIsAlive(true)) exit(1); ! launcher_determine_sleep((AutoVacuumShmem->av_freeWorkers != NULL), ! false, &nap); /* * Sleep for a while according to schedule. *************** AutoVacLauncherMain(int argc, char *argv *** 662,674 **** current_time = GetCurrentTimestamp(); LWLockAcquire(AutovacuumLock, LW_SHARED); ! can_launch = (AutoVacuumShmem->av_freeWorkers != INVALID_OFFSET); ! if (AutoVacuumShmem->av_startingWorker != INVALID_OFFSET) { int waittime; ! ! WorkerInfo worker = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker); /* * We can't launch another worker when another one is still --- 662,673 ---- current_time = GetCurrentTimestamp(); LWLockAcquire(AutovacuumLock, LW_SHARED); ! can_launch = (AutoVacuumShmem->av_freeWorkers != NULL); ! if (AutoVacuumShmem->av_startingWorker != NULL) { int waittime; ! WorkerInfo worker = AutoVacuumShmem->av_startingWorker; /* * We can't launch another worker when another one is still *************** AutoVacLauncherMain(int argc, char *argv *** 698,713 **** * we assume it's the same one we saw above (so we don't * recheck the launch time). */ ! if (AutoVacuumShmem->av_startingWorker != INVALID_OFFSET) { ! worker = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker); worker->wi_dboid = InvalidOid; worker->wi_tableoid = InvalidOid; worker->wi_proc = NULL; worker->wi_launchtime = 0; ! worker->wi_links.next = AutoVacuumShmem->av_freeWorkers; ! AutoVacuumShmem->av_freeWorkers = MAKE_OFFSET(worker); ! AutoVacuumShmem->av_startingWorker = INVALID_OFFSET; elog(WARNING, "worker took too long to start; cancelled"); } } --- 697,712 ---- * we assume it's the same one we saw above (so we don't * recheck the launch time). */ ! if (AutoVacuumShmem->av_startingWorker != NULL) { ! worker = AutoVacuumShmem->av_startingWorker; worker->wi_dboid = InvalidOid; worker->wi_tableoid = InvalidOid; worker->wi_proc = NULL; worker->wi_launchtime = 0; ! worker->wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers; ! AutoVacuumShmem->av_freeWorkers = worker; ! AutoVacuumShmem->av_startingWorker = NULL; elog(WARNING, "worker took too long to start; cancelled"); } } *************** do_start_worker(void) *** 1061,1067 **** /* return quickly when there are no free workers */ LWLockAcquire(AutovacuumLock, LW_SHARED); ! if (AutoVacuumShmem->av_freeWorkers == INVALID_OFFSET) { LWLockRelease(AutovacuumLock); return InvalidOid; --- 1060,1066 ---- /* return quickly when there are no free workers */ LWLockAcquire(AutovacuumLock, LW_SHARED); ! if (AutoVacuumShmem->av_freeWorkers == NULL) { LWLockRelease(AutovacuumLock); return InvalidOid; *************** do_start_worker(void) *** 1192,1198 **** if (avdb != NULL) { WorkerInfo worker; - SHMEM_OFFSET sworker; LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE); --- 1191,1196 ---- *************** do_start_worker(void) *** 1201,1218 **** * really should be a free slot -- complain very loudly if there * isn't. */ ! sworker = AutoVacuumShmem->av_freeWorkers; ! if (sworker == INVALID_OFFSET) elog(FATAL, "no free worker found"); ! worker = (WorkerInfo) MAKE_PTR(sworker); ! AutoVacuumShmem->av_freeWorkers = worker->wi_links.next; worker->wi_dboid = avdb->adw_datid; worker->wi_proc = NULL; worker->wi_launchtime = GetCurrentTimestamp(); ! AutoVacuumShmem->av_startingWorker = sworker; LWLockRelease(AutovacuumLock); --- 1199,1215 ---- * really should be a free slot -- complain very loudly if there * isn't. */ ! worker = AutoVacuumShmem->av_freeWorkers; ! if (worker == NULL) elog(FATAL, "no free worker found"); ! AutoVacuumShmem->av_freeWorkers = (WorkerInfo) worker->wi_links.next; worker->wi_dboid = avdb->adw_datid; worker->wi_proc = NULL; worker->wi_launchtime = GetCurrentTimestamp(); ! AutoVacuumShmem->av_startingWorker = worker; LWLockRelease(AutovacuumLock); *************** AutoVacWorkerMain(int argc, char *argv[] *** 1549,1557 **** * launcher might have decided to remove it from the queue and start * again. */ ! if (AutoVacuumShmem->av_startingWorker != INVALID_OFFSET) { ! MyWorkerInfo = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker); dbid = MyWorkerInfo->wi_dboid; MyWorkerInfo->wi_proc = MyProc; --- 1546,1554 ---- * launcher might have decided to remove it from the queue and start * again. */ ! if (AutoVacuumShmem->av_startingWorker != NULL) { ! MyWorkerInfo = AutoVacuumShmem->av_startingWorker; dbid = MyWorkerInfo->wi_dboid; MyWorkerInfo->wi_proc = MyProc; *************** AutoVacWorkerMain(int argc, char *argv[] *** 1563,1569 **** * 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); --- 1560,1566 ---- * remove from the "starting" pointer, so that the launcher can start * a new worker if required */ ! AutoVacuumShmem->av_startingWorker = NULL; LWLockRelease(AutovacuumLock); on_shmem_exit(FreeWorkerInfo, 0); *************** FreeWorkerInfo(int code, Datum arg) *** 1648,1654 **** AutovacuumLauncherPid = AutoVacuumShmem->av_launcherpid; SHMQueueDelete(&MyWorkerInfo->wi_links); ! MyWorkerInfo->wi_links.next = AutoVacuumShmem->av_freeWorkers; MyWorkerInfo->wi_dboid = InvalidOid; MyWorkerInfo->wi_tableoid = InvalidOid; MyWorkerInfo->wi_proc = NULL; --- 1645,1651 ---- AutovacuumLauncherPid = AutoVacuumShmem->av_launcherpid; SHMQueueDelete(&MyWorkerInfo->wi_links); ! MyWorkerInfo->wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers; MyWorkerInfo->wi_dboid = InvalidOid; MyWorkerInfo->wi_tableoid = InvalidOid; MyWorkerInfo->wi_proc = NULL; *************** FreeWorkerInfo(int code, Datum arg) *** 1656,1662 **** MyWorkerInfo->wi_cost_delay = 0; MyWorkerInfo->wi_cost_limit = 0; MyWorkerInfo->wi_cost_limit_base = 0; ! AutoVacuumShmem->av_freeWorkers = MAKE_OFFSET(MyWorkerInfo); /* not mine anymore */ MyWorkerInfo = NULL; --- 1653,1659 ---- MyWorkerInfo->wi_cost_delay = 0; MyWorkerInfo->wi_cost_limit = 0; MyWorkerInfo->wi_cost_limit_base = 0; ! AutoVacuumShmem->av_freeWorkers = MyWorkerInfo; /* not mine anymore */ MyWorkerInfo = NULL; *************** AutoVacuumShmemInit(void) *** 2793,2801 **** Assert(!found); AutoVacuumShmem->av_launcherpid = 0; ! AutoVacuumShmem->av_freeWorkers = INVALID_OFFSET; SHMQueueInit(&AutoVacuumShmem->av_runningWorkers); ! AutoVacuumShmem->av_startingWorker = INVALID_OFFSET; worker = (WorkerInfo) ((char *) AutoVacuumShmem + MAXALIGN(sizeof(AutoVacuumShmemStruct))); --- 2790,2798 ---- Assert(!found); AutoVacuumShmem->av_launcherpid = 0; ! AutoVacuumShmem->av_freeWorkers = NULL; SHMQueueInit(&AutoVacuumShmem->av_runningWorkers); ! AutoVacuumShmem->av_startingWorker = NULL; worker = (WorkerInfo) ((char *) AutoVacuumShmem + MAXALIGN(sizeof(AutoVacuumShmemStruct))); *************** AutoVacuumShmemInit(void) *** 2803,2810 **** /* initialize the WorkerInfo free list */ for (i = 0; i < autovacuum_max_workers; i++) { ! worker[i].wi_links.next = AutoVacuumShmem->av_freeWorkers; ! AutoVacuumShmem->av_freeWorkers = MAKE_OFFSET(&worker[i]); } } else --- 2800,2807 ---- /* initialize the WorkerInfo free list */ for (i = 0; i < autovacuum_max_workers; i++) { ! worker[i].wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers; ! AutoVacuumShmem->av_freeWorkers = &worker[i]; } } else