PostgreSQL Source Code  git master
freespace.h File Reference
#include "storage/block.h"
#include "storage/relfilenode.h"
#include "utils/relcache.h"
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 (RelFileNode rnode, 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 261 of file freespace.c.

262 {
263  BlockNumber new_nfsmblocks;
264  FSMAddress first_removed_address;
265  uint16 first_removed_slot;
266  Buffer buf;
267 
268  /*
269  * If no FSM has been created yet for this relation, there's nothing to
270  * truncate.
271  */
273  return InvalidBlockNumber;
274 
275  /* Get the location in the FSM of the first removed heap block */
276  first_removed_address = fsm_get_location(nblocks, &first_removed_slot);
277 
278  /*
279  * Zero out the tail of the last remaining FSM page. If the slot
280  * representing the first removed heap block is at a page boundary, as the
281  * first slot on the FSM page that first_removed_address points to, we can
282  * just truncate that page altogether.
283  */
284  if (first_removed_slot > 0)
285  {
286  buf = fsm_readbuf(rel, first_removed_address, false);
287  if (!BufferIsValid(buf))
288  return InvalidBlockNumber; /* nothing to do; the FSM was already
289  * smaller */
291 
292  /* NO EREPORT(ERROR) from here till changes are logged */
294 
295  fsm_truncate_avail(BufferGetPage(buf), first_removed_slot);
296 
297  /*
298  * Truncation of a relation is WAL-logged at a higher-level, and we
299  * will be called at WAL replay. But if checksums are enabled, we need
300  * to still write a WAL record to protect against a torn page, if the
301  * page is flushed to disk before the truncation WAL record. We cannot
302  * use MarkBufferDirtyHint here, because that will not dirty the page
303  * during recovery.
304  */
307  log_newpage_buffer(buf, false);
308 
310 
312 
313  new_nfsmblocks = fsm_logical_to_physical(first_removed_address) + 1;
314  }
315  else
316  {
317  new_nfsmblocks = fsm_logical_to_physical(first_removed_address);
318  if (smgrnblocks(RelationGetSmgr(rel), FSM_FORKNUM) <= new_nfsmblocks)
319  return InvalidBlockNumber; /* nothing to do; the FSM was already
320  * smaller */
321  }
322 
323  return new_nfsmblocks;
324 }
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:3791
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1565
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:4007
#define BufferIsValid(bufnum)
Definition: bufmgr.h:123
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:98
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
unsigned short uint16
Definition: c.h:440
static BlockNumber fsm_logical_to_physical(FSMAddress addr)
Definition: freespace.c:430
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:466
static Buffer fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
Definition: freespace.c:529
bool fsm_truncate_avail(Page page, int nslots)
Definition: fsmpage.c:313
#define START_CRIT_SECTION()
Definition: miscadmin.h:147
#define END_CRIT_SECTION()
Definition: miscadmin.h:149
static char * buf
Definition: pg_test_fsync.c:69
static SMgrRelation RelationGetSmgr(Relation rel)
Definition: rel.h:544
#define RelationNeedsWAL(relation)
Definition: rel.h:601
@ FSM_FORKNUM
Definition: relpath.h:44
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:548
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:247
#define XLogHintBitIsNeeded()
Definition: xlog.h:175
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)
Definition: xloginsert.c:1144
bool InRecovery
Definition: xlogutils.c:52

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 333 of file freespace.c.

334 {
335  bool dummy;
336 
337  /* Recursively scan the tree, starting at the root */
338  (void) fsm_vacuum_page(rel, FSM_ROOT_ADDRESS,
340  &dummy);
341 }
static const FSMAddress FSM_ROOT_ADDRESS
Definition: freespace.c:90
static uint8 fsm_vacuum_page(Relation rel, FSMAddress addr, BlockNumber start, BlockNumber end, bool *eof)
Definition: freespace.c:798

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 352 of file freespace.c.

353 {
354  bool dummy;
355 
356  /* Recursively scan the tree, starting at the root */
357  if (end > start)
358  (void) fsm_vacuum_page(rel, FSM_ROOT_ADDRESS, start, end, &dummy);
359 }

References FSM_ROOT_ADDRESS, and fsm_vacuum_page().

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

◆ GetPageWithFreeSpace()

BlockNumber GetPageWithFreeSpace ( Relation  rel,
Size  spaceNeeded 
)

Definition at line 132 of file freespace.c.

