PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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)
 
void FreeSpaceMapTruncateRel (Relation rel, BlockNumber nblocks)
 
void FreeSpaceMapVacuum (Relation rel)
 
void UpdateFreeSpaceMap (Relation rel, BlockNumber startBlkNum, BlockNumber endBlkNum, Size freespace)
 

Function Documentation

void FreeSpaceMapTruncateRel ( Relation  rel,
BlockNumber  nblocks 
)

Definition at line 299 of file freespace.c.

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, LockBuffer(), log_newpage_buffer(), MarkBufferDirty(), RelationData::rd_smgr, RelationNeedsWAL, RelationOpenSmgr, SMgrRelationData::smgr_fsm_nblocks, smgrexists(), smgrnblocks(), smgrtruncate(), START_CRIT_SECTION, UnlockReleaseBuffer(), and XLogHintBitIsNeeded.

Referenced by RelationTruncate(), and smgr_redo().

300 {
301  BlockNumber new_nfsmblocks;
302  FSMAddress first_removed_address;
303  uint16 first_removed_slot;
304  Buffer buf;
305 
306  RelationOpenSmgr(rel);
307 
308  /*
309  * If no FSM has been created yet for this relation, there's nothing to
310  * truncate.
311  */
312  if (!smgrexists(rel->rd_smgr, FSM_FORKNUM))
313  return;
314 
315  /* Get the location in the FSM of the first removed heap block */
316  first_removed_address = fsm_get_location(nblocks, &first_removed_slot);
317 
318  /*
319  * Zero out the tail of the last remaining FSM page. If the slot
320  * representing the first removed heap block is at a page boundary, as the
321  * first slot on the FSM page that first_removed_address points to, we can
322  * just truncate that page altogether.
323  */
324  if (first_removed_slot > 0)
325  {
326  buf = fsm_readbuf(rel, first_removed_address, false);
327  if (!BufferIsValid(buf))
328  return; /* nothing to do; the FSM was already smaller */
330 
331  /* NO EREPORT(ERROR) from here till changes are logged */
333 
334  fsm_truncate_avail(BufferGetPage(buf), first_removed_slot);
335 
336  /*
337  * Truncation of a relation is WAL-logged at a higher-level, and we
338  * will be called at WAL replay. But if checksums are enabled, we need
339  * to still write a WAL record to protect against a torn page, if the
340  * page is flushed to disk before the truncation WAL record. We cannot
341  * use MarkBufferDirtyHint here, because that will not dirty the page
342  * during recovery.
343  */
344  MarkBufferDirty(buf);
346  log_newpage_buffer(buf, false);
347 
349 
350  UnlockReleaseBuffer(buf);
351 
352  new_nfsmblocks = fsm_logical_to_physical(first_removed_address) + 1;
353  }
354  else
355  {
356  new_nfsmblocks = fsm_logical_to_physical(first_removed_address);
357  if (smgrnblocks(rel->rd_smgr, FSM_FORKNUM) <= new_nfsmblocks)
358  return; /* nothing to do; the FSM was already smaller */
359  }
360 
361  /* Truncate the unused FSM pages, and send smgr inval message */
362  smgrtruncate(rel->rd_smgr, FSM_FORKNUM, new_nfsmblocks);
363 
364  /*
365  * We might as well update the local smgr_fsm_nblocks setting.
366  * smgrtruncate sent an smgr cache inval message, which will cause other
367  * backends to invalidate their copy of smgr_fsm_nblocks, and this one too
368  * at the next command boundary. But this ensures it isn't outright wrong
369  * until then.
370  */
371  if (rel->rd_smgr)
372  rel->rd_smgr->smgr_fsm_nblocks = new_nfsmblocks;
373 }
bool fsm_truncate_avail(Page page, int nslots)
Definition: fsmpage.c:313
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)
Definition: xloginsert.c:1010
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
bool InRecovery
Definition: xlog.c:192
#define END_CRIT_SECTION()
Definition: miscadmin.h:132
void smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks)
Definition: smgr.c:684
#define START_CRIT_SECTION()
Definition: miscadmin.h:130
uint32 BlockNumber
Definition: block.h:31
BlockNumber smgr_fsm_nblocks
Definition: smgr.h:56
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:287
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
#define RelationOpenSmgr(relation)
Definition: rel.h:461
unsigned short uint16
Definition: c.h:267
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
static char * buf
Definition: pg_test_fsync.c:65
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:495
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:672
static BlockNumber fsm_logical_to_physical(FSMAddress addr)
Definition: freespace.c:459
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define RelationNeedsWAL(relation)
Definition: rel.h:506
static Buffer fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
Definition: freespace.c:558
int Buffer
Definition: buf.h:23
#define XLogHintBitIsNeeded()
Definition: xlog.h:156
void FreeSpaceMapVacuum ( Relation  rel)

