PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
bufmgr.h File Reference
#include "storage/block.h"
#include "storage/buf.h"
#include "storage/bufpage.h"
#include "storage/relfilenode.h"
#include "utils/relcache.h"
#include "utils/snapmgr.h"
#include "utils/tqual.h"
Include dependency graph for bufmgr.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MAX_IO_CONCURRENCY   1000
 
#define P_NEW   InvalidBlockNumber /* grow the file to get a new page */
 
#define BUFFER_LOCK_UNLOCK   0
 
#define BUFFER_LOCK_SHARE   1
 
#define BUFFER_LOCK_EXCLUSIVE   2
 
#define BufferIsValid(bufnum)
 
#define BufferGetBlock(buffer)
 
#define BufferGetPageSize(buffer)
 
#define BufferGetPage(buffer)   ((Page)BufferGetBlock(buffer))
 
#define RelationGetNumberOfBlocks(reln)   RelationGetNumberOfBlocksInFork(reln, MAIN_FORKNUM)
 

Typedefs

typedef void * Block
 
typedef enum
BufferAccessStrategyType 
BufferAccessStrategyType
 

Enumerations

enum  BufferAccessStrategyType { BAS_NORMAL, BAS_BULKREAD, BAS_BULKWRITE, BAS_VACUUM }
 
enum  ReadBufferMode {
  RBM_NORMAL, RBM_ZERO_AND_LOCK, RBM_ZERO_AND_CLEANUP_LOCK, RBM_ZERO_ON_ERROR,
  RBM_NORMAL_NO_LOG
}
 

Functions

bool ComputeIoConcurrency (int io_concurrency, double *target)
 
void PrefetchBuffer (Relation reln, ForkNumber forkNum, BlockNumber blockNum)
 
Buffer ReadBuffer (Relation reln, BlockNumber blockNum)
 