133 {
134  uint8 min_cat = fsm_space_needed_to_cat(spaceNeeded);
135 
136  return fsm_search(rel, min_cat);
137 }
unsigned char uint8
Definition: c.h:439
static uint8 fsm_space_needed_to_cat(Size needed)
Definition: freespace.c:407
static BlockNumber fsm_search(Relation rel, uint8 min_cat)
Definition: freespace.c:700

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 230 of file freespace.c.

231 {
232  FSMAddress addr;
233  uint16 slot;
234  Buffer buf;
235  uint8 cat;
236 
237  /* Get the location of the FSM byte representing the heap block */
238  addr = fsm_get_location(heapBlk, &slot);
239 
240  buf = fsm_readbuf(rel, addr, false);
241  if (!BufferIsValid(buf))
242  return 0;
243  cat = fsm_get_avail(BufferGetPage(buf), slot);
245 
246  return fsm_space_cat_to_avail(cat);
247 }
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3768
static Size fsm_space_cat_to_avail(uint8 cat)
Definition: freespace.c:393
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_heap(), pg_freespace(), and statapprox_heap().

◆ RecordAndGetPageWithFreeSpace()

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

Definition at line 149 of file freespace.c.

151 {
152  int old_cat = fsm_space_avail_to_cat(oldSpaceAvail);
153  int search_cat = fsm_space_needed_to_cat(spaceNeeded);
154  FSMAddress addr;
155  uint16 slot;
156  int search_slot;
157 
158  /* Get the location of the FSM byte representing the heap block */
159  addr = fsm_get_location(oldPage, &slot);
160 
161  search_slot = fsm_set_and_search(rel, addr, slot, old_cat, search_cat);
162 
163  /*
164  * If fsm_set_and_search found a suitable new block, return that.
165  * Otherwise, search as usual.
166  */
167  if (search_slot != -1)
168  return fsm_get_heap_blk(addr, search_slot);
169  else
170  return fsm_search(rel, search_cat);
171 }
static uint8 fsm_space_avail_to_cat(Size avail)
Definition: freespace.c:367
static int fsm_set_and_search(Relation rel, FSMAddress addr, uint16 slot, uint8 newValue, uint8 minValue)
Definition: freespace.c:668
static BlockNumber fsm_get_heap_blk(FSMAddress addr, uint16 slot)
Definition: freespace.c:481

References 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 181 of file freespace.c.

182 {
183  int new_cat = fsm_space_avail_to_cat(spaceAvail);
184  FSMAddress addr;
185  uint16 slot;
186 
187  /* Get the location of the FSM byte representing the heap block */
188  addr = fsm_get_location(heapBlk, &slot);
189 
190  fsm_set_and_search(rel, addr, slot, new_cat, 0);
191 }

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_vacuum_heap_rel(), RecordFreeIndexPage(), RecordUsedIndexPage(), RelationAddExtraBlocks(), and terminate_brin_buildstate().

◆ XLogRecordPageWithFreeSpace()

void XLogRecordPageWithFreeSpace ( RelFileNode  rnode,
BlockNumber  heapBlk,
Size  spaceAvail 
)

Definition at line 198 of file freespace.c.

200 {
201  int new_cat = fsm_space_avail_to_cat(spaceAvail);
202  FSMAddress addr;
203  uint16 slot;
204  BlockNumber blkno;
205  Buffer buf;
206  Page page;
207 
208  /* Get the location of the FSM byte representing the heap block */
209  addr = fsm_get_location(heapBlk, &slot);
210  blkno = fsm_logical_to_physical(addr);
211 
212  /* If the page doesn't exist already, extend */
215 
216  page = BufferGetPage(buf);
217  if (PageIsNew(page))
218  PageInit(page, BLCKSZ, 0);
219 
220  if (fsm_set_avail(page, slot, new_cat))
221  MarkBufferDirtyHint(buf, false);
223 }
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
Definition: bufmgr.c:3838
@ RBM_ZERO_ON_ERROR
Definition: bufmgr.h:44
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:42
Pointer Page
Definition: bufpage.h:78
#define PageIsNew(page)
Definition: bufpage.h:228
bool fsm_set_avail(Page page, int slot, uint8 value)
Definition: fsmpage.c:63
Buffer XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum, BlockNumber blkno, ReadBufferMode mode)
Definition: xlogutils.c:459

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

Referenced by heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_prune(), heap_xlog_update(), heap_xlog_vacuum(), and heap_xlog_visible().