Definition at line 379 of file freespace.c.

References fsm_vacuum_page().

Referenced by brin_doinsert(), brin_doupdate(), brin_vacuum_scan(), IndexFreeSpaceMapVacuum(), and lazy_vacuum_rel().

380 {
381  bool dummy;
382 
383  /*
384  * Traverse the tree in depth-first order. The tree is stored physically
385  * in depth-first order, so this should be pretty I/O efficient.
386  */
387  fsm_vacuum_page(rel, FSM_ROOT_ADDRESS, &dummy);
388 }
static const FSMAddress FSM_ROOT_ADDRESS
Definition: freespace.c:90
static uint8 fsm_vacuum_page(Relation rel, FSMAddress addr, bool *eof)
Definition: freespace.c:788
BlockNumber GetPageWithFreeSpace ( Relation  rel,
Size  spaceNeeded 
)

Definition at line 132 of file freespace.c.

References fsm_search(), and fsm_space_needed_to_cat().

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

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:266
static uint8 fsm_space_needed_to_cat(Size needed)
Definition: freespace.c:436
static BlockNumber fsm_search(Relation rel, uint8 min_cat)
Definition: freespace.c:700
Size GetRecordedFreeSpace ( Relation  rel,
BlockNumber  heapBlk 
)

Definition at line 270 of file freespace.c.

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

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

271 {
272  FSMAddress addr;
273  uint16 slot;
274  Buffer buf;
275  uint8 cat;
276 
277  /* Get the location of the FSM byte representing the heap block */
278  addr = fsm_get_location(heapBlk, &slot);
279 
280  buf = fsm_readbuf(rel, addr, false);
281  if (!BufferIsValid(buf))
282  return 0;
283  cat = fsm_get_avail(BufferGetPage(buf), slot);
284  ReleaseBuffer(buf);
285 
286  return fsm_space_cat_to_avail(cat);
287 }
unsigned char uint8
Definition: c.h:266
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
unsigned short uint16
Definition: c.h:267
static Size fsm_space_cat_to_avail(uint8 cat)
Definition: freespace.c:422
static char * buf
Definition: pg_test_fsync.c:65
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:495
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
uint8 fsm_get_avail(Page page, int slot)
Definition: fsmpage.c:122
static Buffer fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
Definition: freespace.c:558
int Buffer
Definition: buf.h:23
BlockNumber RecordAndGetPageWithFreeSpace ( Relation  rel,
BlockNumber  oldPage,
Size  oldSpaceAvail,
Size  spaceNeeded 
)

Definition at line 149 of file freespace.c.

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().

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 BlockNumber fsm_get_heap_blk(FSMAddress addr, uint16 slot)
Definition: freespace.c:510
unsigned short uint16
Definition: c.h:267
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:495
static uint8 fsm_space_avail_to_cat(Size avail)
Definition: freespace.c:396
static uint8 fsm_space_needed_to_cat(Size needed)
Definition: freespace.c:436
static int fsm_set_and_search(Relation rel, FSMAddress addr, uint16 slot, uint8 newValue, uint8 minValue)
Definition: freespace.c:668
static BlockNumber fsm_search(Relation rel, uint8 min_cat)
Definition: freespace.c:700
void RecordPageWithFreeSpace ( Relation  rel,
BlockNumber  heapBlk,
Size  spaceAvail 
)

