PostgreSQL Source Code  git master
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:4867
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:2474
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:5085
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:404
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:195
static bool BufferIsValid(Buffer bufnum)
Definition: bufmgr.h:355
unsigned short uint16
Definition: c.h:505
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:73
static SMgrRelation RelationGetSmgr(Relation rel)
Definition: rel.h:567
#define RelationNeedsWAL(relation)
Definition: rel.h:628
@ FSM_FORKNUM
Definition: relpath.h:51
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:655
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:398
#define XLogHintBitIsNeeded()
Definition: xlog.h:118
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 */
363  (void) fsm_vacuum_page(rel, FSM_ROOT_ADDRESS,
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 }
unsigned char uint8
Definition: c.h:504
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:4850
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:4914
@ RBM_ZERO_ON_ERROR
Definition: bufmgr.h:50
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:42
Pointer Page
Definition: bufpage.h:78
static bool PageIsNew(Page page)
Definition: bufpage.h:230
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().