PostgreSQL Source Code git master
Data Structures | Macros | Typedefs | Functions | Variables
buf_internals.h File Reference
#include "pgstat.h"
#include "port/atomics.h"
#include "storage/aio_types.h"
#include "storage/buf.h"
#include "storage/bufmgr.h"
#include "storage/condition_variable.h"
#include "storage/lwlock.h"
#include "storage/procnumber.h"
#include "storage/shmem.h"
#include "storage/smgr.h"
#include "storage/spin.h"
#include "utils/relcache.h"
#include "utils/resowner.h"
Include dependency graph for buf_internals.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct   buftag
 
struct   BufferDesc
 
union   BufferDescPadded
 
struct   PendingWriteback
 
struct   WritebackContext
 
struct   CkptSortItem
 

Macros

#define  BUF_REFCOUNT_BITS   18
 
#define  BUF_USAGECOUNT_BITS   4
 
#define  BUF_FLAG_BITS   10
 
#define  BUF_REFCOUNT_ONE   1
 
#define  BUF_REFCOUNT_MASK   ((1U << BUF_REFCOUNT_BITS) - 1)
 
#define  BUF_USAGECOUNT_MASK   (((1U << BUF_USAGECOUNT_BITS) - 1) << (BUF_REFCOUNT_BITS))
 
#define  BUF_USAGECOUNT_ONE   (1U << BUF_REFCOUNT_BITS)
 
 
#define  BUF_FLAG_MASK   (((1U << BUF_FLAG_BITS) - 1) << (BUF_REFCOUNT_BITS + BUF_USAGECOUNT_BITS))
 
 
 
#define  BM_LOCKED   (1U << 22) /* buffer header is locked */
 
#define  BM_DIRTY   (1U << 23) /* data needs writing */
 
#define  BM_VALID   (1U << 24) /* data is valid */
 
#define  BM_TAG_VALID   (1U << 25) /* tag is assigned */
 
#define  BM_IO_IN_PROGRESS   (1U << 26) /* read or write in progress */
 
#define  BM_IO_ERROR   (1U << 27) /* previous I/O failed */
 
#define  BM_JUST_DIRTIED   (1U << 28) /* dirtied since write started */
 
#define  BM_PIN_COUNT_WAITER   (1U << 29) /* have waiter for sole pin */
 
#define  BM_CHECKPOINT_NEEDED   (1U << 30) /* must write for checkpoint */
 
#define  BM_PERMANENT
 
#define  BM_MAX_USAGE_COUNT   5
 
#define  BUFFERDESC_PAD_TO_SIZE   (SIZEOF_VOID_P == 8 ? 64 : 1)
 

Typedefs

typedef struct buftag  BufferTag
 
typedef struct BufferDesc  BufferDesc
 
 
 
 
typedef struct CkptSortItem  CkptSortItem
 

Functions

  StaticAssertDecl (BUF_REFCOUNT_BITS+BUF_USAGECOUNT_BITS+BUF_FLAG_BITS==32, "parts of buffer state space need to equal 32")
 
  StaticAssertDecl (BM_MAX_USAGE_COUNT<(1<< BUF_USAGECOUNT_BITS), "BM_MAX_USAGE_COUNT doesn't fit in BUF_USAGECOUNT_BITS bits")
 
  StaticAssertDecl (MAX_BACKENDS_BITS<=BUF_REFCOUNT_BITS, "MAX_BACKENDS_BITS needs to be <= BUF_REFCOUNT_BITS")
 
 
static ForkNumber  BufTagGetForkNum (const BufferTag *tag)
 
static void  BufTagSetRelForkDetails (BufferTag *tag, RelFileNumber relnumber, ForkNumber forknum)
 
 
static void  ClearBufferTag (BufferTag *tag)
 
static void  InitBufferTag (BufferTag *tag, const RelFileLocator *rlocator, ForkNumber forkNum, BlockNumber blockNum)
 
static bool  BufferTagsEqual (const BufferTag *tag1, const BufferTag *tag2)
 
static bool  BufTagMatchesRelFileLocator (const BufferTag *tag, const RelFileLocator *rlocator)
 
static uint32  BufTableHashPartition (uint32 hashcode)
 
static LWLockBufMappingPartitionLock (uint32 hashcode)
 
 
 
 
 
 
 
 
static void  UnlockBufHdr (BufferDesc *desc, uint32 buf_state)
 
static void  ResourceOwnerRememberBuffer (ResourceOwner owner, Buffer buffer)
 
static void  ResourceOwnerForgetBuffer (ResourceOwner owner, Buffer buffer)
 
static void  ResourceOwnerRememberBufferIO (ResourceOwner owner, Buffer buffer)
 
static void  ResourceOwnerForgetBufferIO (ResourceOwner owner, Buffer buffer)
 
void  WritebackContextInit (WritebackContext *context, int *max_pending)
 
void  IssuePendingWritebacks (WritebackContext *wb_context, IOContext io_context)
 
void  ScheduleBufferTagForWriteback (WritebackContext *wb_context, IOContext io_context, BufferTag *tag)
 
bool  StartBufferIO (BufferDesc *buf, bool forInput, bool nowait)
 
void  TerminateBufferIO (BufferDesc *buf, bool clear_dirty, uint32 set_flag_bits, bool forget_owner, bool release_aio)
 
 
BufferDescStrategyGetBuffer (BufferAccessStrategy strategy, uint32 *buf_state, bool *from_ring)
 
bool  StrategyRejectBuffer (BufferAccessStrategy strategy, BufferDesc *buf, bool from_ring)
 
int  StrategySyncStart (uint32 *complete_passes, uint32 *num_buf_alloc)
 
void  StrategyNotifyBgWriter (int bgwprocno)
 
 
void  StrategyInitialize (bool init)
 
Size  BufTableShmemSize (int size)
 
void  InitBufTable (int size)
 
 
int  BufTableLookup (BufferTag *tagPtr, uint32 hashcode)
 
int  BufTableInsert (BufferTag *tagPtr, uint32 hashcode, int buf_id)
 
void  BufTableDelete (BufferTag *tagPtr, uint32 hashcode)
 
bool  PinLocalBuffer (BufferDesc *buf_hdr, bool adjust_usagecount)
 
void  UnpinLocalBuffer (Buffer buffer)
 
 
 
BufferDescLocalBufferAlloc (SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum, bool *foundPtr)
 
BlockNumber  ExtendBufferedRelLocal (BufferManagerRelation bmr, ForkNumber fork, uint32 flags, uint32 extend_by, BlockNumber extend_upto, Buffer *buffers, uint32 *extended_by)
 
void  MarkLocalBufferDirty (Buffer buffer)
 
void  TerminateLocalBufferIO (BufferDesc *bufHdr, bool clear_dirty, uint32 set_flag_bits, bool release_aio)
 
bool  StartLocalBufferIO (BufferDesc *bufHdr, bool forInput, bool nowait)
 
void  FlushLocalBuffer (BufferDesc *bufHdr, SMgrRelation reln)
 
void  InvalidateLocalBuffer (BufferDesc *bufHdr, bool check_unreferenced)
 
void  DropRelationLocalBuffers (RelFileLocator rlocator, ForkNumber *forkNum, int nforks, BlockNumber *firstDelBlock)
 
 
void  AtEOXact_LocalBuffers (bool isCommit)
 

Variables

 
 
 
 
 
 
 

Macro Definition Documentation

BM_CHECKPOINT_NEEDED

#define BM_CHECKPOINT_NEEDED   (1U << 30) /* must write for checkpoint */

Definition at line 76 of file buf_internals.h.

BM_DIRTY

#define BM_DIRTY   (1U << 23) /* data needs writing */

Definition at line 69 of file buf_internals.h.

BM_IO_ERROR

#define BM_IO_ERROR   (1U << 27) /* previous I/O failed */

Definition at line 73 of file buf_internals.h.

BM_IO_IN_PROGRESS

#define BM_IO_IN_PROGRESS   (1U << 26) /* read or write in progress */

Definition at line 72 of file buf_internals.h.

BM_JUST_DIRTIED

#define BM_JUST_DIRTIED   (1U << 28) /* dirtied since write started */

Definition at line 74 of file buf_internals.h.

BM_LOCKED

#define BM_LOCKED   (1U << 22) /* buffer header is locked */

Definition at line 68 of file buf_internals.h.

BM_MAX_USAGE_COUNT

#define BM_MAX_USAGE_COUNT   5

Definition at line 86 of file buf_internals.h.

BM_PERMANENT

#define BM_PERMANENT
Value:
(1U << 31) /* permanent buffer (not unlogged,
* or init fork) */

Definition at line 77 of file buf_internals.h.

BM_PIN_COUNT_WAITER

#define BM_PIN_COUNT_WAITER   (1U << 29) /* have waiter for sole pin */

Definition at line 75 of file buf_internals.h.

BM_TAG_VALID

#define BM_TAG_VALID   (1U << 25) /* tag is assigned */

Definition at line 71 of file buf_internals.h.

BM_VALID

#define BM_VALID   (1U << 24) /* data is valid */

Definition at line 70 of file buf_internals.h.

BUF_FLAG_BITS

#define BUF_FLAG_BITS   10

Definition at line 46 of file buf_internals.h.

BUF_FLAG_MASK

#define BUF_FLAG_MASK   (((1U << BUF_FLAG_BITS) - 1) << (BUF_REFCOUNT_BITS + BUF_USAGECOUNT_BITS))

Definition at line 56 of file buf_internals.h.

BUF_REFCOUNT_BITS

#define BUF_REFCOUNT_BITS   18

Definition at line 44 of file buf_internals.h.

BUF_REFCOUNT_MASK

#define BUF_REFCOUNT_MASK   ((1U << BUF_REFCOUNT_BITS) - 1)

Definition at line 52 of file buf_internals.h.

BUF_REFCOUNT_ONE

#define BUF_REFCOUNT_ONE   1

Definition at line 51 of file buf_internals.h.

BUF_STATE_GET_REFCOUNT

#define BUF_STATE_GET_REFCOUNT (   state )    ((state) & BUF_REFCOUNT_MASK)

Definition at line 59 of file buf_internals.h.

BUF_STATE_GET_USAGECOUNT

#define BUF_STATE_GET_USAGECOUNT (   state )    (((state) & BUF_USAGECOUNT_MASK) >> BUF_USAGECOUNT_SHIFT)

Definition at line 60 of file buf_internals.h.

BUF_USAGECOUNT_BITS

#define BUF_USAGECOUNT_BITS   4

Definition at line 45 of file buf_internals.h.

BUF_USAGECOUNT_MASK

#define BUF_USAGECOUNT_MASK   (((1U << BUF_USAGECOUNT_BITS) - 1) << (BUF_REFCOUNT_BITS))

Definition at line 53 of file buf_internals.h.

BUF_USAGECOUNT_ONE

#define BUF_USAGECOUNT_ONE   (1U << BUF_REFCOUNT_BITS)

Definition at line 54 of file buf_internals.h.

BUF_USAGECOUNT_SHIFT

#define BUF_USAGECOUNT_SHIFT   BUF_REFCOUNT_BITS

Definition at line 55 of file buf_internals.h.

BUFFERDESC_PAD_TO_SIZE

#define BUFFERDESC_PAD_TO_SIZE   (SIZEOF_VOID_P == 8 ? 64 : 1)

Definition at line 290 of file buf_internals.h.

Typedef Documentation

BufferDesc

typedef struct BufferDesc BufferDesc

BufferDescPadded

BufferTag

typedef struct buftag BufferTag

CkptSortItem

typedef struct CkptSortItem CkptSortItem

PendingWriteback

WritebackContext

Function Documentation

AtEOXact_LocalBuffers()

void AtEOXact_LocalBuffers ( bool  isCommit )

