PostgreSQL Source Code git master
blvacuum.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * blvacuum.c
4 * Bloom VACUUM functions.
5 *
6 * Copyright (c) 2016-2025, 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;
41 BloomMetaPageData *metaData;
42 GenericXLogState *gxlogState;
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
66 gxlogState = GenericXLogStart(index);
67 page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
68
69 /* Ignore empty/deleted pages until blvacuumcleanup() */
70 if (PageIsNew(page) || BloomPageIsDeleted(page))
71 {
72 UnlockReleaseBuffer(buffer);
73 GenericXLogAbort(gxlogState);
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 */
81 itup = itupPtr = BloomPageGetTuple(&state, page, FirstOffsetNumber);
82 itupEnd = BloomPageGetTuple(&state, page,
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);
98 itupPtr = BloomPageGetNextTuple(&state, itupPtr);
99 }
100
101 itup = BloomPageGetNextTuple(&state, itup);
102 }
103
104 /* Assert that we counted correctly */
105 Assert(itupPtr == BloomPageGetTuple(&state, page,
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 &&
114 countPage < BloomMetaBlockN)
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 */
126 GenericXLogFinish(gxlogState);
127 }
128 else
129 {
130 /* Didn't change anything: abort WAL-logging */
131 GenericXLogAbort(gxlogState);
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
144 gxlogState = GenericXLogStart(index);
145 page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
146
147 metaData = BloomPageGetMeta(page);
148 memcpy(metaData->notFullPage, notFullPage, sizeof(BlockNumber) * countPage);
149 metaData->nStart = 0;
150 metaData->nEnd = countPage;
151
152 GenericXLogFinish(gxlogState);
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:166
#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 LockBuffer(Buffer buffer, BufferLockMode mode)
Definition: bufmgr.c:5604
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:5383
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:792
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:745
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:294
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:436
@ BUFFER_LOCK_SHARE
Definition: bufmgr.h:206
@ BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:207
@ 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
bool(* IndexBulkDeleteCallback)(ItemPointer itemptr, void *state)
Definition: genam.h:114
Page GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, int flags)
Definition: generic_xlog.c:299
GenericXLogState * GenericXLogStart(Relation relation)
Definition: generic_xlog.c:269
XLogRecPtr GenericXLogFinish(GenericXLogState *state)
Definition: generic_xlog.c:337
void GenericXLogAbort(GenericXLogState *state)
Definition: generic_xlog.c:444
Assert(PointerIsAligned(start, uint64))
void IndexFreeSpaceMapVacuum(Relation rel)
Definition: indexfsm.c:71
void RecordFreeIndexPage(Relation rel, BlockNumber freeBlock)
Definition: indexfsm.c:52
void * palloc0(Size size)
Definition: mcxt.c:1395
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
#define FirstOffsetNumber
Definition: off.h:27
@ MAIN_FORKNUM
Definition: relpath.h:58
FreeBlockNumberArray notFullPage
Definition: bloom.h:124
uint16 nEnd
Definition: bloom.h:122
uint16 nStart
Definition: bloom.h:121
ItemPointerData heapPtr
Definition: bloom.h:159
BlockNumber pages_free
Definition: genam.h:110
BlockNumber num_pages
Definition: genam.h:104
double tuples_removed
Definition: genam.h:107
double num_index_tuples
Definition: genam.h:106
Relation index
Definition: genam.h:73
bool analyze_only
Definition: genam.h:75
BufferAccessStrategy strategy
Definition: genam.h:80
Definition: type.h:96
Definition: regguts.h:323
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46
void vacuum_delay_point(bool is_analyze)
Definition: vacuum.c:2424