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)
 
void FreeSpaceMapTruncateRel (Relation rel, BlockNumber nblocks)
 
void FreeSpaceMapVacuum (Relation rel)
 
void FreeSpaceMapVacuumRange (Relation rel, BlockNumber start, BlockNumber end)
 

Function Documentation

◆ FreeSpaceMapTruncateRel()

void FreeSpaceMapTruncateRel ( Relation  rel,
BlockNumber  nblocks 
)

Definition at line 259 of file freespace.c.

References buf, BUFFER_LOCK_EXCLUSIVE, BufferGetPage, BufferIsValid, END_CRIT_SECTION, FreeSpaceMapVacuumRange(), FSM_FORKNUM, fsm_get_location(), fsm_logical_to_physical(), fsm_readbuf(), fsm_truncate_avail(), InRecovery, InvalidBlockNumber, 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().

260 {
261  BlockNumber new_nfsmblocks;
262  FSMAddress first_removed_address;
263  uint16 first_removed_slot;
264  Buffer buf;
265 
266  RelationOpenSmgr(rel);
267 
268  /*
269  * If no FSM has been created yet for this relation, there's nothing to
270  * truncate.
271  */
272  if (!smgrexists(rel->rd_smgr, FSM_FORKNUM))
273  return;
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; /* nothing to do; the FSM was already smaller */
290 
291  /* NO EREPORT(ERROR) from here till changes are logged */
293 
294  fsm_truncate_avail(BufferGetPage(buf), first_removed_slot);
295 
296  /*
297  * Truncation of a relation is WAL-logged at a higher-level, and we
298  * will be called at WAL replay. But if checksums are enabled, we need
299  * to still write a WAL record to protect against a torn page, if the
300  * page is flushed to disk before the truncation WAL record. We cannot
301  * use MarkBufferDirtyHint here, because that will not dirty the page
302  * during recovery.
303  */
304  MarkBufferDirty(buf);
306  log_newpage_buffer(buf, false);
307 
309 
310  UnlockReleaseBuffer(buf);
311 
312  new_nfsmblocks = fsm_logical_to_physical(first_removed_address) + 1;
313  }
314  else
315  {
316  new_nfsmblocks = fsm_logical_to_physical(first_removed_address);
317  if (smgrnblocks(rel->rd_smgr, FSM_FORKNUM) <= new_nfsmblocks)
318  return; /* nothing to do; the FSM was already smaller */
319  }
320 
321  /* Truncate the unused FSM pages, and send smgr inval message */
322  smgrtruncate(rel->rd_smgr, FSM_FORKNUM, new_nfsmblocks);
323 
324  /*
325  * We might as well update the local smgr_fsm_nblocks setting.
326  * smgrtruncate sent an smgr cache inval message, which will cause other
327  * backends to invalidate their copy of smgr_fsm_nblocks, and this one too
328  * at the next command boundary. But this ensures it isn't outright wrong
329  * until then.
330  */
331  if (rel->rd_smgr)
332  rel->rd_smgr->smgr_fsm_nblocks = new_nfsmblocks;
333 
334  /*
335  * Update upper-level FSM pages to account for the truncation. This is
336  * important because the just-truncated pages were likely marked as
337  * all-free, and would be preferentially selected.
338  */
340 }
bool fsm_truncate_avail(Page page, int nslots)
Definition: fsmpage.c:313
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)
Definition: xloginsert.c:1009
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
struct SMgrRelationData * rd_smgr
Definition: rel.h:57
bool InRecovery
Definition: xlog.c:194
#define END_CRIT_SECTION()
Definition: miscadmin.h:133
void smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks)
Definition: smgr.c:684
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
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:465
unsigned short uint16
Definition: c.h:324
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
static char * buf
Definition: pg_test_fsync.c:67
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:482
#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
#define InvalidBlockNumber
Definition: block.h:33
static BlockNumber fsm_logical_to_physical(FSMAddress addr)
Definition: freespace.c:446
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define RelationNeedsWAL(relation)
Definition: rel.h:510
static Buffer fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
Definition: freespace.c:545
int Buffer
Definition: buf.h:23
void FreeSpaceMapVacuumRange(Relation rel, BlockNumber start, BlockNumber end)
Definition: freespace.c:368
#define XLogHintBitIsNeeded()
Definition: xlog.h:157

