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#include "storage/read_stream.h"
21
22
23/*
24 * Bulk deletion of all index entries pointing to a set of heap tuples.
25 * The set of target tuples is specified via a callback routine that tells
26 * whether any given heap tuple (identified by ItemPointer) is being deleted.
27 *
28 * Result: a palloc'd struct containing statistical info for VACUUM displays.
29 */
32 IndexBulkDeleteCallback callback, void *callback_state)
33{
34 Relation index = info->index;
35 BlockNumber blkno,
36 npages;
37 FreeBlockNumberArray notFullPage;
38 int countPage = 0;
40 Buffer buffer;
41 Page page;
45 ReadStream *stream;
46
47 if (stats == NULL)
49
51
52 /*
53 * Iterate over the pages. We don't care about concurrently added pages,
54 * they can't contain tuples to delete.
55 */
57
58 /* Scan all blocks except the metapage using streaming reads */
60 p.last_exclusive = npages;
61
62 /*
63 * It is safe to use batchmode as block_range_read_stream_cb takes no
64 * locks.
65 */
69 info->strategy,
70 index,
73 &p,
74 0);
75
76 for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
77 {
78 BloomTuple *itup,
79 *itupPtr,
80 *itupEnd;
81
82 vacuum_delay_point(false);
83
84 buffer = read_stream_next_buffer(stream, NULL);
85
88 page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
89
90 /* Ignore empty/deleted pages until blvacuumcleanup() */
91 if (PageIsNew(page) || BloomPageIsDeleted(page))
92 {
93 UnlockReleaseBuffer(buffer);
95 continue;
96 }
97
98 /*
99 * Iterate over the tuples. itup points to current tuple being
100 * scanned, itupPtr points to where to save next non-deleted tuple.
101 */
105 while (itup < itupEnd)
106 {
107 /* Do we have to delete this tuple? */
108 if (callback(&itup->heapPtr, callback_state))
109 {
110 /* Yes; adjust count of tuples that will be left on page */
111 BloomPageGetOpaque(page)->maxoff--;
112 stats->tuples_removed += 1;
113 }
114 else
115 {
116 /* No; copy it to itupPtr++, but skip copy if not needed */
117 if (itupPtr != itup)
118 memmove(itupPtr, itup, state.sizeOfBloomTuple);
120 }
121
122 itup = BloomPageGetNextTuple(&state, itup);
123 }
124
125 /* Assert that we counted correctly */
128
129 /*
130 * Add page to new notFullPage list if we will not mark page as
131 * deleted and there is free space on it
132 */
133 if (BloomPageGetMaxOffset(page) != 0 &&
134 BloomPageGetFreeSpace(&state, page) >= state.sizeOfBloomTuple &&
136 notFullPage[countPage++] = blkno;
137
138 /* Did we delete something? */
139 if (itupPtr != itup)
140 {
141 /* Is it empty page now? */
142 if (BloomPageGetMaxOffset(page) == 0)
144 /* Adjust pd_lower */
145 ((PageHeader) page)->pd_lower = (char *) itupPtr - page;
146 /* Finish WAL-logging */
148 }
149 else
150 {
151 /* Didn't change anything: abort WAL-logging */
153 }
154 UnlockReleaseBuffer(buffer);
155 }
156
158 read_stream_end(stream);
159
160 /*
161 * Update the metapage's notFullPage list with whatever we found. Our
162 * info could already be out of date at this point, but blinsert() will
163 * cope if so.
164 */
167
169 page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
170
172 memcpy(metaData->notFullPage, notFullPage, sizeof(BlockNumber) * countPage);
173 metaData->nStart = 0;
174 metaData->nEnd = countPage;
175
177 UnlockReleaseBuffer(buffer);
178
179 return stats;
180}
181
182/*
183 * Post-VACUUM cleanup.
184 *
185 * Result: a palloc'd struct containing statistical info for VACUUM displays.
186 */
189{
190 Relation index = info->index;
191 BlockNumber npages,
192 blkno;
194 ReadStream *stream;
195
196 if (info->analyze_only)
197 return stats;
198
199 if (stats == NULL)
201
202 /*
203 * Iterate over the pages: insert deleted pages into FSM and collect
204 * statistics.
205 */
207 stats->num_pages = npages;
208 stats->pages_free = 0;
209 stats->num_index_tuples = 0;
210
211 /* Scan all blocks except the metapage using streaming reads */
213 p.last_exclusive = npages;
214
215 /*
216 * It is safe to use batchmode as block_range_read_stream_cb takes no
217 * locks.
218 */
222 info->strategy,
223 index,
226 &p,
227 0);
228
229 for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
230 {
231 Buffer buffer;
232 Page page;
233
234 vacuum_delay_point(false);
235
236 buffer = read_stream_next_buffer(stream, NULL);
238 page = BufferGetPage(buffer);
239
240 if (PageIsNew(page) || BloomPageIsDeleted(page))
241 {
243 stats->pages_free++;
244 }
245 else
246 {
248 }
249
250 UnlockReleaseBuffer(buffer);
251 }
252
254 read_stream_end(stream);
255
257
258 return stats;
259}
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:31
IndexBulkDeleteResult * blvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
Definition blvacuum.c:188
int Buffer
Definition buf.h:23
#define InvalidBuffer
Definition buf.h:25
void UnlockReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5522
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition bufmgr.c:874
#define RelationGetNumberOfBlocks(reln)
Definition bufmgr.h:307
static Page BufferGetPage(Buffer buffer)
Definition bufmgr.h:470
@ BUFFER_LOCK_SHARE
Definition bufmgr.h:210
@ BUFFER_LOCK_EXCLUSIVE
Definition bufmgr.h:220
static void LockBuffer(Buffer buffer, BufferLockMode mode)
Definition bufmgr.h:332
PageHeaderData * PageHeader
Definition bufpage.h:199
static bool PageIsNew(const PageData *page)
Definition bufpage.h:259
PageData * Page
Definition bufpage.h:81
#define Assert(condition)
Definition c.h:945
#define palloc0_object(type)
Definition fe_memutils.h:75
bool(* IndexBulkDeleteCallback)(ItemPointer itemptr, void *state)
Definition genam.h:95
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)
Buffer read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
ReadStream * read_stream_begin_relation(int flags, BufferAccessStrategy strategy, Relation rel, ForkNumber forknum, ReadStreamBlockNumberCB callback, void *callback_private_data, size_t per_buffer_data_size)
void read_stream_end(ReadStream *stream)
BlockNumber block_range_read_stream_cb(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
#define READ_STREAM_MAINTENANCE
Definition read_stream.h:28
#define READ_STREAM_USE_BATCHING
Definition read_stream.h:64
#define READ_STREAM_FULL
Definition read_stream.h:43
@ MAIN_FORKNUM
Definition relpath.h:58
ItemPointerData heapPtr
Definition bloom.h:159
BlockNumber pages_free
Definition genam.h:91
BlockNumber num_pages
Definition genam.h:85
double tuples_removed
Definition genam.h:88
double num_index_tuples
Definition genam.h:87
Relation index
Definition genam.h:54
bool analyze_only
Definition genam.h:56
BufferAccessStrategy strategy
Definition genam.h:61
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:2431