diff options
author | Heikki Linnakangas | 2009-01-22 19:25:00 +0000 |
---|---|---|
committer | Heikki Linnakangas | 2009-01-22 19:25:00 +0000 |
commit | 17702d29507f13838959cf09481293d96006bacb (patch) | |
tree | ffc9216b013c5cf606297a3a4b68d4bb2324f108 | |
parent | 66fe9339b03ec748e247bc6a1e4e6ec5b7155c4e (diff) |
Only skip pages marked as clean in the visibility map, if the last 32
pages were marked as clean as well. The idea is to avoid defeating OS
readahead by skipping a page here and there, and also makes it less likely
that we miss an opportunity to advance relfrozenxid, for the sake of only
a few skipped pages.
-rw-r--r-- | src/backend/commands/vacuumlazy.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c index 3b06711be5..59c02e2083 100644 --- a/src/backend/commands/vacuumlazy.c +++ b/src/backend/commands/vacuumlazy.c @@ -74,6 +74,12 @@ */ #define LAZY_ALLOC_TUPLES MaxHeapTuplesPerPage +/* + * Before we consider skipping a page that's marked as clean in + * visibility map, we must've seen at least this many clean pages. + */ +#define SKIP_PAGES_THRESHOLD 32 + typedef struct LVRelStats { /* hasindex = true means two-pass strategy; false means one-pass */ @@ -271,6 +277,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats, int i; PGRUsage ru0; Buffer vmbuffer = InvalidBuffer; + BlockNumber all_visible_streak; pg_rusage_init(&ru0); @@ -292,6 +299,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats, lazy_space_alloc(vacrelstats, nblocks); + all_visible_streak = 0; for (blkno = 0; blkno < nblocks; blkno++) { Buffer buf; @@ -309,7 +317,14 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats, /* * Skip pages that don't require vacuuming according to the - * visibility map. + * visibility map. But only if we've seen a streak of at least + * SKIP_PAGES_THRESHOLD pages marked as clean. Since we're reading + * sequentially, the OS should be doing readahead for us and there's + * no gain in skipping a page now and then. You need a longer run of + * consecutive skipped pages before it's worthwhile. Also, skipping + * even a single page means that we can't update relfrozenxid or + * reltuples, so we only want to do it if there's a good chance to + * skip a goodly number of pages. */ if (!scan_all) { @@ -317,9 +332,15 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats, visibilitymap_test(onerel, blkno, &vmbuffer); if (all_visible_according_to_vm) { - vacrelstats->scanned_all = false; - continue; + all_visible_streak++; + if (all_visible_streak >= SKIP_PAGES_THRESHOLD) + { + vacrelstats->scanned_all = false; + continue; + } } + else + all_visible_streak = 0; } vacuum_delay_point(); |