PostgreSQL Source Code git master
Loading...
Searching...
No Matches
blvacuum.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * blvacuum.c
4 * Bloom VACUUM functions.
5 *
6 * Copyright (c) 2016-2026, PostgreSQL Global Development Group
7 *
8 * IDENTIFICATION
9 * contrib/bloom/blvacuum.c
10 *
11 *-------------------------------------------------------------------------
12 */
13#include "postgres.h"
14
15#include "access/genam.h"
16#include "bloom.h"
17#include "commands/vacuum.h"
18#include "storage/bufmgr.h"
19#include "storage/indexfsm.h"
20
21
22/*
23 * Bulk deletion of all index entries pointing to a set of heap tuples.
24 * The set of target tuples is specified via a callback routine that tells
25 * whether any given heap tuple (identified by ItemPointer) is being deleted.
26 *
27 * Result: a palloc'd struct containing statistical info for VACUUM displays.
28 */
31 IndexBulkDeleteCallback callback, void *callback_state)
32{
33 Relation index = info->index;
34 BlockNumber blkno,
35 npages;
36 FreeBlockNumberArray notFullPage;
37 int countPage = 0;
39 Buffer buffer;
40 Page page;
43
44 if (stats == NULL)
46
48
49 /*
50 * Iterate over the pages. We don't care about concurrently added pages,
51 * they can't contain tuples to delete.
52 */
54 for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
55 {
56 BloomTuple *itup,
57 *itupPtr,
58 *itupEnd;
59
60 vacuum_delay_point(false);
61
62 buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno,
63 RBM_NORMAL, info->strategy);
64
67 page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
68
69 /* Ignore empty/deleted pages until blvacuumcleanup() */
70 if (PageIsNew(page) || BloomPageIsDeleted(page))
71 {
72 UnlockReleaseBuffer(buffer);
74 continue;
75 }
76
77 /*
78 * Iterate over the tuples. itup points to current tuple being
79 * scanned, itupPtr points to where to save next non-deleted tuple.
80 */
84 while (itup < itupEnd)
85 {
86 /* Do we have to delete this tuple? */
87 if (callback(&itup->heapPtr, callback_state))
88 {
89 /* Yes; adjust count of tuples that will be left on page */
90 BloomPageGetOpaque(page)->maxoff--;
91 stats->tuples_removed += 1;
92 }
93 else
94 {
95 /* No; copy it to itupPtr++, but skip copy if not needed */
96 if (itupPtr != itup)
97 memmove(itupPtr, itup, state.sizeOfBloomTuple);
99 }
100
101 itup = BloomPageGetNextTuple(&state, itup);
102 }
103
104 /* Assert that we counted correctly */
107
108 /*
109 * Add page to new notFullPage list if we will not mark page as
110 * deleted and there is free space on it
111 */
112 if (BloomPageGetMaxOffset(page) != 0 &&
113 BloomPageGetFreeSpace(&state, page) >= state.sizeOfBloomTuple &&
115 notFullPage[countPage++] = blkno;
116
117 /* Did we delete something? */
118 if (itupPtr != itup)
119 {
120 /* Is it empty page now? */
121 if (BloomPageGetMaxOffset(page) == 0)
123 /* Adjust pd_lower */
124 ((PageHeader) page)->pd_lower = (char *) itupPtr - page;
125 /* Finish WAL-logging */
127 }
128 else
129 {
130 /* Didn't change anything: abort WAL-logging */
132 }
133 UnlockReleaseBuffer(buffer);
134 }
135
136 /*
137 * Update the metapage's notFullPage list with whatever we found. Our
138 * info could already be out of date at this point, but blinsert() will
139 * cope if so.
140 */
143
145 page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
146
148 memcpy(metaData->notFullPage, notFullPage, sizeof(BlockNumber) * countPage);
149 metaData->nStart = 0;
150 metaData->nEnd = countPage;
151
153 UnlockReleaseBuffer(buffer);
154
155 return stats;
156}
157
158/*
159 * Post-VACUUM cleanup.
160 *
161 * Result: a palloc'd struct containing statistical info for VACUUM displays.
162 */
165{
166 Relation index = info->index;
167 BlockNumber npages,
168 blkno;
169
170 if (info->analyze_only)
171 return stats;
172
173 if (stats == NULL)
175
176 /*
177 * Iterate over the pages: insert deleted pages into FSM and collect
178 * statistics.
179 */
181 stats->num_pages = npages;
182 stats->pages_free = 0;
183 stats->num_index_tuples = 0;
184 for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
185 {
186 Buffer buffer;
187 Page page;
188
189 vacuum_delay_point(false);
190
191 buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno,
192 RBM_NORMAL, info->strategy);
194 page = BufferGetPage(buffer);
195
196 if (PageIsNew(page) || BloomPageIsDeleted(page))
197 {
199 stats->pages_free++;
200 }
201 else
202 {
204 }
205
206 UnlockReleaseBuffer(buffer);
207 }
208
210
211 return stats;
212}
uint32 BlockNumber
Definition block.h:31
#define BloomPageGetOpaque(page)
Definition bloom.h:60
#define BloomPageGetFreeSpace(state, page)
Definition bloom.h:149
#define BloomPageGetMeta(page)
Definition bloom.h:133
BlockNumber FreeBlockNumberArray[MAXALIGN_DOWN(BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(BloomPageOpaqueData)) - MAXALIGN(sizeof(uint16) *2+sizeof(uint32)+sizeof(BloomOptions)))/sizeof(BlockNumber)]
Definition bloom.h:115
#define BloomPageGetMaxOffset(page)
Definition bloom.h:61
#define BloomPageGetTuple(state, page, offset)
Definition bloom.h:71
#define BloomPageSetDeleted(page)
Definition bloom.h:66
#define BloomPageGetNextTuple(state, tuple)
Definition bloom.h:74
#define BloomPageIsDeleted(page)
Definition bloom.h:64
void initBloomState(BloomState *state, Relation index)
Definition blutils.c:167
#define BLOOM_HEAD_BLKNO
Definition bloom.h:79
#define BloomMetaBlockN
Definition bloom.h:131
#define BLOOM_METAPAGE_BLKNO
Definition bloom.h:78
IndexBulkDeleteResult * blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
Definition blvacuum.c:30
IndexBulkDeleteResult * blvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
Definition blvacuum.c:164
int Buffer
Definition buf.h:23
void UnlockReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5518
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition bufmgr.c:911
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition bufmgr.c:864
#define RelationGetNumberOfBlocks(reln)
Definition bufmgr.h:307
static Page BufferGetPage(Buffer buffer)
Definition bufmgr.h:466
@ BUFFER_LOCK_SHARE
Definition bufmgr.h:210
@ BUFFER_LOCK_EXCLUSIVE
Definition bufmgr.h:220
static void LockBuffer(Buffer buffer, BufferLockMode mode)
Definition bufmgr.h:328
@ RBM_NORMAL
Definition bufmgr.h:46
PageHeaderData * PageHeader
Definition bufpage.h:173
static bool PageIsNew(const PageData *page)
Definition bufpage.h:233
PageData * Page
Definition bufpage.h:81
#define Assert(condition)
Definition c.h:873
#define palloc0_object(type)
Definition fe_memutils.h:75
bool(* IndexBulkDeleteCallback)(ItemPointer itemptr, void *state)
Definition genam.h:93
Page GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, int flags)
GenericXLogState * GenericXLogStart(Relation relation)
XLogRecPtr GenericXLogFinish(GenericXLogState *state)
void GenericXLogAbort(GenericXLogState *state)
void IndexFreeSpaceMapVacuum(Relation rel)
Definition indexfsm.c:71
void RecordFreeIndexPage(Relation rel, BlockNumber freeBlock)
Definition indexfsm.c:52
#define OffsetNumberNext(offsetNumber)
Definition off.h:52
#define FirstOffsetNumber
Definition off.h:27
static int fb(int x)
@ MAIN_FORKNUM
Definition relpath.h:58
ItemPointerData heapPtr
Definition bloom.h:159
BlockNumber pages_free
Definition genam.h:89
BlockNumber num_pages
Definition genam.h:83
double tuples_removed
Definition genam.h:86
double num_index_tuples
Definition genam.h:85
Relation index
Definition genam.h:52
bool analyze_only
Definition genam.h:54
BufferAccessStrategy strategy
Definition genam.h:59
Definition type.h:96
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
void vacuum_delay_point(bool is_analyze)
Definition vacuum.c:2426