Definition at line 1001 of file localbuf.c.

1002{
1004}
static void CheckForLocalBufferLeaks(void)
Definition: localbuf.c:968

References CheckForLocalBufferLeaks().

Referenced by AtEOXact_Buffers().

BufferDescriptorGetBuffer()

static Buffer BufferDescriptorGetBuffer ( const BufferDescbdesc )
inlinestatic

Definition at line 343 of file buf_internals.h.

345{
346 return (Buffer) (bdesc->buf_id + 1);
int Buffer
Definition: buf.h:23

References BufferDesc::buf_id.

Referenced by AddBufferToRing(), ExtendBufferedRelLocal(), ExtendBufferedRelShared(), FlushLocalBuffer(), FlushRelationBuffers(), GetLocalVictimBuffer(), GetVictimBuffer(), InvalidateBuffer(), InvalidateLocalBuffer(), InvalidateVictimBuffer(), LockBufHdr(), pg_buffercache_numa_pages(), pg_buffercache_pages(), PinBuffer(), PinBuffer_Locked(), PinBufferForBlock(), PinLocalBuffer(), StartBufferIO(), StrategyRejectBuffer(), TerminateBufferIO(), UnpinBuffer(), and UnpinBufferNoOwner().

BufferDescriptorGetContentLock()

static LWLock * BufferDescriptorGetContentLock ( const BufferDescbdesc )
inlinestatic

Definition at line 355 of file buf_internals.h.

357{
358 return (LWLock *) (&bdesc->content_lock);
LWLock content_lock
Definition: buf_internals.h:267
Definition: lwlock.h:42

References BufferDesc::content_lock.

Referenced by buffer_stage_common(), BufferIsDirty(), BufferIsExclusiveLocked(), BufferManagerShmemInit(), ConditionalLockBuffer(), EvictUnpinnedBufferInternal(), ExtendBufferedRelShared(), FlushDatabaseBuffers(), FlushOneBuffer(), FlushRelationBuffers(), FlushRelationsAllBuffers(), GetVictimBuffer(), IsBufferCleanupOK(), LockBuffer(), MarkBufferDirty(), MarkBufferDirtyHint(), SyncOneBuffer(), UnpinBufferNoOwner(), and ZeroAndLockBuffer().

BufferDescriptorGetIOCV()

static ConditionVariable * BufferDescriptorGetIOCV ( const BufferDescbdesc )
inlinestatic

Definition at line 349 of file buf_internals.h.

351{
352 return &(BufferIOCVArray[bdesc->buf_id]).cv;
PGDLLIMPORT ConditionVariableMinimallyPadded * BufferIOCVArray
Definition: buf_init.c:23

References BufferDesc::buf_id, and BufferIOCVArray.

Referenced by BufferManagerShmemInit(), TerminateBufferIO(), and WaitIO().

BufferTagsEqual()

static bool BufferTagsEqual ( const BufferTagtag1,
const BufferTagtag2 
)
inlinestatic

Definition at line 166 of file buf_internals.h.

168{
169 return (tag1->spcOid == tag2->spcOid) &&
170 (tag1->dbOid == tag2->dbOid) &&
171 (tag1->relNumber == tag2->relNumber) &&
172 (tag1->blockNum == tag2->blockNum) &&
173 (tag1->forkNum == tag2->forkNum);
BlockNumber blockNum
Definition: buf_internals.h:111
RelFileNumber relNumber
Definition: buf_internals.h:109
ForkNumber forkNum
Definition: buf_internals.h:110
Oid spcOid
Definition: buf_internals.h:107
Oid dbOid
Definition: buf_internals.h:108

References buftag::blockNum, buftag::dbOid, buftag::forkNum, buftag::relNumber, and buftag::spcOid.

Referenced by InvalidateBuffer(), InvalidateVictimBuffer(), LocalBufferAlloc(), and ReadRecentBuffer().

BufMappingPartitionLock()

static LWLock * BufMappingPartitionLock ( uint32  hashcode )
inlinestatic

Definition at line 198 of file buf_internals.h.

200{
202 BufTableHashPartition(hashcode)].lock;
static uint32 BufTableHashPartition(uint32 hashcode)
Definition: buf_internals.h:192
LWLockPadded * MainLWLockArray
Definition: lwlock.c:161
#define BUFFER_MAPPING_LWLOCK_OFFSET
Definition: lwlock.h:102
LWLock lock
Definition: lwlock.h:70

References BUFFER_MAPPING_LWLOCK_OFFSET, BufTableHashPartition(), LWLockPadded::lock, and MainLWLockArray.

Referenced by BufferAlloc(), ExtendBufferedRelShared(), FindAndDropRelationBuffers(), InvalidateBuffer(), InvalidateVictimBuffer(), and PrefetchSharedBuffer().

BufMappingPartitionLockByIndex()

static LWLock * BufMappingPartitionLockByIndex ( uint32  index )
inlinestatic

Definition at line 205 of file buf_internals.h.

References BUFFER_MAPPING_LWLOCK_OFFSET, LWLockPadded::lock, and MainLWLockArray.

BufTableDelete()

void BufTableDelete ( BufferTagtagPtr,
uint32  hashcode 
)

Definition at line 148 of file buf_table.c.

149{
150 BufferLookupEnt *result;
151
152 result = (BufferLookupEnt *)
154 tagPtr,
155 hashcode,
157 NULL);
158
159 if (!result) /* shouldn't happen */
160 elog(ERROR, "shared buffer hash table corrupted");
161}
static HTAB * SharedBufHash
Definition: buf_table.c:33
void * hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, uint32 hashvalue, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:965
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
@ HASH_REMOVE
Definition: hsearch.h:115

References elog, ERROR, HASH_REMOVE, hash_search_with_hash_value(), and SharedBufHash.

Referenced by InvalidateBuffer(), and InvalidateVictimBuffer().

BufTableHashCode()

uint32 BufTableHashCode ( BufferTagtagPtr )

Definition at line 78 of file buf_table.c.

79{
80 return get_hash_value(SharedBufHash, tagPtr);
81}
uint32 get_hash_value(HTAB *hashp, const void *keyPtr)
Definition: dynahash.c:908

References get_hash_value(), and SharedBufHash.

Referenced by BufferAlloc(), ExtendBufferedRelShared(), FindAndDropRelationBuffers(), InvalidateBuffer(), InvalidateVictimBuffer(), and PrefetchSharedBuffer().

BufTableHashPartition()

static uint32 BufTableHashPartition ( uint32  hashcode )
inlinestatic

Definition at line 192 of file buf_internals.h.

194{
195 return hashcode % NUM_BUFFER_PARTITIONS;
#define NUM_BUFFER_PARTITIONS
Definition: lwlock.h:91

References NUM_BUFFER_PARTITIONS.

Referenced by BufMappingPartitionLock().

BufTableInsert()

int BufTableInsert ( BufferTagtagPtr,
uint32  hashcode,
int  buf_id 
)

Definition at line 118 of file buf_table.c.

119{
120 BufferLookupEnt *result;
121 bool found;
122
123 Assert(buf_id >= 0); /* -1 is reserved for not-in-table */
124 Assert(tagPtr->blockNum != P_NEW); /* invalid tag */
125
126 result = (BufferLookupEnt *)
128 tagPtr,
129 hashcode,
131 &found);
132
133 if (found) /* found something already in the table */
134 return result->id;
135
136 result->id = buf_id;
137
138 return -1;
139}
#define P_NEW
Definition: bufmgr.h:191
Assert(PointerIsAligned(start, uint64))
@ HASH_ENTER
Definition: hsearch.h:114

References Assert(), buftag::blockNum, HASH_ENTER, hash_search_with_hash_value(), BufferLookupEnt::id, P_NEW, and SharedBufHash.

Referenced by BufferAlloc(), and ExtendBufferedRelShared().

BufTableLookup()

int BufTableLookup ( BufferTagtagPtr,
uint32  hashcode 
)

Definition at line 90 of file buf_table.c.

91{
92 BufferLookupEnt *result;
93
94 result = (BufferLookupEnt *)
96 tagPtr,
97 hashcode,
99 NULL);
100
101 if (!result)
102 return -1;
103
104 return result->id;
105}
@ HASH_FIND
Definition: hsearch.h:113

References HASH_FIND, hash_search_with_hash_value(), BufferLookupEnt::id, and SharedBufHash.

Referenced by BufferAlloc(), FindAndDropRelationBuffers(), and PrefetchSharedBuffer().

BufTableShmemSize()

Size BufTableShmemSize ( int  size )

Definition at line 41 of file buf_table.c.

42{
43 return hash_estimate_size(size, sizeof(BufferLookupEnt));
44}
Size hash_estimate_size(int64 num_entries, Size entrysize)
Definition: dynahash.c:783

References hash_estimate_size().

Referenced by StrategyShmemSize().

BufTagGetForkNum()

static ForkNumber BufTagGetForkNum ( const BufferTagtag )
inlinestatic

Definition at line 121 of file buf_internals.h.

123{
124 return tag->forkNum;

References buftag::forkNum.

Referenced by AbortBufferIO(), apw_dump_now(), BufferGetTag(), BufferSync(), buffertag_comparator(), DebugPrintBufferRefcount(), DropRelationBuffers(), DropRelationLocalBuffers(), FindAndDropRelationBuffers(), FlushBuffer(), FlushLocalBuffer(), InvalidateLocalBuffer(), IssuePendingWritebacks(), local_buffer_write_error_callback(), pg_buffercache_pages(), ReleaseAndReadBuffer(), and shared_buffer_write_error_callback().

BufTagGetRelFileLocator()

static RelFileLocator BufTagGetRelFileLocator ( const BufferTagtag )
inlinestatic

Definition at line 135 of file buf_internals.h.

137{
138 RelFileLocator rlocator;
139
140 rlocator.spcOid = tag->spcOid;
141 rlocator.dbOid = tag->dbOid;
142 rlocator.relNumber = BufTagGetRelNumber(tag);
143
144 return rlocator;
static RelFileNumber BufTagGetRelNumber(const BufferTag *tag)
Definition: buf_internals.h:115
RelFileNumber relNumber
Definition: relfilelocator.h:62

References BufTagGetRelNumber(), buftag::dbOid, RelFileLocator::dbOid, RelFileLocator::relNumber, buftag::spcOid, and RelFileLocator::spcOid.

Referenced by AbortBufferIO(), BufferGetTag(), buffertag_comparator(), DebugPrintBufferRefcount(), DropRelationsAllBuffers(), FlushBuffer(), FlushLocalBuffer(), FlushRelationsAllBuffers(), InvalidateLocalBuffer(), IssuePendingWritebacks(), local_buffer_write_error_callback(), MarkBufferDirtyHint(), and shared_buffer_write_error_callback().

BufTagGetRelNumber()

static RelFileNumber BufTagGetRelNumber ( const BufferTagtag )
inlinestatic

Definition at line 115 of file buf_internals.h.

117{
118 return tag->relNumber;

References buftag::relNumber.

Referenced by apw_dump_now(), BufferSync(), BufTagGetRelFileLocator(), BufTagMatchesRelFileLocator(), and pg_buffercache_pages().

BufTagMatchesRelFileLocator()

static bool BufTagMatchesRelFileLocator ( const BufferTagtag,
const RelFileLocatorrlocator 
)
inlinestatic

Definition at line 176 of file buf_internals.h.

179{
180 return (tag->spcOid == rlocator->spcOid) &&
181 (tag->dbOid == rlocator->dbOid) &&
182 (BufTagGetRelNumber(tag) == rlocator->relNumber);

References BufTagGetRelNumber(), buftag::dbOid, RelFileLocator::dbOid, RelFileLocator::relNumber, buftag::spcOid, and RelFileLocator::spcOid.

Referenced by DropRelationAllLocalBuffers(), DropRelationBuffers(), DropRelationLocalBuffers(), DropRelationsAllBuffers(), EvictRelUnpinnedBuffers(), FindAndDropRelationBuffers(), FlushRelationBuffers(), FlushRelationsAllBuffers(), and ReleaseAndReadBuffer().

BufTagSetRelForkDetails()

static void BufTagSetRelForkDetails ( BufferTagtag,
RelFileNumber  relnumber,
ForkNumber  forknum 
)
inlinestatic

Definition at line 127 of file buf_internals.h.

130{
131 tag->relNumber = relnumber;
132 tag->forkNum = forknum;

References buftag::forkNum, and buftag::relNumber.

Referenced by ClearBufferTag(), and InitBufferTag().

ClearBufferTag()

static void ClearBufferTag ( BufferTagtag )
inlinestatic

Definition at line 147 of file buf_internals.h.

149{
150 tag->spcOid = InvalidOid;
151 tag->dbOid = InvalidOid;
#define InvalidBlockNumber
Definition: block.h:33
static void BufTagSetRelForkDetails(BufferTag *tag, RelFileNumber relnumber, ForkNumber forknum)
Definition: buf_internals.h:127
#define InvalidOid
Definition: postgres_ext.h:37
@ InvalidForkNumber
Definition: relpath.h:57
#define InvalidRelFileNumber
Definition: relpath.h:26

References buftag::blockNum, BufTagSetRelForkDetails(), buftag::dbOid, InvalidBlockNumber, InvalidForkNumber, InvalidOid, InvalidRelFileNumber, and buftag::spcOid.

Referenced by BufferManagerShmemInit(), InvalidateBuffer(), InvalidateLocalBuffer(), and InvalidateVictimBuffer().

DropRelationAllLocalBuffers()

void DropRelationAllLocalBuffers ( RelFileLocator  rlocator )

Definition at line 700 of file localbuf.c.

701{
702 int i;
703
704 for (i = 0; i < NLocBuffer; i++)
705 {
707 uint32 buf_state;
708
709 buf_state = pg_atomic_read_u32(&bufHdr->state);
710
711 if ((buf_state & BM_TAG_VALID) &&
712 BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator))
713 {
714 InvalidateLocalBuffer(bufHdr, true);
715 }
716 }
717}
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:237
#define BM_TAG_VALID
Definition: buf_internals.h:71
static bool BufTagMatchesRelFileLocator(const BufferTag *tag, const RelFileLocator *rlocator)
Definition: buf_internals.h:176
static BufferDesc * GetLocalBufferDescriptor(uint32 id)
Definition: buf_internals.h:337
uint32_t uint32
Definition: c.h:538
i
int i
Definition: isn.c:77
void InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced)
Definition: localbuf.c:603
int NLocBuffer
Definition: localbuf.c:44
BufferTag tag
Definition: buf_internals.h:258
pg_atomic_uint32 state
Definition: buf_internals.h:262

References BM_TAG_VALID, BufTagMatchesRelFileLocator(), GetLocalBufferDescriptor(), i, InvalidateLocalBuffer(), NLocBuffer, pg_atomic_read_u32(), BufferDesc::state, and BufferDesc::tag.

Referenced by DropRelationsAllBuffers().

DropRelationLocalBuffers()

void DropRelationLocalBuffers ( RelFileLocator  rlocator,
ForkNumberforkNum,
int  nforks,
BlockNumberfirstDelBlock 
)

Definition at line 663 of file localbuf.c.

665{
666 int i;
667 int j;
668
669 for (i = 0; i < NLocBuffer; i++)
670 {
672 uint32 buf_state;
673
674 buf_state = pg_atomic_read_u32(&bufHdr->state);
675
676 if (!(buf_state & BM_TAG_VALID) ||
677 !BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator))
678 continue;
679
680 for (j = 0; j < nforks; j++)
681 {
682 if (BufTagGetForkNum(&bufHdr->tag) == forkNum[j] &&
683 bufHdr->tag.blockNum >= firstDelBlock[j])
684 {
685 InvalidateLocalBuffer(bufHdr, true);
686 break;
687 }
688 }
689 }
690}
static ForkNumber BufTagGetForkNum(const BufferTag *tag)
Definition: buf_internals.h:121
j
int j
Definition: isn.c:78

References buftag::blockNum, BM_TAG_VALID, BufTagGetForkNum(), BufTagMatchesRelFileLocator(), GetLocalBufferDescriptor(), i, InvalidateLocalBuffer(), j, NLocBuffer, pg_atomic_read_u32(), BufferDesc::state, and BufferDesc::tag.

Referenced by DropRelationBuffers().

ExtendBufferedRelLocal()

BlockNumber ExtendBufferedRelLocal ( BufferManagerRelation  bmr,
ForkNumber  fork,
uint32  flags,
uint32  extend_by,
BlockNumber  extend_upto,
Bufferbuffers,
uint32extended_by 
)

Definition at line 345 of file localbuf.c.

352{
353 BlockNumber first_block;
354 instr_time io_start;
355
356 /* Initialize local buffers if first request in this session */
357 if (LocalBufHash == NULL)
359
360 LimitAdditionalLocalPins(&extend_by);
361
362 for (uint32 i = 0; i < extend_by; i++)
363 {
364 BufferDesc *buf_hdr;
365 Block buf_block;
366
367 buffers[i] = GetLocalVictimBuffer();
368 buf_hdr = GetLocalBufferDescriptor(-buffers[i] - 1);
369 buf_block = LocalBufHdrGetBlock(buf_hdr);
370
371 /* new buffers are zero-filled */
372 MemSet(buf_block, 0, BLCKSZ);
373 }
374
375 first_block = smgrnblocks(bmr.smgr, fork);
376
377 if (extend_upto != InvalidBlockNumber)
378 {
379 /*
380 * In contrast to shared relations, nothing could change the relation
381 * size concurrently. Thus we shouldn't end up finding that we don't
382 * need to do anything.
383 */
384 Assert(first_block <= extend_upto);
385
386 Assert((uint64) first_block + extend_by <= extend_upto);
387 }
388
389 /* Fail if relation is already at maximum possible length */
390 if ((uint64) first_block + extend_by >= MaxBlockNumber)
392 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
393 errmsg("cannot extend relation %s beyond %u blocks",
394 relpath(bmr.smgr->smgr_rlocator, fork).str,
396
397 for (uint32 i = 0; i < extend_by; i++)
398 {
399 int victim_buf_id;
400 BufferDesc *victim_buf_hdr;
401 BufferTag tag;
402 LocalBufferLookupEnt *hresult;
403 bool found;
404
405 victim_buf_id = -buffers[i] - 1;
406 victim_buf_hdr = GetLocalBufferDescriptor(victim_buf_id);
407
408 /* in case we need to pin an existing buffer below */
410
411 InitBufferTag(&tag, &bmr.smgr->smgr_rlocator.locator, fork, first_block + i);
412
413 hresult = (LocalBufferLookupEnt *)
414 hash_search(LocalBufHash, &tag, HASH_ENTER, &found);
415 if (found)
416 {
417 BufferDesc *existing_hdr;
418 uint32 buf_state;
419
421
422 existing_hdr = GetLocalBufferDescriptor(hresult->id);
423 PinLocalBuffer(existing_hdr, false);
424 buffers[i] = BufferDescriptorGetBuffer(existing_hdr);
425
426 /*
427 * Clear the BM_VALID bit, do StartLocalBufferIO() and proceed.
428 */
429 buf_state = pg_atomic_read_u32(&existing_hdr->state);
430 Assert(buf_state & BM_TAG_VALID);
431 Assert(!(buf_state & BM_DIRTY));
432 buf_state &= ~BM_VALID;
433 pg_atomic_unlocked_write_u32(&existing_hdr->state, buf_state);
434
435 /* no need to loop for local buffers */
436 StartLocalBufferIO(existing_hdr, true, false);
437 }
438 else
439 {
440 uint32 buf_state = pg_atomic_read_u32(&victim_buf_hdr->state);
441
442 Assert(!(buf_state & (BM_VALID | BM_TAG_VALID | BM_DIRTY | BM_JUST_DIRTIED)));
443
444 victim_buf_hdr->tag = tag;
445
446 buf_state |= BM_TAG_VALID | BUF_USAGECOUNT_ONE;
447
448 pg_atomic_unlocked_write_u32(&victim_buf_hdr->state, buf_state);
449
450 hresult->id = victim_buf_id;
451
452 StartLocalBufferIO(victim_buf_hdr, true, false);
453 }
454 }
455
457
458 /* actually extend relation */
459 smgrzeroextend(bmr.smgr, fork, first_block, extend_by, false);
460
462 io_start, 1, extend_by * BLCKSZ);
463
464 for (uint32 i = 0; i < extend_by; i++)
465 {
466 Buffer buf = buffers[i];
467 BufferDesc *buf_hdr;
468 uint32 buf_state;
469
470 buf_hdr = GetLocalBufferDescriptor(-buf - 1);
471
472 buf_state = pg_atomic_read_u32(&buf_hdr->state);
473 buf_state |= BM_VALID;
474 pg_atomic_unlocked_write_u32(&buf_hdr->state, buf_state);
475 }
476
477 *extended_by = extend_by;
478
480
481 return first_block;
482}
static void pg_atomic_unlocked_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:293
uint32 BlockNumber
Definition: block.h:31
#define MaxBlockNumber
Definition: block.h:35
static void InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator, ForkNumber forkNum, BlockNumber blockNum)
Definition: buf_internals.h:156
#define BM_DIRTY
Definition: buf_internals.h:69
#define BM_JUST_DIRTIED
Definition: buf_internals.h:74
#define BUF_USAGECOUNT_ONE
Definition: buf_internals.h:54
#define BM_VALID
Definition: buf_internals.h:70
static Buffer BufferDescriptorGetBuffer(const BufferDesc *bdesc)
Definition: buf_internals.h:343
bool track_io_timing
Definition: bufmgr.c:147
void * Block
Definition: bufmgr.h:26
uint64_t uint64
Definition: c.h:539
#define MemSet(start, val, len)
Definition: c.h:1019
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:952
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ereport(elevel,...)
Definition: elog.h:150
BufferUsage pgBufferUsage
Definition: instrument.c:20
void UnpinLocalBuffer(Buffer buffer)
Definition: localbuf.c:839
bool StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool nowait)
Definition: localbuf.c:521
static HTAB * LocalBufHash
Definition: localbuf.c:52
#define LocalBufHdrGetBlock(bufHdr)
Definition: localbuf.c:41
bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount)
Definition: localbuf.c:803
static void InitLocalBuffers(void)
Definition: localbuf.c:726
void LimitAdditionalLocalPins(uint32 *additional_pins)
Definition: localbuf.c:322
static Buffer GetLocalVictimBuffer(void)
Definition: localbuf.c:223
static char * buf
Definition: pg_test_fsync.c:72
@ IOOBJECT_TEMP_RELATION
Definition: pgstat.h:276
@ IOCONTEXT_NORMAL
Definition: pgstat.h:287
@ IOOP_EXTEND
Definition: pgstat.h:312
instr_time pgstat_prepare_io_time(bool track_io_guc)
Definition: pgstat_io.c:91
void pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op, instr_time start_time, uint32 cnt, uint64 bytes)
Definition: pgstat_io.c:122
#define relpath(rlocator, forknum)
Definition: relpath.h:150
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:449
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:819
void smgrzeroextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks, bool skipFsync)
Definition: smgr.c:649
SMgrRelation smgr
Definition: bufmgr.h:107
int64 local_blks_written
Definition: instrument.h:33
RelFileLocator locator
Definition: relfilelocator.h:75
RelFileLocatorBackend smgr_rlocator
Definition: smgr.h:38

