diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index a0da444af0..981789b988 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -167,6 +167,15 @@ typedef struct LVDeadTuples
 {
 	int			max_tuples;		/* # slots allocated in array */
 	int			num_tuples;		/* current # of entries */
+
+	/*
+	 * The boundaries of block numbers of recorded dead tuples.
+	 * min_blkno <= blk < max_blkno exists in the itemptrs array. These values are
+	 * InvalidBlockNumber if not set yet.
+	 */
+	BlockNumber	min_blkno;
+	BlockNumber	max_blkno;
+
 	/* List of TIDs of tuples we intend to delete */
 	/* NB: this list is ordered by TID address */
 	ItemPointerData itemptrs[FLEXIBLE_ARRAY_MEMBER];	/* array of
@@ -1062,6 +1071,9 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 				vmbuffer = InvalidBuffer;
 			}
 
+			/* Update the upper bound */
+			vacrelstats->dead_tuples->max_blkno = blkno;
+
 			/* Work on all the indexes, then the heap */
 			lazy_vacuum_all_indexes(onerel, Irel, indstats,
 									vacrelstats, lps, nindexes);
@@ -1083,6 +1095,10 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 			FreeSpaceMapVacuumRange(onerel, next_fsm_block_to_vacuum, blkno);
 			next_fsm_block_to_vacuum = blkno;
 
+			/* Reset both boundaries for next heap scan */
+			vacrelstats->dead_tuples->min_blkno = InvalidBlockNumber;
+			vacrelstats->dead_tuples->max_blkno = InvalidBlockNumber;
+
 			/* Report that we are once again scanning the heap */
 			pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
 										 PROGRESS_VACUUM_PHASE_SCAN_HEAP);
@@ -1712,6 +1728,10 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 	/* XXX put a threshold on min number of tuples here? */
 	if (dead_tuples->num_tuples > 0)
 	{
+		/* Update the upper bound */
+		vacrelstats->dead_tuples->max_blkno = blkno;
+		Assert(vacrelstats->dead_tuples->max_blkno == nblocks);
+
 		/* Work on all the indexes, and then the heap */
 		lazy_vacuum_all_indexes(onerel, Irel, indstats, vacrelstats,
 								lps, nindexes);
@@ -1797,6 +1817,8 @@ lazy_vacuum_all_indexes(Relation onerel, Relation *Irel,
 {
 	Assert(!IsParallelWorker());
 	Assert(nindexes > 0);
+	Assert(BlockNumberIsValid(vacrelstats->dead_tuples->min_blkno) &&
+			BlockNumberIsValid(vacrelstats->dead_tuples->max_blkno));
 
 	/* Log cleanup info before we touch indexes */
 	vacuum_log_cleanup_info(onerel, vacrelstats);
@@ -2907,6 +2929,8 @@ lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks)
 	dead_tuples = (LVDeadTuples *) palloc(SizeOfDeadTuples(maxtuples));
 	dead_tuples->num_tuples = 0;
 	dead_tuples->max_tuples = (int) maxtuples;
+	dead_tuples->min_blkno = InvalidBlockNumber;
+	dead_tuples->max_blkno = InvalidBlockNumber;
 
 	vacrelstats->dead_tuples = dead_tuples;
 }
@@ -2928,6 +2952,10 @@ lazy_record_dead_tuple(LVDeadTuples *dead_tuples, ItemPointer itemptr)
 		dead_tuples->num_tuples++;
 		pgstat_progress_update_param(PROGRESS_VACUUM_NUM_DEAD_TUPLES,
 									 dead_tuples->num_tuples);
+
+		/* Remember the lower bound */
+		if (!BlockNumberIsValid(dead_tuples->min_blkno))
+			dead_tuples->min_blkno = ItemPointerGetBlockNumberNoCheck(itemptr);
 	}
 }
 
@@ -2942,8 +2970,13 @@ static bool
 lazy_tid_reaped(ItemPointer itemptr, void *state)
 {
 	LVDeadTuples *dead_tuples = (LVDeadTuples *) state;
+	BlockNumber	blkno = ItemPointerGetBlockNumberNoCheck(itemptr);
 	ItemPointer res;
 
+	/* Boundary value check */
+	if (blkno < dead_tuples->min_blkno || blkno >= dead_tuples->max_blkno)
+		return false;
+
 	res = (ItemPointer) bsearch((void *) itemptr,
 								(void *) dead_tuples->itemptrs,
 								dead_tuples->num_tuples,
