PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
freespace.h File Reference
Include dependency graph for freespace.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

Size GetRecordedFreeSpace (Relation rel, BlockNumber heapBlk)
 
BlockNumber GetPageWithFreeSpace (Relation rel, Size spaceNeeded)
 
BlockNumber RecordAndGetPageWithFreeSpace (Relation rel, BlockNumber oldPage, Size oldSpaceAvail, Size spaceNeeded)
 
void RecordPageWithFreeSpace (Relation rel, BlockNumber heapBlk, Size spaceAvail)
 
void XLogRecordPageWithFreeSpace (RelFileLocator rlocator, BlockNumber heapBlk, Size spaceAvail)
 
BlockNumber FreeSpaceMapPrepareTruncateRel (Relation rel, BlockNumber nblocks)
 
void FreeSpaceMapVacuum (Relation rel)
 
void FreeSpaceMapVacuumRange (Relation rel, BlockNumber start, BlockNumber end)
 

Function Documentation

◆ FreeSpaceMapPrepareTruncateRel()

BlockNumber FreeSpaceMapPrepareTruncateRel ( Relation  rel,
BlockNumber  nblocks 
)

Definition at line 275 of file freespace.c.

276{
277 BlockNumber new_nfsmblocks;
278 FSMAddress first_removed_address;
279 uint16 first_removed_slot;
280 Buffer buf;
281
282 /*
283 * If no FSM has been created yet for this relation, there's nothing to
284 * truncate.
285 */
287 return InvalidBlockNumber;
288
289 /* Get the location in the FSM of the first removed heap block */
290 first_removed_address = fsm_get_location(nblocks, &first_removed_slot);
291
292 /*
293 * Zero out the tail of the last remaining FSM page. If the slot
294 * representing the first removed heap block is at a page boundary, as the
295 * first slot on the FSM page that first_removed_address points to, we can
296 * just truncate that page altogether.
297 */
298 if (first_removed_slot > 0)
299 {
300 buf = fsm_readbuf(rel, first_removed_address, false);
301 if (!BufferIsValid(buf))
302 return InvalidBlockNumber; /* nothing to do; the FSM was already
303 * smaller */
305
306 /* NO EREPORT(ERROR) from here till changes are logged */
308
309 fsm_truncate_avail(BufferGetPage(buf), first_removed_slot);
310
311 /*
312 * This change is non-critical, because fsm_does_block_exist() would
313 * stop us from returning a truncated-away block. However, since this
314 * may remove up to SlotsPerFSMPage slots, it's nice to avoid the cost
315 * of that many fsm_does_block_exist() rejections. Use a full
316 * MarkBufferDirty(), not MarkBufferDirtyHint().
317 */
319
320 /*
321 * WAL-log like MarkBufferDirtyHint() might have done, just to avoid
322 * differing from the rest of the file in this respect. This is
323 * optional; see README mention of full page images. XXX consider
324 * XLogSaveBufferForHint() for even closer similarity.
325 *
326 * A higher-level operation calls us at WAL replay. If we crash
327 * before the XLOG_SMGR_TRUNCATE flushes to disk, main fork length has
328 * not changed, and our fork remains valid. If we crash after that
329 * flush, redo will return here.
330 */
332 log_newpage_buffer(buf, false);
333
335
337
338 new_nfsmblocks = fsm_logical_to_physical(first_removed_address) + 1;
339 }
340 else
341 {
342 new_nfsmblocks = fsm_logical_to_physical(first_removed_address);
343 if (smgrnblocks(RelationGetSmgr(rel), FSM_FORKNUM) <= new_nfsmblocks)
344 return InvalidBlockNumber; /* nothing to do; the FSM was already
345 * smaller */
346 }
347
348 return new_nfsmblocks;
349}
uint32 BlockNumber
Definition: block.h:31
#define InvalidBlockNumber
Definition: block.h:33
int Buffer
Definition: buf.h:23
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:4883
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:2532
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:5100
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:396
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:191
static bool BufferIsValid(Buffer bufnum)
Definition: bufmgr.h:347
uint16_t uint16
Definition: c.h:487
static BlockNumber fsm_logical_to_physical(FSMAddress addr)
Definition: freespace.c:455
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:491
static Buffer fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
Definition: freespace.c:554
bool fsm_truncate_avail(Page page, int nslots)
Definition: fsmpage.c:313
#define START_CRIT_SECTION()
Definition: miscadmin.h:149
#define END_CRIT_SECTION()
Definition: miscadmin.h:151
static char * buf
Definition: pg_test_fsync.c:72
static SMgrRelation RelationGetSmgr(Relation rel)
Definition: rel.h:567
#define RelationNeedsWAL(relation)
Definition: rel.h:628
@ FSM_FORKNUM
Definition: relpath.h:59
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:677
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:401
#define XLogHintBitIsNeeded()
Definition: xlog.h:120
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)
Definition: xloginsert.c:1237
bool InRecovery
Definition: xlogutils.c:50

