2929 *
3030 *
3131 * IDENTIFICATION
32- * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.117 2009/01/16 13:27:23 heikki Exp $
32+ * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.118 2009/01/22 19:25:00 heikki Exp $
3333 *
3434 *-------------------------------------------------------------------------
3535 */
7474 */
7575#define LAZY_ALLOC_TUPLES MaxHeapTuplesPerPage
7676
77+ /*
78+ * Before we consider skipping a page that's marked as clean in
79+ * visibility map, we must've seen at least this many clean pages.
80+ */
81+ #define SKIP_PAGES_THRESHOLD 32
82+
7783typedef struct LVRelStats
7884{
7985/* hasindex = true means two-pass strategy; false means one-pass */
@@ -271,6 +277,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
271277int i ;
272278PGRUsage ru0 ;
273279Buffer vmbuffer = InvalidBuffer ;
280+ BlockNumber all_visible_streak ;
274281
275282pg_rusage_init (& ru0 );
276283
@@ -292,6 +299,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
292299
293300lazy_space_alloc (vacrelstats ,nblocks );
294301
302+ all_visible_streak = 0 ;
295303for (blkno = 0 ;blkno < nblocks ;blkno ++ )
296304{
297305Buffer buf ;
@@ -309,17 +317,30 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
309317
310318/*
311319 * Skip pages that don't require vacuuming according to the
312- * visibility map.
320+ * visibility map. But only if we've seen a streak of at least
321+ * SKIP_PAGES_THRESHOLD pages marked as clean. Since we're reading
322+ * sequentially, the OS should be doing readahead for us and there's
323+ * no gain in skipping a page now and then. You need a longer run of
324+ * consecutive skipped pages before it's worthwhile. Also, skipping
325+ * even a single page means that we can't update relfrozenxid or
326+ * reltuples, so we only want to do it if there's a good chance to
327+ * skip a goodly number of pages.
313328 */
314329if (!scan_all )
315330{
316331all_visible_according_to_vm =
317332visibilitymap_test (onerel ,blkno ,& vmbuffer );
318333if (all_visible_according_to_vm )
319334{
320- vacrelstats -> scanned_all = false;
321- continue ;
335+ all_visible_streak ++ ;
336+ if (all_visible_streak >=SKIP_PAGES_THRESHOLD )
337+ {
338+ vacrelstats -> scanned_all = false;
339+ continue ;
340+ }
322341}
342+ else
343+ all_visible_streak = 0 ;
323344}
324345
325346vacuum_delay_point ();