Skip to content

Commit 09a311d

Browse files
author
Konstantin Knizhnik
committed
Change prefetch logic in vacuum
1 parent 66114c2 commit 09a311d

File tree

1 file changed

+35
-36
lines changed

1 file changed

+35
-36
lines changed

src/backend/access/heap/vacuumlazy.c

+35-36
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ typedef struct LVRelState
221221
BlockNumber current_block; /* last block returned */
222222
BlockNumber next_unskippable_block; /* next unskippable block */
223223
bool next_unskippable_allvis; /* its visibility status */
224+
bool next_skipsallvis; /* next all-visible range can be skipped */
224225
Buffer next_unskippable_vmbuffer; /* buffer containing its VM bit */
225226
} LVRelState;
226227

@@ -237,7 +238,7 @@ typedef struct LVSavedErrInfo
237238
static void lazy_scan_heap(LVRelState *vacrel);
238239
static bool heap_vac_scan_next_block(LVRelState *vacrel, BlockNumber *blkno,
239240
bool *all_visible_according_to_vm);
240-
static void find_next_unskippable_block(LVRelState *vacrel, bool *skipsallvis);
241+
static void find_next_unskippable_block(LVRelState *vacrel);
241242
static bool lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf,
242243
BlockNumber blkno, Page page,
243244
bool sharelock, Buffer vmbuffer);
@@ -935,9 +936,9 @@ lazy_scan_heap(LVRelState *vacrel)
935936
if (next_prefetch_block + prefetch_budget > blkno + vacrel->io_concurrency)
936937
prefetch_budget = blkno + vacrel->io_concurrency - next_prefetch_block;
937938

938-
/* And only up to the next unskippable block */
939-
if (next_prefetch_block + prefetch_budget > vacrel->next_unskippable_block)
940-
prefetch_budget = vacrel->next_unskippable_block - next_prefetch_block;
939+
/* If next SKIP_PAGES_THRESHOLD are skapable then do not perform prefetch because vacuum will skip this blocks */
940+
if (next_prefetch_block + SKIP_PAGES_THRESHOLD <= vacrel->next_unskippable_block)
941+
prefetch_budget = 0;
941942

942943
for (; prefetch_budget-- > 0; next_prefetch_block++)
943944
PrefetchBuffer(vacrel->rel, MAIN_FORKNUM, next_prefetch_block);
@@ -1150,31 +1151,30 @@ heap_vac_scan_next_block(LVRelState *vacrel, BlockNumber *blkno,
11501151
* beginning of the scan). Find the next unskippable block using the
11511152
* visibility map.
11521153
*/
1153-
bool skipsallvis;
1154-
1155-
find_next_unskippable_block(vacrel, &skipsallvis);
1154+
find_next_unskippable_block(vacrel);
1155+
}
1156+
Assert(next_block <= vacrel->next_unskippable_block);
11561157

1157-
/*
1158-
* We now know the next block that we must process. It can be the
1159-
* next block after the one we just processed, or something further
1160-
* ahead. If it's further ahead, we can jump to it, but we choose to
1161-
* do so only if we can skip at least SKIP_PAGES_THRESHOLD consecutive
1162-
* pages. Since we're reading sequentially, the OS should be doing
1163-
* readahead for us, so there's no gain in skipping a page now and
1164-
* then. Skipping such a range might even discourage sequential
1165-
* detection.
1166-
*
1167-
* This test also enables more frequent relfrozenxid advancement
1168-
* during non-aggressive VACUUMs. If the range has any all-visible
1169-
* pages then skipping makes updating relfrozenxid unsafe, which is a
1170-
* real downside.
1171-
*/
1172-
if (vacrel->next_unskippable_block - next_block >= SKIP_PAGES_THRESHOLD)
1173-
{
1174-
next_block = vacrel->next_unskippable_block;
1175-
if (skipsallvis)
1176-
vacrel->skippedallvis = true;
1177-
}
1158+
/*
1159+
* We now know the next block that we must process. It can be the
1160+
* next block after the one we just processed, or something further
1161+
* ahead. If it's further ahead, we can jump to it, but we choose to
1162+
* do so only if we can skip at least SKIP_PAGES_THRESHOLD consecutive
1163+
* pages. Since we're reading sequentially, the OS should be doing
1164+
* readahead for us, so there's no gain in skipping a page now and
1165+
* then. Skipping such a range might even discourage sequential
1166+
* detection.
1167+
*
1168+
* This test also enables more frequent relfrozenxid advancement
1169+
* during non-aggressive VACUUMs. If the range has any all-visible
1170+
* pages then skipping makes updating relfrozenxid unsafe, which is a
1171+
* real downside.
1172+
*/
1173+
if (vacrel->next_unskippable_block - next_block >= SKIP_PAGES_THRESHOLD)
1174+
{
1175+
next_block = vacrel->next_unskippable_block;
1176+
if (vacrel->next_skipsallvis)
1177+
vacrel->skippedallvis = true;
11781178
}
11791179