References Assert(), BM_DIRTY, BM_JUST_DIRTIED, BM_TAG_VALID, BM_VALID, buf, BUF_USAGECOUNT_ONE, BufferDescriptorGetBuffer(), CurrentResourceOwner, ereport, errcode(), errmsg(), ERROR, GetLocalBufferDescriptor(), GetLocalVictimBuffer(), HASH_ENTER, hash_search(), i, LocalBufferLookupEnt::id, InitBufferTag(), InitLocalBuffers(), InvalidBlockNumber, IOCONTEXT_NORMAL, IOOBJECT_TEMP_RELATION, IOOP_EXTEND, LimitAdditionalLocalPins(), BufferUsage::local_blks_written, LocalBufHash, LocalBufHdrGetBlock, RelFileLocatorBackend::locator, MaxBlockNumber, MemSet, pg_atomic_read_u32(), pg_atomic_unlocked_write_u32(), pgBufferUsage, pgstat_count_io_op_time(), pgstat_prepare_io_time(), PinLocalBuffer(), relpath, ResourceOwnerEnlarge(), BufferManagerRelation::smgr, SMgrRelationData::smgr_rlocator, smgrnblocks(), smgrzeroextend(), StartLocalBufferIO(), BufferDesc::state, BufferDesc::tag, track_io_timing, and UnpinLocalBuffer().

