diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
new file mode 100644
index a01cfb4..d2cce18
*** a/src/backend/commands/vacuumlazy.c
--- b/src/backend/commands/vacuumlazy.c
*************** typedef struct LVRelStats
*** 113,118 ****
--- 113,119 ----
  	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 */
*************** lazy_scan_heap(Relation onerel, LVRelSta
*** 475,480 ****
--- 476,482 ----
  	vacrelstats->rel_pages = nblocks;
  	vacrelstats->scanned_pages = 0;
  	vacrelstats->nonempty_pages = 0;
+ 	vacrelstats->skipped_pages = 0;
  	vacrelstats->latestRemovedXid = InvalidTransactionId;
  
  	lazy_space_alloc(vacrelstats, nblocks);
*************** lazy_scan_heap(Relation onerel, LVRelSta
*** 568,574 ****
--- 570,579 ----
  		{
  			/* Current block is all-visible */
  			if (skipping_all_visible_blocks && !scan_all)
+ 			{
+ 				vacrelstats->skipped_pages = blkno + 1;
  				continue;
+ 			}
  			all_visible_according_to_vm = true;
  		}
  
*************** static BlockNumber
*** 1559,1568 ****
--- 1564,1583 ----
  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;
*************** count_nondeletable_pages(Relation onerel
*** 1600,1605 ****
--- 1615,1622 ----
  									RelationGetRelationName(onerel))));
  
  					vacrelstats->lock_waiter_detected = true;
+ 					if (BufferIsValid(vmbuffer)) 
+ 						ReleaseBuffer(vmbuffer);
  					return blkno;
  				}
  				starttime = currenttime;
*************** count_nondeletable_pages(Relation onerel
*** 1615,1620 ****
--- 1632,1648 ----
  
  		blkno--;
  
+ 		if (blkno >= trust_vm)
+ 		{
+ 			if (!visibilitymap_test(onerel,blkno,&vmbuffer))
+ 			{
+ 				if (BufferIsValid(vmbuffer))
+ 					ReleaseBuffer(vmbuffer);
+ 				return blkno + 1;
+ 			}
+ 			continue;
+ 		}
+ 
  		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, blkno,
  								 RBM_NORMAL, vac_strategy);
  
*************** count_nondeletable_pages(Relation onerel
*** 1657,1663 ****
--- 1685,1695 ----
  
  		/* Done scanning if we found a tuple here */
  		if (hastup)
+ 		{
+ 			if (BufferIsValid(vmbuffer))
+ 				ReleaseBuffer(vmbuffer);
  			return blkno + 1;
+ 		}
  	}
  
  	/*
*************** count_nondeletable_pages(Relation onerel
*** 1665,1670 ****
--- 1697,1704 ----
  	 * pages still are; we need not bother to look at the last known-nonempty
  	 * page.
  	 */
+ 	if (BufferIsValid(vmbuffer))
+ 		ReleaseBuffer(vmbuffer);
  	return vacrelstats->nonempty_pages;
  }
  
