ITAGAKI Takahiro wrote:
> I wrote:
> > I found that autovacuum launcher does not launch any workers in HEAD.
> 
> The attached autovacuum-fix.patch could fix the problem. I changed
> to use 'greater or equal' instead of 'greater' at the decision of
> next autovacuum target.

I developed a different fix, which is possible due to the addition of
TimestampDifferenceExceeds to the TimestampTz API.  (Thanks Tom).

It continues to work for me here, but please confirm that it fixes the
bug you reported -- I don't have a low-resolution platform handy.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Index: src/backend/postmaster/autovacuum.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/autovacuum.c,v
retrieving revision 1.42
diff -c -p -r1.42 autovacuum.c
*** src/backend/postmaster/autovacuum.c	18 Apr 2007 16:44:18 -0000	1.42
--- src/backend/postmaster/autovacuum.c	2 May 2007 01:53:02 -0000
*************** AutoVacLauncherMain(int argc, char *argv
*** 549,556 ****
  
  		if (can_launch && AutoVacuumShmem->av_startingWorker != INVALID_OFFSET)
  		{
- 			long	secs;
- 			int		usecs;
  			WorkerInfo worker = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker);
  
  			if (current_time == 0)
--- 549,554 ----
*************** AutoVacLauncherMain(int argc, char *argv
*** 566,576 ****
  			 * startingWorker pointer before trying to connect; only low-level
  			 * problems, like fork() failure, can get us here.
  			 */
! 			TimestampDifference(worker->wi_launchtime, current_time,
! 								&secs, &usecs);
! 
! 			/* ignore microseconds, as they cannot make any difference */
! 			if (secs > autovacuum_naptime)
  			{
  				LWLockRelease(AutovacuumLock);
  				LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
--- 564,571 ----
  			 * startingWorker pointer before trying to connect; only low-level
  			 * problems, like fork() failure, can get us here.
  			 */
! 			if (TimestampDifferenceExceeds(worker->wi_launchtime, current_time,
! 										   autovacuum_naptime * 1000))
  			{
  				LWLockRelease(AutovacuumLock);
  				LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
*************** AutoVacLauncherMain(int argc, char *argv
*** 618,630 ****
  			if (elem != NULL)
  			{
  				avl_dbase *avdb = DLE_VAL(elem);
- 				long	secs;
- 				int		usecs;
- 
- 				TimestampDifference(current_time, avdb->adl_next_worker, &secs, &usecs);
  
! 				/* do we have to start a worker? */
! 				if (secs <= 0 && usecs <= 0)
  					launch_worker(current_time);
  			}
  			else
--- 613,625 ----
  			if (elem != NULL)
  			{
  				avl_dbase *avdb = DLE_VAL(elem);
  
! 				/*
! 				 * launch a worker if next_worker is right now or it is in the
! 				 * past
! 				 */
! 				if (TimestampDifferenceExceeds(avdb->adl_next_worker,
! 											   current_time, 0))
  					launch_worker(current_time);
  			}
  			else
*************** do_start_worker(void)
*** 1037,1058 ****
  
  			if (dbp->adl_datid == tmp->adw_datid)
  			{
- 				TimestampTz		curr_plus_naptime;
- 				TimestampTz		next = dbp->adl_next_worker;
- 				
- 				curr_plus_naptime =
- 					TimestampTzPlusMilliseconds(current_time,
- 												autovacuum_naptime * 1000);
- 
  				/*
! 				 * What we want here if to skip if next_worker falls between
  				 * the current time and the current time plus naptime.
  				 */
! 				if (timestamp_cmp_internal(current_time, next) > 0)
! 					skipit = false;
! 				else if (timestamp_cmp_internal(next, curr_plus_naptime) > 0)
! 					skipit = false;
! 				else
  					skipit = true;
  
  				break;
--- 1032,1046 ----
  
  			if (dbp->adl_datid == tmp->adw_datid)
  			{
  				/*
! 				 * Skip this database if its next_worker value falls between
  				 * the current time and the current time plus naptime.
  				 */
! 				if (TimestampDifferenceExceeds(current_time,
! 											   dbp->adl_next_worker, 0) &&
! 					!TimestampDifferenceExceeds(current_time,
! 												dbp->adl_next_worker,
! 												autovacuum_naptime * 1000))
  					skipit = true;
  
  				break;
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Reply via email to