Referenced by ExtendBufferedRelCommon().

FlushLocalBuffer()

void FlushLocalBuffer ( BufferDescbufHdr,
SMgrRelation  reln 
)

Definition at line 182 of file localbuf.c.

183{
184 instr_time io_start;
185 Page localpage = (char *) LocalBufHdrGetBlock(bufHdr);
186
188
189 /*
190 * Try to start an I/O operation. There currently are no reasons for
191 * StartLocalBufferIO to return false, so we raise an error in that case.
192 */
193 if (!StartLocalBufferIO(bufHdr, false, false))
194 elog(ERROR, "failed to start write IO on local buffer");
195
196 /* Find smgr relation for buffer */
197 if (reln == NULL)
198 reln = smgropen(BufTagGetRelFileLocator(&bufHdr->tag),
200
201 PageSetChecksumInplace(localpage, bufHdr->tag.blockNum);
202
204
205 /* And write... */
206 smgrwrite(reln,
207 BufTagGetForkNum(&bufHdr->tag),
208 bufHdr->tag.blockNum,
209 localpage,
210 false);
211
212 /* Temporary table I/O does not use Buffer Access Strategies */
214 IOOP_WRITE, io_start, 1, BLCKSZ);
215
216 /* Mark not-dirty */
217 TerminateLocalBufferIO(bufHdr, true, 0, false);
218
220}
static RelFileLocator BufTagGetRelFileLocator(const BufferTag *tag)
Definition: buf_internals.h:135
void PageSetChecksumInplace(Page page, BlockNumber blkno)
Definition: bufpage.c:1541
PageData * Page
Definition: bufpage.h:82
ProcNumber MyProcNumber
Definition: globals.c:90
int32 * LocalRefCount
Definition: localbuf.c:48
void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint32 set_flag_bits, bool release_aio)
Definition: localbuf.c:560
@ IOOP_WRITE
Definition: pgstat.h:314
SMgrRelation smgropen(RelFileLocator rlocator, ProcNumber backend)
Definition: smgr.c:240
static void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void *buffer, bool skipFsync)
Definition: smgr.h:131

References Assert(), buftag::blockNum, BufferDescriptorGetBuffer(), BufTagGetForkNum(), BufTagGetRelFileLocator(), elog, ERROR, IOCONTEXT_NORMAL, IOOBJECT_TEMP_RELATION, IOOP_WRITE, BufferUsage::local_blks_written, LocalBufHdrGetBlock, LocalRefCount, MyProcNumber, PageSetChecksumInplace(), pgBufferUsage, pgstat_count_io_op_time(), pgstat_prepare_io_time(), smgropen(), smgrwrite(), StartLocalBufferIO(), BufferDesc::tag, TerminateLocalBufferIO(), and track_io_timing.

Referenced by FlushRelationBuffers(), GetLocalVictimBuffer(), and invalidate_rel_block().

GetBufferDescriptor()

static BufferDesc * GetBufferDescriptor ( uint32  id )
inlinestatic

Definition at line 331 of file buf_internals.h.