11801180
/* Now we must be in one of the two remaining states: */
@@ -1185,9 +1185,7 @@ heap_vac_scan_next_block(LVRelState *vacrel, BlockNumber *blkno,
11851185
* but chose not to. We know that they are all-visible in the VM,
11861186
* otherwise they would've been unskippable.
11871187
*/
1188-
*blkno = vacrel->current_block = next_block;
11891188
*all_visible_according_to_vm = true;
1190-
return true;
11911189
}
11921190
else
11931191
{
@@ -1197,10 +1195,11 @@ heap_vac_scan_next_block(LVRelState *vacrel, BlockNumber *blkno,
11971195
*/
11981196
Assert(next_block == vacrel->next_unskippable_block);
11991197

1200-
*blkno = vacrel->current_block = next_block;
12011198
*all_visible_according_to_vm = vacrel->next_unskippable_allvis;
1202-
return true;
1199+
find_next_unskippable_block(vacrel);
12031200
}
1201+
*blkno = vacrel->current_block = next_block;
1202+
return true;
12041203
}
12051204

12061205
/*
@@ -1213,18 +1212,18 @@ heap_vac_scan_next_block(LVRelState *vacrel, BlockNumber *blkno,
12131212
* was concurrently cleared, though. All that matters is that caller scan all
12141213
* pages whose tuples might contain XIDs < OldestXmin, or MXIDs < OldestMxact.
12151214
* (Actually, non-aggressive VACUUMs can choose to skip all-visible pages with
1216-
* older XIDs/MXIDs. The *skippedallvis flag will be set here when the choice
1215+
* older XIDs/MXIDs. The vacrel->next_skippedallvis flag will be set here when the choice
12171216
* to skip such a range is actually made, making everything safe.)
12181217
*/
12191218
static void
1220-
find_next_unskippable_block(LVRelState *vacrel, bool *skipsallvis)
1219+
find_next_unskippable_block(LVRelState *vacrel)
12211220
{
12221221
BlockNumber rel_pages = vacrel->rel_pages;
12231222
BlockNumber next_unskippable_block = vacrel->next_unskippable_block + 1;
12241223
Buffer next_unskippable_vmbuffer = vacrel->next_unskippable_vmbuffer;
12251224
bool next_unskippable_allvis;
12261225

1227-
*skipsallvis = false;
1226+
vacrel->next_skipsallvis = false;
12281227

12291228
for (;;)
12301229
{
@@ -1275,7 +1274,7 @@ find_next_unskippable_block(LVRelState *vacrel, bool *skipsallvis)
12751274
* All-visible block is safe to skip in non-aggressive case. But
12761275
* remember that the final range contains such a block for later.
12771276
*/
1278-
*skipsallvis = true;
1277+
vacrel->next_skipsallvis = true;
12791278
}
12801279

12811280
next_unskippable_block++;

0 commit comments

Comments
 (0)