Buffer ReadBufferExtended (Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
 
Buffer ReadBufferWithoutRelcache (RelFileNode rnode, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
 
void ReleaseBuffer (Buffer buffer)
 
void UnlockReleaseBuffer (Buffer buffer)
 
void MarkBufferDirty (Buffer buffer)
 
void IncrBufferRefCount (Buffer buffer)
 
Buffer ReleaseAndReadBuffer (Buffer buffer, Relation relation, BlockNumber blockNum)
 
void InitBufferPool (void)
 
void InitBufferPoolAccess (void)
 
void InitBufferPoolBackend (void)
 
void AtEOXact_Buffers (bool isCommit)
 
void PrintBufferLeakWarning (Buffer buffer)
 
void CheckPointBuffers (int flags)
 
BlockNumber BufferGetBlockNumber (Buffer buffer)
 
BlockNumber RelationGetNumberOfBlocksInFork (Relation relation, ForkNumber forkNum)
 
void FlushOneBuffer (Buffer buffer)
 
void FlushRelationBuffers (Relation rel)
 
void FlushDatabaseBuffers (Oid dbid)
 
void DropRelFileNodeBuffers (RelFileNodeBackend rnode, ForkNumber forkNum, BlockNumber firstDelBlock)
 
void DropRelFileNodesAllBuffers (RelFileNodeBackend *rnodes, int nnodes)
 
void DropDatabaseBuffers (Oid dbid)
 
bool BufferIsPermanent (Buffer buffer)
 
XLogRecPtr BufferGetLSNAtomic (Buffer buffer)
 
Size BufferShmemSize (void)
 
void BufferGetTag (Buffer buffer, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
 
void MarkBufferDirtyHint (Buffer buffer, bool buffer_std)
 
void UnlockBuffers (void)
 
void LockBuffer (Buffer buffer, int mode)
 
bool ConditionalLockBuffer (Buffer buffer)
 
void LockBufferForCleanup (Buffer buffer)
 
bool ConditionalLockBufferForCleanup (Buffer buffer)
 
bool IsBufferCleanupOK (Buffer buffer)
 
bool HoldingBufferPinThatDelaysRecovery (void)
 
void AbortBufferIO (void)
 
void BufmgrCommit (void)
 
bool BgBufferSync (struct WritebackContext *wb_context)
 
void AtProcExit_LocalBuffers (void)
 
void TestForOldSnapshot_impl (Snapshot snapshot, Relation relation)
 
BufferAccessStrategy GetAccessStrategy (BufferAccessStrategyType btype)
 
void FreeAccessStrategy (BufferAccessStrategy strategy)
 
static void TestForOldSnapshot (Snapshot snapshot, Relation relation, Page page)
 

Variables

PGDLLIMPORT int NBuffers
 
bool zero_damaged_pages
 
int bgwriter_lru_maxpages
 
double bgwriter_lru_multiplier
 
bool track_io_timing
 
int target_prefetch_pages
 
int checkpoint_flush_after
 
int backend_flush_after
 
int bgwriter_flush_after
 
PGDLLIMPORT char * BufferBlocks
 
int effective_io_concurrency
 
PGDLLIMPORT int NLocBuffer
 
PGDLLIMPORT BlockLocalBufferBlockPointers
 
PGDLLIMPORT int32LocalRefCount
 

Macro Definition Documentation

#define BUFFER_LOCK_UNLOCK   0

Definition at line 87 of file bufmgr.h.

Referenced by _bt_doinsert(), _bt_drop_lock_and_maybe_pin(), _bt_endpoint(), _bt_first(), _bt_getroot(), _bt_killitems(), _bt_moveright(), _bt_pagedel(), _bt_relandgetbuf(), _bt_unlink_halfdead_page(), _hash_addovflpage(), _hash_doinsert(), _hash_expandtable(), _hash_finish_split(), _hash_first(), _hash_freeovflpage(), _hash_getcachedmetap(), _hash_getovflpage(), _hash_metapinit(), _hash_readnext(), _hash_readprev(), _hash_splitbucket_guts(), _hash_squeezebucket(), bitgetpage(), blinsert(), BloomNewBuffer(), brin_doinsert(), brin_doupdate(), brin_evacuate_page(), brin_getinsertbuffer(), brin_page_cleanup(), bringetbitmap(), brinGetTupleForHeapBlock(), brininsert(), brinRevmapInitialize(), brinsummarize(), btvacuumpage(), ConditionalLockBufferForCleanup(), copy_heap_data(), ExecCheckHeapTupleVisible(), fsm_search_avail(), fsm_vacuum_page(), get_raw_page_internal(), GetTupleForTrigger(), GetVisibilityMapPins(), hashbucketcleanup(), hashbulkdelete(), hashgettuple(), heap_abort_speculative(), heap_delete(), heap_fetch(), heap_hot_search(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_page_prune_opt(), heap_update(), heap_xlog_visible(), heapgetpage(), heapgettup(), index_fetch_heap(), IndexBuildHeapRangeScan(), lazy_scan_heap(), LockBuffer(), LockBufferForCleanup(), pgrowlocks(), pgstat_heap(), pgstatindex_impl(), RelationGetBufferForTuple(), revmap_physical_extend(), RI_FKey_check(), SpGistNewBuffer(), summarize_range(), systable_recheck_tuple(), tablesample_getnext(), UnlockReleaseBuffer(), validate_index_heapscan(), visibilitymap_clear(), visibilitymap_set(), and XLogReadBufferExtended().

#define BufferGetBlock (   buffer)
Value:
( \
BufferIsLocal(buffer) ? \
LocalBufferBlockPointers[-(buffer) - 1] \
: \
(Block) (BufferBlocks + ((Size) ((buffer) - 1)) * BLCKSZ) \
)
PGDLLIMPORT char * BufferBlocks
Definition: buf_init.c:22
#define AssertMacro(condition)
Definition: c.h:672
size_t Size
Definition: c.h:353
#define BufferIsLocal(buffer)
Definition: buf.h:37
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
PGDLLIMPORT Block * LocalBufferBlockPointers
Definition: localbuf.c:44
void * Block
Definition: bufmgr.h:25

Definition at line 127 of file bufmgr.h.

Referenced by XLogSaveBufferForHint().

#define BufferGetPage (   buffer)    ((Page)BufferGetBlock(buffer))

Definition at line 160 of file bufmgr.h.

Referenced by _bt_binsrch(), _bt_check_unique(), _bt_checkpage(), _bt_clear_incomplete_split(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_endpoint(), _bt_findinsertloc(), _bt_finish_split(), _bt_get_endpoint(), _bt_getbuf(), _bt_getroot(), _bt_getrootheight(), _bt_getstackbuf(), _bt_gettrueroot(), _bt_insert_parent(), _bt_insertonpg(), _bt_is_page_halfdead(), _bt_killitems(), _bt_lock_branch_parent(), _bt_mark_page_halfdead(), _bt_moveright(), _bt_newroot(), _bt_pagedel(), _bt_readnextpage(), _bt_readpage(), _bt_restore_meta(), _bt_search(), _bt_split(), _bt_unlink_halfdead_page(), _bt_vacuum_one_page(), _bt_walk_left(), _hash_addovflpage(), _hash_checkpage(), _hash_doinsert(), _hash_expandtable(), _hash_finish_split(), _hash_first(), _hash_freeovflpage(), _hash_get_newblock_from_oldbucket(), _hash_get_oldblock_from_newbucket(), _hash_getbucketbuf_from_hashkey(), _hash_getcachedmetap(), _hash_getinitbuf(), _hash_getnewbuf(), _hash_getovflpage(), _hash_initbitmap(), _hash_metapinit(), _hash_next(), _hash_pgaddtup(), _hash_readnext(), _hash_readprev(), _hash_splitbucket(), _hash_splitbucket_guts(), _hash_squeezebucket(), _hash_step(), acquire_sample_rows(), allocNewBuffer(), AlterSequence(), bitgetpage(), BitmapHeapNext(), blgetbitmap(), blinsert(), BloomNewBuffer(), blvacuumcleanup(), brin_can_do_samepage_update(), brin_doinsert(), brin_doupdate(), brin_evacuate_page(), brin_getinsertbuffer(), brin_initialize_empty_new_buffer(), brin_page_cleanup(), brin_start_evacuating_page(), brin_xlog_createidx(), brin_xlog_insert_update(), brin_xlog_revmap_extend(), brin_xlog_samepage_update(), brin_xlog_update(), brinbuild(), brinbuildempty(), brinGetTupleForHeapBlock(), brininsert(), brinRevmapInitialize(), brinSetHeapBlockItemptr(), bt_metap(), bt_page_items(), btree_xlog_delete(), btree_xlog_delete_get_latestRemovedXid(), btree_xlog_insert(), btree_xlog_mark_page_halfdead(), btree_xlog_newroot(), btree_xlog_split(), btree_xlog_unlink_page(), btree_xlog_vacuum(), btvacuumpage(), BufferGetLSNAtomic(), checkXLogConsistency(), collect_corrupt_items(), collect_visibility_data(), collectMatchBitmap(), collectMatchesForHeapRow(), count_nondeletable_pages(), createPostingTree(), dataBeginPlaceToPage(), dataBeginPlaceToPageInternal(), dataBeginPlaceToPageLeaf(), dataExecPlaceToPage(), dataExecPlaceToPageInternal(), dataLocateItem(), dataPlaceToPageLeafRecompress(), dataPrepareDownlink(), dataSplitPageInternal(), do_setval(), doPickSplit(), entryExecPlaceToPage(), entryIsEnoughSpace(), entryLoadMoreItems(), entryLocateEntry(), entryLocateLeafEntry(), entryPrepareDownlink(), entrySplitPage(), fill_seq_with_data(), FreeSpaceMapTruncateRel(), fsm_readbuf(), fsm_search(), fsm_search_avail(), fsm_set_and_search(), fsm_vacuum_page(), generic_redo(), GenericXLogFinish(), GenericXLogRegisterBuffer(), get_raw_page_internal(), GetBTPageStatistics(), GetRecordedFreeSpace(), GetTupleForTrigger(), GetVisibilityMapPins(), ginbuild(), ginbulkdelete(), ginDeletePage(), ginEntryInsert(), ginFindLeafPage(), ginFindParents(), ginFinishSplit(), ginGetStats(), ginHeapTupleFastInsert(), GinInitBuffer(), GinInitMetabuffer(), ginInsertCleanup(), ginInsertValue(), GinNewBuffer(), ginPlaceToPage(), ginRedoClearIncompleteSplit(), ginRedoCreateIndex(), ginRedoCreatePTree(), ginRedoDeleteListPages(), ginRedoDeletePage(), ginRedoInsert(), ginRedoInsertData(), ginRedoInsertEntry(), ginRedoInsertListPage(), ginRedoUpdateMetapage(), ginRedoVacuumDataLeafPage(), ginScanToDelete(), ginStepRight(), ginTraverseLock(), ginUpdateStats(), ginvacuumcleanup(), ginVacuumEntryPage(), ginVacuumPostingTreeLeaf(), ginVacuumPostingTreeLeaves(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistbuild(), gistbulkdelete(), gistcheckpage(), gistdoinsert(), gistFindCorrectParent(), gistFindPath(), gistfixsplit(), gistformdownlink(), gistGetMaxLevel(), GISTInitBuffer(), gistkillitems(), gistMemorizeAllDownlinks(), gistNewBuffer(), gistplacetopage(), gistProcessItup(), gistRedoClearFollowRight(), gistRedoCreateIndex(), gistRedoPageSplitRecord(), gistRedoPageUpdateRecord(), gistScanPage(), gistvacuumcleanup(), hash_bitmap_info(), hashbucketcleanup(), hashbulkdelete(), hashgetbitmap(), hashgettuple(), heap_abort_speculative(), heap_delete(), heap_fetch(), heap_finish_speculative(), heap_get_latest_tid(), heap_hot_search_buffer(), heap_inplace_update(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_page_is_all_visible(), heap_page_prune(), heap_page_prune_execute(), heap_page_prune_opt(), heap_prune_chain(), heap_update(), heap_xlog_clean(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_freeze_page(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), heapgetpage(), heapgettup(), heapgettup_pagemode(), IndexBuildHeapRangeScan(), initBloomState(), lazy_check_needs_freeze(), lazy_scan_heap(), lazy_vacuum_heap(), lazy_vacuum_page(), log_heap_update(), log_newpage_buffer(), MarkBufferDirtyHint(), moveLeafs(), moveRightIfItNeeded(), nextval_internal(), pg_visibility(), pgstat_btree_page(), pgstat_gist_page(), pgstat_hash_page(), pgstat_heap(), pgstatginindex_internal(), pgstathashindex(), pgstatindex_impl(), read_seq_tuple(), RelationAddExtraBlocks(), RelationGetBufferForTuple(), RelationPutHeapTuple(), revmap_physical_extend(), scanGetCandidate(), scanPendingInsert(), scanPostingTree(), seq_redo(), shiftList(), spgAddNodeAction(), spgbuild(), spgdoinsert(), spgGetCache(), SpGistGetBuffer(), SpGistInitBuffer(), SpGistNewBuffer(), SpGistSetLastUsedPage(), SpGistUpdateMetaPage(), spgprocesspending(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoCreateIndex(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoSplitTuple(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgRedoVacuumRoot(), spgSplitNodeAction(), spgvacuumpage(), spgWalk(), startScanEntry(), statapprox_heap(), tablesample_getnext(), terminate_brin_buildstate(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), validate_index_heapscan(), visibilitymap_clear(), visibilitymap_count(), visibilitymap_get_status(), visibilitymap_set(), visibilitymap_truncate(), vm_readbuf(), writeListPage(), XLogCheckBufferNeedsBackup(), XLogReadBufferExtended(), XLogReadBufferForRedoExtended(), XLogRecordPageWithFreeSpace(), XLogRegisterBuffer(), XLogSaveBufferForHint(), and xlogVacuumPage().

#define BufferIsValid (   bufnum)
Value:
( \
AssertMacro((bufnum) <= NBuffers && (bufnum) >= -NLocBuffer), \
(bufnum) != InvalidBuffer \
)
#define InvalidBuffer
Definition: buf.h:25
#define AssertMacro(condition)
Definition: c.h:672
PGDLLIMPORT int NLocBuffer
Definition: localbuf.c:41
PGDLLIMPORT int NBuffers
Definition: globals.c:122

Definition at line 114 of file bufmgr.h.

Referenced by _bt_clear_incomplete_split(), _bt_endpoint(), _bt_first(), _bt_get_endpoint(), _bt_insertonpg(), _bt_killitems(), _bt_readpage(), _bt_relandgetbuf(), _bt_search(), _bt_split(), _bt_unlink_halfdead_page(), _hash_dropscanbuf(), _hash_getbucketbuf_from_hashkey(), _hash_getcachedmetap(), _hash_next(), _hash_readnext(), _hash_readprev(), _hash_step(), brin_doinsert(), brin_doupdate(), brin_getinsertbuffer(), brin_xlog_createidx(), brin_xlog_insert_update(), brin_xlog_revmap_extend(), brin_xlog_samepage_update(), brin_xlog_update(), brinGetTupleForHeapBlock(), brininsert(), brinsummarize(), btree_xlog_delete(), btree_xlog_delete_get_latestRemovedXid(), btree_xlog_insert(), btree_xlog_mark_page_halfdead(), btree_xlog_split(), btree_xlog_unlink_page(), btree_xlog_vacuum(), BufferGetLSNAtomic(), BufferIsPermanent(), CheckForSerializableConflictIn(), checkXLogConsistency(), ConditionalLockBuffer(), ConditionalLockBufferForCleanup(), doPickSplit(), entryGetItem(), entryLoadMoreItems(), ExecClearTuple(), ExecDelete(), ExecMaterializeSlot(), ExecStoreMinimalTuple(), ExecStoreTuple(), FreeSpaceMapTruncateRel(), fsm_search(), fsm_vacuum_page(), generic_redo(), GetPrivateRefCount(), GetPrivateRefCountEntry(), GetRecordedFreeSpace(), GetVisibilityMapPins(), ginPlaceToPage(), ginRedoClearIncompleteSplit(), ginRedoDeletePage(), ginRedoInsert(), ginRedoUpdateMetapage(), ginRedoVacuumDataLeafPage(), gistinserttuples(), gistkillitems(), gistplacetopage(), gistRedoClearFollowRight(), gistRedoPageUpdateRecord(), gistXLogSplit(), gistXLogUpdate(), hashgettuple(), heap_endscan(), heap_lock_tuple(), heap_rescan(), heap_update(), heap_xlog_clean(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_freeze_page(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), heapgetpage(), heapgettup(), heapgettup_pagemode(), index_endscan(), index_getnext(), index_getnext_tid(), index_rescan(), IsBufferCleanupOK(), lazy_scan_heap(), lazy_vacuum_heap(), lazy_vacuum_page(), LockBuffer(), LockBufferForCleanup(), log_heap_visible(), MarkBufferDirty(), MarkBufferDirtyHint(), PrintBufferLeakWarning(), ReleaseAndReadBuffer(), ReleaseBuffer(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoSplitTuple(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgRedoVacuumRoot(), statapprox_heap(), systable_recheck_tuple(), tablesample_getnext(), visibilitymap_clear(), visibilitymap_count(), visibilitymap_get_status(), visibilitymap_pin(), visibilitymap_pin_ok(), visibilitymap_set(), visibilitymap_truncate(), and XLogReadBufferForRedoExtended().

#define MAX_IO_CONCURRENCY   1000

Definition at line 79 of file bufmgr.h.

Referenced by ComputeIoConcurrency().

Typedef Documentation

typedef void* Block

Definition at line 25 of file bufmgr.h.

Enumeration Type Documentation

Enumerator
BAS_NORMAL 
BAS_BULKREAD 
BAS_BULKWRITE 
BAS_VACUUM 

Definition at line 28 of file bufmgr.h.

29 {
30  BAS_NORMAL, /* Normal random access */
31  BAS_BULKREAD, /* Large read-only scan (hint bit updates are
32  * ok) */
33  BAS_BULKWRITE, /* Large multi-block write (e.g. COPY IN) */
34  BAS_VACUUM /* VACUUM */
BufferAccessStrategyType
Definition: bufmgr.h:28
Enumerator
RBM_NORMAL 
RBM_ZERO_AND_LOCK 
RBM_ZERO_AND_CLEANUP_LOCK 
RBM_ZERO_ON_ERROR 
RBM_NORMAL_NO_LOG 

Definition at line 38 of file bufmgr.h.

39 {
40  RBM_NORMAL, /* Normal read */
41  RBM_ZERO_AND_LOCK, /* Don't read from disk, caller will
42  * initialize. Also locks the page. */
43  RBM_ZERO_AND_CLEANUP_LOCK, /* Like RBM_ZERO_AND_LOCK, but locks the page
44  * in "cleanup" mode */
45  RBM_ZERO_ON_ERROR, /* Read, but return an all-zeros page on error */
46  RBM_NORMAL_NO_LOG /* Don't log page as invalid during WAL
47  * replay; otherwise same as RBM_NORMAL */
ReadBufferMode
Definition: bufmgr.h:38

Function Documentation

void AbortBufferIO ( void  )

Definition at line 3957 of file bufmgr.c.

References Assert, buftag::blockNum, BM_DIRTY, BM_IO_ERROR, BM_IO_IN_PROGRESS, BM_VALID, BufferDescriptorGetIOLock, ereport, errcode(), errdetail(), errmsg(), buftag::forkNum, InProgressBuf, IsForInput, LockBufHdr(), LW_EXCLUSIVE, LWLockAcquire(), pfree(), relpathperm, buftag::rnode, BufferDesc::tag, TerminateBufferIO(), UnlockBufHdr, and WARNING.

Referenced by AbortSubTransaction(), AbortTransaction(), AtProcExit_Buffers(), BackgroundWriterMain(), CheckpointerMain(), and WalWriterMain().

3958 {
3960 
3961  if (buf)
3962  {
3963  uint32 buf_state;
3964 
3965  /*
3966  * Since LWLockReleaseAll has already been called, we're not holding
3967  * the buffer's io_in_progress_lock. We have to re-acquire it so that
3968  * we can use TerminateBufferIO. Anyone who's executing WaitIO on the
3969  * buffer will be in a busy spin until we succeed in doing this.
3970  */
3972 
3973  buf_state = LockBufHdr(buf);
3974  Assert(buf_state & BM_IO_IN_PROGRESS);
3975  if (IsForInput)
3976  {
3977  Assert(!(buf_state & BM_DIRTY));
3978 
3979  /* We'd better not think buffer is valid yet */
3980  Assert(!(buf_state & BM_VALID));
3981  UnlockBufHdr(buf, buf_state);
3982  }
3983  else
3984  {
3985  Assert(buf_state & BM_DIRTY);
3986  UnlockBufHdr(buf, buf_state);
3987  /* Issue notice if this is not the first failure... */
3988  if (buf_state & BM_IO_ERROR)
3989  {
3990  /* Buffer is pinned, so we can read tag without spinlock */
3991  char *path;
3992 
3993  path = relpathperm(buf->tag.rnode, buf->tag.forkNum);
3994  ereport(WARNING,
3995  (errcode(ERRCODE_IO_ERROR),
3996  errmsg("could not write block %u of %s",
3997  buf->tag.blockNum, path),
3998  errdetail("Multiple failures --- write error might be permanent.")));
3999  pfree(path);
4000  }
4001  }
4002  TerminateBufferIO(buf, false, BM_IO_ERROR);
4003  }
4004 }
#define relpathperm(rnode, forknum)
Definition: relpath.h:67
ForkNumber forkNum
Definition: buf_internals.h:94
int errcode(int sqlerrcode)
Definition: elog.c:575
#define BM_DIRTY
Definition: buf_internals.h:59
#define BufferDescriptorGetIOLock(bdesc)
static BufferDesc * InProgressBuf
Definition: bufmgr.c:132
void pfree(void *pointer)
Definition: mcxt.c:992
static char * buf
Definition: pg_test_fsync.c:65
int errdetail(const char *fmt,...)
Definition: elog.c:873
unsigned int uint32
Definition: c.h:265
static bool IsForInput
Definition: bufmgr.c:133
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
static void TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint32 set_flag_bits)
Definition: bufmgr.c:3925
#define BM_VALID
Definition: buf_internals.h:60
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
#define Assert(condition)
Definition: c.h:671
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1110
BlockNumber blockNum
Definition: buf_internals.h:95
RelFileNode rnode
Definition: buf_internals.h:93
#define BM_IO_ERROR
Definition: buf_internals.h:63
BufferTag tag
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define UnlockBufHdr(desc, s)
#define BM_IO_IN_PROGRESS
Definition: buf_internals.h:62
void AtEOXact_Buffers ( bool  isCommit)

Definition at line 2398 of file bufmgr.c.

References Assert, AtEOXact_LocalBuffers(), CheckForBufferLeaks(), and PrivateRefCountOverflowed.

Referenced by AbortTransaction(), BackgroundWriterMain(), CheckpointerMain(), CommitTransaction(), PrepareTransaction(), and WalWriterMain().

2399 {
2401 
2402  AtEOXact_LocalBuffers(isCommit);
2403 
2405 }
static int32 PrivateRefCountOverflowed
Definition: bufmgr.c:170
#define Assert(condition)
Definition: c.h:671
static void CheckForBufferLeaks(void)
Definition: bufmgr.c:2473
void AtEOXact_LocalBuffers(bool isCommit)
Definition: localbuf.c:572
void AtProcExit_LocalBuffers ( void  )

Definition at line 583 of file localbuf.c.

References CheckForLocalBufferLeaks().

Referenced by AtProcExit_Buffers().

584 {
585  /*
586  * We shouldn't be holding any remaining pins; if we are, and assertions
587  * aren't enabled, we'll fail later in DropRelFileNodeBuffers while trying
588  * to drop the temp rels.
589  */
591 }
static void CheckForLocalBufferLeaks(void)
Definition: localbuf.c:543
bool BgBufferSync ( struct WritebackContext wb_context)

Definition at line 2028 of file bufmgr.c.

References Assert, bgwriter_lru_maxpages, bgwriter_lru_multiplier, BgWriterDelay, BgWriterStats, BUF_REUSABLE, BUF_WRITTEN, CurrentResourceOwner, DEBUG1, DEBUG2, elog, PgStat_MsgBgWriter::m_buf_alloc, PgStat_MsgBgWriter::m_buf_written_clean, PgStat_MsgBgWriter::m_maxwritten_clean, NBuffers, ResourceOwnerEnlargeBuffers(), StrategySyncStart(), and SyncOneBuffer().

Referenced by BackgroundWriterMain().

2029 {
2030  /* info obtained from freelist.c */
2031  int strategy_buf_id;
2032  uint32 strategy_passes;
2033  uint32 recent_alloc;
2034 
2035  /*
2036  * Information saved between calls so we can determine the strategy
2037  * point's advance rate and avoid scanning already-cleaned buffers.
2038  */
2039  static bool saved_info_valid = false;
2040  static int prev_strategy_buf_id;
2041  static uint32 prev_strategy_passes;
2042  static int next_to_clean;
2043  static uint32 next_passes;
2044 
2045  /* Moving averages of allocation rate and clean-buffer density */
2046  static float smoothed_alloc = 0;
2047  static float smoothed_density = 10.0;
2048 
2049  /* Potentially these could be tunables, but for now, not */
2050  float smoothing_samples = 16;
2051  float scan_whole_pool_milliseconds = 120000.0;
2052 
2053  /* Used to compute how far we scan ahead */
2054  long strategy_delta;
2055  int bufs_to_lap;
2056  int bufs_ahead;
2057  float scans_per_alloc;
2058  int reusable_buffers_est;
2059  int upcoming_alloc_est;
2060  int min_scan_buffers;
2061 
2062  /* Variables for the scanning loop proper */
2063  int num_to_scan;
2064  int num_written;
2065  int reusable_buffers;
2066 
2067  /* Variables for final smoothed_density update */
2068  long new_strategy_delta;
2069  uint32 new_recent_alloc;
2070 
2071  /*
2072  * Find out where the freelist clock sweep currently is, and how many
2073  * buffer allocations have happened since our last call.
2074  */
2075  strategy_buf_id = StrategySyncStart(&strategy_passes, &recent_alloc);
2076 
2077  /* Report buffer alloc counts to pgstat */
2078  BgWriterStats.m_buf_alloc += recent_alloc;
2079 
2080  /*
2081  * If we're not running the LRU scan, just stop after doing the stats
2082  * stuff. We mark the saved state invalid so that we can recover sanely
2083  * if LRU scan is turned back on later.
2084  */
2085  if (bgwriter_lru_maxpages <= 0)
2086  {
2087  saved_info_valid = false;
2088  return true;
2089  }
2090 
2091  /*
2092  * Compute strategy_delta = how many buffers have been scanned by the
2093  * clock sweep since last time. If first time through, assume none. Then
2094  * see if we are still ahead of the clock sweep, and if so, how many
2095  * buffers we could scan before we'd catch up with it and "lap" it. Note:
2096  * weird-looking coding of xxx_passes comparisons are to avoid bogus
2097  * behavior when the passes counts wrap around.
2098  */
2099  if (saved_info_valid)
2100  {
2101  int32 passes_delta = strategy_passes - prev_strategy_passes;
2102 
2103  strategy_delta = strategy_buf_id - prev_strategy_buf_id;
2104  strategy_delta += (long) passes_delta *NBuffers;
2105 
2106  Assert(strategy_delta >= 0);
2107 
2108  if ((int32) (next_passes - strategy_passes) > 0)
2109  {
2110  /* we're one pass ahead of the strategy point */
2111  bufs_to_lap = strategy_buf_id - next_to_clean;
2112 #ifdef BGW_DEBUG
2113  elog(DEBUG2, "bgwriter ahead: bgw %u-%u strategy %u-%u delta=%ld lap=%d",
2114  next_passes, next_to_clean,
2115  strategy_passes, strategy_buf_id,
2116  strategy_delta, bufs_to_lap);
2117 #endif
2118  }
2119  else if (next_passes == strategy_passes &&
2120  next_to_clean >= strategy_buf_id)
2121  {
2122  /* on same pass, but ahead or at least not behind */
2123  bufs_to_lap = NBuffers - (next_to_clean - strategy_buf_id);
2124 #ifdef BGW_DEBUG
2125  elog(DEBUG2, "bgwriter ahead: bgw %u-%u strategy %u-%u delta=%ld lap=%d",
2126  next_passes, next_to_clean,
2127  strategy_passes, strategy_buf_id,
2128  strategy_delta, bufs_to_lap);
2129 #endif
2130  }
2131  else
2132  {
2133  /*
2134  * We're behind, so skip forward to the strategy point and start
2135  * cleaning from there.
2136  */
2137 #ifdef BGW_DEBUG
2138  elog(DEBUG2, "bgwriter behind: bgw %u-%u strategy %u-%u delta=%ld",
2139  next_passes, next_to_clean,
2140  strategy_passes, strategy_buf_id,
2141  strategy_delta);
2142 #endif
2143  next_to_clean = strategy_buf_id;
2144  next_passes = strategy_passes;
2145  bufs_to_lap = NBuffers;
2146  }
2147  }
2148  else
2149  {
2150  /*
2151  * Initializing at startup or after LRU scanning had been off. Always
2152  * start at the strategy point.
2153  */
2154 #ifdef BGW_DEBUG
2155  elog(DEBUG2, "bgwriter initializing: strategy %u-%u",
2156  strategy_passes, strategy_buf_id);
2157 #endif
2158  strategy_delta = 0;
2159  next_to_clean = strategy_buf_id;
2160  next_passes = strategy_passes;
2161  bufs_to_lap = NBuffers;
2162  }
2163 
2164  /* Update saved info for next time */
2165  prev_strategy_buf_id = strategy_buf_id;
2166  prev_strategy_passes = strategy_passes;
2167  saved_info_valid = true;
2168 
2169  /*
2170  * Compute how many buffers had to be scanned for each new allocation, ie,
2171  * 1/density of reusable buffers, and track a moving average of that.
2172  *
2173  * If the strategy point didn't move, we don't update the density estimate
2174  */
2175  if (strategy_delta > 0 && recent_alloc > 0)
2176  {
2177  scans_per_alloc = (float) strategy_delta / (float) recent_alloc;
2178  smoothed_density += (scans_per_alloc - smoothed_density) /
2179  smoothing_samples;
2180  }
2181 
2182  /*
2183  * Estimate how many reusable buffers there are between the current
2184  * strategy point and where we've scanned ahead to, based on the smoothed
2185  * density estimate.
2186  */
2187  bufs_ahead = NBuffers - bufs_to_lap;
2188  reusable_buffers_est = (float) bufs_ahead / smoothed_density;
2189 
2190  /*
2191  * Track a moving average of recent buffer allocations. Here, rather than
2192  * a true average we want a fast-attack, slow-decline behavior: we
2193  * immediately follow any increase.
2194  */
2195  if (smoothed_alloc <= (float) recent_alloc)
2196  smoothed_alloc = recent_alloc;
2197  else
2198  smoothed_alloc += ((float) recent_alloc - smoothed_alloc) /
2199  smoothing_samples;
2200 
2201  /* Scale the estimate by a GUC to allow more aggressive tuning. */
2202  upcoming_alloc_est = (int) (smoothed_alloc * bgwriter_lru_multiplier);
2203 
2204  /*
2205  * If recent_alloc remains at zero for many cycles, smoothed_alloc will
2206  * eventually underflow to zero, and the underflows produce annoying
2207  * kernel warnings on some platforms. Once upcoming_alloc_est has gone to
2208  * zero, there's no point in tracking smaller and smaller values of
2209  * smoothed_alloc, so just reset it to exactly zero to avoid this
2210  * syndrome. It will pop back up as soon as recent_alloc increases.
2211  */
2212  if (upcoming_alloc_est == 0)
2213  smoothed_alloc = 0;
2214 
2215  /*
2216  * Even in cases where there's been little or no buffer allocation
2217  * activity, we want to make a small amount of progress through the buffer
2218  * cache so that as many reusable buffers as possible are clean after an
2219  * idle period.
2220  *
2221  * (scan_whole_pool_milliseconds / BgWriterDelay) computes how many times
2222  * the BGW will be called during the scan_whole_pool time; slice the
2223  * buffer pool into that many sections.
2224  */
2225  min_scan_buffers = (int) (NBuffers / (scan_whole_pool_milliseconds / BgWriterDelay));
2226 
2227  if (upcoming_alloc_est < (min_scan_buffers + reusable_buffers_est))
2228  {
2229 #ifdef BGW_DEBUG
2230  elog(DEBUG2, "bgwriter: alloc_est=%d too small, using min=%d + reusable_est=%d",
2231  upcoming_alloc_est, min_scan_buffers, reusable_buffers_est);
2232 #endif
2233  upcoming_alloc_est = min_scan_buffers + reusable_buffers_est;
2234  }
2235 
2236  /*
2237  * Now write out dirty reusable buffers, working forward from the
2238  * next_to_clean point, until we have lapped the strategy scan, or cleaned
2239  * enough buffers to match our estimate of the next cycle's allocation
2240  * requirements, or hit the bgwriter_lru_maxpages limit.
2241  */
2242 
2243  /* Make sure we can handle the pin inside SyncOneBuffer */
2245 
2246  num_to_scan = bufs_to_lap;
2247  num_written = 0;
2248  reusable_buffers = reusable_buffers_est;
2249 
2250  /* Execute the LRU scan */
2251  while (num_to_scan > 0 && reusable_buffers < upcoming_alloc_est)
2252  {
2253  int sync_state = SyncOneBuffer(next_to_clean, true,
2254  wb_context);
2255 
2256  if (++next_to_clean >= NBuffers)
2257  {
2258  next_to_clean = 0;
2259  next_passes++;
2260  }
2261  num_to_scan--;
2262 
2263  if (sync_state & BUF_WRITTEN)
2264  {
2265  reusable_buffers++;
2266  if (++num_written >= bgwriter_lru_maxpages)
2267  {
2269  break;
2270  }
2271  }
2272  else if (sync_state & BUF_REUSABLE)
2273  reusable_buffers++;
2274  }
2275 
2276  BgWriterStats.m_buf_written_clean += num_written;
2277 
2278 #ifdef BGW_DEBUG
2279  elog(DEBUG1, "bgwriter: recent_alloc=%u smoothed=%.2f delta=%ld ahead=%d density=%.2f reusable_est=%d upcoming_est=%d scanned=%d wrote=%d reusable=%d",
2280  recent_alloc, smoothed_alloc, strategy_delta, bufs_ahead,
2281  smoothed_density, reusable_buffers_est, upcoming_alloc_est,
2282  bufs_to_lap - num_to_scan,
2283  num_written,
2284  reusable_buffers - reusable_buffers_est);
2285 #endif
2286 
2287  /*
2288  * Consider the above scan as being like a new allocation scan.
2289  * Characterize its density and update the smoothed one based on it. This
2290  * effectively halves the moving average period in cases where both the
2291  * strategy and the background writer are doing some useful scanning,
2292  * which is helpful because a long memory isn't as desirable on the
2293  * density estimates.
2294  */
2295  new_strategy_delta = bufs_to_lap - num_to_scan;
2296  new_recent_alloc = reusable_buffers - reusable_buffers_est;
2297  if (new_strategy_delta > 0 && new_recent_alloc > 0)
2298  {
2299  scans_per_alloc = (float) new_strategy_delta / (float) new_recent_alloc;
2300  smoothed_density += (scans_per_alloc - smoothed_density) /
2301  smoothing_samples;
2302 
2303 #ifdef BGW_DEBUG
2304  elog(DEBUG2, "bgwriter: cleaner density alloc=%u scan=%ld density=%.2f new smoothed=%.2f",
2305  new_recent_alloc, new_strategy_delta,
2306  scans_per_alloc, smoothed_density);
2307 #endif
2308  }
2309 
2310  /* Return true if OK to hibernate */
2311  return (bufs_to_lap == 0 && recent_alloc == 0);
2312 }
PgStat_Counter m_buf_alloc
Definition: pgstat.h:420
int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc)
Definition: freelist.c:378
#define DEBUG1
Definition: elog.h:25
int BgWriterDelay
Definition: bgwriter.c:67
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
PgStat_Counter m_maxwritten_clean
Definition: pgstat.h:417
PgStat_Counter m_buf_written_clean
Definition: pgstat.h:416
PgStat_MsgBgWriter BgWriterStats
Definition: pgstat.c:127
double bgwriter_lru_multiplier
Definition: bufmgr.c:110
signed int int32
Definition: c.h:253
#define BUF_REUSABLE
Definition: bufmgr.c:66
int bgwriter_lru_maxpages
Definition: bufmgr.c:109
#define DEBUG2
Definition: elog.h:24
unsigned int uint32
Definition: c.h:265
#define BUF_WRITTEN
Definition: bufmgr.c:65
void ResourceOwnerEnlargeBuffers(ResourceOwner owner)
Definition: resowner.c:839
static int SyncOneBuffer(int buf_id, bool skip_recently_used, WritebackContext *flush_context)
Definition: bufmgr.c:2331
#define Assert(condition)
Definition: c.h:671
int NBuffers
Definition: globals.c:122
#define elog
Definition: elog.h:219
BlockNumber BufferGetBlockNumber ( Buffer  buffer)

Definition at line 2588 of file bufmgr.c.

References Assert, buftag::blockNum, BufferIsLocal, BufferIsPinned, GetBufferDescriptor, GetLocalBufferDescriptor, and BufferDesc::tag.

Referenced by _bt_checkpage(), _bt_endpoint(), _bt_finish_split(), _bt_first(), _bt_getroot(), _bt_insert_parent(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_moveright(), _bt_newroot(), _bt_pagedel(), _bt_readnextpage(), _bt_readpage(), _bt_restore_meta(), _bt_search(), _bt_split(), _bt_unlink_halfdead_page(), _bt_walk_left(), _hash_addovflpage(), _hash_checkpage(), _hash_freeovflpage(), _hash_getnewbuf(), _hash_step(), allocNewBuffer(), blinsert(), BloomInitMetapage(), brin_doinsert(), brin_doupdate(), brin_getinsertbuffer(), brin_initialize_empty_new_buffer(), brin_page_cleanup(), brin_xlog_insert_update(), brinbuild(), brinGetTupleForHeapBlock(), CheckForSerializableConflictIn(), createPostingTree(), dataBeginPlaceToPageLeaf(), dataPrepareDownlink(), doPickSplit(), entryPrepareDownlink(), fill_seq_with_data(), ginFindParents(), ginFinishSplit(), ginPlaceToPage(), ginRedoCreateIndex(), ginRedoDeleteListPages(), ginRedoUpdateMetapage(), gistbufferinginserttuples(), gistbuild(), gistcheckpage(), gistformdownlink(), gistMemorizeAllDownlinks(), gistplacetopage(), gistRedoCreateIndex(), gistRelocateBuildBuffersOnSplit(), heap_delete(), heap_hot_search_buffer(), heap_insert(), heap_multi_insert(), heap_page_is_all_visible(), heap_prune_chain(), heap_update(), heap_xlog_confirm(), heap_xlog_lock(), index_getnext(), makeSublist(), moveLeafs(), moveRightIfItNeeded(), pgstathashindex(), ReadBufferBI(), RelationAddExtraBlocks(), RelationGetBufferForTuple(), RelationPutHeapTuple(), revmap_get_buffer(), revmap_physical_extend(), spgAddNodeAction(), spgbuild(), spgdoinsert(), SpGistSetLastUsedPage(), spgRedoCreateIndex(), spgSplitNodeAction(), spgWalk(), terminate_brin_buildstate(), vacuumLeafPage(), visibilitymap_clear(), visibilitymap_get_status(), visibilitymap_pin(), visibilitymap_pin_ok(), visibilitymap_set(), and XLogReadBufferExtended().

2589 {
2590  BufferDesc *bufHdr;
2591 
2592  Assert(BufferIsPinned(buffer));
2593 
2594  if (BufferIsLocal(buffer))
2595  bufHdr = GetLocalBufferDescriptor(-buffer - 1);
2596  else
2597  bufHdr = GetBufferDescriptor(buffer - 1);
2598 
2599  /* pinned, so OK to read tag without spinlock */
2600  return bufHdr->tag.blockNum;
2601 }
#define BufferIsPinned(bufnum)
Definition: bufmgr.c:419
#define GetLocalBufferDescriptor(id)
#define GetBufferDescriptor(id)
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
BlockNumber blockNum
Definition: buf_internals.h:95
BufferTag tag
XLogRecPtr BufferGetLSNAtomic ( Buffer  buffer)

Definition at line 2815 of file bufmgr.c.

References Assert, BufferGetPage, BufferIsLocal, BufferIsPinned, BufferIsValid, GetBufferDescriptor, LockBufHdr(), PageGetLSN, UnlockBufHdr, and XLogHintBitIsNeeded.

Referenced by gistScanPage(), SetHintBits(), and XLogSaveBufferForHint().

2816 {
2817  BufferDesc *bufHdr = GetBufferDescriptor(buffer - 1);
2818  char *page = BufferGetPage(buffer);
2819  XLogRecPtr lsn;
2820  uint32 buf_state;
2821 
2822  /*
2823  * If we don't need locking for correctness, fastpath out.
2824  */
2825  if (!XLogHintBitIsNeeded() || BufferIsLocal(buffer))
2826  return PageGetLSN(page);
2827 
2828  /* Make sure we've got a real buffer, and that we hold a pin on it. */
2829  Assert(BufferIsValid(buffer));
2830  Assert(BufferIsPinned(buffer));
2831 
2832  buf_state = LockBufHdr(bufHdr);
2833  lsn = PageGetLSN(page);
2834  UnlockBufHdr(bufHdr, buf_state);
2835 
2836  return lsn;
2837 }
#define BufferIsPinned(bufnum)
Definition: bufmgr.c:419
#define GetBufferDescriptor(id)
unsigned int uint32
Definition: c.h:265
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define PageGetLSN(page)
Definition: bufpage.h:363
#define UnlockBufHdr(desc, s)
#define XLogHintBitIsNeeded()
Definition: xlog.h:156
void BufferGetTag ( Buffer  buffer,
RelFileNode rnode,
ForkNumber forknum,
BlockNumber blknum 
)

Definition at line 2609 of file bufmgr.c.

References Assert, buftag::blockNum, BufferIsLocal, BufferIsPinned, buftag::forkNum, GetBufferDescriptor, GetLocalBufferDescriptor, buftag::rnode, and BufferDesc::tag.

Referenced by fsm_search_avail(), ginRedoInsertEntry(), log_newpage_buffer(), ResolveCminCmaxDuringDecoding(), XLogRegisterBuffer(), and XLogSaveBufferForHint().

2611 {
2612  BufferDesc *bufHdr;
2613 
2614  /* Do the same checks as BufferGetBlockNumber. */
2615  Assert(BufferIsPinned(buffer));
2616 
2617  if (BufferIsLocal(buffer))
2618  bufHdr = GetLocalBufferDescriptor(-buffer - 1);
2619  else
2620  bufHdr = GetBufferDescriptor(buffer - 1);
2621 
2622  /* pinned, so OK to read tag without spinlock */
2623  *rnode = bufHdr->tag.rnode;
2624  *forknum = bufHdr->tag.forkNum;
2625  *blknum = bufHdr->tag.blockNum;
2626 }
#define BufferIsPinned(bufnum)
Definition: bufmgr.c:419
ForkNumber forkNum
Definition: buf_internals.h:94
#define GetLocalBufferDescriptor(id)
#define GetBufferDescriptor(id)
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
BlockNumber blockNum
Definition: buf_internals.h:95
RelFileNode rnode
Definition: buf_internals.h:93
BufferTag tag
bool BufferIsPermanent ( Buffer  buffer)

Definition at line 2785 of file bufmgr.c.

References Assert, BM_PERMANENT, BufferIsLocal, BufferIsPinned, BufferIsValid, GetBufferDescriptor, pg_atomic_read_u32(), and BufferDesc::state.

Referenced by SetHintBits().

2786 {
2787  BufferDesc *bufHdr;
2788 
2789  /* Local buffers are used only for temp relations. */
2790  if (BufferIsLocal(buffer))
2791  return false;
2792 
2793  /* Make sure we've got a real buffer, and that we hold a pin on it. */
2794  Assert(BufferIsValid(buffer));
2795  Assert(BufferIsPinned(buffer));
2796 
2797  /*
2798  * BM_PERMANENT can't be changed while we hold a pin on the buffer, so we
2799  * need not bother with the buffer header spinlock. Even if someone else
2800  * changes the buffer header state while we're doing this, the state is
2801  * changed atomically, so we'll read the old value or the new value, but
2802  * not random garbage.
2803  */
2804  bufHdr = GetBufferDescriptor(buffer - 1);
2805  return (pg_atomic_read_u32(&bufHdr->state) & BM_PERMANENT) != 0;
2806 }
#define BufferIsPinned(bufnum)
Definition: bufmgr.c:419
#define BM_PERMANENT
Definition: buf_internals.h:67
#define GetBufferDescriptor(id)
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
pg_atomic_uint32 state
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:251
Size BufferShmemSize ( void  )

Definition at line 161 of file buf_init.c.

References add_size(), mul_size(), NBuffers, PG_CACHE_LINE_SIZE, and StrategyShmemSize().

Referenced by CreateSharedMemoryAndSemaphores().

162 {
163  Size size = 0;
164 
165  /* size of buffer descriptors */
166  size = add_size(size, mul_size(NBuffers, sizeof(BufferDescPadded)));
167  /* to allow aligning buffer descriptors */
168  size = add_size(size, PG_CACHE_LINE_SIZE);
169 
170  /* size of data pages */
171  size = add_size(size, mul_size(NBuffers, BLCKSZ));
172 
173  /* size of stuff controlled by freelist.c */
174  size = add_size(size, StrategyShmemSize());
175 
176  /*
177  * It would be nice to include the I/O locks in the BufferDesc, but that
178  * would increase the size of a BufferDesc to more than one cache line,
179  * and benchmarking has shown that keeping every BufferDesc aligned on a
180  * cache line boundary is important for performance. So, instead, the
181  * array of I/O locks is allocated in a separate tranche. Because those
182  * locks are not highly contentended, we lay out the array with minimal
183  * padding.
184  */
185  size = add_size(size, mul_size(NBuffers, sizeof(LWLockMinimallyPadded)));
186  /* to allow aligning the above */
187  size = add_size(size, PG_CACHE_LINE_SIZE);
188 
189  /* size of checkpoint sort array in bufmgr.c */
190  size = add_size(size, mul_size(NBuffers, sizeof(CkptSortItem)));
191 
192  return size;
193 }
#define PG_CACHE_LINE_SIZE
Size mul_size(Size s1, Size s2)
Definition: shmem.c:492
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
size_t Size
Definition: c.h:353
int NBuffers
Definition: globals.c:122
Size StrategyShmemSize(void)
Definition: freelist.c:437
void BufmgrCommit ( void  )

Definition at line 2574 of file bufmgr.c.

Referenced by PrepareTransaction(), and RecordTransactionCommit().

2575 {
2576  /* Nothing to do in bufmgr anymore... */
2577 }
void CheckPointBuffers ( int  flags)

Definition at line 2557 of file bufmgr.c.

References BufferSync(), CheckpointStats, CheckpointStatsData::ckpt_sync_end_t, CheckpointStatsData::ckpt_sync_t, CheckpointStatsData::ckpt_write_t, GetCurrentTimestamp(), and smgrsync().

Referenced by CheckPointGuts().

2558 {
2559  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags);
2561  BufferSync(flags);
2563  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START();
2564  smgrsync();
2566  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE();
2567 }
TimestampTz ckpt_sync_end_t
Definition: xlog.h:202
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
static void BufferSync(int flags)
Definition: bufmgr.c:1761
CheckpointStatsData CheckpointStats
Definition: xlog.c:172
TimestampTz ckpt_write_t
Definition: xlog.h:200
TimestampTz ckpt_sync_t
Definition: xlog.h:201
void smgrsync(void)
Definition: smgr.c:759
bool ComputeIoConcurrency ( int  io_concurrency,
double *  target 
)

Definition at line 467 of file bufmgr.c.

References i, Max, MAX_IO_CONCURRENCY, and Min.

Referenced by check_effective_io_concurrency(), and ExecInitBitmapHeapScan().

468 {
469  double new_prefetch_pages = 0.0;
470  int i;
471 
472  /*
473  * Make sure the io_concurrency value is within valid range; it may have
474  * been forced with a manual pg_tablespace update.
475  */
476  io_concurrency = Min(Max(io_concurrency, 0), MAX_IO_CONCURRENCY);
477 
478  /*----------
479  * The user-visible GUC parameter is the number of drives (spindles),
480  * which we need to translate to a number-of-pages-to-prefetch target.
481  * The target value is stashed in *extra and then assigned to the actual
482  * variable by assign_effective_io_concurrency.
483  *
484  * The expected number of prefetch pages needed to keep N drives busy is:
485  *
486  * drives | I/O requests
487  * -------+----------------
488  * 1 | 1
489  * 2 | 2/1 + 2/2 = 3
490  * 3 | 3/1 + 3/2 + 3/3 = 5 1/2
491  * 4 | 4/1 + 4/2 + 4/3 + 4/4 = 8 1/3
492  * n | n * H(n)
493  *
494  * This is called the "coupon collector problem" and H(n) is called the
495  * harmonic series. This could be approximated by n * ln(n), but for
496  * reasonable numbers of drives we might as well just compute the series.
497  *
498  * Alternatively we could set the target to the number of pages necessary
499  * so that the expected number of active spindles is some arbitrary
500  * percentage of the total. This sounds the same but is actually slightly
501  * different. The result ends up being ln(1-P)/ln((n-1)/n) where P is
502  * that desired fraction.
503  *
504  * Experimental results show that both of these formulas aren't aggressive
505  * enough, but we don't really have any better proposals.
506  *
507  * Note that if io_concurrency = 0 (disabled), we must set target = 0.
508  *----------
509  */
510 
511  for (i = 1; i <= io_concurrency; i++)
512  new_prefetch_pages += (double) io_concurrency / (double) i;
513 
514  *target = new_prefetch_pages;
515 
516  /* This range check shouldn't fail, but let's be paranoid */
517  return (new_prefetch_pages >= 0.0 && new_prefetch_pages < (double) INT_MAX);
518 }
#define MAX_IO_CONCURRENCY
Definition: bufmgr.h:79
#define Min(x, y)
Definition: c.h:802
#define Max(x, y)
Definition: c.h:796
int i
bool ConditionalLockBuffer ( Buffer  buffer)

Definition at line 3555 of file bufmgr.c.

References Assert, buf, BufferDescriptorGetContentLock, BufferIsLocal, BufferIsValid, GetBufferDescriptor, LW_EXCLUSIVE, and LWLockConditionalAcquire().

Referenced by _bt_getbuf(), BloomNewBuffer(), ConditionalLockBufferForCleanup(), GinNewBuffer(), gistNewBuffer(), spgdoinsert(), SpGistGetBuffer(), SpGistNewBuffer(), and SpGistUpdateMetaPage().

3556 {
3557  BufferDesc *buf;
3558 
3559  Assert(BufferIsValid(buffer));
3560  if (BufferIsLocal(buffer))
3561  return true; /* act as though we got it */
3562 
3563  buf = GetBufferDescriptor(buffer - 1);
3564 
3566  LW_EXCLUSIVE);
3567 }
bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1282
static char * buf
Definition: pg_test_fsync.c:65
#define GetBufferDescriptor(id)
#define BufferDescriptorGetContentLock(bdesc)
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
bool ConditionalLockBufferForCleanup ( Buffer  buffer)

Definition at line 3701 of file bufmgr.c.

References Assert, BUF_STATE_GET_REFCOUNT, BUFFER_LOCK_UNLOCK, BufferIsLocal, BufferIsValid, ConditionalLockBuffer(), GetBufferDescriptor, GetPrivateRefCount(), LocalRefCount, LockBuffer(), LockBufHdr(), PrivateRefCountEntry::refcount, and UnlockBufHdr.

Referenced by _hash_finish_split(), _hash_getbuf_with_condlock_cleanup(), heap_page_prune_opt(), lazy_scan_heap(), and lazy_vacuum_heap().

3702 {
3703  BufferDesc *bufHdr;
3704  uint32 buf_state,
3705  refcount;
3706 
3707  Assert(BufferIsValid(buffer));
3708 
3709  if (BufferIsLocal(buffer))
3710  {
3711  refcount = LocalRefCount[-buffer - 1];
3712  /* There should be exactly one pin */
3713  Assert(refcount > 0);
3714  if (refcount != 1)
3715  return false;
3716  /* Nobody else to wait for */
3717  return true;
3718  }
3719 
3720  /* There should be exactly one local pin */
3721  refcount = GetPrivateRefCount(buffer);
3722  Assert(refcount);
3723  if (refcount != 1)
3724  return false;
3725 
3726  /* Try to acquire lock */
3727  if (!ConditionalLockBuffer(buffer))
3728  return false;
3729 
3730  bufHdr = GetBufferDescriptor(buffer - 1);
3731  buf_state = LockBufHdr(bufHdr);
3732  refcount = BUF_STATE_GET_REFCOUNT(buf_state);
3733 
3734  Assert(refcount > 0);
3735  if (refcount == 1)
3736  {
3737  /* Successfully acquired exclusive lock with pincount 1 */
3738  UnlockBufHdr(bufHdr, buf_state);
3739  return true;
3740  }
3741 
3742  /* Failed, so release the lock */
3743  UnlockBufHdr(bufHdr, buf_state);
3744  LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
3745  return false;
3746 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
#define GetBufferDescriptor(id)
static int32 GetPrivateRefCount(Buffer buffer)
Definition: bufmgr.c:358
unsigned int uint32
Definition: c.h:265
bool ConditionalLockBuffer(Buffer buffer)
Definition: bufmgr.c:3555
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define UnlockBufHdr(desc, s)
int32 * LocalRefCount
Definition: localbuf.c:45
#define BUF_STATE_GET_REFCOUNT(state)
Definition: buf_internals.h:49
void DropDatabaseBuffers ( Oid  dbid)

Definition at line 3026 of file bufmgr.c.

References RelFileNode::dbNode, GetBufferDescriptor, i, InvalidateBuffer(), LockBufHdr(), NBuffers, buftag::rnode, BufferDesc::tag, and UnlockBufHdr.

Referenced by dbase_redo(), dropdb(), and movedb().

3027 {
3028  int i;
3029 
3030  /*
3031  * We needn't consider local buffers, since by assumption the target
3032  * database isn't our own.
3033  */
3034 
3035  for (i = 0; i < NBuffers; i++)
3036  {
3037  BufferDesc *bufHdr = GetBufferDescriptor(i);
3038  uint32 buf_state;
3039 
3040  /*
3041  * As in DropRelFileNodeBuffers, an unlocked precheck should be safe
3042  * and saves some cycles.
3043  */
3044  if (bufHdr->tag.rnode.dbNode != dbid)
3045  continue;
3046 
3047  buf_state = LockBufHdr(bufHdr);
3048  if (bufHdr->tag.rnode.dbNode == dbid)
3049  InvalidateBuffer(bufHdr); /* releases spinlock */
3050  else
3051  UnlockBufHdr(bufHdr, buf_state);
3052  }
3053 }
static void InvalidateBuffer(BufferDesc *buf)
Definition: bufmgr.c:1347
#define GetBufferDescriptor(id)
unsigned int uint32
Definition: c.h:265
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
RelFileNode rnode
Definition: buf_internals.h:93
BufferTag tag
#define UnlockBufHdr(desc, s)
int i
int NBuffers
Definition: globals.c:122
void DropRelFileNodeBuffers ( RelFileNodeBackend  rnode,
ForkNumber  forkNum,
BlockNumber  firstDelBlock 
)

Definition at line 2866 of file bufmgr.c.

References RelFileNodeBackend::backend, buftag::blockNum, DropRelFileNodeLocalBuffers(), buftag::forkNum, GetBufferDescriptor, i, InvalidateBuffer(), LockBufHdr(), MyBackendId, NBuffers, RelFileNodeBackend::node, RelFileNodeBackendIsTemp, RelFileNodeEquals, buftag::rnode, BufferDesc::tag, and UnlockBufHdr.

Referenced by smgrdounlinkfork(), and smgrtruncate().

2868 {
2869  int i;
2870 
2871  /* If it's a local relation, it's localbuf.c's problem. */
2872  if (RelFileNodeBackendIsTemp(rnode))
2873  {
2874  if (rnode.backend == MyBackendId)
2875  DropRelFileNodeLocalBuffers(rnode.node, forkNum, firstDelBlock);
2876  return;
2877  }
2878 
2879  for (i = 0; i < NBuffers; i++)
2880  {
2881  BufferDesc *bufHdr = GetBufferDescriptor(i);
2882  uint32 buf_state;
2883 
2884  /*
2885  * We can make this a tad faster by prechecking the buffer tag before
2886  * we attempt to lock the buffer; this saves a lot of lock
2887  * acquisitions in typical cases. It should be safe because the
2888  * caller must have AccessExclusiveLock on the relation, or some other
2889  * reason to be certain that no one is loading new pages of the rel
2890  * into the buffer pool. (Otherwise we might well miss such pages
2891  * entirely.) Therefore, while the tag might be changing while we
2892  * look at it, it can't be changing *to* a value we care about, only
2893  * *away* from such a value. So false negatives are impossible, and
2894  * false positives are safe because we'll recheck after getting the
2895  * buffer lock.
2896  *
2897  * We could check forkNum and blockNum as well as the rnode, but the
2898  * incremental win from doing so seems small.
2899  */
2900  if (!RelFileNodeEquals(bufHdr->tag.rnode, rnode.node))
2901  continue;
2902 
2903  buf_state = LockBufHdr(bufHdr);
2904  if (RelFileNodeEquals(bufHdr->tag.rnode, rnode.node) &&
2905  bufHdr->tag.forkNum == forkNum &&
2906  bufHdr->tag.blockNum >= firstDelBlock)
2907  InvalidateBuffer(bufHdr); /* releases spinlock */
2908  else
2909  UnlockBufHdr(bufHdr, buf_state);
2910  }
2911 }
BackendId MyBackendId
Definition: globals.c:72
#define RelFileNodeBackendIsTemp(rnode)
Definition: relfilenode.h:78
ForkNumber forkNum
Definition: buf_internals.h:94
static void InvalidateBuffer(BufferDesc *buf)
Definition: bufmgr.c:1347
void DropRelFileNodeLocalBuffers(RelFileNode rnode, ForkNumber forkNum, BlockNumber firstDelBlock)
Definition: localbuf.c:320
#define GetBufferDescriptor(id)
unsigned int uint32
Definition: c.h:265
RelFileNode node
Definition: relfilenode.h:74
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
BackendId backend
Definition: relfilenode.h:75
BlockNumber blockNum
Definition: buf_internals.h:95
RelFileNode rnode
Definition: buf_internals.h:93
BufferTag tag
#define UnlockBufHdr(desc, s)
int i
int NBuffers
Definition: globals.c:122
#define RelFileNodeEquals(node1, node2)
Definition: relfilenode.h:88
void DropRelFileNodesAllBuffers ( RelFileNodeBackend rnodes,
int  nnodes 
)

Definition at line 2923 of file bufmgr.c.

References DROP_RELS_BSEARCH_THRESHOLD, DropRelFileNodeAllLocalBuffers(), GetBufferDescriptor, i, InvalidateBuffer(), LockBufHdr(), MyBackendId, NBuffers, RelFileNodeBackend::node, NULL, palloc(), pfree(), pg_qsort(), RelFileNodeBackendIsTemp, RelFileNodeEquals, buftag::rnode, rnode_comparator(), BufferDesc::tag, and UnlockBufHdr.

Referenced by smgrdounlink(), and smgrdounlinkall().

2924 {
2925  int i,
2926  n = 0;
2927  RelFileNode *nodes;
2928  bool use_bsearch;
2929 
2930  if (nnodes == 0)
2931  return;
2932 
2933  nodes = palloc(sizeof(RelFileNode) * nnodes); /* non-local relations */
2934 
2935  /* If it's a local relation, it's localbuf.c's problem. */
2936  for (i = 0; i < nnodes; i++)
2937  {
2938  if (RelFileNodeBackendIsTemp(rnodes[i]))
2939  {
2940  if (rnodes[i].backend == MyBackendId)
2941  DropRelFileNodeAllLocalBuffers(rnodes[i].node);
2942  }
2943  else
2944  nodes[n++] = rnodes[i].node;
2945  }
2946 
2947  /*
2948  * If there are no non-local relations, then we're done. Release the
2949  * memory and return.
2950  */
2951  if (n == 0)
2952  {
2953  pfree(nodes);
2954  return;
2955  }
2956 
2957  /*
2958  * For low number of relations to drop just use a simple walk through, to
2959  * save the bsearch overhead. The threshold to use is rather a guess than
2960  * an exactly determined value, as it depends on many factors (CPU and RAM
2961  * speeds, amount of shared buffers etc.).
2962  */
2963  use_bsearch = n > DROP_RELS_BSEARCH_THRESHOLD;
2964 
2965  /* sort the list of rnodes if necessary */
2966  if (use_bsearch)
2967  pg_qsort(nodes, n, sizeof(RelFileNode), rnode_comparator);
2968 
2969  for (i = 0; i < NBuffers; i++)
2970  {
2971  RelFileNode *rnode = NULL;
2972  BufferDesc *bufHdr = GetBufferDescriptor(i);
2973  uint32 buf_state;
2974 
2975  /*
2976  * As in DropRelFileNodeBuffers, an unlocked precheck should be safe
2977  * and saves some cycles.
2978  */
2979 
2980  if (!use_bsearch)
2981  {
2982  int j;
2983 
2984  for (j = 0; j < n; j++)
2985  {
2986  if (RelFileNodeEquals(bufHdr->tag.rnode, nodes[j]))
2987  {
2988  rnode = &nodes[j];
2989  break;
2990  }
2991  }
2992  }
2993  else
2994  {
2995  rnode = bsearch((const void *) &(bufHdr->tag.rnode),
2996  nodes, n, sizeof(RelFileNode),
2998  }
2999 
3000  /* buffer doesn't belong to any of the given relfilenodes; skip it */
3001  if (rnode == NULL)
3002  continue;
3003 
3004  buf_state = LockBufHdr(bufHdr);
3005  if (RelFileNodeEquals(bufHdr->tag.rnode, (*rnode)))
3006  InvalidateBuffer(bufHdr); /* releases spinlock */
3007  else
3008  UnlockBufHdr(bufHdr, buf_state);
3009  }
3010 
3011  pfree(nodes);
3012 }
BackendId MyBackendId
Definition: globals.c:72
#define RelFileNodeBackendIsTemp(rnode)
Definition: relfilenode.h:78
static void InvalidateBuffer(BufferDesc *buf)
Definition: bufmgr.c:1347
#define DROP_RELS_BSEARCH_THRESHOLD
Definition: bufmgr.c:68
void DropRelFileNodeAllLocalBuffers(RelFileNode rnode)
Definition: localbuf.c:367
void pfree(void *pointer)
Definition: mcxt.c:992
#define GetBufferDescriptor(id)
unsigned int uint32
Definition: c.h:265
static int rnode_comparator(const void *p1, const void *p2)
Definition: bufmgr.c:4048
RelFileNode node
Definition: relfilenode.h:74
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
#define NULL
Definition: c.h:226
void pg_qsort(void *base, size_t nel, size_t elsize, int(*cmp)(const void *, const void *))
Definition: qsort.c:113
RelFileNode rnode
Definition: buf_internals.h:93
BufferTag tag
void * palloc(Size size)
Definition: mcxt.c:891
#define UnlockBufHdr(desc, s)
int i
int NBuffers
Definition: globals.c:122
#define RelFileNodeEquals(node1, node2)
Definition: relfilenode.h:88
void FlushDatabaseBuffers ( Oid  dbid)

Definition at line 3229 of file bufmgr.c.

References BM_DIRTY, BM_VALID, BufferDescriptorGetContentLock, CurrentResourceOwner, RelFileNode::dbNode, FlushBuffer(), GetBufferDescriptor, i, LockBufHdr(), LW_SHARED, LWLockAcquire(), LWLockRelease(), NBuffers, NULL, PinBuffer_Locked(), ReservePrivateRefCountEntry(), ResourceOwnerEnlargeBuffers(), buftag::rnode, BufferDesc::tag, UnlockBufHdr, and UnpinBuffer().

Referenced by dbase_redo().

3230 {
3231  int i;
3232  BufferDesc *bufHdr;
3233 
3234  /* Make sure we can handle the pin inside the loop */
3236 
3237  for (i = 0; i < NBuffers; i++)
3238  {
3239  uint32 buf_state;
3240 
3241  bufHdr = GetBufferDescriptor(i);
3242 
3243  /*
3244  * As in DropRelFileNodeBuffers, an unlocked precheck should be safe
3245  * and saves some cycles.
3246  */
3247  if (bufHdr->tag.rnode.dbNode != dbid)
3248  continue;
3249 
3251 
3252  buf_state = LockBufHdr(bufHdr);
3253  if (bufHdr->tag.rnode.dbNode == dbid &&
3254  (buf_state & (BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY))
3255  {
3256  PinBuffer_Locked(bufHdr);
3258  FlushBuffer(bufHdr, NULL);
3260  UnpinBuffer(bufHdr, true);
3261  }
3262  else
3263  UnlockBufHdr(bufHdr, buf_state);
3264  }
3265 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
#define BM_DIRTY
Definition: buf_internals.h:59
static void FlushBuffer(BufferDesc *buf, SMgrRelation reln)
Definition: bufmgr.c:2648
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1714
#define GetBufferDescriptor(id)
unsigned int uint32
Definition: c.h:265
static void UnpinBuffer(BufferDesc *buf, bool fixOwner)
Definition: bufmgr.c:1677
void ResourceOwnerEnlargeBuffers(ResourceOwner owner)
Definition: resowner.c:839
#define BM_VALID
Definition: buf_internals.h:60
#define BufferDescriptorGetContentLock(bdesc)
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
#define NULL
Definition: c.h:226
static void PinBuffer_Locked(BufferDesc *buf)
Definition: bufmgr.c:1639
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1110
RelFileNode rnode
Definition: buf_internals.h:93
BufferTag tag
#define UnlockBufHdr(desc, s)
int i
int NBuffers
Definition: globals.c:122
static void ReservePrivateRefCountEntry(void)
Definition: bufmgr.c:186
void FlushOneBuffer ( Buffer  buffer)

Definition at line 3272 of file bufmgr.c.

References Assert, BufferDescriptorGetContentLock, BufferIsLocal, BufferIsPinned, FlushBuffer(), GetBufferDescriptor, LWLockHeldByMe(), and NULL.

Referenced by XLogReadBufferForRedoExtended().

3273 {
3274  BufferDesc *bufHdr;
3275 
3276  /* currently not needed, but no fundamental reason not to support */
3277  Assert(!BufferIsLocal(buffer));
3278 
3279  Assert(BufferIsPinned(buffer));
3280 
3281  bufHdr = GetBufferDescriptor(buffer - 1);
3282 
3284 
3285  FlushBuffer(bufHdr, NULL);
3286 }
#define BufferIsPinned(bufnum)
Definition: bufmgr.c:419
bool LWLockHeldByMe(LWLock *l)
Definition: lwlock.c:1830
static void FlushBuffer(BufferDesc *buf, SMgrRelation reln)
Definition: bufmgr.c:2648
#define GetBufferDescriptor(id)
#define BufferDescriptorGetContentLock(bdesc)
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
void FlushRelationBuffers ( Relation  rel)

Definition at line 3131 of file bufmgr.c.

References ErrorContextCallback::arg, buftag::blockNum, BM_DIRTY, BM_JUST_DIRTIED, BM_VALID, BufferDescriptorGetContentLock, ErrorContextCallback::callback, CurrentResourceOwner, error_context_stack, FlushBuffer(), buftag::forkNum, GetBufferDescriptor, GetLocalBufferDescriptor, i, local_buffer_write_error_callback(), LocalBufHdrGetBlock, LockBufHdr(), LW_SHARED, LWLockAcquire(), LWLockRelease(), NBuffers, NLocBuffer, PageSetChecksumInplace(), pg_atomic_read_u32(), pg_atomic_unlocked_write_u32(), PinBuffer_Locked(), ErrorContextCallback::previous, RelationData::rd_node, RelationData::rd_smgr, RelationOpenSmgr, RelationUsesLocalBuffers, RelFileNodeEquals, ReservePrivateRefCountEntry(), ResourceOwnerEnlargeBuffers(), buftag::rnode, smgrwrite(), BufferDesc::state, BufferDesc::tag, UnlockBufHdr, and UnpinBuffer().

Referenced by ATExecSetTableSpace(), and heap_sync().

3132 {
3133  int i;
3134  BufferDesc *bufHdr;
3135 
3136  /* Open rel at the smgr level if not already done */
3137  RelationOpenSmgr(rel);
3138 
3139  if (RelationUsesLocalBuffers(rel))
3140  {
3141  for (i = 0; i < NLocBuffer; i++)
3142  {
3143  uint32 buf_state;
3144 
3145  bufHdr = GetLocalBufferDescriptor(i);
3146  if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node) &&
3147  ((buf_state = pg_atomic_read_u32(&bufHdr->state)) &
3148  (BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY))
3149  {
3150  ErrorContextCallback errcallback;
3151  Page localpage;
3152 
3153  localpage = (char *) LocalBufHdrGetBlock(bufHdr);
3154 
3155  /* Setup error traceback support for ereport() */
3157  errcallback.arg = (void *) bufHdr;
3158  errcallback.previous = error_context_stack;
3159  error_context_stack = &errcallback;
3160 
3161  PageSetChecksumInplace(localpage, bufHdr->tag.blockNum);
3162 
3163  smgrwrite(rel->rd_smgr,
3164  bufHdr->tag.forkNum,
3165  bufHdr->tag.blockNum,
3166  localpage,
3167  false);
3168 
3169  buf_state &= ~(BM_DIRTY | BM_JUST_DIRTIED);
3170  pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
3171 
3172  /* Pop the error context stack */
3173  error_context_stack = errcallback.previous;
3174  }
3175  }
3176 
3177  return;
3178  }
3179 
3180  /* Make sure we can handle the pin inside the loop */
3182 
3183  for (i = 0; i < NBuffers; i++)
3184  {
3185  uint32 buf_state;
3186 
3187  bufHdr = GetBufferDescriptor(i);
3188 
3189  /*
3190  * As in DropRelFileNodeBuffers, an unlocked precheck should be safe
3191  * and saves some cycles.
3192  */
3193  if (!RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
3194  continue;
3195 
3197 
3198  buf_state = LockBufHdr(bufHdr);
3199  if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node) &&
3200  (buf_state & (BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY))
3201  {
3202  PinBuffer_Locked(bufHdr);
3204  FlushBuffer(bufHdr, rel->rd_smgr);
3206  UnpinBuffer(bufHdr, true);
3207  }
3208  else
3209  UnlockBufHdr(bufHdr, buf_state);
3210  }
3211 }
#define LocalBufHdrGetBlock(bufHdr)
Definition: bufmgr.c:61
ForkNumber forkNum
Definition: buf_internals.h:94
static void local_buffer_write_error_callback(void *arg)
Definition: bufmgr.c:4029
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
#define GetLocalBufferDescriptor(id)
#define BM_DIRTY
Definition: buf_internals.h:59
struct ErrorContextCallback * previous
Definition: elog.h:238
static void FlushBuffer(BufferDesc *buf, SMgrRelation reln)
Definition: bufmgr.c:2648
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1714
ErrorContextCallback * error_context_stack
Definition: elog.c:88
#define RelationOpenSmgr(relation)
Definition: rel.h:457
int NLocBuffer
Definition: localbuf.c:41
void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync)
Definition: smgr.c:647
#define GetBufferDescriptor(id)
#define BM_JUST_DIRTIED
Definition: buf_internals.h:64
unsigned int uint32
Definition: c.h:265
static void UnpinBuffer(BufferDesc *buf, bool fixOwner)
Definition: bufmgr.c:1677
void ResourceOwnerEnlargeBuffers(ResourceOwner owner)
Definition: resowner.c:839
#define BM_VALID
Definition: buf_internals.h:60
RelFileNode rd_node
Definition: rel.h:85
#define BufferDescriptorGetContentLock(bdesc)
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
static void PinBuffer_Locked(BufferDesc *buf)
Definition: bufmgr.c:1639
void PageSetChecksumInplace(Page page, BlockNumber blkno)
Definition: bufpage.c:1172
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1110
BlockNumber blockNum
Definition: buf_internals.h:95
RelFileNode rnode
Definition: buf_internals.h:93
#define RelationUsesLocalBuffers(relation)
Definition: rel.h:509
BufferTag tag
void(* callback)(void *arg)
Definition: elog.h:239
#define UnlockBufHdr(desc, s)
int i
int NBuffers
Definition: globals.c:122
static void pg_atomic_unlocked_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:287
static void ReservePrivateRefCountEntry(void)
Definition: bufmgr.c:186
pg_atomic_uint32 state
Pointer Page
Definition: bufpage.h:74
#define RelFileNodeEquals(node1, node2)
Definition: relfilenode.h:88
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:251
void FreeAccessStrategy ( BufferAccessStrategy  strategy)

Definition at line 580 of file freelist.c.

References NULL, and pfree().

Referenced by blgetbitmap(), FreeBulkInsertState(), heap_endscan(), and initscan().

581 {
582  /* don't crash if called on a "default" strategy */
583  if (strategy != NULL)
584  pfree(strategy);
585 }
void pfree(void *pointer)
Definition: mcxt.c:992
#define NULL
Definition: c.h:226
BufferAccessStrategy GetAccessStrategy ( BufferAccessStrategyType  btype)

Definition at line 525 of file freelist.c.

References BAS_BULKREAD, BAS_BULKWRITE, BAS_NORMAL, BAS_VACUUM, BufferAccessStrategyData::btype, elog, ERROR, Min, NBuffers, NULL, offsetof, palloc0(), and BufferAccessStrategyData::ring_size.

Referenced by blgetbitmap(), collect_corrupt_items(), collect_visibility_data(), do_autovacuum(), GetBulkInsertState(), initscan(), pgstat_index(), pgstathashindex(), pgstatindex_impl(), statapprox_heap(), and vacuum().

526 {
527  BufferAccessStrategy strategy;
528  int ring_size;
529 
530  /*
531  * Select ring size to use. See buffer/README for rationales.
532  *
533  * Note: if you change the ring size for BAS_BULKREAD, see also
534  * SYNC_SCAN_REPORT_INTERVAL in access/heap/syncscan.c.
535  */
536  switch (btype)
537  {
538  case BAS_NORMAL:
539  /* if someone asks for NORMAL, just give 'em a "default" object */
540  return NULL;
541 
542  case BAS_BULKREAD:
543  ring_size = 256 * 1024 / BLCKSZ;
544  break;
545  case BAS_BULKWRITE:
546  ring_size = 16 * 1024 * 1024 / BLCKSZ;
547  break;
548  case BAS_VACUUM:
549  ring_size = 256 * 1024 / BLCKSZ;
550  break;
551 
552  default:
553  elog(ERROR, "unrecognized buffer access strategy: %d",
554  (int) btype);
555  return NULL; /* keep compiler quiet */
556  }
557 
558  /* Make sure ring isn't an undue fraction of shared buffers */
559  ring_size = Min(NBuffers / 8, ring_size);
560 
561  /* Allocate the object and initialize all elements to zeroes */
562  strategy = (BufferAccessStrategy)
564  ring_size * sizeof(Buffer));
565 
566  /* Set fields that don't start out zero */
567  strategy->btype = btype;
568  strategy->ring_size = ring_size;
569 
570  return strategy;
571 }
struct BufferAccessStrategyData * BufferAccessStrategy
Definition: buf.h:44
#define Min(x, y)
Definition: c.h:802
#define ERROR
Definition: elog.h:43
BufferAccessStrategyType btype
Definition: freelist.c:74
void * palloc0(Size size)
Definition: mcxt.c:920
#define NULL
Definition: c.h:226
int NBuffers
Definition: globals.c:122
#define elog
Definition: elog.h:219
int Buffer
Definition: buf.h:23
#define offsetof(type, field)
Definition: c.h:551
bool HoldingBufferPinThatDelaysRecovery ( void  )

Definition at line 3675 of file bufmgr.c.

References GetPrivateRefCount(), and GetStartupBufferPinWaitBufId().

Referenced by CheckRecoveryConflictDeadlock(), and RecoveryConflictInterrupt().

3676 {
3677  int bufid = GetStartupBufferPinWaitBufId();
3678 
3679  /*
3680  * If we get woken slowly then it's possible that the Startup process was
3681  * already woken by other backends before we got here. Also possible that
3682  * we get here by multiple interrupts or interrupts at inappropriate
3683  * times, so make sure we do nothing if the bufid is not set.
3684  */
3685  if (bufid < 0)
3686  return false;
3687 
3688  if (GetPrivateRefCount(bufid + 1) > 0)
3689  return true;
3690 
3691  return false;
3692 }
static int32 GetPrivateRefCount(Buffer buffer)
Definition: bufmgr.c:358
int GetStartupBufferPinWaitBufId(void)
Definition: proc.c:623
void IncrBufferRefCount ( Buffer  buffer)

Definition at line 3330 of file bufmgr.c.

References Assert, BufferIsLocal, BufferIsPinned, CurrentResourceOwner, GetPrivateRefCountEntry(), LocalRefCount, NULL, PrivateRefCountEntry::refcount, ResourceOwnerEnlargeBuffers(), and ResourceOwnerRememberBuffer().

Referenced by _bt_steppage(), btrestrpos(), entryLoadMoreItems(), ExecStoreTuple(), ReadBufferBI(), scanPostingTree(), and startScanEntry().

3331 {
3332  Assert(BufferIsPinned(buffer));
3335  if (BufferIsLocal(buffer))
3336  LocalRefCount[-buffer - 1]++;
3337  else
3338  {
3339  PrivateRefCountEntry *ref;
3340 
3341  ref = GetPrivateRefCountEntry(buffer, true);
3342  Assert(ref != NULL);
3343  ref->refcount++;
3344  }
3345 }
static PrivateRefCountEntry * GetPrivateRefCountEntry(Buffer buffer, bool do_move)
Definition: bufmgr.c:278
#define BufferIsPinned(bufnum)
Definition: bufmgr.c:419
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
void ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer)
Definition: resowner.c:855
void ResourceOwnerEnlargeBuffers(ResourceOwner owner)
Definition: resowner.c:839
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
int32 * LocalRefCount
Definition: localbuf.c:45
void InitBufferPool ( void  )

Definition at line 68 of file buf_init.c.

References Assert, backend_flush_after, buf, BufferDesc::buf_id, BufferBlocks, BufferDescriptorGetContentLock, BufferDescriptorGetIOLock, CLEAR_BUFFERTAG, BufferDesc::freeNext, FREENEXT_END_OF_LIST, GetBufferDescriptor, i, LWLockInitialize(), LWLockRegisterTranche(), LWTRANCHE_BUFFER_CONTENT, LWTRANCHE_BUFFER_IO_IN_PROGRESS, NBuffers, pg_atomic_init_u32(), ShmemInitStruct(), BufferDesc::state, StrategyInitialize(), BufferDesc::tag, BufferDesc::wait_backend_pid, and WritebackContextInit().

Referenced by CreateSharedMemoryAndSemaphores().

69 {
70  bool foundBufs,
71  foundDescs,
72  foundIOLocks,
73  foundBufCkpt;
74 
75  /* Align descriptors to a cacheline boundary. */
77  ShmemInitStruct("Buffer Descriptors",
78  NBuffers * sizeof(BufferDescPadded),
79  &foundDescs);
80 
81  BufferBlocks = (char *)
82  ShmemInitStruct("Buffer Blocks",
83  NBuffers * (Size) BLCKSZ, &foundBufs);
84 
85  /* Align lwlocks to cacheline boundary */
87  ShmemInitStruct("Buffer IO Locks",
89  &foundIOLocks);
90 
93 
94  /*
95  * The array used to sort to-be-checkpointed buffer ids is located in
96  * shared memory, to avoid having to allocate significant amounts of
97  * memory at runtime. As that'd be in the middle of a checkpoint, or when
98  * the checkpointer is restarted, memory allocation failures would be
99  * painful.
100  */
102  ShmemInitStruct("Checkpoint BufferIds",
103  NBuffers * sizeof(CkptSortItem), &foundBufCkpt);
104 
105  if (foundDescs || foundBufs || foundIOLocks || foundBufCkpt)
106  {
107  /* should find all of these, or none of them */
108  Assert(foundDescs && foundBufs && foundIOLocks && foundBufCkpt);
109  /* note: this path is only taken in EXEC_BACKEND case */
110  }
111  else
112  {
113  int i;
114 
115  /*
116  * Initialize all the buffer headers.
117  */
118  for (i = 0; i < NBuffers; i++)
119  {
121 
122  CLEAR_BUFFERTAG(buf->tag);
123 
124  pg_atomic_init_u32(&buf->state, 0);
125  buf->wait_backend_pid = 0;
126 
127  buf->buf_id = i;
128 
129  /*
130  * Initially link all the buffers together as unused. Subsequent
131  * management of this list is done by freelist.c.
132  */
133  buf->freeNext = i + 1;
134 
137 
140  }
141 
142  /* Correct last entry of linked list */
143  GetBufferDescriptor(NBuffers - 1)->freeNext = FREENEXT_END_OF_LIST;
144  }
145 
146  /* Init other shared buffer-management stuff */
147  StrategyInitialize(!foundDescs);
148 
149  /* Initialize per-backend file flush context */
152 }
#define FREENEXT_END_OF_LIST
LWLockMinimallyPadded * BufferIOLWLockArray
Definition: buf_init.c:23
int wait_backend_pid
int backend_flush_after
Definition: bufmgr.c:120
#define BufferDescriptorGetIOLock(bdesc)
void StrategyInitialize(bool init)
Definition: freelist.c:458
void WritebackContextInit(WritebackContext *context, int *max_pending)
Definition: bufmgr.c:4213
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:372
WritebackContext BackendWritebackContext
Definition: buf_init.c:24
static char * buf
Definition: pg_test_fsync.c:65
BufferDescPadded * BufferDescriptors
Definition: buf_init.c:21
#define GetBufferDescriptor(id)
union LWLockMinimallyPadded LWLockMinimallyPadded
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:666
#define BufferDescriptorGetContentLock(bdesc)
#define Assert(condition)
Definition: c.h:671
#define CLEAR_BUFFERTAG(a)
Definition: buf_internals.h:98
CkptSortItem * CkptBufferIds
Definition: buf_init.c:25
size_t Size
Definition: c.h:353
void LWLockRegisterTranche(int tranche_id, char *tranche_name)
Definition: lwlock.c:591
BufferTag tag
int i
int NBuffers
Definition: globals.c:122
pg_atomic_uint32 state
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:233
char * BufferBlocks
Definition: buf_init.c:22
void InitBufferPoolAccess ( void  )

Definition at line 2420 of file bufmgr.c.

References HASHCTL::entrysize, HASH_BLOBS, hash_create(), HASH_ELEM, HASHCTL::keysize, MemSet, and PrivateRefCountArray.

Referenced by BaseInit().

2421 {
2422  HASHCTL hash_ctl;
2423 
2424  memset(&PrivateRefCountArray, 0, sizeof(PrivateRefCountArray));
2425 
2426  MemSet(&hash_ctl, 0, sizeof(hash_ctl));
2427  hash_ctl.keysize = sizeof(int32);
2428  hash_ctl.entrysize = sizeof(PrivateRefCountEntry);
2429 
2430  PrivateRefCountHash = hash_create("PrivateRefCount", 100, &hash_ctl,
2431  HASH_ELEM | HASH_BLOBS);
2432 }
struct PrivateRefCountEntry PrivateRefCountEntry
#define HASH_ELEM
Definition: hsearch.h:87
Size entrysize
Definition: hsearch.h:73
#define MemSet(start, val, len)
Definition: c.h:853
signed int int32
Definition: c.h:253
static struct PrivateRefCountEntry PrivateRefCountArray[REFCOUNT_ARRAY_ENTRIES]
Definition: bufmgr.c:168
#define HASH_BLOBS
Definition: hsearch.h:88
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:301
Size keysize
Definition: hsearch.h:72
static HTAB * PrivateRefCountHash
Definition: bufmgr.c:169
void InitBufferPoolBackend ( void  )

Definition at line 2444 of file bufmgr.c.

References AtProcExit_Buffers(), and on_shmem_exit().

Referenced by AuxiliaryProcessMain(), and InitPostgres().

2445 {
2447 }
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:348
static void AtProcExit_Buffers(int code, Datum arg)
Definition: bufmgr.c:2454
bool IsBufferCleanupOK ( Buffer  buffer)

Definition at line 3757 of file bufmgr.c.

References Assert, BUF_STATE_GET_REFCOUNT, BufferDescriptorGetContentLock, BufferIsLocal, BufferIsValid, GetBufferDescriptor, GetPrivateRefCount(), LocalRefCount, LockBufHdr(), LW_EXCLUSIVE, LWLockHeldByMeInMode(), and UnlockBufHdr.

Referenced by _hash_doinsert(), _hash_expandtable(), and hashbucketcleanup().

3758 {
3759  BufferDesc *bufHdr;
3760  uint32 buf_state;
3761 
3762  Assert(BufferIsValid(buffer));
3763 
3764  if (BufferIsLocal(buffer))
3765  {
3766  /* There should be exactly one pin */
3767  if (LocalRefCount[-buffer - 1] != 1)
3768  return false;
3769  /* Nobody else to wait for */
3770  return true;
3771  }
3772 
3773  /* There should be exactly one local pin */
3774  if (GetPrivateRefCount(buffer) != 1)
3775  return false;
3776 
3777  bufHdr = GetBufferDescriptor(buffer - 1);
3778 
3779  /* caller must hold exclusive lock on buffer */
3781  LW_EXCLUSIVE));
3782 
3783  buf_state = LockBufHdr(bufHdr);
3784 
3785  Assert(BUF_STATE_GET_REFCOUNT(buf_state) > 0);
3786  if (BUF_STATE_GET_REFCOUNT(buf_state) == 1)
3787  {
3788  /* pincount is OK. */
3789  UnlockBufHdr(bufHdr, buf_state);
3790  return true;
3791  }
3792 
3793  UnlockBufHdr(bufHdr, buf_state);
3794  return false;
3795 }
bool LWLockHeldByMeInMode(LWLock *l, LWLockMode mode)
Definition: lwlock.c:1848
#define GetBufferDescriptor(id)
static int32 GetPrivateRefCount(Buffer buffer)
Definition: bufmgr.c:358
unsigned int uint32
Definition: c.h:265
#define BufferDescriptorGetContentLock(bdesc)
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define UnlockBufHdr(desc, s)
int32 * LocalRefCount
Definition: localbuf.c:45
#define BUF_STATE_GET_REFCOUNT(state)
Definition: buf_internals.h:49
void LockBuffer ( Buffer  buffer,
int  mode 
)

Definition at line 3529 of file bufmgr.c.

References Assert, buf, BUFFER_LOCK_EXCLUSIVE, BUFFER_LOCK_SHARE, BUFFER_LOCK_UNLOCK, BufferDescriptorGetContentLock, BufferIsLocal, BufferIsValid, elog, ERROR, GetBufferDescriptor, LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), and LWLockRelease().

Referenced by _bt_doinsert(), _bt_drop_lock_and_maybe_pin(), _bt_endpoint(), _bt_first(), _bt_getbuf(), _bt_getroot(), _bt_killitems(), _bt_moveright(), _bt_pagedel(), _bt_readnextpage(), _bt_relandgetbuf(), _bt_unlink_halfdead_page(), _hash_addovflpage(), _hash_doinsert(), _hash_expandtable(), _hash_finish_split(), _hash_first(), _hash_freeovflpage(), _hash_getbuf(), _hash_getbuf_with_strategy(), _hash_getcachedmetap(), _hash_getnewbuf(), _hash_getovflpage(), _hash_metapinit(), _hash_readnext(), _hash_readprev(), _hash_splitbucket_guts(), _hash_squeezebucket(), acquire_sample_rows(), bitgetpage(), blbulkdelete(), blgetbitmap(), blinsert(), BloomNewBuffer(), blvacuumcleanup(), brin_doinsert(), brin_doupdate(), brin_evacuate_page(), brin_getinsertbuffer(), brin_page_cleanup(), brinbuild(), brinbuildempty(), bringetbitmap(), brinGetTupleForHeapBlock(), brininsert(), brinLockRevmapPageForUpdate(), brinRevmapInitialize(), brinsummarize(), bt_metap(), bt_page_items(), bt_page_stats(), btree_xlog_delete_get_latestRemovedXid(), btvacuumpage(), checkXLogConsistency(), collect_corrupt_items(), collect_visibility_data(), collectMatchBitmap(), ConditionalLockBufferForCleanup(), copy_heap_data(), count_nondeletable_pages(), entryLoadMoreItems(), ExecCheckHeapTupleVisible(), fill_seq_with_data(), FreeSpaceMapTruncateRel(), fsm_search(), fsm_search_avail(), fsm_set_and_search(), fsm_vacuum_page(), get_raw_page_internal(), GetTupleForTrigger(), GetVisibilityMapPins(), ginbuildempty(), ginbulkdelete(), ginDeletePage(), ginEntryInsert(), ginFindLeafPage(), ginFindParents(), ginFinishSplit(), ginGetStats(), ginHeapTupleFastInsert(), ginInsertCleanup(), ginInsertValue(), GinNewBuffer(), ginStepRight(), ginTraverseLock(), ginUpdateStats(), ginvacuumcleanup(), ginVacuumPostingTreeLeaves(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistbuildempty(), gistbulkdelete(), gistdoinsert(), gistFindCorrectParent(), gistFindPath(), gistfinishsplit(), gistfixsplit(), gistformdownlink(), gistGetMaxLevel(), gistinserttuples(), gistkillitems(), gistNewBuffer(), gistProcessItup(), gistScanPage(), gistvacuumcleanup(), hashbucketcleanup(), hashbulkdelete(), hashgettuple(), heap_abort_speculative(), heap_delete(), heap_fetch(), heap_finish_speculative(), heap_get_latest_tid(), heap_hot_search(), heap_inplace_update(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_page_prune_opt(), heap_update(), heap_xlog_visible(), heapgetpage(), heapgettup(), index_fetch_heap(), IndexBuildHeapRangeScan(), initBloomState(), lazy_scan_heap(), LockBufferForCleanup(), pg_visibility(), pgrowlocks(), pgstat_btree_page(), pgstat_gist_page(), pgstat_heap(), pgstatginindex_internal(), pgstathashindex(), pgstatindex_impl(), read_seq_tuple(), RelationAddExtraBlocks(), RelationGetBufferForTuple(), revmap_physical_extend(), RI_FKey_check(), scanGetCandidate(), scanPendingInsert(), shiftList(), spgdoinsert(), spgGetCache(), SpGistNewBuffer(), spgprocesspending(), spgvacuumpage(), spgWalk(), startScanEntry(), statapprox_heap(), summarize_range(), systable_recheck_tuple(), tablesample_getnext(), UnlockReleaseBuffer(), validate_index_heapscan(), visibilitymap_clear(), visibilitymap_set(), visibilitymap_truncate(), XLogReadBufferExtended(), XLogReadBufferForRedoExtended(), and XLogRecordPageWithFreeSpace().

3530 {
3531  BufferDesc *buf;
3532 
3533  Assert(BufferIsValid(buffer));
3534  if (BufferIsLocal(buffer))
3535  return; /* local buffers need no lock */
3536 
3537  buf = GetBufferDescriptor(buffer - 1);
3538 
3539  if (mode == BUFFER_LOCK_UNLOCK)
3541  else if (mode == BUFFER_LOCK_SHARE)
3543  else if (mode == BUFFER_LOCK_EXCLUSIVE)
3545  else
3546  elog(ERROR, "unrecognized buffer lock mode: %d", mode);
3547 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1714
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:65
#define GetBufferDescriptor(id)
#define BufferDescriptorGetContentLock(bdesc)
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1110
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
#define elog
Definition: elog.h:219
void LockBufferForCleanup ( Buffer  buffer)

Definition at line 3586 of file bufmgr.c.

References Assert, BM_PIN_COUNT_WAITER, BUF_STATE_GET_REFCOUNT, BUFFER_LOCK_EXCLUSIVE, BUFFER_LOCK_UNLOCK, BufferIsLocal, BufferIsValid, elog, ERROR, GetBufferDescriptor, GetPrivateRefCount(), InHotStandby, LocalRefCount, LockBuffer(), LockBufHdr(), MyProcPid, NULL, PG_WAIT_BUFFER_PIN, ProcWaitForSignal(), ResolveRecoveryConflictWithBufferPin(), SetStartupBufferPinWaitBufId(), UnlockBufHdr, and BufferDesc::wait_backend_pid.

Referenced by btree_xlog_vacuum(), btvacuumpage(), btvacuumscan(), ginVacuumPostingTreeLeaves(), hashbulkdelete(), lazy_scan_heap(), ReadBuffer_common(), and XLogReadBufferForRedoExtended().

3587 {
3588  BufferDesc *bufHdr;
3589 
3590  Assert(BufferIsValid(buffer));
3592 
3593  if (BufferIsLocal(buffer))
3594  {
3595  /* There should be exactly one pin */
3596  if (LocalRefCount[-buffer - 1] != 1)
3597  elog(ERROR, "incorrect local pin count: %d",
3598  LocalRefCount[-buffer - 1]);
3599  /* Nobody else to wait for */
3600  return;
3601  }
3602 
3603  /* There should be exactly one local pin */
3604  if (GetPrivateRefCount(buffer) != 1)
3605  elog(ERROR, "incorrect local pin count: %d",
3606  GetPrivateRefCount(buffer));
3607 
3608  bufHdr = GetBufferDescriptor(buffer - 1);
3609 
3610  for (;;)
3611  {
3612  uint32 buf_state;
3613 
3614  /* Try to acquire lock */
3616  buf_state = LockBufHdr(bufHdr);
3617 
3618  Assert(BUF_STATE_GET_REFCOUNT(buf_state) > 0);
3619  if (BUF_STATE_GET_REFCOUNT(buf_state) == 1)
3620  {
3621  /* Successfully acquired exclusive lock with pincount 1 */
3622  UnlockBufHdr(bufHdr, buf_state);
3623  return;
3624  }
3625  /* Failed, so mark myself as waiting for pincount 1 */
3626  if (buf_state & BM_PIN_COUNT_WAITER)
3627  {
3628  UnlockBufHdr(bufHdr, buf_state);
3629  LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
3630  elog(ERROR, "multiple backends attempting to wait for pincount 1");
3631  }
3632  bufHdr->wait_backend_pid = MyProcPid;
3633  PinCountWaitBuf = bufHdr;
3634  buf_state |= BM_PIN_COUNT_WAITER;
3635  UnlockBufHdr(bufHdr, buf_state);
3636  LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
3637 
3638  /* Wait to be signaled by UnpinBuffer() */
3639  if (InHotStandby)
3640  {
3641  /* Publish the bufid that Startup process waits on */
3642  SetStartupBufferPinWaitBufId(buffer - 1);
3643  /* Set alarm and then wait to be signaled by UnpinBuffer() */
3645  /* Reset the published bufid */
3647  }
3648  else
3650 
3651  /*
3652  * Remove flag marking us as waiter. Normally this will not be set
3653  * anymore, but ProcWaitForSignal() can return for other signals as
3654  * well. We take care to only reset the flag if we're the waiter, as
3655  * theoretically another backend could have started waiting. That's
3656  * impossible with the current usages due to table level locking, but
3657  * better be safe.
3658  */
3659  buf_state = LockBufHdr(bufHdr);
3660  if ((buf_state & BM_PIN_COUNT_WAITER) != 0 &&
3661  bufHdr->wait_backend_pid == MyProcPid)
3662  buf_state &= ~BM_PIN_COUNT_WAITER;
3663  UnlockBufHdr(bufHdr, buf_state);
3664 
3666  /* Loop back and try again */
3667  }
3668 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
int MyProcPid
Definition: globals.c:38
int wait_backend_pid
#define InHotStandby
Definition: xlog.h:74
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
#define ERROR
Definition: elog.h:43
void ResolveRecoveryConflictWithBufferPin(void)
Definition: standby.c:434
void SetStartupBufferPinWaitBufId(int bufid)
Definition: proc.c:611
#define GetBufferDescriptor(id)
static int32 GetPrivateRefCount(Buffer buffer)
Definition: bufmgr.c:358
unsigned int uint32
Definition: c.h:265
void ProcWaitForSignal(uint32 wait_event_info)
Definition: proc.c:1739
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529
#define PG_WAIT_BUFFER_PIN
Definition: pgstat.h:720
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define UnlockBufHdr(desc, s)
static BufferDesc * PinCountWaitBuf
Definition: bufmgr.c:136
#define elog
Definition: elog.h:219
int32 * LocalRefCount
Definition: localbuf.c:45
#define BUF_STATE_GET_REFCOUNT(state)
Definition: buf_internals.h:49
#define BM_PIN_COUNT_WAITER
Definition: buf_internals.h:65
void MarkBufferDirty ( Buffer  buffer)

Definition at line 1445 of file bufmgr.c.

References Assert, BM_DIRTY, BM_JUST_DIRTIED, BM_LOCKED, BUF_STATE_GET_REFCOUNT, BufferDescriptorGetContentLock, BufferIsLocal, BufferIsPinned, BufferIsValid, elog, ERROR, GetBufferDescriptor, LW_EXCLUSIVE, LWLockHeldByMeInMode(), MarkLocalBufferDirty(), pg_atomic_compare_exchange_u32(), pg_atomic_read_u32(), pgBufferUsage, BufferUsage::shared_blks_dirtied, BufferDesc::state, VacuumCostActive, VacuumCostBalance, VacuumCostPageDirty, VacuumPageDirty, and WaitBufHdrUnlocked().

Referenced by _bt_clear_incomplete_split(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_newroot(), _bt_restore_meta(), _bt_split(), _bt_unlink_halfdead_page(), _hash_addovflpage(), _hash_doinsert(), _hash_expandtable(), _hash_freeovflpage(), _hash_getovflpage(), _hash_initbitmap(), _hash_metapinit(), _hash_splitbucket_guts(), _hash_squeezebucket(), addLeafTuple(), AlterSequence(), brin_doinsert(), brin_doupdate(), brin_initialize_empty_new_buffer(), brin_xlog_createidx(), brin_xlog_insert_update(), brin_xlog_revmap_extend(), brin_xlog_samepage_update(), brin_xlog_update(), brinbuild(), brinbuildempty(), btree_xlog_delete(), btree_xlog_insert(), btree_xlog_mark_page_halfdead(), btree_xlog_newroot(), btree_xlog_split(), btree_xlog_unlink_page(), btree_xlog_vacuum(), createPostingTree(), do_setval(), doPickSplit(), fill_seq_with_data(), FreeSpaceMapTruncateRel(), generic_redo(), GenericXLogFinish(), ginbuild(), ginbuildempty(), ginbulkdelete(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginRedoClearIncompleteSplit(), ginRedoCreateIndex(), ginRedoCreatePTree(), ginRedoDeleteListPages(), ginRedoDeletePage(), ginRedoInsert(), ginRedoInsertListPage(), ginRedoUpdateMetapage(), ginRedoVacuumDataLeafPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gistbuild(), gistbuildempty(), gistbulkdelete(), gistplacetopage(), gistRedoClearFollowRight(), gistRedoCreateIndex(), gistRedoPageSplitRecord(), gistRedoPageUpdateRecord(), gistvacuumpage(), hashbucketcleanup(), hashbulkdelete(), heap_abort_speculative(), heap_delete(), heap_finish_speculative(), heap_inplace_update(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_page_prune(), heap_update(), heap_xlog_clean(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_freeze_page(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), lazy_scan_heap(), lazy_vacuum_page(), moveLeafs(), nextval_internal(), RelationAddExtraBlocks(), revmap_physical_extend(), saveNodeLink(), seq_redo(), shiftList(), spgAddNodeAction(), spgbuild(), SpGistUpdateMetaPage(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoCreateIndex(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoSplitTuple(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgRedoVacuumRoot(), spgSplitNodeAction(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), visibilitymap_clear(), visibilitymap_set(), visibilitymap_truncate(), writeListPage(), and XLogReadBufferForRedoExtended().

1446 {
1447  BufferDesc *bufHdr;
1448  uint32 buf_state;
1449  uint32 old_buf_state;
1450 
1451  if (!BufferIsValid(buffer))
1452  elog(ERROR, "bad buffer ID: %d", buffer);
1453 
1454  if (BufferIsLocal(buffer))
1455  {
1456  MarkLocalBufferDirty(buffer);
1457  return;
1458  }
1459 
1460  bufHdr = GetBufferDescriptor(buffer - 1);
1461 
1462  Assert(BufferIsPinned(buffer));
1464  LW_EXCLUSIVE));
1465 
1466  old_buf_state = pg_atomic_read_u32(&bufHdr->state);
1467  for (;;)
1468  {
1469  if (old_buf_state & BM_LOCKED)
1470  old_buf_state = WaitBufHdrUnlocked(bufHdr);
1471 
1472  buf_state = old_buf_state;
1473 
1474  Assert(BUF_STATE_GET_REFCOUNT(buf_state) > 0);
1475  buf_state |= BM_DIRTY | BM_JUST_DIRTIED;
1476 
1477  if (pg_atomic_compare_exchange_u32(&bufHdr->state, &old_buf_state,
1478  buf_state))
1479  break;
1480  }
1481 
1482  /*
1483  * If the buffer was not dirty already, do vacuum accounting.
1484  */
1485  if (!(old_buf_state & BM_DIRTY))
1486  {
1487  VacuumPageDirty++;
1489  if (VacuumCostActive)
1491  }
1492 }
#define BufferIsPinned(bufnum)
Definition: bufmgr.c:419
bool LWLockHeldByMeInMode(LWLock *l, LWLockMode mode)
Definition: lwlock.c:1848
int VacuumCostBalance
Definition: globals.c:138
static bool pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 *expected, uint32 newval)
Definition: atomics.h:321
#define BM_DIRTY
Definition: buf_internals.h:59
int VacuumCostPageDirty
Definition: globals.c:130
#define ERROR
Definition: elog.h:43
#define GetBufferDescriptor(id)
#define BM_JUST_DIRTIED
Definition: buf_internals.h:64
long shared_blks_dirtied
Definition: instrument.h:23
unsigned int uint32
Definition: c.h:265
void MarkLocalBufferDirty(Buffer buffer)
Definition: localbuf.c:280
#define BM_LOCKED
Definition: buf_internals.h:58
int VacuumPageDirty
Definition: globals.c:136
#define BufferDescriptorGetContentLock(bdesc)
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
static uint32 WaitBufHdrUnlocked(BufferDesc *buf)
Definition: bufmgr.c:4103
pg_atomic_uint32 state
#define elog
Definition: elog.h:219
BufferUsage pgBufferUsage
Definition: instrument.c:20
#define BUF_STATE_GET_REFCOUNT(state)
Definition: buf_internals.h:49
bool VacuumCostActive
Definition: globals.c:139
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:251
void MarkBufferDirtyHint ( Buffer  buffer,
bool  buffer_std 
)

Definition at line 3362 of file bufmgr.c.

References Assert, BM_DIRTY, BM_JUST_DIRTIED, BM_PERMANENT, BUF_STATE_GET_REFCOUNT, BufferDescriptorGetContentLock, BufferGetPage, BufferIsLocal, BufferIsValid, PGXACT::delayChkpt, elog, ERROR, GetBufferDescriptor, GetPrivateRefCount(), InvalidXLogRecPtr, LockBufHdr(), LWLockHeldByMe(), MarkLocalBufferDirty(), MyPgXact, PageSetLSN, pg_atomic_read_u32(), pgBufferUsage, RecoveryInProgress(), BufferUsage::shared_blks_dirtied, BufferDesc::state, UnlockBufHdr, VacuumCostActive, VacuumCostBalance, VacuumCostPageDirty, VacuumPageDirty, XLogHintBitIsNeeded, XLogRecPtrIsInvalid, and XLogSaveBufferForHint().

Referenced by _bt_check_unique(), _bt_killitems(), brin_start_evacuating_page(), btvacuumpage(), fsm_search_avail(), fsm_set_and_search(), fsm_vacuum_page(), gistkillitems(), hashgettuple(), heap_page_prune(), read_seq_tuple(), SetHintBits(), and XLogRecordPageWithFreeSpace().

3363 {
3364  BufferDesc *bufHdr;
3365  Page page = BufferGetPage(buffer);
3366 
3367  if (!BufferIsValid(buffer))
3368  elog(ERROR, "bad buffer ID: %d", buffer);
3369 
3370  if (BufferIsLocal(buffer))
3371  {
3372  MarkLocalBufferDirty(buffer);
3373  return;
3374  }
3375 
3376  bufHdr = GetBufferDescriptor(buffer - 1);
3377 
3378  Assert(GetPrivateRefCount(buffer) > 0);
3379  /* here, either share or exclusive lock is OK */
3381 
3382  /*
3383  * This routine might get called many times on the same page, if we are
3384  * making the first scan after commit of an xact that added/deleted many
3385  * tuples. So, be as quick as we can if the buffer is already dirty. We
3386  * do this by not acquiring spinlock if it looks like the status bits are
3387  * already set. Since we make this test unlocked, there's a chance we
3388  * might fail to notice that the flags have just been cleared, and failed
3389  * to reset them, due to memory-ordering issues. But since this function
3390  * is only intended to be used in cases where failing to write out the
3391  * data would be harmless anyway, it doesn't really matter.
3392  */
3393  if ((pg_atomic_read_u32(&bufHdr->state) & (BM_DIRTY | BM_JUST_DIRTIED)) !=
3395  {
3397  bool dirtied = false;
3398  bool delayChkpt = false;
3399  uint32 buf_state;
3400 
3401  /*
3402  * If we need to protect hint bit updates from torn writes, WAL-log a
3403  * full page image of the page. This full page image is only necessary
3404  * if the hint bit update is the first change to the page since the
3405  * last checkpoint.
3406  *
3407  * We don't check full_page_writes here because that logic is included
3408  * when we call XLogInsert() since the value changes dynamically.
3409  */
3410  if (XLogHintBitIsNeeded() &&
3411  (pg_atomic_read_u32(&bufHdr->state) & BM_PERMANENT))
3412  {
3413  /*
3414  * If we're in recovery we cannot dirty a page because of a hint.
3415  * We can set the hint, just not dirty the page as a result so the
3416  * hint is lost when we evict the page or shutdown.
3417  *
3418  * See src/backend/storage/page/README for longer discussion.
3419  */
3420  if (RecoveryInProgress())
3421  return;
3422 
3423  /*
3424  * If the block is already dirty because we either made a change
3425  * or set a hint already, then we don't need to write a full page
3426  * image. Note that aggressive cleaning of blocks dirtied by hint
3427  * bit setting would increase the call rate. Bulk setting of hint
3428  * bits would reduce the call rate...
3429  *
3430  * We must issue the WAL record before we mark the buffer dirty.
3431  * Otherwise we might write the page before we write the WAL. That
3432  * causes a race condition, since a checkpoint might occur between
3433  * writing the WAL record and marking the buffer dirty. We solve
3434  * that with a kluge, but one that is already in use during
3435  * transaction commit to prevent race conditions. Basically, we
3436  * simply prevent the checkpoint WAL record from being written
3437  * until we have marked the buffer dirty. We don't start the
3438  * checkpoint flush until we have marked dirty, so our checkpoint
3439  * must flush the change to disk successfully or the checkpoint
3440  * never gets written, so crash recovery will fix.
3441  *
3442  * It's possible we may enter here without an xid, so it is
3443  * essential that CreateCheckpoint waits for virtual transactions
3444  * rather than full transactionids.
3445  */
3446  MyPgXact->delayChkpt = delayChkpt = true;
3447  lsn = XLogSaveBufferForHint(buffer, buffer_std);
3448  }
3449 
3450  buf_state = LockBufHdr(bufHdr);
3451 
3452  Assert(BUF_STATE_GET_REFCOUNT(buf_state) > 0);
3453 
3454  if (!(buf_state & BM_DIRTY))
3455  {
3456  dirtied = true; /* Means "will be dirtied by this action" */
3457 
3458  /*
3459  * Set the page LSN if we wrote a backup block. We aren't supposed
3460  * to set this when only holding a share lock but as long as we
3461  * serialise it somehow we're OK. We choose to set LSN while
3462  * holding the buffer header lock, which causes any reader of an
3463  * LSN who holds only a share lock to also obtain a buffer header
3464  * lock before using PageGetLSN(), which is enforced in
3465  * BufferGetLSNAtomic().
3466  *
3467  * If checksums are enabled, you might think we should reset the
3468  * checksum here. That will happen when the page is written
3469  * sometime later in this checkpoint cycle.
3470  */
3471  if (!XLogRecPtrIsInvalid(lsn))
3472  PageSetLSN(page, lsn);
3473  }
3474 
3475  buf_state |= BM_DIRTY | BM_JUST_DIRTIED;
3476  UnlockBufHdr(bufHdr, buf_state);
3477 
3478  if (delayChkpt)
3479  MyPgXact->delayChkpt = false;
3480 
3481  if (dirtied)
3482  {
3483  VacuumPageDirty++;
3485  if (VacuumCostActive)
3487  }
3488  }
3489 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define BM_PERMANENT
Definition: buf_internals.h:67
int VacuumCostBalance
Definition: globals.c:138
bool LWLockHeldByMe(LWLock *l)
Definition: lwlock.c:1830
XLogRecPtr XLogSaveBufferForHint(Buffer buffer, bool buffer_std)
Definition: xloginsert.c:894
bool RecoveryInProgress(void)
Definition: xlog.c:7805
#define BM_DIRTY
Definition: buf_internals.h:59
int VacuumCostPageDirty
Definition: globals.c:130
PGXACT * MyPgXact
Definition: proc.c:68
#define ERROR
Definition: elog.h:43
#define GetBufferDescriptor(id)
#define BM_JUST_DIRTIED
Definition: buf_internals.h:64
long shared_blks_dirtied
Definition: instrument.h:23
static int32 GetPrivateRefCount(Buffer buffer)
Definition: bufmgr.c:358
unsigned int uint32
Definition: c.h:265
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
bool delayChkpt
Definition: proc.h:210
void MarkLocalBufferDirty(Buffer buffer)
Definition: localbuf.c:280
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
int VacuumPageDirty
Definition: globals.c:136
#define BufferDescriptorGetContentLock(bdesc)
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define UnlockBufHdr(desc, s)
pg_atomic_uint32 state
#define elog
Definition: elog.h:219
#define PageSetLSN(page, lsn)
Definition: bufpage.h:365
#define XLogHintBitIsNeeded()
Definition: xlog.h:156
Pointer Page
Definition: bufpage.h:74
BufferUsage pgBufferUsage
Definition: instrument.c:20
#define BUF_STATE_GET_REFCOUNT(state)
Definition: buf_internals.h:49
bool VacuumCostActive
Definition: globals.c:139
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:251
void PrefetchBuffer ( Relation  reln,
ForkNumber  forkNum,
BlockNumber  blockNum 
)

Definition at line 529 of file bufmgr.c.

References Assert, BlockNumberIsValid, BufMappingPartitionLock, BufTableHashCode(), BufTableLookup(), ereport, errcode(), errmsg(), ERROR, INIT_BUFFERTAG, LocalPrefetchBuffer(), LW_SHARED, LWLockAcquire(), LWLockRelease(), RelFileNodeBackend::node, RelationData::rd_smgr, RELATION_IS_OTHER_TEMP, RelationIsValid, RelationOpenSmgr, RelationUsesLocalBuffers, SMgrRelationData::smgr_rnode, and smgrprefetch().

Referenced by BitmapHeapNext(), count_nondeletable_pages(), and pg_prewarm().

530 {
531 #ifdef USE_PREFETCH
532  Assert(RelationIsValid(reln));
533  Assert(BlockNumberIsValid(blockNum));
534 
535  /* Open it at the smgr level if not already done */
536  RelationOpenSmgr(reln);
537 
538  if (RelationUsesLocalBuffers(reln))
539  {
540  /* see comments in ReadBufferExtended */
541  if (RELATION_IS_OTHER_TEMP(reln))
542  ereport(ERROR,
543  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
544  errmsg("cannot access temporary tables of other sessions")));
545 
546  /* pass it off to localbuf.c */
547  LocalPrefetchBuffer(reln->rd_smgr, forkNum, blockNum);
548  }
549  else
550  {
551  BufferTag newTag; /* identity of requested block */
552  uint32 newHash; /* hash value for newTag */
553  LWLock *newPartitionLock; /* buffer partition lock for it */
554  int buf_id;
555 
556  /* create a tag so we can lookup the buffer */
557  INIT_BUFFERTAG(newTag, reln->rd_smgr->smgr_rnode.node,
558  forkNum, blockNum);
559 
560  /* determine its hash code and partition lock ID */
561  newHash = BufTableHashCode(&newTag);
562  newPartitionLock = BufMappingPartitionLock(newHash);
563 
564  /* see if the block is in the buffer pool already */
565  LWLockAcquire(newPartitionLock, LW_SHARED);
566  buf_id = BufTableLookup(&newTag, newHash);
567  LWLockRelease(newPartitionLock);
568 
569  /* If not in buffers, initiate prefetch */
570  if (buf_id < 0)
571  smgrprefetch(reln->rd_smgr, forkNum, blockNum);
572 
573  /*
574  * If the block *is* in buffers, we do nothing. This is not really
575  * ideal: the block might be just about to be evicted, which would be
576  * stupid since we know we are going to need it soon. But the only
577  * easy answer is to bump the usage_count, which does not seem like a
578  * great solution: when the caller does ultimately touch the block,
579  * usage_count would get bumped again, resulting in too much
580  * favoritism for blocks that are involved in a prefetch sequence. A
581  * real fix would involve some additional per-buffer state, and it's
582  * not clear that there's enough of a problem to justify that.
583  */
584  }
585 #endif /* USE_PREFETCH */
586 }
Definition: lwlock.h:32
#define BufMappingPartitionLock(hashcode)
void LocalPrefetchBuffer(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum)
Definition: localbuf.c:64
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
uint32 BufTableHashCode(BufferTag *tagPtr)
Definition: buf_table.c:80
int errcode(int sqlerrcode)
Definition: elog.c:575
int BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
Definition: buf_table.c:92
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1714
#define RelationOpenSmgr(relation)
Definition: rel.h:457
#define ERROR
Definition: elog.h:43
#define RelationIsValid(relation)
Definition: rel.h:386
RelFileNodeBackend smgr_rnode
Definition: smgr.h:43
unsigned int uint32
Definition: c.h:265
#define ereport(elevel, rest)
Definition: elog.h:122
#define BlockNumberIsValid(blockNumber)
Definition: block.h:70
RelFileNode node
Definition: relfilenode.h:74
#define Assert(condition)
Definition: c.h:671
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:530
#define INIT_BUFFERTAG(a, xx_rnode, xx_forkNum, xx_blockNum)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1110
#define RelationUsesLocalBuffers(relation)
Definition: rel.h:509
int errmsg(const char *fmt,...)
Definition: elog.c:797
void smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum)
Definition: smgr.c:611
void PrintBufferLeakWarning ( Buffer  buffer)

Definition at line 2514 of file bufmgr.c.

References Assert, buftag::blockNum, buf, BUF_FLAG_MASK, BUF_STATE_GET_REFCOUNT, BufferIsLocal, BufferIsValid, elog, buftag::forkNum, GetBufferDescriptor, GetLocalBufferDescriptor, GetPrivateRefCount(), InvalidBackendId, LocalRefCount, MyBackendId, pfree(), pg_atomic_read_u32(), relpathbackend, buftag::rnode, BufferDesc::state, BufferDesc::tag, and WARNING.

Referenced by CheckForBufferLeaks(), CheckForLocalBufferLeaks(), and ResourceOwnerReleaseInternal().

2515 {
2516  BufferDesc *buf;
2517  int32 loccount;
2518  char *path;
2519  BackendId backend;
2520  uint32 buf_state;
2521 
2522  Assert(BufferIsValid(buffer));
2523  if (BufferIsLocal(buffer))
2524  {
2525  buf = GetLocalBufferDescriptor(-buffer - 1);
2526  loccount = LocalRefCount[-buffer - 1];
2527  backend = MyBackendId;
2528  }
2529  else
2530  {
2531  buf = GetBufferDescriptor(buffer - 1);
2532  loccount = GetPrivateRefCount(buffer);
2533  backend = InvalidBackendId;
2534  }
2535 
2536  /* theoretically we should lock the bufhdr here */
2537  path = relpathbackend(buf->tag.rnode, backend, buf->tag.forkNum);
2538  buf_state = pg_atomic_read_u32(&buf->state);
2539  elog(WARNING,
2540  "buffer refcount leak: [%03d] "
2541  "(rel=%s, blockNum=%u, flags=0x%x, refcount=%u %d)",
2542  buffer, path,
2543  buf->tag.blockNum, buf_state & BUF_FLAG_MASK,
2544  BUF_STATE_GET_REFCOUNT(buf_state), loccount);
2545  pfree(path);
2546 }
BackendId MyBackendId
Definition: globals.c:72
ForkNumber forkNum
Definition: buf_internals.h:94
#define GetLocalBufferDescriptor(id)
signed int int32
Definition: c.h:253
void pfree(void *pointer)
Definition: mcxt.c:992
#define BUF_FLAG_MASK
Definition: buf_internals.h:46
static char * buf
Definition: pg_test_fsync.c:65
#define GetBufferDescriptor(id)
static int32 GetPrivateRefCount(Buffer buffer)
Definition: bufmgr.c:358
unsigned int uint32
Definition: c.h:265
#define WARNING
Definition: elog.h:40
#define InvalidBackendId
Definition: backendid.h:23
int BackendId
Definition: backendid.h:21
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
BlockNumber blockNum
Definition: buf_internals.h:95
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
RelFileNode rnode
Definition: buf_internals.h:93
BufferTag tag
pg_atomic_uint32 state
#define elog
Definition: elog.h:219
#define relpathbackend(rnode, backend, forknum)
Definition: relpath.h:62
int32 * LocalRefCount
Definition: localbuf.c:45
#define BUF_STATE_GET_REFCOUNT(state)
Definition: buf_internals.h:49
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:251
Buffer ReadBuffer ( Relation  reln,
BlockNumber  blockNum 
)

Definition at line 594 of file bufmgr.c.

References MAIN_FORKNUM, NULL, RBM_NORMAL, and ReadBufferExtended().

Referenced by _bt_getbuf(), _hash_getbuf(), _hash_getbuf_with_condlock_cleanup(), blbulkdelete(), blinsert(), BloomNewBuffer(), brin_getinsertbuffer(), brinbuild(), brinGetTupleForHeapBlock(), brinRevmapInitialize(), bt_metap(), bt_page_items(), bt_page_stats(), fill_seq_with_data(), GetTupleForTrigger(), ginFindLeafPage(), ginFindParents(), ginGetStats(), ginHeapTupleFastInsert(), ginInsertCleanup(), GinNewBuffer(), ginStepRight(), ginUpdateStats(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistdoinsert(), gistFindCorrectParent(), gistFindPath(), gistfixsplit(), gistGetMaxLevel(), gistkillitems(), gistNewBuffer(), gistProcessItup(), gistScanPage(), heap_abort_speculative(), heap_delete(), heap_fetch(), heap_finish_speculative(), heap_get_latest_tid(), heap_hot_search(), heap_inplace_update(), heap_lock_tuple(), heap_update(), initBloomState(), pg_visibility(), pgstatginindex_internal(), read_seq_tuple(), ReadBufferBI(), RelationGetBufferForTuple(), ReleaseAndReadBuffer(), revmap_get_buffer(), revmap_physical_extend(), scanGetCandidate(), scanPendingInsert(), shiftList(), spgdoinsert(), spgGetCache(), SpGistGetBuffer(), SpGistNewBuffer(), SpGistUpdateMetaPage(), and spgWalk().

595 {
596  return ReadBufferExtended(reln, MAIN_FORKNUM, blockNum, RBM_NORMAL, NULL);
597 }
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:640
#define NULL
Definition: c.h:226
Buffer ReadBufferExtended ( Relation  reln,
ForkNumber  forkNum,
BlockNumber  blockNum,
ReadBufferMode  mode,
BufferAccessStrategy  strategy 
)

Definition at line 640 of file bufmgr.c.

References buf, ereport, errcode(), errmsg(), ERROR, pgstat_count_buffer_hit, pgstat_count_buffer_read, RelationData::rd_rel, RelationData::rd_smgr, ReadBuffer_common(), RELATION_IS_OTHER_TEMP, and RelationOpenSmgr.

Referenced by _hash_getbuf_with_strategy(), _hash_getinitbuf(), _hash_getnewbuf(), acquire_sample_rows(), blbulkdelete(), blgetbitmap(), blvacuumcleanup(), brin_vacuum_scan(), brinbuildempty(), btvacuumpage(), btvacuumscan(), collect_corrupt_items(), collect_visibility_data(), count_nondeletable_pages(), fsm_readbuf(), get_raw_page_internal(), ginbuildempty(), ginbulkdelete(), ginDeletePage(), ginScanToDelete(), ginvacuumcleanup(), ginVacuumPostingTreeLeaves(), gistbuildempty(), gistbulkdelete(), gistvacuumcleanup(), hashbulkdelete(), heapgetpage(), lazy_scan_heap(), lazy_vacuum_heap(), pg_prewarm(), pgstat_btree_page(), pgstat_gist_page(), pgstat_heap(), pgstathashindex(), pgstatindex_impl(), ReadBuffer(), ReadBufferBI(), spgprocesspending(), spgvacuumpage(), statapprox_heap(), and vm_readbuf().

642 {
643  bool hit;
644  Buffer buf;
645 
646  /* Open it at the smgr level if not already done */
647  RelationOpenSmgr(reln);
648 
649  /*
650  * Reject attempts to read non-local temporary relations; we would be
651  * likely to get wrong data since we have no visibility into the owning
652  * session's local buffers.
653  */
654  if (RELATION_IS_OTHER_TEMP(reln))
655  ereport(ERROR,
656  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
657  errmsg("cannot access temporary tables of other sessions")));
658 
659  /*
660  * Read the buffer, and update pgstat counters to reflect a cache hit or
661  * miss.
662  */
664  buf = ReadBuffer_common(reln->rd_smgr, reln->rd_rel->relpersistence,
665  forkNum, blockNum, mode, strategy, &hit);
666  if (hit)
668  return buf;
669 }
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
int errcode(int sqlerrcode)
Definition: elog.c:575
Form_pg_class rd_rel
Definition: rel.h:113
#define RelationOpenSmgr(relation)
Definition: rel.h:457
#define ERROR
Definition: elog.h:43
#define pgstat_count_buffer_read(rel)
Definition: pgstat.h:1165
static char * buf
Definition: pg_test_fsync.c:65
#define ereport(elevel, rest)
Definition: elog.h:122
#define pgstat_count_buffer_hit(rel)
Definition: pgstat.h:1170
static Buffer ReadBuffer_common(SMgrRelation reln, char relpersistence, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy, bool *hit)
Definition: bufmgr.c:703
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:530
int errmsg(const char *fmt,...)
Definition: elog.c:797
int Buffer
Definition: buf.h:23
Buffer ReadBufferWithoutRelcache ( RelFileNode  rnode,
ForkNumber  forkNum,
BlockNumber  blockNum,
ReadBufferMode  mode,
BufferAccessStrategy  strategy 
)

Definition at line 682 of file bufmgr.c.

References Assert, InRecovery, InvalidBackendId, ReadBuffer_common(), RELPERSISTENCE_PERMANENT, and smgropen().

Referenced by XLogReadBufferExtended().

685 {
686  bool hit;
687 
688  SMgrRelation smgr = smgropen(rnode, InvalidBackendId);
689 
691 
692  return ReadBuffer_common(smgr, RELPERSISTENCE_PERMANENT, forkNum, blockNum,
693  mode, strategy, &hit);
694 }
bool InRecovery
Definition: xlog.c:191
#define RELPERSISTENCE_PERMANENT
Definition: pg_class.h:170
SMgrRelation smgropen(RelFileNode rnode, BackendId backend)
Definition: smgr.c:137
#define InvalidBackendId
Definition: backendid.h:23
static Buffer ReadBuffer_common(SMgrRelation reln, char relpersistence, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy, bool *hit)
Definition: bufmgr.c:703
#define Assert(condition)
Definition: c.h:671
BlockNumber RelationGetNumberOfBlocksInFork ( Relation  relation,
ForkNumber  forkNum 
)

Definition at line 2771 of file bufmgr.c.

References RelationData::rd_smgr, RelationOpenSmgr, and smgrnblocks().

Referenced by _hash_getnewbuf(), _hash_metapinit(), get_raw_page_internal(), and pg_prewarm().

2772 {
2773  /* Open it at the smgr level if not already done */
2774  RelationOpenSmgr(relation);
2775 
2776  return smgrnblocks(relation->rd_smgr, forkNum);
2777 }
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
#define RelationOpenSmgr(relation)
Definition: rel.h:457
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:672
Buffer ReleaseAndReadBuffer ( Buffer  buffer,
Relation  relation,
BlockNumber  blockNum 
)

Definition at line 1508 of file bufmgr.c.

References Assert, buftag::blockNum, PrivateRefCountEntry::buffer, BufferIsLocal, BufferIsPinned, BufferIsValid, CurrentResourceOwner, buftag::forkNum, GetBufferDescriptor, GetLocalBufferDescriptor, LocalRefCount, MAIN_FORKNUM, RelationData::rd_node, ReadBuffer(), RelFileNodeEquals, ResourceOwnerForgetBuffer(), buftag::rnode, BufferDesc::tag, and UnpinBuffer().

Referenced by _bt_relandgetbuf(), bitgetpage(), ginFindLeafPage(), and index_fetch_heap().

1511 {
1512  ForkNumber forkNum = MAIN_FORKNUM;
1513  BufferDesc *bufHdr;
1514 
1515  if (BufferIsValid(buffer))
1516  {
1517  Assert(BufferIsPinned(buffer));
1518  if (BufferIsLocal(buffer))
1519  {
1520  bufHdr = GetLocalBufferDescriptor(-buffer - 1);
1521  if (bufHdr->tag.blockNum == blockNum &&
1522  RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node) &&
1523  bufHdr->tag.forkNum == forkNum)
1524  return buffer;
1526  LocalRefCount[-buffer - 1]--;
1527  }
1528  else
1529  {
1530  bufHdr = GetBufferDescriptor(buffer - 1);
1531  /* we have pin, so it's ok to examine tag without spinlock */
1532  if (bufHdr->tag.blockNum == blockNum &&
1533  RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node) &&
1534  bufHdr->tag.forkNum == forkNum)
1535  return buffer;
1536  UnpinBuffer(bufHdr, true);
1537  }
1538  }
1539 
1540  return ReadBuffer(relation, blockNum);
1541 }
#define BufferIsPinned(bufnum)
Definition: bufmgr.c:419
ForkNumber forkNum
Definition: buf_internals.h:94
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
#define GetLocalBufferDescriptor(id)
#define GetBufferDescriptor(id)
ForkNumber
Definition: relpath.h:24
static void UnpinBuffer(BufferDesc *buf, bool fixOwner)
Definition: bufmgr.c:1677
RelFileNode rd_node
Definition: rel.h:85
#define Assert(condition)
Definition: c.h:671
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
#define BufferIsLocal(buffer)
Definition: buf.h:37
BlockNumber blockNum
Definition: buf_internals.h:95
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
RelFileNode rnode
Definition: buf_internals.h:93
BufferTag tag
int32 * LocalRefCount
Definition: localbuf.c:45
#define RelFileNodeEquals(node1, node2)
Definition: relfilenode.h:88
void ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer)
Definition: resowner.c:869
void ReleaseBuffer ( Buffer  buffer)

Definition at line 3292 of file bufmgr.c.

References Assert, BufferIsLocal, BufferIsValid, CurrentResourceOwner, elog, ERROR, GetBufferDescriptor, LocalRefCount, ResourceOwnerForgetBuffer(), and UnpinBuffer().

Referenced by _bt_drop_lock_and_maybe_pin(), _bt_getbuf(), _bt_pagedel(), _bt_unlink_halfdead_page(), _hash_dropbuf(), _hash_getbuf_with_condlock_cleanup(), AfterTriggerExecute(), blinsert(), BloomNewBuffer(), brin_getinsertbuffer(), brin_vacuum_scan(), bringetbitmap(), brinGetTupleForHeapBlock(), brininsert(), brinRevmapTerminate(), brinsummarize(), collect_corrupt_items(), collect_visibility_data(), entryLoadMoreItems(), EvalPlanQualFetch(), EvalPlanQualFetchRowMarks(), ExecCheckTIDVisible(), ExecClearTuple(), ExecDelete(), ExecEndIndexOnlyScan(), ExecLockRows(), ExecMaterializeSlot(), ExecOnConflictUpdate(), ExecStoreMinimalTuple(), ExecStoreTuple(), FreeBulkInsertState(), freeGinBtreeStack(), fsm_vacuum_page(), get_raw_page_internal(), GetRecordedFreeSpace(), GetTupleForTrigger(), ginDeletePage(), ginFindParents(), ginFinishSplit(), ginFreeScanKeys(), ginInsertCleanup(), GinNewBuffer(), ginScanToDelete(), gistdoinsert(), gistFindCorrectParent(), gistNewBuffer(), heap_abort_speculative(), heap_delete(), heap_endscan(), heap_fetch(), heap_hot_search(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_rescan(), heap_update(), heap_xlog_delete(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), heapgetpage(), heapgettup(), heapgettup_pagemode(), index_endscan(), index_getnext_tid(), index_rescan(), lazy_scan_heap(), lazy_vacuum_heap(), pg_prewarm(), pg_visibility(), pg_visibility_map(), pg_visibility_map_summary(), pgstatindex_impl(), ReadBufferBI(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), RelationGetBufferForTuple(), ReleaseBulkInsertStatePin(), ResourceOwnerReleaseInternal(), revmap_get_buffer(), revmap_physical_extend(), spgdoinsert(), SpGistGetBuffer(), SpGistNewBuffer(), SpGistUpdateMetaPage(), statapprox_heap(), summarize_range(), tablesample_getnext(), terminate_brin_buildstate(), TidNext(), UnlockReleaseBuffer(), visibilitymap_count(), visibilitymap_get_status(), visibilitymap_pin(), and XLogReadBufferExtended().

3293 {
3294  if (!BufferIsValid(buffer))
3295  elog(ERROR, "bad buffer ID: %d", buffer);
3296 
3297  if (BufferIsLocal(buffer))
3298  {
3300 
3301  Assert(LocalRefCount[-buffer - 1] > 0);
3302  LocalRefCount[-buffer - 1]--;
3303  return;
3304  }
3305 
3306  UnpinBuffer(GetBufferDescriptor(buffer - 1), true);
3307 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
#define ERROR
Definition: elog.h:43
#define GetBufferDescriptor(id)
static void UnpinBuffer(BufferDesc *buf, bool fixOwner)
Definition: bufmgr.c:1677
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define elog
Definition: elog.h:219
int32 * LocalRefCount
Definition: localbuf.c:45
void ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer)
Definition: resowner.c:869
static void TestForOldSnapshot ( Snapshot  snapshot,
Relation  relation,
Page  page 
)
inlinestatic

Definition at line 265 of file bufmgr.h.

References Assert, HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesToast(), NULL, old_snapshot_threshold, PageGetLSN, TestForOldSnapshot_impl(), and XLogRecPtrIsInvalid.

Referenced by _bt_get_endpoint(), _bt_moveright(), _bt_readnextpage(), _bt_walk_left(), blgetbitmap(), brinGetTupleForHeapBlock(), brinRevmapInitialize(), collectMatchBitmap(), collectMatchesForHeapRow(), ginFindLeafPage(), gistScanPage(), heap_fetch(), heap_get_latest_tid(), heapgetpage(), heapgettup(), heapgettup_pagemode(), scanGetCandidate(), scanPendingInsert(), and spgWalk().

266 {
267  Assert(relation != NULL);
268 
269  if (old_snapshot_threshold >= 0
270  && (snapshot) != NULL
271  && ((snapshot)->satisfies == HeapTupleSatisfiesMVCC
272  || (snapshot)->satisfies == HeapTupleSatisfiesToast)
273  && !XLogRecPtrIsInvalid((snapshot)->lsn)
274  && PageGetLSN(page) > (snapshot)->lsn)
275  TestForOldSnapshot_impl(snapshot, relation);
276 }
bool HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:366
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define PageGetLSN(page)
Definition: bufpage.h:363
int old_snapshot_threshold
Definition: snapmgr.c:74
void TestForOldSnapshot_impl(Snapshot snapshot, Relation relation)
Definition: bufmgr.c:4333
bool HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:963
void TestForOldSnapshot_impl ( Snapshot  snapshot,
Relation  relation 
)

Definition at line 4333 of file bufmgr.c.

References ereport, errcode(), errmsg(), ERROR, GetOldSnapshotThresholdTimestamp(), and RelationAllowsEarlyPruning.

Referenced by TestForOldSnapshot().

4334 {
4335  if (RelationAllowsEarlyPruning(relation)
4336  && (snapshot)->whenTaken < GetOldSnapshotThresholdTimestamp())
4337  ereport(ERROR,
4338  (errcode(ERRCODE_SNAPSHOT_TOO_OLD),
4339  errmsg("snapshot too old")));
4340 }
TimestampTz GetOldSnapshotThresholdTimestamp(void)
Definition: snapmgr.c:1659
#define RelationAllowsEarlyPruning(rel)
Definition: snapmgr.h:38
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
void UnlockBuffers ( void  )

Definition at line 3501 of file bufmgr.c.

References BM_PIN_COUNT_WAITER, LockBufHdr(), MyProcPid, NULL, PinCountWaitBuf, UnlockBufHdr, and BufferDesc::wait_backend_pid.

Referenced by AbortSubTransaction(), AbortTransaction(), AtProcExit_Buffers(), BackgroundWriterMain(), CheckpointerMain(), and WalWriterMain().

3502 {
3504 
3505  if (buf)
3506  {
3507  uint32 buf_state;
3508 
3509  buf_state = LockBufHdr(buf);
3510 
3511  /*
3512  * Don't complain if flag bit not set; it could have been reset but we
3513  * got a cancel/die interrupt before getting the signal.
3514  */
3515  if ((buf_state & BM_PIN_COUNT_WAITER) != 0 &&
3516  buf->wait_backend_pid == MyProcPid)
3517  buf_state &= ~BM_PIN_COUNT_WAITER;
3518 
3519  UnlockBufHdr(buf, buf_state);
3520 
3522  }
3523 }
int MyProcPid
Definition: globals.c:38
int wait_backend_pid
static char * buf
Definition: pg_test_fsync.c:65
unsigned int uint32
Definition: c.h:265
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:4075
#define NULL
Definition: c.h:226
#define UnlockBufHdr(desc, s)
static BufferDesc * PinCountWaitBuf
Definition: bufmgr.c:136
#define BM_PIN_COUNT_WAITER
Definition: buf_internals.h:65
void UnlockReleaseBuffer ( Buffer  buffer)

Definition at line 3315 of file bufmgr.c.

References BUFFER_LOCK_UNLOCK, LockBuffer(), and ReleaseBuffer().

Referenced by _bt_clear_incomplete_split(), _bt_relbuf(), _bt_restore_meta(), _hash_relbuf(), acquire_sample_rows(), allocNewBuffer(), AlterSequence(), blbulkdelete(), blgetbitmap(), blinsert(), BloomInitMetapage(), blvacuumcleanup(), brin_doinsert(), brin_doupdate(), brin_evacuate_page(), brin_getinsertbuffer(), brin_xlog_createidx(), brin_xlog_insert_update(), brin_xlog_revmap_extend(), brin_xlog_samepage_update(), brin_xlog_update(), brinbuild(), brinbuildempty(), bt_metap(), bt_page_items(), bt_page_stats(), btree_xlog_delete(), btree_xlog_delete_get_latestRemovedXid(), btree_xlog_insert(), btree_xlog_mark_page_halfdead(), btree_xlog_newroot(), btree_xlog_split(), btree_xlog_unlink_page(), btree_xlog_vacuum(), checkXLogConsistency(), collect_corrupt_items(), collect_visibility_data(), count_nondeletable_pages(), createPostingTree(), do_setval(), doPickSplit(), entryLoadMoreItems(), fill_seq_with_data(), flushCachedPage(), FreeSpaceMapTruncateRel(), fsm_search(), fsm_set_and_search(), generic_redo(), ginbuild(), ginbuildempty(), ginbulkdelete(), ginDeletePage(), ginFindParents(), ginGetStats(), ginHeapTupleFastInsert(), ginInsertCleanup(), ginPlaceToPage(), ginRedoClearIncompleteSplit(), ginRedoCreateIndex(), ginRedoCreatePTree(), ginRedoDeleteListPages(), ginRedoDeletePage(), ginRedoInsert(), ginRedoInsertListPage(), ginRedoSplit(), ginRedoUpdateMetapage(), ginRedoVacuumDataLeafPage(), ginRedoVacuumPage(), ginStepRight(), ginUpdateStats(), ginvacuumcleanup(), ginVacuumPostingTree(), ginVacuumPostingTreeLeaves(), gistbufferinginserttuples(), gistbuild(), gistbuildempty(), gistbulkdelete(), gistdoinsert(), gistFindCorrectParent(), gistFindPath(), gistGetMaxLevel(), gistinserttuples(), gistkillitems(), gistplacetopage(), gistProcessItup(), gistRedoClearFollowRight(), gistRedoCreateIndex(), gistRedoPageSplitRecord(), gistRedoPageUpdateRecord(), gistScanPage(), gistvacuumcleanup(), heap_delete(), heap_finish_speculative(), heap_get_latest_tid(), heap_inplace_update(), heap_insert(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_update(), heap_xlog_clean(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_freeze_page(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), initBloomState(), lazy_scan_heap(), lazy_vacuum_heap(), moveLeafs(), nextval_internal(), pg_sequence_last_value(), pg_visibility(), pgstat_gist_page(), pgstat_heap(), pgstatginindex_internal(), pgstathashindex(), RelationAddExtraBlocks(), ResetSequence(), revmap_physical_extend(), scanGetCandidate(), scanPendingInsert(), scanPostingTree(), seq_redo(), shiftList(), spgAddNodeAction(), spgbuild(), spgdoinsert(), spgGetCache(), SpGistGetBuffer(), SpGistUpdateMetaPage(), spgMatchNodeAction(), spgprocesspending(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoCreateIndex(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoSplitTuple(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgRedoVacuumRoot(), spgSplitNodeAction(), spgvacuumpage(), spgWalk(), statapprox_heap(), visibilitymap_truncate(), writeListPage(), xlog_redo(), and XLogRecordPageWithFreeSpace().

3316 {
3317  LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
3318  ReleaseBuffer(buffer);
3319 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3292
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529

Variable Documentation

int backend_flush_after

Definition at line 120 of file bufmgr.c.

Referenced by InitBufferPool().

int bgwriter_flush_after

Definition at line 119 of file bufmgr.c.

Referenced by BackgroundWriterMain().

int bgwriter_lru_maxpages

Definition at line 109 of file bufmgr.c.

Referenced by BgBufferSync().

double bgwriter_lru_multiplier

Definition at line 110 of file bufmgr.c.

Referenced by BgBufferSync().

PGDLLIMPORT char* BufferBlocks

Definition at line 22 of file buf_init.c.

Referenced by InitBufferPool().

int checkpoint_flush_after

Definition at line 118 of file bufmgr.c.

Referenced by BufferSync().

int effective_io_concurrency
PGDLLIMPORT Block* LocalBufferBlockPointers

Definition at line 44 of file localbuf.c.

Referenced by InitLocalBuffers().

int target_prefetch_pages

Definition at line 129 of file bufmgr.c.

Referenced by assign_effective_io_concurrency(), and ExecInitBitmapHeapScan().

bool track_io_timing

Definition at line 111 of file bufmgr.c.

Referenced by FlushBuffer(), ReadBuffer_common(), and show_buffer_usage().

bool zero_damaged_pages

Definition at line 108 of file bufmgr.c.

Referenced by mdread(), and ReadBuffer_common().