333{
334 return &(BufferDescriptors[id]).bufferdesc;
PGDLLIMPORT BufferDescPadded * BufferDescriptors
Definition: buf_init.c:21

References BufferDescriptors.

Referenced by AbortBufferIO(), apw_dump_now(), buffer_call_start_io(), buffer_call_terminate_io(), buffer_readv_complete_one(), buffer_stage_common(), BufferAlloc(), BufferGetBlockNumber(), BufferGetLSNAtomic(), BufferGetTag(), BufferIsDirty(), BufferIsExclusiveLocked(), BufferIsPermanent(), BufferManagerShmemInit(), BufferSync(), CheckReadBuffersOperation(), ConditionalLockBuffer(), ConditionalLockBufferForCleanup(), create_toy_buffer(), DebugPrintBufferRefcount(), DropDatabaseBuffers(), DropRelationBuffers(), DropRelationsAllBuffers(), EvictAllUnpinnedBuffers(), EvictRelUnpinnedBuffers(), EvictUnpinnedBuffer(), ExtendBufferedRelShared(), FindAndDropRelationBuffers(), FlushDatabaseBuffers(), FlushOneBuffer(), FlushRelationBuffers(), FlushRelationsAllBuffers(), GetBufferFromRing(), invalidate_rel_block(), IsBufferCleanupOK(), LockBuffer(), LockBufferForCleanup(), MarkBufferDirty(), MarkBufferDirtyHint(), pg_buffercache_numa_pages(), pg_buffercache_pages(), pg_buffercache_summary(), read_rel_block_ll(), ReadBuffersCanStartIOOnce(), ReadRecentBuffer(), ReleaseAndReadBuffer(), ReleaseBuffer(), ResOwnerReleaseBufferPin(), StartReadBuffersImpl(), StrategyGetBuffer(), SyncOneBuffer(), and ZeroAndLockBuffer().

GetLocalBufferDescriptor()

static BufferDesc * GetLocalBufferDescriptor ( uint32  id )
inlinestatic

Definition at line 337 of file buf_internals.h.

339{
340 return &LocalBufferDescriptors[id];
PGDLLIMPORT BufferDesc * LocalBufferDescriptors
Definition: localbuf.c:46

References LocalBufferDescriptors.

Referenced by buffer_call_start_io(), buffer_call_terminate_io(), buffer_readv_complete_one(), buffer_stage_common(), BufferGetBlockNumber(), BufferGetTag(), BufferIsDirty(), CheckReadBuffersOperation(), create_toy_buffer(), DebugPrintBufferRefcount(), DropRelationAllLocalBuffers(), DropRelationLocalBuffers(), ExtendBufferedRelLocal(), FlushRelationBuffers(), GetLocalVictimBuffer(), InitLocalBuffers(), invalidate_rel_block(), LocalBufferAlloc(), MarkLocalBufferDirty(), modify_rel_block(), read_rel_block_ll(), ReadBuffersCanStartIOOnce(), ReadRecentBuffer(), ReleaseAndReadBuffer(), StartReadBuffersImpl(), UnpinLocalBufferNoOwner(), and ZeroAndLockBuffer().

InitBufferTag()

static void InitBufferTag ( BufferTagtag,
const RelFileLocatorrlocator,
ForkNumber  forkNum,
BlockNumber  blockNum 
)
inlinestatic

Definition at line 156 of file buf_internals.h.

159{
160 tag->spcOid = rlocator->spcOid;
161 tag->dbOid = rlocator->dbOid;
162 BufTagSetRelForkDetails(tag, rlocator->relNumber, forkNum);
163 tag->blockNum = blockNum;

References buftag::blockNum, BufTagSetRelForkDetails(), buftag::dbOid, RelFileLocator::dbOid, RelFileLocator::relNumber, buftag::spcOid, and RelFileLocator::spcOid.

Referenced by BufferAlloc(), ExtendBufferedRelLocal(), ExtendBufferedRelShared(), FindAndDropRelationBuffers(), LocalBufferAlloc(), PrefetchLocalBuffer(), PrefetchSharedBuffer(), and ReadRecentBuffer().

InitBufTable()

void InitBufTable ( int  size )

Definition at line 51 of file buf_table.c.

52{
53 HASHCTL info;
54
55 /* assume no locking is needed yet */
56
57 /* BufferTag maps to Buffer */
58 info.keysize = sizeof(BufferTag);
59 info.entrysize = sizeof(BufferLookupEnt);
61
62 SharedBufHash = ShmemInitHash("Shared Buffer Lookup Table",
63 size, size,
64 &info,
66}
struct buftag BufferTag
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_BLOBS
Definition: hsearch.h:97
#define HASH_FIXED_SIZE
Definition: hsearch.h:105
#define HASH_PARTITION
Definition: hsearch.h:92
HTAB * ShmemInitHash(const char *name, int64 init_size, int64 max_size, HASHCTL *infoP, int hash_flags)
Definition: shmem.c:332
Definition: hsearch.h:66
Size keysize
Definition: hsearch.h:75
Size entrysize
Definition: hsearch.h:76
int64 num_partitions
Definition: hsearch.h:68

References HASHCTL::entrysize, HASH_BLOBS, HASH_ELEM, HASH_FIXED_SIZE, HASH_PARTITION, HASHCTL::keysize, NUM_BUFFER_PARTITIONS, HASHCTL::num_partitions, SharedBufHash, and ShmemInitHash().

Referenced by StrategyInitialize().

InvalidateLocalBuffer()

void InvalidateLocalBuffer ( BufferDescbufHdr,
bool  check_unreferenced 
)

Definition at line 603 of file localbuf.c.

604{
605 Buffer buffer = BufferDescriptorGetBuffer(bufHdr);
606 int bufid = -buffer - 1;
607 uint32 buf_state;
608 LocalBufferLookupEnt *hresult;
609
610 /*
611 * It's possible that we started IO on this buffer before e.g. aborting
612 * the transaction that created a table. We need to wait for that IO to
613 * complete before removing / reusing the buffer.
614 */
615 if (pgaio_wref_valid(&bufHdr->io_wref))
616 {
617 PgAioWaitRef iow = bufHdr->io_wref;
618
619 pgaio_wref_wait(&iow);
620 Assert(!pgaio_wref_valid(&bufHdr->io_wref));
621 }
622
623 buf_state = pg_atomic_read_u32(&bufHdr->state);
624
625 /*
626 * We need to test not just LocalRefCount[bufid] but also the BufferDesc
627 * itself, as the latter is used to represent a pin by the AIO subsystem.
628 * This can happen if AIO is initiated and then the query errors out.
629 */
630 if (check_unreferenced &&
631 (LocalRefCount[bufid] != 0 || BUF_STATE_GET_REFCOUNT(buf_state) != 0))
632 elog(ERROR, "block %u of %s is still referenced (local %d)",
633 bufHdr->tag.blockNum,
636 BufTagGetForkNum(&bufHdr->tag)).str,
637 LocalRefCount[bufid]);
638
639 /* Remove entry from hashtable */
640 hresult = (LocalBufferLookupEnt *)
641 hash_search(LocalBufHash, &bufHdr->tag, HASH_REMOVE, NULL);
642 if (!hresult) /* shouldn't happen */
643 elog(ERROR, "local buffer hash table corrupted");
644 /* Mark buffer invalid */
645 ClearBufferTag(&bufHdr->tag);
646 buf_state &= ~BUF_FLAG_MASK;
647 buf_state &= ~BUF_USAGECOUNT_MASK;
648 pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
649}
bool pgaio_wref_valid(PgAioWaitRef *iow)
Definition: aio.c:968
void pgaio_wref_wait(PgAioWaitRef *iow)
Definition: aio.c:988
static void ClearBufferTag(BufferTag *tag)
Definition: buf_internals.h:147
#define BUF_STATE_GET_REFCOUNT(state)
Definition: buf_internals.h:59
#define relpathbackend(rlocator, backend, forknum)
Definition: relpath.h:141
PgAioWaitRef io_wref
Definition: buf_internals.h:266

References Assert(), buftag::blockNum, BUF_STATE_GET_REFCOUNT, BufferDescriptorGetBuffer(), BufTagGetForkNum(), BufTagGetRelFileLocator(), ClearBufferTag(), elog, ERROR, HASH_REMOVE, hash_search(), BufferDesc::io_wref, LocalBufHash, LocalRefCount, MyProcNumber, pg_atomic_read_u32(), pg_atomic_unlocked_write_u32(), pgaio_wref_valid(), pgaio_wref_wait(), relpathbackend, BufferDesc::state, and BufferDesc::tag.

Referenced by DropRelationAllLocalBuffers(), DropRelationLocalBuffers(), GetLocalVictimBuffer(), invalidate_rel_block(), and modify_rel_block().

IOContextForStrategy()

IOContext IOContextForStrategy ( BufferAccessStrategy  strategy )

Definition at line 683 of file freelist.c.

684{
685 if (!strategy)
686 return IOCONTEXT_NORMAL;
687
688 switch (strategy->btype)
689 {
690 case BAS_NORMAL:
691
692 /*
693 * Currently, GetAccessStrategy() returns NULL for
694 * BufferAccessStrategyType BAS_NORMAL, so this case is
695 * unreachable.
696 */
698 return IOCONTEXT_NORMAL;
699 case BAS_BULKREAD:
700 return IOCONTEXT_BULKREAD;
701 case BAS_BULKWRITE:
702 return IOCONTEXT_BULKWRITE;
703 case BAS_VACUUM:
704 return IOCONTEXT_VACUUM;
705 }
706
707 elog(ERROR, "unrecognized BufferAccessStrategyType: %d", strategy->btype);
709}
@ BAS_BULKREAD
Definition: bufmgr.h:37
@ BAS_NORMAL
Definition: bufmgr.h:36
@ BAS_VACUUM
Definition: bufmgr.h:40
@ BAS_BULKWRITE
Definition: bufmgr.h:39
#define pg_unreachable()
Definition: c.h:331
@ IOCONTEXT_VACUUM
Definition: pgstat.h:288
@ IOCONTEXT_BULKREAD
Definition: pgstat.h:284
@ IOCONTEXT_BULKWRITE
Definition: pgstat.h:285
BufferAccessStrategyType btype
Definition: freelist.c:67

References BAS_BULKREAD, BAS_BULKWRITE, BAS_NORMAL, BAS_VACUUM, BufferAccessStrategyData::btype, elog, ERROR, IOCONTEXT_BULKREAD, IOCONTEXT_BULKWRITE, IOCONTEXT_NORMAL, IOCONTEXT_VACUUM, and pg_unreachable.

Referenced by AsyncReadBuffers(), ExtendBufferedRelShared(), PinBufferForBlock(), and WaitReadBuffers().

IssuePendingWritebacks()

void IssuePendingWritebacks ( WritebackContextwb_context,
IOContext  io_context 
)

Definition at line 6428 of file bufmgr.c.

6429{
6430 instr_time io_start;
6431 int i;
6432
6433 if (wb_context->nr_pending == 0)
6434 return;
6435
6436 /*
6437 * Executing the writes in-order can make them a lot faster, and allows to
6438 * merge writeback requests to consecutive blocks into larger writebacks.
6439 */
6440 sort_pending_writebacks(wb_context->pending_writebacks,
6441 wb_context->nr_pending);
6442
6444
6445 /*
6446 * Coalesce neighbouring writes, but nothing else. For that we iterate
6447 * through the, now sorted, array of pending flushes, and look forward to
6448 * find all neighbouring (or identical) writes.
6449 */
6450 for (i = 0; i < wb_context->nr_pending; i++)
6451 {
6454 SMgrRelation reln;
6455 int ahead;
6456 BufferTag tag;
6457 RelFileLocator currlocator;
6458 Size nblocks = 1;
6459
6460 cur = &wb_context->pending_writebacks[i];
6461 tag = cur->tag;
6462 currlocator = BufTagGetRelFileLocator(&tag);
6463
6464 /*
6465 * Peek ahead, into following writeback requests, to see if they can
6466 * be combined with the current one.
6467 */
6468 for (ahead = 0; i + ahead + 1 < wb_context->nr_pending; ahead++)
6469 {
6470
6471 next = &wb_context->pending_writebacks[i + ahead + 1];
6472
6473 /* different file, stop */
6474 if (!RelFileLocatorEquals(currlocator,
6475 BufTagGetRelFileLocator(&next->tag)) ||
6476 BufTagGetForkNum(&cur->tag) != BufTagGetForkNum(&next->tag))
6477 break;
6478
6479 /* ok, block queued twice, skip */
6480 if (cur->tag.blockNum == next->tag.blockNum)
6481 continue;
6482
6483 /* only merge consecutive writes */
6484 if (cur->tag.blockNum + 1 != next->tag.blockNum)
6485 break;
6486
6487 nblocks++;
6488 cur = next;
6489 }
6490
6491 i += ahead;
6492
6493 /* and finally tell the kernel to write the data to storage */
6494 reln = smgropen(currlocator, INVALID_PROC_NUMBER);
6495 smgrwriteback(reln, BufTagGetForkNum(&tag), tag.blockNum, nblocks);
6496 }
6497
6498 /*
6499 * Assume that writeback requests are only issued for buffers containing
6500 * blocks of permanent relations.
6501 */
6503 IOOP_WRITEBACK, io_start, wb_context->nr_pending, 0);
6504
6505 wb_context->nr_pending = 0;
6506}
static int32 next
Definition: blutils.c:224
size_t Size
Definition: c.h:610
struct cursor * cur
Definition: ecpg.c:29
@ IOOBJECT_RELATION
Definition: pgstat.h:275
@ IOOP_WRITEBACK
Definition: pgstat.h:309
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
#define RelFileLocatorEquals(locator1, locator2)
Definition: relfilelocator.h:89
void smgrwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks)
Definition: smgr.c:805
PendingWriteback pending_writebacks[WRITEBACK_MAX_PENDING_FLUSHES]
Definition: buf_internals.h:318

References buftag::blockNum, BufTagGetForkNum(), BufTagGetRelFileLocator(), cur, i, INVALID_PROC_NUMBER, IOOBJECT_RELATION, IOOP_WRITEBACK, next, WritebackContext::nr_pending, WritebackContext::pending_writebacks, pgstat_count_io_op_time(), pgstat_prepare_io_time(), RelFileLocatorEquals, smgropen(), smgrwriteback(), and track_io_timing.

Referenced by BufferSync(), and ScheduleBufferTagForWriteback().

LocalBufferAlloc()

BufferDesc * LocalBufferAlloc ( SMgrRelation  smgr,
ForkNumber  forkNum,
BlockNumber  blockNum,
bool *  foundPtr 
)

Definition at line 118 of file localbuf.c.

120{
121 BufferTag newTag; /* identity of requested block */
122 LocalBufferLookupEnt *hresult;
123 BufferDesc *bufHdr;
124 Buffer victim_buffer;
125 int bufid;
126 bool found;
127
128 InitBufferTag(&newTag, &smgr->smgr_rlocator.locator, forkNum, blockNum);
129
130 /* Initialize local buffers if first request in this session */
131 if (LocalBufHash == NULL)
133
135
136 /* See if the desired buffer already exists */
137 hresult = (LocalBufferLookupEnt *)
138 hash_search(LocalBufHash, &newTag, HASH_FIND, NULL);
139
140 if (hresult)
141 {
142 bufid = hresult->id;
143 bufHdr = GetLocalBufferDescriptor(bufid);
144 Assert(BufferTagsEqual(&bufHdr->tag, &newTag));
145
146 *foundPtr = PinLocalBuffer(bufHdr, true);
147 }
148 else
149 {
150 uint32 buf_state;
151
152 victim_buffer = GetLocalVictimBuffer();
153 bufid = -victim_buffer - 1;
154 bufHdr = GetLocalBufferDescriptor(bufid);
155
156 hresult = (LocalBufferLookupEnt *)
157 hash_search(LocalBufHash, &newTag, HASH_ENTER, &found);
158 if (found) /* shouldn't happen */
159 elog(ERROR, "local buffer hash table corrupted");
160 hresult->id = bufid;
161
162 /*
163 * it's all ours now.
164 */
165 bufHdr->tag = newTag;
166
167 buf_state = pg_atomic_read_u32(&bufHdr->state);
168 buf_state &= ~(BUF_FLAG_MASK | BUF_USAGECOUNT_MASK);
169 buf_state |= BM_TAG_VALID | BUF_USAGECOUNT_ONE;
170 pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
171
172 *foundPtr = false;
173 }
174
175 return bufHdr;
176}
#define BUF_USAGECOUNT_MASK
Definition: buf_internals.h:53
static bool BufferTagsEqual(const BufferTag *tag1, const BufferTag *tag2)
Definition: buf_internals.h:166
#define BUF_FLAG_MASK
Definition: buf_internals.h:56

References Assert(), BM_TAG_VALID, BUF_FLAG_MASK, BUF_USAGECOUNT_MASK, BUF_USAGECOUNT_ONE, BufferTagsEqual(), CurrentResourceOwner, elog, ERROR, GetLocalBufferDescriptor(), GetLocalVictimBuffer(), HASH_ENTER, HASH_FIND, hash_search(), LocalBufferLookupEnt::id, InitBufferTag(), InitLocalBuffers(), LocalBufHash, RelFileLocatorBackend::locator, pg_atomic_read_u32(), pg_atomic_unlocked_write_u32(), PinLocalBuffer(), ResourceOwnerEnlarge(), SMgrRelationData::smgr_rlocator, BufferDesc::state, and BufferDesc::tag.

Referenced by PinBufferForBlock().

LockBufHdr()

uint32 LockBufHdr ( BufferDescdesc )

Definition at line 6224 of file bufmgr.c.

6225{
6226 SpinDelayStatus delayStatus;
6227 uint32 old_buf_state;
6228
6230
6231 init_local_spin_delay(&delayStatus);
6232
6233 while (true)
6234 {
6235 /* set BM_LOCKED flag */
6236 old_buf_state = pg_atomic_fetch_or_u32(&desc->state, BM_LOCKED);
6237 /* if it wasn't set before we're OK */
6238 if (!(old_buf_state & BM_LOCKED))
6239 break;
6240 perform_spin_delay(&delayStatus);
6241 }
6242 finish_spin_delay(&delayStatus);
6243 return old_buf_state | BM_LOCKED;
6244}
static uint32 pg_atomic_fetch_or_u32(volatile pg_atomic_uint32 *ptr, uint32 or_)
Definition: atomics.h:408
#define BufferIsLocal(buffer)
Definition: buf.h:37
#define BM_LOCKED
Definition: buf_internals.h:68
void perform_spin_delay(SpinDelayStatus *status)
Definition: s_lock.c:126
void finish_spin_delay(SpinDelayStatus *status)
Definition: s_lock.c:186
#define init_local_spin_delay(status)
Definition: s_lock.h:733

References Assert(), BM_LOCKED, BufferDescriptorGetBuffer(), BufferIsLocal, finish_spin_delay(), init_local_spin_delay, perform_spin_delay(), pg_atomic_fetch_or_u32(), and BufferDesc::state.

Referenced by AbortBufferIO(), apw_dump_now(), buffer_stage_common(), BufferAlloc(), BufferGetLSNAtomic(), BufferSync(), ConditionalLockBufferForCleanup(), create_toy_buffer(), DropDatabaseBuffers(), DropRelationBuffers(), DropRelationsAllBuffers(), EvictAllUnpinnedBuffers(), EvictRelUnpinnedBuffers(), EvictUnpinnedBuffer(), ExtendBufferedRelShared(), FindAndDropRelationBuffers(), FlushBuffer(), FlushDatabaseBuffers(), FlushRelationBuffers(), FlushRelationsAllBuffers(), GetBufferFromRing(), GetVictimBuffer(), InvalidateBuffer(), InvalidateVictimBuffer(), IsBufferCleanupOK(), LockBufferForCleanup(), MarkBufferDirtyHint(), pg_buffercache_numa_pages(), pg_buffercache_pages(), ReadRecentBuffer(), StartBufferIO(), StrategyGetBuffer(), SyncOneBuffer(), TerminateBufferIO(), UnlockBuffers(), WaitIO(), and WakePinCountWaiter().

MarkLocalBufferDirty()

void MarkLocalBufferDirty ( Buffer  buffer )

Definition at line 489 of file localbuf.c.

490{
491 int bufid;
492 BufferDesc *bufHdr;
493 uint32 buf_state;
494
495 Assert(BufferIsLocal(buffer));
496
497#ifdef LBDEBUG
498 fprintf(stderr, "LB DIRTY %d\n", buffer);
499#endif
500
501 bufid = -buffer - 1;
502
503 Assert(LocalRefCount[bufid] > 0);
504
505 bufHdr = GetLocalBufferDescriptor(bufid);
506
507 buf_state = pg_atomic_read_u32(&bufHdr->state);
508
509 if (!(buf_state & BM_DIRTY))
511
512 buf_state |= BM_DIRTY;
513
514 pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
515}
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
int64 local_blks_dirtied
Definition: instrument.h:32

References Assert(), BM_DIRTY, BufferIsLocal, fprintf, GetLocalBufferDescriptor(), BufferUsage::local_blks_dirtied, LocalRefCount, pg_atomic_read_u32(), pg_atomic_unlocked_write_u32(), pgBufferUsage, and BufferDesc::state.

Referenced by MarkBufferDirty(), and MarkBufferDirtyHint().

PinLocalBuffer()

bool PinLocalBuffer ( BufferDescbuf_hdr,
bool  adjust_usagecount 
)

Definition at line 803 of file localbuf.c.

804{
805 uint32 buf_state;
806 Buffer buffer = BufferDescriptorGetBuffer(buf_hdr);
807 int bufid = -buffer - 1;
808
809 buf_state = pg_atomic_read_u32(&buf_hdr->state);
810
811 if (LocalRefCount[bufid] == 0)
812 {
814 buf_state += BUF_REFCOUNT_ONE;
815 if (adjust_usagecount &&
817 {
818 buf_state += BUF_USAGECOUNT_ONE;
819 }
820 pg_atomic_unlocked_write_u32(&buf_hdr->state, buf_state);
821
822 /*
823 * See comment in PinBuffer().
824 *
825 * If the buffer isn't allocated yet, it'll be marked as defined in
826 * GetLocalBufferStorage().
827 */
828 if (LocalBufHdrGetBlock(buf_hdr) != NULL)
830 }
831 LocalRefCount[bufid]++;
834
835 return buf_state & BM_VALID;
836}
#define BM_MAX_USAGE_COUNT
Definition: buf_internals.h:86
#define BUF_REFCOUNT_ONE
Definition: buf_internals.h:51
#define BUF_STATE_GET_USAGECOUNT(state)
Definition: buf_internals.h:60
static void ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer)
Definition: buf_internals.h:398
static int NLocalPinnedBuffers
Definition: localbuf.c:55
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26

References BM_MAX_USAGE_COUNT, BM_VALID, BUF_REFCOUNT_ONE, BUF_STATE_GET_USAGECOUNT, BUF_USAGECOUNT_ONE, BufferDescriptorGetBuffer(), CurrentResourceOwner, LocalBufHdrGetBlock, LocalRefCount, NLocalPinnedBuffers, pg_atomic_read_u32(), pg_atomic_unlocked_write_u32(), ResourceOwnerRememberBuffer(), BufferDesc::state, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by ExtendBufferedRelLocal(), FlushRelationBuffers(), GetLocalVictimBuffer(), LocalBufferAlloc(), and ReadRecentBuffer().

PrefetchLocalBuffer()

PrefetchBufferResult PrefetchLocalBuffer ( SMgrRelation  smgr,
ForkNumber  forkNum,
BlockNumber  blockNum 
)

Definition at line 71 of file localbuf.c.

73{
74 PrefetchBufferResult result = {InvalidBuffer, false};
75 BufferTag newTag; /* identity of requested block */
76 LocalBufferLookupEnt *hresult;
77
78 InitBufferTag(&newTag, &smgr->smgr_rlocator.locator, forkNum, blockNum);
79
80 /* Initialize local buffers if first request in this session */
81 if (LocalBufHash == NULL)
83
84 /* See if the desired buffer already exists */
85 hresult = (LocalBufferLookupEnt *)
86 hash_search(LocalBufHash, &newTag, HASH_FIND, NULL);
87
88 if (hresult)
89 {
90 /* Yes, so nothing to do */
91 result.recent_buffer = -hresult->id - 1;
92 }
93 else
94 {
95#ifdef USE_PREFETCH
96 /* Not in buffers, so initiate prefetch */
97 if ((io_direct_flags & IO_DIRECT_DATA) == 0 &&
98 smgrprefetch(smgr, forkNum, blockNum, 1))
99 {
100 result.initiated_io = true;
101 }
102#endif /* USE_PREFETCH */
103 }
104
105 return result;
106}
#define InvalidBuffer
Definition: buf.h:25
int io_direct_flags
Definition: fd.c:168
#define IO_DIRECT_DATA
Definition: fd.h:54
bool smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks)
Definition: smgr.c:678
Buffer recent_buffer
Definition: bufmgr.h:61
bool initiated_io
Definition: bufmgr.h:62