Definition at line 181 of file freespace.c.

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

Referenced by brin_doupdate(), brin_getinsertbuffer(), brin_initialize_empty_new_buffer(), brin_page_cleanup(), lazy_scan_heap(), lazy_vacuum_heap(), RecordFreeIndexPage(), RecordUsedIndexPage(), RelationAddExtraBlocks(), and terminate_brin_buildstate().

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 }
unsigned short uint16
Definition: c.h:267
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:495
static uint8 fsm_space_avail_to_cat(Size avail)
Definition: freespace.c:396
static int fsm_set_and_search(Relation rel, FSMAddress addr, uint16 slot, uint8 newValue, uint8 minValue)
Definition: freespace.c:668
void UpdateFreeSpaceMap ( Relation  rel,
BlockNumber  startBlkNum,
BlockNumber  endBlkNum,
Size  freespace 
)

Definition at line 201 of file freespace.c.

References fsm_get_lastblckno(), fsm_get_location(), fsm_space_avail_to_cat(), and fsm_update_recursive().

Referenced by RelationAddExtraBlocks().

203 {
204  int new_cat = fsm_space_avail_to_cat(freespace);
205  FSMAddress addr;
206  uint16 slot;
207  BlockNumber blockNum;
208  BlockNumber lastBlkOnPage;
209 
210  blockNum = startBlkNum;
211 
212  while (blockNum <= endBlkNum)
213  {
214  /*
215  * Find FSM address for this block; update tree all the way to the
216  * root.
217  */
218  addr = fsm_get_location(blockNum, &slot);
219  fsm_update_recursive(rel, addr, new_cat);
220 
221  /*
222  * Get the last block number on this FSM page. If that's greater than
223  * or equal to our endBlkNum, we're done. Otherwise, advance to the
224  * first block on the next page.
225  */
226  lastBlkOnPage = fsm_get_lastblckno(rel, addr);
227  if (lastBlkOnPage >= endBlkNum)
228  break;
229  blockNum = lastBlkOnPage + 1;
230  }
231 }
uint32 BlockNumber
Definition: block.h:31
unsigned short uint16
Definition: c.h:267
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:495
static uint8 fsm_space_avail_to_cat(Size avail)
Definition: freespace.c:396
static BlockNumber fsm_get_lastblckno(Relation rel, FSMAddress addr)
Definition: freespace.c:857
static void fsm_update_recursive(Relation rel, FSMAddress addr, uint8 new_cat)
Definition: freespace.c:874
void XLogRecordPageWithFreeSpace ( RelFileNode  rnode,
BlockNumber  heapBlk,
Size  spaceAvail 
)

Definition at line 238 of file freespace.c.

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_clean(), heap_xlog_insert(), heap_xlog_multi_insert(), and heap_xlog_update().

240 {
241  int new_cat = fsm_space_avail_to_cat(spaceAvail);
242  FSMAddress addr;
243  uint16 slot;
244  BlockNumber blkno;
245  Buffer buf;
246  Page page;
247 
248  /* Get the location of the FSM byte representing the heap block */
249  addr = fsm_get_location(heapBlk, &slot);
250  blkno = fsm_logical_to_physical(addr);
251 
252  /* If the page doesn't exist already, extend */
255 
256  page = BufferGetPage(buf);
257  if (PageIsNew(page))
258  PageInit(page, BLCKSZ, 0);
259 
260  if (fsm_set_avail(page, slot, new_cat))
261  MarkBufferDirtyHint(buf, false);
262  UnlockReleaseBuffer(buf);
263 }
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
Definition: bufmgr.c:3379
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:438
uint32 BlockNumber
Definition: block.h:31
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
unsigned short uint16
Definition: c.h:267
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
static char * buf
Definition: pg_test_fsync.c:65
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:495
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
static uint8 fsm_space_avail_to_cat(Size avail)
Definition: freespace.c:396
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
static BlockNumber fsm_logical_to_physical(FSMAddress addr)
Definition: freespace.c:459
#define PageIsNew(page)
Definition: bufpage.h:226
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:41