References buf, BUFFER_LOCK_EXCLUSIVE, BufferGetPage(), BufferIsValid(), END_CRIT_SECTION, FSM_FORKNUM, fsm_get_location(), fsm_logical_to_physical(), fsm_readbuf(), fsm_truncate_avail(), InRecovery, InvalidBlockNumber, LockBuffer(), log_newpage_buffer(), MarkBufferDirty(), RelationGetSmgr(), RelationNeedsWAL, smgrexists(), smgrnblocks(), START_CRIT_SECTION, UnlockReleaseBuffer(), and XLogHintBitIsNeeded.

Referenced by RelationTruncate(), and smgr_redo().

◆ FreeSpaceMapVacuum()

void FreeSpaceMapVacuum ( Relation  rel)

Definition at line 358 of file freespace.c.

359{
360 bool dummy;
361
362 /* Recursively scan the tree, starting at the root */
365 &dummy);
366}
static uint8 fsm_vacuum_page(Relation rel, FSMAddress addr, BlockNumber start, BlockNumber end, bool *eof_p)
Definition: freespace.c:812
static const FSMAddress FSM_ROOT_ADDRESS
Definition: freespace.c:91

References FSM_ROOT_ADDRESS, fsm_vacuum_page(), and InvalidBlockNumber.

Referenced by brin_vacuum_scan(), and IndexFreeSpaceMapVacuum().

◆ FreeSpaceMapVacuumRange()

void FreeSpaceMapVacuumRange ( Relation  rel,
BlockNumber  start,
BlockNumber  end 
)

Definition at line 377 of file freespace.c.

378{
379 bool dummy;
380
381 /* Recursively scan the tree, starting at the root */
382 if (end > start)
383 (void) fsm_vacuum_page(rel, FSM_ROOT_ADDRESS, start, end, &dummy);
384}
return str start

References FSM_ROOT_ADDRESS, fsm_vacuum_page(), and start.

Referenced by brin_doinsert(), brin_doupdate(), brin_getinsertbuffer(), lazy_scan_heap(), RelationAddBlocks(), RelationTruncate(), smgr_redo(), and terminate_brin_buildstate().

◆ GetPageWithFreeSpace()

BlockNumber GetPageWithFreeSpace ( Relation  rel,
Size  spaceNeeded 
)

Definition at line 137 of file freespace.c.

138{
139 uint8 min_cat = fsm_space_needed_to_cat(spaceNeeded);
140
141 return fsm_search(rel, min_cat);
142}
uint8_t uint8
Definition: c.h:486
static uint8 fsm_space_needed_to_cat(Size needed)
Definition: freespace.c:432
static BlockNumber fsm_search(Relation rel, uint8 min_cat)
Definition: freespace.c:678

References fsm_search(), and fsm_space_needed_to_cat().

Referenced by brin_getinsertbuffer(), GetFreeIndexPage(), and RelationGetBufferForTuple().

◆ GetRecordedFreeSpace()

Size GetRecordedFreeSpace ( Relation  rel,
BlockNumber  heapBlk 
)

Definition at line 244 of file freespace.c.

245{
246 FSMAddress addr;
247 uint16 slot;
248 Buffer buf;
249 uint8 cat;
250
251 /* Get the location of the FSM byte representing the heap block */
252 addr = fsm_get_location(heapBlk, &slot);
253
254 buf = fsm_readbuf(rel, addr, false);
255 if (!BufferIsValid(buf))
256 return 0;
257 cat = fsm_get_avail(BufferGetPage(buf), slot);
259
260 return fsm_space_cat_to_avail(cat);
261}
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:4866
static Size fsm_space_cat_to_avail(uint8 cat)
Definition: freespace.c:418
uint8 fsm_get_avail(Page page, int slot)
Definition: fsmpage.c:122

References buf, BufferGetPage(), BufferIsValid(), fsm_get_avail(), fsm_get_location(), fsm_readbuf(), fsm_space_cat_to_avail(), and ReleaseBuffer().

Referenced by lazy_scan_new_or_empty(), pg_freespace(), and statapprox_heap().

◆ RecordAndGetPageWithFreeSpace()

BlockNumber RecordAndGetPageWithFreeSpace ( Relation  rel,
BlockNumber  oldPage,
Size  oldSpaceAvail,
Size  spaceNeeded 
)

Definition at line 154 of file freespace.c.