References HASH_FIND, hash_search(), LocalBufferLookupEnt::id, InitBufferTag(), PrefetchBufferResult::initiated_io, InitLocalBuffers(), InvalidBuffer, IO_DIRECT_DATA, io_direct_flags, LocalBufHash, RelFileLocatorBackend::locator, PrefetchBufferResult::recent_buffer, SMgrRelationData::smgr_rlocator, and smgrprefetch().

Referenced by PrefetchBuffer().

ResourceOwnerForgetBuffer()

static void ResourceOwnerForgetBuffer ( ResourceOwner  owner,
Buffer  buffer 
)
inlinestatic

Definition at line 403 of file buf_internals.h.

405{
PGDLLIMPORT const ResourceOwnerDesc buffer_pin_resowner_desc
Definition: bufmgr.c:244
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:222
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:561

References buffer_pin_resowner_desc, Int32GetDatum(), and ResourceOwnerForget().

Referenced by UnpinBuffer(), and UnpinLocalBuffer().

ResourceOwnerForgetBufferIO()

static void ResourceOwnerForgetBufferIO ( ResourceOwner  owner,
Buffer  buffer 
)
inlinestatic

Definition at line 413 of file buf_internals.h.

415{
PGDLLIMPORT const ResourceOwnerDesc buffer_io_resowner_desc
Definition: bufmgr.c:235

References buffer_io_resowner_desc, Int32GetDatum(), and ResourceOwnerForget().

Referenced by buffer_call_start_io(), buffer_stage_common(), and TerminateBufferIO().

ResourceOwnerRememberBuffer()

static void ResourceOwnerRememberBuffer ( ResourceOwner  owner,
Buffer  buffer 
)
inlinestatic

Definition at line 398 of file buf_internals.h.

400{
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:521

References buffer_pin_resowner_desc, Int32GetDatum(), and ResourceOwnerRemember().

Referenced by IncrBufferRefCount(), PinBuffer(), PinBuffer_Locked(), and PinLocalBuffer().

ResourceOwnerRememberBufferIO()

static void ResourceOwnerRememberBufferIO ( ResourceOwner  owner,
Buffer  buffer 
)
inlinestatic

Definition at line 408 of file buf_internals.h.

References buffer_io_resowner_desc, Int32GetDatum(), and ResourceOwnerRemember().

Referenced by StartBufferIO().

ScheduleBufferTagForWriteback()

void ScheduleBufferTagForWriteback ( WritebackContextwb_context,
IOContext  io_context,
BufferTagtag 
)

Definition at line 6378 of file bufmgr.c.

6380{
6381 PendingWriteback *pending;
6382
6383 /*
6384 * As pg_flush_data() doesn't do anything with fsync disabled, there's no
6385 * point in tracking in that case.
6386 */
6388 !enableFsync)
6389 return;
6390
6391 /*
6392 * Add buffer to the pending writeback array, unless writeback control is
6393 * disabled.
6394 */
6395 if (*wb_context->max_pending > 0)
6396 {
6398
6399 pending = &wb_context->pending_writebacks[wb_context->nr_pending++];
6400
6401 pending->tag = *tag;
6402 }
6403
6404 /*
6405 * Perform pending flushes if the writeback limit is exceeded. This
6406 * includes the case where previously an item has been added, but control
6407 * is now disabled.
6408 */
6409 if (wb_context->nr_pending >= *wb_context->max_pending)
6410 IssuePendingWritebacks(wb_context, io_context);
6411}
void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context)
Definition: bufmgr.c:6428
bool enableFsync
Definition: globals.c:129
#define WRITEBACK_MAX_PENDING_FLUSHES
BufferTag tag
Definition: buf_internals.h:305

References Assert(), enableFsync, IO_DIRECT_DATA, io_direct_flags, IssuePendingWritebacks(), WritebackContext::max_pending, WritebackContext::nr_pending, WritebackContext::pending_writebacks, PendingWriteback::tag, and WRITEBACK_MAX_PENDING_FLUSHES.

Referenced by GetVictimBuffer(), and SyncOneBuffer().

StartBufferIO()

bool StartBufferIO ( BufferDescbuf,
bool  forInput,
bool  nowait 
)

Definition at line 6010 of file bufmgr.c.

6011{
6012 uint32 buf_state;
6013
6015
6016 for (;;)
6017 {
6018 buf_state = LockBufHdr(buf);
6019
6020 if (!(buf_state & BM_IO_IN_PROGRESS))
6021 break;
6022 UnlockBufHdr(buf, buf_state);
6023 if (nowait)
6024 return false;
6025 WaitIO(buf);
6026 }
6027
6028 /* Once we get here, there is definitely no I/O active on this buffer */
6029
6030 /* Check if someone else already did the I/O */
6031 if (forInput ? (buf_state & BM_VALID) : !(buf_state & BM_DIRTY))
6032 {
6033 UnlockBufHdr(buf, buf_state);
6034 return false;
6035 }
6036
6037 buf_state |= BM_IO_IN_PROGRESS;
6038 UnlockBufHdr(buf, buf_state);
6039
6042
6043 return true;
6044}
static void UnlockBufHdr(BufferDesc *desc, uint32 buf_state)
Definition: buf_internals.h:367
static void ResourceOwnerRememberBufferIO(ResourceOwner owner, Buffer buffer)
Definition: buf_internals.h:408
#define BM_IO_IN_PROGRESS
Definition: buf_internals.h:72
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:6224
static void WaitIO(BufferDesc *buf)
Definition: bufmgr.c:5931

References BM_DIRTY, BM_IO_IN_PROGRESS, BM_VALID, buf, BufferDescriptorGetBuffer(), CurrentResourceOwner, LockBufHdr(), ResourceOwnerEnlarge(), ResourceOwnerRememberBufferIO(), UnlockBufHdr(), and WaitIO().

Referenced by buffer_call_start_io(), ExtendBufferedRelShared(), FlushBuffer(), read_rel_block_ll(), ReadBuffersCanStartIOOnce(), and ZeroAndLockBuffer().

StartLocalBufferIO()

bool StartLocalBufferIO ( BufferDescbufHdr,
bool  forInput,
bool  nowait 
)

Definition at line 521 of file localbuf.c.

522{
523 uint32 buf_state;
524
525 /*
526 * With AIO the buffer could have IO in progress, e.g. when there are two
527 * scans of the same relation. Either wait for the other IO or return
528 * false.
529 */
530 if (pgaio_wref_valid(&bufHdr->io_wref))
531 {
532 PgAioWaitRef iow = bufHdr->io_wref;
533
534 if (nowait)
535 return false;
536
537 pgaio_wref_wait(&iow);
538 }
539
540 /* Once we get here, there is definitely no I/O active on this buffer */
541
542 /* Check if someone else already did the I/O */
543 buf_state = pg_atomic_read_u32(&bufHdr->state);
544 if (forInput ? (buf_state & BM_VALID) : !(buf_state & BM_DIRTY))
545 {
546 return false;
547 }
548
549 /* BM_IO_IN_PROGRESS isn't currently used for local buffers */
550
551 /* local buffers don't track IO using resowners */
552
553 return true;
554}

References BM_DIRTY, BM_VALID, BufferDesc::io_wref, pg_atomic_read_u32(), pgaio_wref_valid(), pgaio_wref_wait(), and BufferDesc::state.

Referenced by buffer_call_start_io(), ExtendBufferedRelLocal(), FlushLocalBuffer(), read_rel_block_ll(), ReadBuffersCanStartIOOnce(), and ZeroAndLockBuffer().

StaticAssertDecl() [1/3]

StaticAssertDecl ( )

StaticAssertDecl() [2/3]

StaticAssertDecl ( BUF_REFCOUNT_BITS+BUF_USAGECOUNT_BITSBUF_FLAG_BITS = =32,
"parts of buffer state space need to equal 32"   
)

StaticAssertDecl() [3/3]

StaticAssertDecl ( MAX_BACKENDS_BITS<=  BUF_REFCOUNT_BITS,
"MAX_BACKENDS_BITS needs to be <= BUF_REFCOUNT_BITS"   
)

StrategyGetBuffer()

BufferDesc * StrategyGetBuffer ( BufferAccessStrategy  strategy,
uint32buf_state,
bool *  from_ring 
)

Definition at line 171 of file freelist.c.

172{
174 int bgwprocno;
175 int trycounter;
176 uint32 local_buf_state; /* to avoid repeated (de-)referencing */
177
178 *from_ring = false;
179
180 /*
181 * If given a strategy object, see whether it can select a buffer. We
182 * assume strategy objects don't need buffer_strategy_lock.
183 */
184 if (strategy != NULL)
185 {
186 buf = GetBufferFromRing(strategy, buf_state);
187 if (buf != NULL)
188 {
189 *from_ring = true;
190 return buf;
191 }
192 }
193
194 /*
195 * If asked, we need to waken the bgwriter. Since we don't want to rely on
196 * a spinlock for this we force a read from shared memory once, and then
197 * set the latch based on that value. We need to go through that length
198 * because otherwise bgwprocno might be reset while/after we check because
199 * the compiler might just reread from memory.
200 *
201 * This can possibly set the latch of the wrong process if the bgwriter
202 * dies in the wrong moment. But since PGPROC->procLatch is never
203 * deallocated the worst consequence of that is that we set the latch of
204 * some arbitrary process.
205 */
207 if (bgwprocno != -1)
208 {
209 /* reset bgwprocno first, before setting the latch */
211
212 /*
213 * Not acquiring ProcArrayLock here which is slightly icky. It's
214 * actually fine because procLatch isn't ever freed, so we just can
215 * potentially set the wrong process' (or no process') latch.
216 */
218 }
219
220 /*
221 * We count buffer allocation requests so that the bgwriter can estimate
222 * the rate of buffer consumption. Note that buffers recycled by a
223 * strategy object are intentionally not counted here.
224 */
226
227 /* Use the "clock sweep" algorithm to find a free buffer */
228 trycounter = NBuffers;
229 for (;;)
230 {
232
233 /*
234 * If the buffer is pinned or has a nonzero usage_count, we cannot use
235 * it; decrement the usage_count (unless pinned) and keep scanning.
236 */
237 local_buf_state = LockBufHdr(buf);
238
239 if (BUF_STATE_GET_REFCOUNT(local_buf_state) == 0)
240 {
241 if (BUF_STATE_GET_USAGECOUNT(local_buf_state) != 0)
242 {
243 local_buf_state -= BUF_USAGECOUNT_ONE;
244
245 trycounter = NBuffers;
246 }
247 else
248 {
249 /* Found a usable buffer */
250 if (strategy != NULL)
251 AddBufferToRing(strategy, buf);
252 *buf_state = local_buf_state;
253 return buf;
254 }
255 }
256 else if (--trycounter == 0)
257 {
258 /*
259 * We've scanned all the buffers without making any state changes,
260 * so all the buffers are pinned (or were when we looked at them).
261 * We could hope that someone will free one eventually, but it's
262 * probably better to fail than to risk getting stuck in an
263 * infinite loop.
264 */
265 UnlockBufHdr(buf, local_buf_state);
266 elog(ERROR, "no unpinned buffers available");
267 }
268 UnlockBufHdr(buf, local_buf_state);
269 }
270}
static uint32 pg_atomic_fetch_add_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
Definition: atomics.h:364
static BufferDesc * GetBufferDescriptor(uint32 id)
Definition: buf_internals.h:331
static BufferStrategyControl * StrategyControl
Definition: freelist.c:57
static uint32 ClockSweepTick(void)
Definition: freelist.c:100
static void AddBufferToRing(BufferAccessStrategy strategy, BufferDesc *buf)
Definition: freelist.c:673
#define INT_ACCESS_ONCE(var)
Definition: freelist.c:24
static BufferDesc * GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
Definition: freelist.c:620
int NBuffers
Definition: globals.c:142
void SetLatch(Latch *latch)
Definition: latch.c:290
PROC_HDR * ProcGlobal
Definition: proc.c:78
pg_atomic_uint32 numBufferAllocs
Definition: freelist.c:47
Latch procLatch
Definition: proc.h:186
PGPROC * allProcs
Definition: proc.h:388

References AddBufferToRing(), PROC_HDR::allProcs, BufferStrategyControl::bgwprocno, buf, BUF_STATE_GET_REFCOUNT, BUF_STATE_GET_USAGECOUNT, BUF_USAGECOUNT_ONE, ClockSweepTick(), elog, ERROR, GetBufferDescriptor(), GetBufferFromRing(), INT_ACCESS_ONCE, LockBufHdr(), NBuffers, BufferStrategyControl::numBufferAllocs, pg_atomic_fetch_add_u32(), ProcGlobal, PGPROC::procLatch, SetLatch(), StrategyControl, and UnlockBufHdr().

Referenced by GetVictimBuffer().

StrategyInitialize()

void StrategyInitialize ( bool  init )

Definition at line 364 of file freelist.c.

365{
366 bool found;
367
368 /*
369 * Initialize the shared buffer lookup hashtable.
370 *
371 * Since we can't tolerate running out of lookup table entries, we must be
372 * sure to specify an adequate table size here. The maximum steady-state
373 * usage is of course NBuffers entries, but BufferAlloc() tries to insert
374 * a new entry before deleting the old. In principle this could be
375 * happening in each partition concurrently, so we could need as many as
376 * NBuffers + NUM_BUFFER_PARTITIONS entries.
377 */
379
380 /*
381 * Get or create the shared strategy control block
382 */
384 ShmemInitStruct("Buffer Strategy Status",
385 sizeof(BufferStrategyControl),
386 &found);
387
388 if (!found)
389 {
390 /*
391 * Only done once, usually in postmaster
392 */
393 Assert(init);
394
396
397 /* Initialize the clock-sweep pointer */
399
400 /* Clear statistics */
403
404 /* No pending notification */
406 }
407 else
408 Assert(!init);
409}
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:219
void InitBufTable(int size)
Definition: buf_table.c:51
int init
Definition: isn.c:79
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:387
#define SpinLockInit(lock)
Definition: spin.h:57
pg_atomic_uint32 nextVictimBuffer
Definition: freelist.c:40
uint32 completePasses
Definition: freelist.c:46
slock_t buffer_strategy_lock
Definition: freelist.c:33

References Assert(), BufferStrategyControl::bgwprocno, BufferStrategyControl::buffer_strategy_lock, BufferStrategyControl::completePasses, init, InitBufTable(), NBuffers, BufferStrategyControl::nextVictimBuffer, NUM_BUFFER_PARTITIONS, BufferStrategyControl::numBufferAllocs, pg_atomic_init_u32(), ShmemInitStruct(), SpinLockInit, and StrategyControl.

Referenced by BufferManagerShmemInit().

StrategyNotifyBgWriter()

void StrategyNotifyBgWriter ( int  bgwprocno )

Definition at line 321 of file freelist.c.

322{
323 /*
324 * We acquire buffer_strategy_lock just to ensure that the store appears
325 * atomic to StrategyGetBuffer. The bgwriter should call this rather
326 * infrequently, so there's no performance penalty from being safe.
327 */
329 StrategyControl->bgwprocno = bgwprocno;
331}
#define SpinLockRelease(lock)
Definition: spin.h:61
#define SpinLockAcquire(lock)
Definition: spin.h:59

References BufferStrategyControl::bgwprocno, BufferStrategyControl::buffer_strategy_lock, SpinLockAcquire, SpinLockRelease, and StrategyControl.

Referenced by BackgroundWriterMain().

StrategyRejectBuffer()

bool StrategyRejectBuffer ( BufferAccessStrategy  strategy,
BufferDescbuf,
bool  from_ring 
)

Definition at line 723 of file freelist.c.

724{
725 /* We only do this in bulkread mode */
726 if (strategy->btype != BAS_BULKREAD)
727 return false;
728
729 /* Don't muck with behavior of normal buffer-replacement strategy */
730 if (!from_ring ||
731 strategy->buffers[strategy->current] != BufferDescriptorGetBuffer(buf))
732 return false;
733
734 /*
735 * Remove the dirty buffer from the ring; necessary to prevent infinite
736 * loop if all ring members are dirty.
737 */
738 strategy->buffers[strategy->current] = InvalidBuffer;
739
740 return true;
741}
Buffer buffers[FLEXIBLE_ARRAY_MEMBER]
Definition: freelist.c:83

References BAS_BULKREAD, BufferAccessStrategyData::btype, buf, BufferDescriptorGetBuffer(), BufferAccessStrategyData::buffers, BufferAccessStrategyData::current, and InvalidBuffer.

Referenced by GetVictimBuffer().

StrategyShmemSize()

Size StrategyShmemSize ( void  )

Definition at line 343 of file freelist.c.

344{
345 Size size = 0;
346
347 /* size of lookup hash table ... see comment in StrategyInitialize */
349
350 /* size of the shared replacement strategy control block */
351 size = add_size(size, MAXALIGN(sizeof(BufferStrategyControl)));
352
353 return size;
354}
Size BufTableShmemSize(int size)
Definition: buf_table.c:41
#define MAXALIGN(LEN)
Definition: c.h:810
Size add_size(Size s1, Size s2)
Definition: shmem.c:493

References add_size(), BufTableShmemSize(), MAXALIGN, NBuffers, and NUM_BUFFER_PARTITIONS.

Referenced by BufferManagerShmemSize().

StrategySyncStart()

int StrategySyncStart ( uint32complete_passes,
uint32num_buf_alloc 
)

Definition at line 284 of file freelist.c.

285{
286 uint32 nextVictimBuffer;
287 int result;
288
291 result = nextVictimBuffer % NBuffers;
292
293 if (complete_passes)
294 {
295 *complete_passes = StrategyControl->completePasses;
296
297 /*
298 * Additionally add the number of wraparounds that happened before
299 * completePasses could be incremented. C.f. ClockSweepTick().
300 */
301 *complete_passes += nextVictimBuffer / NBuffers;
302 }
303
304 if (num_buf_alloc)
305 {
307 }
309 return result;
310}
static uint32 pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)
Definition: atomics.h:328

