*** a/src/backend/commands/vacuumlazy.c
--- b/src/backend/commands/vacuumlazy.c
***************
*** 97,102 ****
--- 97,109 ----
   */
  #define SKIP_PAGES_THRESHOLD	((BlockNumber) 32)
  
+ /*
+  * Macro used to specify the number of pages to be prefetched before
+  * reading the page, used for truncating a relation by verifing the page
+  * is empty or not.
+  */
+ #define VACUUM_TRUNCATE_PREFETCH 32
+ 
  typedef struct LVRelStats
  {
  	/* hasindex = true means two-pass strategy; false means one-pass */
***************
*** 113,118 **** typedef struct LVRelStats
--- 120,126 ----
  	BlockNumber pages_removed;
  	double		tuples_deleted;
  	BlockNumber nonempty_pages; /* actually, last nonempty page + 1 */
+ 	BlockNumber skipped_pages;  /* actually, last skipped page + 1 */
  	/* List of TIDs of tuples we intend to delete */
  	/* NB: this list is ordered by TID address */
  	int			num_dead_tuples;	/* current # of entries */
***************
*** 475,480 **** lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
--- 483,489 ----
  	vacrelstats->rel_pages = nblocks;
  	vacrelstats->scanned_pages = 0;
  	vacrelstats->nonempty_pages = 0;
+ 	vacrelstats->skipped_pages = 0;
  	vacrelstats->latestRemovedXid = InvalidTransactionId;
  
  	lazy_space_alloc(vacrelstats, nblocks);
***************
*** 568,574 **** lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
--- 577,586 ----
  		{
  			/* Current block is all-visible */
  			if (skipping_all_visible_blocks && !scan_all)
+ 			{
+ 				vacrelstats->skipped_pages = blkno + 1;
  				continue;
+ 			}
  			all_visible_according_to_vm = true;
  		}
  
***************
*** 1559,1568 **** static BlockNumber
--- 1571,1590 ----
  count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
  {
  	BlockNumber blkno;
+ 	BlockNumber trust_vm;
  	instr_time	starttime;
+ 	Buffer		vmbuffer = InvalidBuffer;
  
  	/* Initialize the starttime if we check for conflicting lock requests */
  	INSTR_TIME_SET_CURRENT(starttime);
+ 	
+ 	/*
+ 	 * Pages that were inspected and found to be empty by this vacuum run
+ 	 * must still be empty if the vm bit is still set.  Only vacuum sets
+ 	 * vm bits, and only one vacuum can exist in a table at one time.
+ 	 */
+ 	trust_vm=vacrelstats->nonempty_pages>vacrelstats->skipped_pages ?
+ 		vacrelstats->nonempty_pages : vacrelstats->skipped_pages;
  
  	/* Strange coding of loop control is needed because blkno is unsigned */
  	blkno = vacrelstats->rel_pages;
***************
*** 1600,1605 **** count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
--- 1622,1629 ----
  									RelationGetRelationName(onerel))));
  
  					vacrelstats->lock_waiter_detected = true;
+ 					if (BufferIsValid(vmbuffer)) 
+ 						ReleaseBuffer(vmbuffer);
  					return blkno;
  				}
  				starttime = currenttime;
***************
*** 1615,1620 **** count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
--- 1639,1662 ----
  
  		blkno--;
  
+ 		if (blkno >= trust_vm)
+ 		{
+ 			if (!visibilitymap_test(onerel,blkno,&vmbuffer))
+ 			{
+ 				if (BufferIsValid(vmbuffer))
+ 					ReleaseBuffer(vmbuffer);
+ 				return blkno + 1;
+ 			}
+ 			continue;
+ 		}
+ 
+ 		if ((blkno % VACUUM_TRUNCATE_PREFETCH) == 0 && blkno >= VACUUM_TRUNCATE_PREFETCH)
+ 		{
+ 			int i;
+ 			for (i = -VACUUM_TRUNCATE_PREFETCH; i<0; i++)
+ 				PrefetchBuffer(onerel, MAIN_FORKNUM, blkno + i);
+ 		}
+ 
  		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, blkno,
  								 RBM_NORMAL, vac_strategy);
  
***************
*** 1657,1663 **** count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
--- 1699,1709 ----
  
  		/* Done scanning if we found a tuple here */
  		if (hastup)
+ 		{
+ 			if (BufferIsValid(vmbuffer))
+ 				ReleaseBuffer(vmbuffer);
  			return blkno + 1;
+ 		}
  	}
  
  	/*
***************
*** 1665,1670 **** count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
--- 1711,1718 ----
  	 * pages still are; we need not bother to look at the last known-nonempty
  	 * page.
  	 */
+ 	if (BufferIsValid(vmbuffer))
+ 		ReleaseBuffer(vmbuffer);
  	return vacrelstats->nonempty_pages;
  }
  