◆ FreeSpaceMapVacuum()

void FreeSpaceMapVacuum ( Relation  rel)

Definition at line 349 of file freespace.c.

References fsm_vacuum_page(), and InvalidBlockNumber.

Referenced by brin_vacuum_scan(), and IndexFreeSpaceMapVacuum().

350 {
351  bool dummy;
352 
353  /* Recursively scan the tree, starting at the root */
354  (void) fsm_vacuum_page(rel, FSM_ROOT_ADDRESS,
356  &dummy);
357 }
uint32 BlockNumber
Definition: block.h:31
static uint8 fsm_vacuum_page(Relation rel, FSMAddress addr, BlockNumber start, BlockNumber end, bool *eof)
Definition: freespace.c:785
static const FSMAddress FSM_ROOT_ADDRESS
Definition: freespace.c:90
#define InvalidBlockNumber
Definition: block.h:33

◆ FreeSpaceMapVacuumRange()

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

Definition at line 368 of file freespace.c.

References fsm_vacuum_page().

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

369 {
370  bool dummy;
371 
372  /* Recursively scan the tree, starting at the root */
373  if (end > start)
374  (void) fsm_vacuum_page(rel, FSM_ROOT_ADDRESS, start, end, &dummy);
375 }
static uint8 fsm_vacuum_page(Relation rel, FSMAddress addr, BlockNumber start, BlockNumber end, bool *eof)
Definition: freespace.c:785
static const FSMAddress FSM_ROOT_ADDRESS
Definition: freespace.c:90

◆ GetPageWithFreeSpace()

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:323
static uint8 fsm_space_needed_to_cat(Size needed)
Definition: freespace.c:423
static BlockNumber fsm_search(Relation rel, uint8 min_cat)
Definition: freespace.c:687

◆ GetRecordedFreeSpace()

Size GetRecordedFreeSpace ( Relation  rel,
BlockNumber  heapBlk 
)

Definition at line 230 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 pg_freespace(), and statapprox_heap().

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);
244  ReleaseBuffer(buf);
245 
246  return fsm_space_cat_to_avail(cat);
247 }
unsigned char uint8
Definition: c.h:323
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
unsigned short uint16
Definition: c.h:324
static Size fsm_space_cat_to_avail(uint8 cat)
Definition: freespace.c:409
static char * buf
Definition: pg_test_fsync.c:67
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:482
#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:545
int Buffer
Definition: buf.h:23

◆ RecordAndGetPageWithFreeSpace()

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:497
unsigned short uint16
Definition: c.h:324
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:482
static uint8 fsm_space_avail_to_cat(Size avail)
Definition: freespace.c:383
static uint8 fsm_space_needed_to_cat(Size needed)
Definition: freespace.c:423
static int fsm_set_and_search(Relation rel, FSMAddress addr, uint16 slot, uint8 newValue, uint8 minValue)
Definition: freespace.c:655
static BlockNumber fsm_search(Relation rel, uint8 min_cat)
Definition: freespace.c:687

◆ RecordPageWithFreeSpace()

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_doinsert(), brin_doupdate(), 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:324
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:482
static uint8 fsm_space_avail_to_cat(Size avail)
Definition: freespace.c:383
static int fsm_set_and_search(Relation rel, FSMAddress addr, uint16 slot, uint8 newValue, uint8 minValue)
Definition: freespace.c:655

◆ XLogRecordPageWithFreeSpace()

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

Definition at line 198 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().

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);
222  UnlockReleaseBuffer(buf);
223 }
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:437
uint32 BlockNumber
Definition: block.h:31
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
unsigned short uint16
Definition: c.h:324
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
static char * buf
Definition: pg_test_fsync.c:67
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
Definition: freespace.c:482
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
static uint8 fsm_space_avail_to_cat(Size avail)
Definition: freespace.c:383
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
static BlockNumber fsm_logical_to_physical(FSMAddress addr)
Definition: freespace.c:446
#define PageIsNew(page)
Definition: bufpage.h:225
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:41