References BufferStrategyControl::buffer_strategy_lock, BufferStrategyControl::completePasses, NBuffers, BufferStrategyControl::nextVictimBuffer, BufferStrategyControl::numBufferAllocs, pg_atomic_exchange_u32(), pg_atomic_read_u32(), SpinLockAcquire, SpinLockRelease, and StrategyControl.

Referenced by BgBufferSync().

TerminateBufferIO()

void TerminateBufferIO ( BufferDescbuf,
bool  clear_dirty,
uint32  set_flag_bits,
bool  forget_owner,
bool  release_aio 
)

Definition at line 6067 of file bufmgr.c.

6069{
6070 uint32 buf_state;
6071
6072 buf_state = LockBufHdr(buf);
6073
6074 Assert(buf_state & BM_IO_IN_PROGRESS);
6075 buf_state &= ~BM_IO_IN_PROGRESS;
6076
6077 /* Clear earlier errors, if this IO failed, it'll be marked again */
6078 buf_state &= ~BM_IO_ERROR;
6079
6080 if (clear_dirty && !(buf_state & BM_JUST_DIRTIED))
6081 buf_state &= ~(BM_DIRTY | BM_CHECKPOINT_NEEDED);
6082
6083 if (release_aio)
6084 {
6085 /* release ownership by the AIO subsystem */
6086 Assert(BUF_STATE_GET_REFCOUNT(buf_state) > 0);
6087 buf_state -= BUF_REFCOUNT_ONE;
6088 pgaio_wref_clear(&buf->io_wref);
6089 }
6090
6091 buf_state |= set_flag_bits;
6092 UnlockBufHdr(buf, buf_state);
6093
6094 if (forget_owner)
6097
6099
6100 /*
6101 * Support LockBufferForCleanup()
6102 *
6103 * We may have just released the last pin other than the waiter's. In most
6104 * cases, this backend holds another pin on the buffer. But, if, for
6105 * example, this backend is completing an IO issued by another backend, it
6106 * may be time to wake the waiter.
6107 */
6108 if (release_aio && (buf_state & BM_PIN_COUNT_WAITER))
6110}
void pgaio_wref_clear(PgAioWaitRef *iow)
Definition: aio.c:961
static ConditionVariable * BufferDescriptorGetIOCV(const BufferDesc *bdesc)
Definition: buf_internals.h:349
#define BM_PIN_COUNT_WAITER
Definition: buf_internals.h:75
static void ResourceOwnerForgetBufferIO(ResourceOwner owner, Buffer buffer)
Definition: buf_internals.h:413
#define BM_CHECKPOINT_NEEDED
Definition: buf_internals.h:76
static void WakePinCountWaiter(BufferDesc *buf)
Definition: bufmgr.c:3198
void ConditionVariableBroadcast(ConditionVariable *cv)