156{
157 int old_cat = fsm_space_avail_to_cat(oldSpaceAvail);
158 int search_cat = fsm_space_needed_to_cat(spaceNeeded);
159 FSMAddress addr;
160 uint16 slot;
161 int search_slot;
162
163 /* Get the location of the FSM byte representing the heap block */
164 addr = fsm_get_location(oldPage, &slot);
165
166 search_slot = fsm_set_and_search(rel, addr, slot, old_cat, search_cat);
167
168 /*
169 * If fsm_set_and_search found a suitable new block, return that.
170 * Otherwise, search as usual.
171 */
172 if (search_slot != -1)
173 {
174 BlockNumber blknum = fsm_get_heap_blk(addr, search_slot);
175
176 /*
177 * Check that the blknum is actually in the relation. Don't try to
178 * update the FSM in that case, just fall back to the other case
179 */
180 if (fsm_does_block_exist(rel, blknum))
181 return blknum;
182 }
183 return fsm_search(rel, search_cat);
184}
static bool fsm_does_block_exist(Relation rel, BlockNumber blknumber)
Definition: freespace.c:926
static uint8 fsm_space_avail_to_cat(Size avail)
Definition: freespace.c:392
static int fsm_set_and_search(Relation rel, FSMAddress addr, uint16 slot, uint8 newValue, uint8 minValue)
Definition: freespace.c:646
static BlockNumber fsm_get_heap_blk(FSMAddress addr, uint16 slot)
Definition: freespace.c:506

References fsm_does_block_exist(), fsm_get_heap_blk(), fsm_get_location(), fsm_search(), fsm_set_and_search(), fsm_space_avail_to_cat(), and fsm_space_needed_to_cat().

Referenced by brin_getinsertbuffer(), and RelationGetBufferForTuple().

◆ RecordPageWithFreeSpace()

void RecordPageWithFreeSpace ( Relation  rel,
BlockNumber  heapBlk,
Size  spaceAvail 
)

Definition at line 194 of file freespace.c.

195{
196 int new_cat = fsm_space_avail_to_cat(spaceAvail);
197 FSMAddress addr;
198 uint16 slot;
199
200 /* Get the location of the FSM byte representing the heap block */
201 addr = fsm_get_location(heapBlk, &slot);
202
203 fsm_set_and_search(rel, addr, slot, new_cat, 0);
204}

References fsm_get_location(), fsm_set_and_search(), and fsm_space_avail_to_cat().

Referenced by brin_doinsert(), brin_doupdate(), brin_initialize_empty_new_buffer(), brin_page_cleanup(), lazy_scan_heap(), lazy_scan_new_or_empty(), lazy_vacuum_heap_rel(), RecordFreeIndexPage(), RecordUsedIndexPage(), RelationAddBlocks(), RelationGetBufferForTuple(), and terminate_brin_buildstate().

◆ XLogRecordPageWithFreeSpace()

void XLogRecordPageWithFreeSpace ( RelFileLocator  rlocator,
BlockNumber  heapBlk,
Size  spaceAvail 
)

Definition at line 211 of file freespace.c.

213{
214 int new_cat = fsm_space_avail_to_cat(spaceAvail);
215 FSMAddress addr;
216 uint16 slot;
217 BlockNumber blkno;
218 Buffer buf;
219 Page page;
220
221 /* Get the location of the FSM byte representing the heap block */
222 addr = fsm_get_location(heapBlk, &slot);
223 blkno = fsm_logical_to_physical(addr);
224
225 /* If the page doesn't exist already, extend */
226 buf = XLogReadBufferExtended(rlocator, FSM_FORKNUM, blkno,
229
230 page = BufferGetPage(buf);
231 if (PageIsNew(page))
232 PageInit(page, BLCKSZ, 0);
233
234 if (fsm_set_avail(page, slot, new_cat))
235 MarkBufferDirtyHint(buf, false);
237}
#define InvalidBuffer
Definition: buf.h:25
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
Definition: bufmgr.c:4930
@ RBM_ZERO_ON_ERROR
Definition: bufmgr.h:50
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:42
static bool PageIsNew(const PageData *page)
Definition: bufpage.h:234
PageData * Page
Definition: bufpage.h:82
bool fsm_set_avail(Page page, int slot, uint8 value)
Definition: fsmpage.c:63
Buffer XLogReadBufferExtended(RelFileLocator rlocator, ForkNumber forknum, BlockNumber blkno, ReadBufferMode mode, Buffer recent_buffer)
Definition: xlogutils.c:471

References buf, BUFFER_LOCK_EXCLUSIVE, BufferGetPage(), FSM_FORKNUM, fsm_get_location(), fsm_logical_to_physical(), fsm_set_avail(), fsm_space_avail_to_cat(), InvalidBuffer, LockBuffer(), MarkBufferDirtyHint(), PageInit(), PageIsNew(), RBM_ZERO_ON_ERROR, UnlockReleaseBuffer(), and XLogReadBufferExtended().

Referenced by heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_prune_freeze(), heap_xlog_update(), and heap_xlog_visible().