References Assert(), BM_CHECKPOINT_NEEDED, BM_DIRTY, BM_IO_IN_PROGRESS, BM_JUST_DIRTIED, BM_PIN_COUNT_WAITER, buf, BUF_REFCOUNT_ONE, BUF_STATE_GET_REFCOUNT, BufferDescriptorGetBuffer(), BufferDescriptorGetIOCV(), ConditionVariableBroadcast(), CurrentResourceOwner, LockBufHdr(), pgaio_wref_clear(), ResourceOwnerForgetBufferIO(), UnlockBufHdr(), and WakePinCountWaiter().

Referenced by AbortBufferIO(), buffer_call_terminate_io(), buffer_readv_complete_one(), ExtendBufferedRelShared(), FlushBuffer(), and ZeroAndLockBuffer().

TerminateLocalBufferIO()

void TerminateLocalBufferIO ( BufferDescbufHdr,
bool  clear_dirty,
uint32  set_flag_bits,
bool  release_aio 
)

Definition at line 560 of file localbuf.c.

562{
563 /* Only need to adjust flags */
564 uint32 buf_state = pg_atomic_read_u32(&bufHdr->state);
565
566 /* BM_IO_IN_PROGRESS isn't currently used for local buffers */
567
568 /* Clear earlier errors, if this IO failed, it'll be marked again */
569 buf_state &= ~BM_IO_ERROR;
570
571 if (clear_dirty)
572 buf_state &= ~BM_DIRTY;
573
574 if (release_aio)
575 {
576 /* release pin held by IO subsystem, see also buffer_stage_common() */
577 Assert(BUF_STATE_GET_REFCOUNT(buf_state) > 0);
578 buf_state -= BUF_REFCOUNT_ONE;
579 pgaio_wref_clear(&bufHdr->io_wref);
580 }
581
582 buf_state |= set_flag_bits;
583 pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
584
585 /* local buffers don't track IO using resowners */
586
587 /* local buffers don't use the IO CV, as no other process can see buffer */
588
589 /* local buffers don't use BM_PIN_COUNT_WAITER, so no need to wake */
590}

References Assert(), BUF_REFCOUNT_ONE, BUF_STATE_GET_REFCOUNT, BufferDesc::io_wref, pg_atomic_read_u32(), pg_atomic_unlocked_write_u32(), pgaio_wref_clear(), and BufferDesc::state.

Referenced by buffer_call_terminate_io(), buffer_readv_complete_one(), FlushLocalBuffer(), and ZeroAndLockBuffer().

UnlockBufHdr()

static void UnlockBufHdr ( BufferDescdesc,
uint32  buf_state 
)
inlinestatic

Definition at line 367 of file buf_internals.h.

369{
371 pg_atomic_write_u32(&desc->state, buf_state & (~BM_LOCKED));
#define pg_write_barrier()
Definition: atomics.h:155
static void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:274

References BM_LOCKED, pg_atomic_write_u32(), pg_write_barrier, and BufferDesc::state.

Referenced by AbortBufferIO(), apw_dump_now(), buffer_stage_common(), BufferAlloc(), BufferGetLSNAtomic(), BufferSync(), ConditionalLockBufferForCleanup(), create_toy_buffer(), DropDatabaseBuffers(), DropRelationBuffers(), DropRelationsAllBuffers(), EvictRelUnpinnedBuffers(), EvictUnpinnedBufferInternal(), ExtendBufferedRelShared(), FindAndDropRelationBuffers(), FlushBuffer(), FlushDatabaseBuffers(), FlushRelationBuffers(), FlushRelationsAllBuffers(), GetBufferFromRing(), GetVictimBuffer(), InvalidateBuffer(), InvalidateVictimBuffer(), IsBufferCleanupOK(), LockBufferForCleanup(), MarkBufferDirtyHint(), pg_buffercache_numa_pages(), pg_buffercache_pages(), PinBuffer_Locked(), ReadRecentBuffer(), StartBufferIO(), StrategyGetBuffer(), SyncOneBuffer(), TerminateBufferIO(), UnlockBuffers(), WaitIO(), and WakePinCountWaiter().

UnpinLocalBuffer()

void UnpinLocalBuffer ( Buffer  buffer )

Definition at line 839 of file localbuf.c.

840{
843}
static void ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer)
Definition: buf_internals.h:403
void UnpinLocalBufferNoOwner(Buffer buffer)
Definition: localbuf.c:846

References CurrentResourceOwner, ResourceOwnerForgetBuffer(), and UnpinLocalBufferNoOwner().

Referenced by ExtendBufferedRelLocal(), FlushRelationBuffers(), ReleaseAndReadBuffer(), and ReleaseBuffer().

UnpinLocalBufferNoOwner()

void UnpinLocalBufferNoOwner ( Buffer  buffer )

Definition at line 846 of file localbuf.c.

847{
848 int buffid = -buffer - 1;
849
850 Assert(BufferIsLocal(buffer));
851 Assert(LocalRefCount[buffid] > 0);
853
854 if (--LocalRefCount[buffid] == 0)
855 {
856 BufferDesc *buf_hdr = GetLocalBufferDescriptor(buffid);
857 uint32 buf_state;
858
860
861 buf_state = pg_atomic_read_u32(&buf_hdr->state);
862 Assert(BUF_STATE_GET_REFCOUNT(buf_state) > 0);
863 buf_state -= BUF_REFCOUNT_ONE;
864 pg_atomic_unlocked_write_u32(&buf_hdr->state, buf_state);
865
866 /* see comment in UnpinBufferNoOwner */
868 }
869}
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
Definition: memdebug.h:27

References Assert(), BUF_REFCOUNT_ONE, BUF_STATE_GET_REFCOUNT, BufferIsLocal, GetLocalBufferDescriptor(), LocalBufHdrGetBlock, LocalRefCount, NLocalPinnedBuffers, pg_atomic_read_u32(), pg_atomic_unlocked_write_u32(), BufferDesc::state, and VALGRIND_MAKE_MEM_NOACCESS.

Referenced by ResOwnerReleaseBufferPin(), and UnpinLocalBuffer().

WritebackContextInit()

void WritebackContextInit ( WritebackContextcontext,
int *  max_pending 
)

Definition at line 6366 of file bufmgr.c.

6367{
6368 Assert(*max_pending <= WRITEBACK_MAX_PENDING_FLUSHES);
6369
6370 context->max_pending = max_pending;
6371 context->nr_pending = 0;
6372}

References Assert(), WritebackContext::max_pending, WritebackContext::nr_pending, and WRITEBACK_MAX_PENDING_FLUSHES.

Referenced by BackgroundWriterMain(), BufferManagerShmemInit(), and BufferSync().

Variable Documentation

BackendWritebackContext

PGDLLIMPORT WritebackContext BackendWritebackContext
extern

Definition at line 24 of file buf_init.c.

Referenced by BufferManagerShmemInit(), and GetVictimBuffer().

buffer_io_resowner_desc

PGDLLIMPORT const ResourceOwnerDesc buffer_io_resowner_desc
extern

Definition at line 235 of file bufmgr.c.

Referenced by ResourceOwnerForgetBufferIO(), and ResourceOwnerRememberBufferIO().

buffer_pin_resowner_desc

PGDLLIMPORT const ResourceOwnerDesc buffer_pin_resowner_desc
extern

Definition at line 244 of file bufmgr.c.

Referenced by ResourceOwnerForgetBuffer(), and ResourceOwnerRememberBuffer().

BufferDescriptors

PGDLLIMPORT BufferDescPadded* BufferDescriptors
extern

Definition at line 21 of file buf_init.c.

Referenced by BufferManagerShmemInit(), and GetBufferDescriptor().

BufferIOCVArray

Definition at line 23 of file buf_init.c.

Referenced by BufferDescriptorGetIOCV(), and BufferManagerShmemInit().

CkptBufferIds

PGDLLIMPORT CkptSortItem* CkptBufferIds
extern

Definition at line 25 of file buf_init.c.

Referenced by BufferManagerShmemInit(), and BufferSync().

LocalBufferDescriptors

PGDLLIMPORT BufferDesc* LocalBufferDescriptors
extern

Definition at line 46 of file localbuf.c.

Referenced by GetLocalBufferDescriptor(), and InitLocalBuffers().

AltStyle によって変換されたページ (->オリジナル) /