PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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/proclist_types.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   12
 
#define BUF_LOCK_BITS   (18+2)
 
#define BUF_REFCOUNT_ONE   1
 
#define BUF_REFCOUNT_MASK    ((UINT64CONST(1) << BUF_REFCOUNT_BITS) - 1)
 
#define BUF_USAGECOUNT_SHIFT    BUF_REFCOUNT_BITS
 
#define BUF_USAGECOUNT_MASK    (((UINT64CONST(1) << BUF_USAGECOUNT_BITS) - 1) << (BUF_USAGECOUNT_SHIFT))
 
#define BUF_USAGECOUNT_ONE    (UINT64CONST(1) << BUF_REFCOUNT_BITS)
 
#define BUF_FLAG_SHIFT    (BUF_REFCOUNT_BITS + BUF_USAGECOUNT_BITS)
 
#define BUF_FLAG_MASK    (((UINT64CONST(1) << BUF_FLAG_BITS) - 1) << BUF_FLAG_SHIFT)
 
#define BM_LOCK_SHIFT    (BUF_FLAG_SHIFT + BUF_FLAG_BITS)
 
#define BM_LOCK_VAL_SHARED    (UINT64CONST(1) << (BM_LOCK_SHIFT))
 
#define BM_LOCK_VAL_SHARE_EXCLUSIVE    (UINT64CONST(1) << (BM_LOCK_SHIFT + MAX_BACKENDS_BITS))
 
#define BM_LOCK_VAL_EXCLUSIVE    (UINT64CONST(1) << (BM_LOCK_SHIFT + MAX_BACKENDS_BITS + 1))
 
#define BM_LOCK_MASK    ((((uint64) MAX_BACKENDS) << BM_LOCK_SHIFT) | BM_LOCK_VAL_SHARE_EXCLUSIVE | BM_LOCK_VAL_EXCLUSIVE)
 
#define BUF_STATE_GET_REFCOUNT(state)    ((uint32)((state) & BUF_REFCOUNT_MASK))
 
#define BUF_STATE_GET_USAGECOUNT(state)    ((uint32)(((state) & BUF_USAGECOUNT_MASK) >> BUF_USAGECOUNT_SHIFT))
 
#define BUF_DEFINE_FLAG(flagno)    (UINT64CONST(1) << (BUF_FLAG_SHIFT + (flagno)))
 
#define BM_LOCKED   BUF_DEFINE_FLAG( 0)
 
#define BM_DIRTY   BUF_DEFINE_FLAG( 1)
 
#define BM_VALID   BUF_DEFINE_FLAG( 2)
 
#define BM_TAG_VALID   BUF_DEFINE_FLAG( 3)
 
#define BM_IO_IN_PROGRESS   BUF_DEFINE_FLAG( 4)
 
#define BM_IO_ERROR   BUF_DEFINE_FLAG( 5)
 
#define BM_JUST_DIRTIED   BUF_DEFINE_FLAG( 6)
 
#define BM_PIN_COUNT_WAITER   BUF_DEFINE_FLAG( 7)
 
#define BM_CHECKPOINT_NEEDED   BUF_DEFINE_FLAG( 8)
 
#define BM_PERMANENT   BUF_DEFINE_FLAG( 9)
 
#define BM_LOCK_HAS_WAITERS   BUF_DEFINE_FLAG(10)
 
#define BM_LOCK_WAKE_IN_PROGRESS   BUF_DEFINE_FLAG(11)
 
#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 union BufferDescPadded BufferDescPadded
 
typedef struct PendingWriteback PendingWriteback
 
typedef struct WritebackContext WritebackContext
 
typedef struct CkptSortItem CkptSortItem
 

Functions

 StaticAssertDecl (BUF_REFCOUNT_BITS+BUF_USAGECOUNT_BITS+BUF_FLAG_BITS+BUF_LOCK_BITS<=64, "parts of buffer state space need to be <= 64")
 
 StaticAssertDecl (MAX_BACKENDS_BITS<=BUF_REFCOUNT_BITS, "MAX_BACKENDS_BITS needs to be <= BUF_REFCOUNT_BITS")
 
 StaticAssertDecl (MAX_BACKENDS_BITS<=(BUF_LOCK_BITS - 2), "MAX_BACKENDS_BITS needs to be <= BUF_LOCK_BITS - 2")
 
 StaticAssertDecl (BM_MAX_USAGE_COUNT<(UINT64CONST(1)<< BUF_USAGECOUNT_BITS), "BM_MAX_USAGE_COUNT doesn't fit in BUF_USAGECOUNT_BITS bits")
 
static RelFileNumber BufTagGetRelNumber (const BufferTag *tag)
 
static ForkNumber BufTagGetForkNum (const BufferTag *tag)
 
static void BufTagSetRelForkDetails (BufferTag *tag, RelFileNumber relnumber, ForkNumber forknum)
 
static RelFileLocator BufTagGetRelFileLocator (const BufferTag *tag)
 
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 LWLockBufMappingPartitionLockByIndex (uint32 index)
 
static BufferDescGetBufferDescriptor (uint32 id)
 
static BufferDescGetLocalBufferDescriptor (uint32 id)
 
static Buffer BufferDescriptorGetBuffer (const BufferDesc *bdesc)
 
static ConditionVariableBufferDescriptorGetIOCV (const BufferDesc *bdesc)
 
uint64 LockBufHdr (BufferDesc *desc)
 
static void UnlockBufHdr (BufferDesc *desc)
 
static uint64 UnlockBufHdrExt (BufferDesc *desc, uint64 old_buf_state, uint64 set_bits, uint64 unset_bits, int refcount_change)
 
uint64 WaitBufHdrUnlocked (BufferDesc *buf)
 
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)
 
void TrackNewBufferPin (Buffer buf)
 
bool StartBufferIO (BufferDesc *buf, bool forInput, bool nowait)
 
void TerminateBufferIO (BufferDesc *buf, bool clear_dirty, uint64 set_flag_bits, bool forget_owner, bool release_aio)
 
IOContext IOContextForStrategy (BufferAccessStrategy strategy)
 
BufferDescStrategyGetBuffer (BufferAccessStrategy strategy, uint64 *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)
 
Size StrategyShmemSize (void)
 
void StrategyInitialize (bool init)
 
Size BufTableShmemSize (int size)
 
void InitBufTable (int size)
 
uint32 BufTableHashCode (BufferTag *tagPtr)
 
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)
 
void UnpinLocalBufferNoOwner (Buffer buffer)
 
PrefetchBufferResult PrefetchLocalBuffer (SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum)
 
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, uint64 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 DropRelationAllLocalBuffers (RelFileLocator rlocator)
 
void AtEOXact_LocalBuffers (bool isCommit)
 

Variables

PGDLLIMPORT BufferDescPaddedBufferDescriptors
 
PGDLLIMPORT ConditionVariableMinimallyPaddedBufferIOCVArray
 
PGDLLIMPORT WritebackContext BackendWritebackContext
 
PGDLLIMPORT BufferDescLocalBufferDescriptors
 
PGDLLIMPORT CkptSortItemCkptBufferIds
 
PGDLLIMPORT const ResourceOwnerDesc buffer_io_resowner_desc
 
PGDLLIMPORT const ResourceOwnerDesc buffer_resowner_desc
 

Macro Definition Documentation

◆ BM_CHECKPOINT_NEEDED

#define BM_CHECKPOINT_NEEDED   BUF_DEFINE_FLAG( 8)

Definition at line 122 of file buf_internals.h.

◆ BM_DIRTY

#define BM_DIRTY   BUF_DEFINE_FLAG( 1)

Definition at line 108 of file buf_internals.h.

◆ BM_IO_ERROR

#define BM_IO_ERROR   BUF_DEFINE_FLAG( 5)

Definition at line 116 of file buf_internals.h.

◆ BM_IO_IN_PROGRESS

#define BM_IO_IN_PROGRESS   BUF_DEFINE_FLAG( 4)

Definition at line 114 of file buf_internals.h.

◆ BM_JUST_DIRTIED

#define BM_JUST_DIRTIED   BUF_DEFINE_FLAG( 6)

Definition at line 118 of file buf_internals.h.

◆ BM_LOCK_HAS_WAITERS

#define BM_LOCK_HAS_WAITERS   BUF_DEFINE_FLAG(10)

Definition at line 126 of file buf_internals.h.

◆ BM_LOCK_MASK

Definition at line 85 of file buf_internals.h.

162{
163 Oid spcOid; /* tablespace oid */
164 Oid dbOid; /* database oid */
165 RelFileNumber relNumber; /* relation file number */
166 ForkNumber forkNum; /* fork number */
167 BlockNumber blockNum; /* blknum relative to begin of reln */
168} BufferTag;
169
170static inline RelFileNumber
172{
173 return tag->relNumber;
174}
175
176static inline ForkNumber
177BufTagGetForkNum(const BufferTag *tag)
178{
179 return tag->forkNum;
180}
181
182static inline void
184 ForkNumber forknum)
185{
186 tag->relNumber = relnumber;
187 tag->forkNum = forknum;
188}
189
190static inline RelFileLocator
192{
193 RelFileLocator rlocator;
194
195 rlocator.spcOid = tag->spcOid;
196 rlocator.dbOid = tag->dbOid;
197 rlocator.relNumber = BufTagGetRelNumber(tag);
198
199 return rlocator;
200}
201
202static inline void
204{
205 tag->spcOid = InvalidOid;
206 tag->dbOid = InvalidOid;
209}
210
211static inline void
212InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator,
213 ForkNumber forkNum, BlockNumber blockNum)
214{
215 tag->spcOid = rlocator->spcOid;
216 tag->dbOid = rlocator->dbOid;
217 BufTagSetRelForkDetails(tag, rlocator->relNumber, forkNum);
218 tag->blockNum = blockNum;
219}
220
221static inline bool
223{
224 return (tag1->spcOid == tag2->spcOid) &&
225 (tag1->dbOid == tag2->dbOid) &&
226 (tag1->relNumber == tag2->relNumber) &&
227 (tag1->blockNum == tag2->blockNum) &&
228 (tag1->forkNum == tag2->forkNum);
229}
230
231static inline bool
233 const RelFileLocator *rlocator)
234{
235 return (tag->spcOid == rlocator->spcOid) &&
236 (tag->dbOid == rlocator->dbOid) &&
237 (BufTagGetRelNumber(tag) == rlocator->relNumber);
238}
239
240
241/*
242 * The shared buffer mapping table is partitioned to reduce contention.
243 * To determine which partition lock a given tag requires, compute the tag's
244 * hash code with BufTableHashCode(), then apply BufMappingPartitionLock().
245 * NB: NUM_BUFFER_PARTITIONS must be a power of 2!
246 */
247static inline uint32
249{
250 return hashcode % NUM_BUFFER_PARTITIONS;
251}
252
253static inline LWLock *
255{
257 BufTableHashPartition(hashcode)].lock;
258}
259
260static inline LWLock *
262{
264}
265
266/*
267 * BufferDesc -- shared descriptor/state data for a single shared buffer.
268 *
269 * The state of the buffer is controlled by the, drumroll, state variable. It
270 * only may be modified using atomic operations. The state variable combines
271 * various flags, the buffer's refcount and usage count. See comment above
272 * BUF_REFCOUNT_BITS for details about the division. This layout allow us to
273 * do some operations in a single atomic operation, without actually acquiring
274 * and releasing the spinlock; for instance, increasing or decreasing the
275 * refcount.
276 *
277 * One of the aforementioned flags is BM_LOCKED, used to implement the buffer
278 * header lock. See the following paragraphs, as well as the documentation for
279 * individual fields, for more details.
280 *
281 * The identity of the buffer (BufferDesc.tag) can only be changed by the
282 * backend holding the buffer header lock.
283 *
284 * If the lock is held by another backend, neither additional buffer pins may
285 * be established (we would like to relax this eventually), nor can flags be
286 * set/cleared. These operations either need to acquire the buffer header
287 * spinlock, or need to use a CAS loop, waiting for the lock to be released if
288 * it is held. However, existing buffer pins may be released while the buffer
289 * header spinlock is held, using an atomic subtraction.
290 *
291 * If we have the buffer pinned, its tag can't change underneath us, so we can
292 * examine the tag without locking the buffer header. Also, in places we do
293 * one-time reads of the flags without bothering to lock the buffer header;
294 * this is generally for situations where we don't expect the flag bit being
295 * tested to be changing.
296 *
297 * We can't physically remove items from a disk page if another backend has
298 * the buffer pinned. Hence, a backend may need to wait for all other pins
299 * to go away. This is signaled by storing its own pgprocno into
300 * wait_backend_pgprocno and setting flag bit BM_PIN_COUNT_WAITER. At present,
301 * there can be only one such waiter per buffer.
302 *
303 * The content of buffers is protected via the buffer content lock,
304 * implemented as part of the buffer state. Note that the buffer header lock
305 * is *not* used to control access to the data in the buffer! We used to use
306 * an LWLock to implement the content lock, but having a dedicated
307 * implementation of content locks allows us to implement some otherwise hard
308 * things (e.g. race-freely checking if AIO is in progress before locking a
309 * buffer exclusively) and enables otherwise impossible optimizations
310 * (e.g. unlocking and unpinning a buffer in one atomic operation).
311 *
312 * We use this same struct for local buffer headers, but the locks are not
313 * used and not all of the flag bits are useful either. To avoid unnecessary
314 * overhead, manipulations of the state field should be done without actual
315 * atomic operations (i.e. only pg_atomic_read_u64() and
316 * pg_atomic_unlocked_write_u64()).
317 *
318 * Be careful to avoid increasing the size of the struct when adding or
319 * reordering members. Keeping it below 64 bytes (the most common CPU
320 * cache line size) is fairly important for performance.
321 *
322 * Per-buffer I/O condition variables are currently kept outside this struct in
323 * a separate array. They could be moved in here and still fit within that
324 * limit on common systems, but for now that is not done.
325 */
326typedef struct BufferDesc
327{
328 /*
329 * ID of page contained in buffer. The buffer header spinlock needs to be
330 * held to modify this field.
331 */
333
334 /*
335 * Buffer's index number (from 0). The field never changes after
336 * initialization, so does not need locking.
337 */
338 int buf_id;
339
340 /*
341 * State of the buffer, containing flags, refcount and usagecount. See
342 * BUF_* and BM_* defines at the top of this file.
343 */
345
346 /*
347 * Backend of pin-count waiter. The buffer header spinlock needs to be
348 * held to modify this field.
349 */
351
352 PgAioWaitRef io_wref; /* set iff AIO is in progress */
353
354 /*
355 * List of PGPROCs waiting for the buffer content lock. Protected by the
356 * buffer header spinlock.
357 */
359} BufferDesc;
360
361/*
362 * Concurrent access to buffer headers has proven to be more efficient if
363 * they're cache line aligned. So we force the start of the BufferDescriptors
364 * array to be on a cache line boundary and force the elements to be cache
365 * line sized.
366 *
367 * XXX: As this is primarily matters in highly concurrent workloads which
368 * probably all are 64bit these days, and the space wastage would be a bit
369 * more noticeable on 32bit systems, we don't force the stride to be cache
370 * line sized on those. If somebody does actual performance testing, we can
371 * reevaluate.
372 *
373 * Note that local buffer descriptors aren't forced to be aligned - as there's
374 * no concurrent access to those it's unlikely to be beneficial.
375 *
376 * We use a 64-byte cache line size here, because that's the most common
377 * size. Making it bigger would be a waste of memory. Even if running on a
378 * platform with either 32 or 128 byte line sizes, it's good to align to
379 * boundaries and avoid false sharing.
380 */
381#define BUFFERDESC_PAD_TO_SIZE (SIZEOF_VOID_P == 8 ? 64 : 1)
382
383typedef union BufferDescPadded
384{
388
389/*
390 * The PendingWriteback & WritebackContext structure are used to keep
391 * information about pending flush requests to be issued to the OS.
392 */
393typedef struct PendingWriteback
394{
395 /* could store different types of pending flushes here */
398
399/* struct forward declared in bufmgr.h */
400typedef struct WritebackContext
401{
402 /* pointer to the max number of writeback requests to coalesce */
403 int *max_pending;
404
405 /* current number of pending writeback requests */
406 int nr_pending;
407
408 /* pending requests */
411
412/* in buf_init.c */
416
417/* in localbuf.c */
419
420
421static inline BufferDesc *
423{
424 return &(BufferDescriptors[id]).bufferdesc;
425}
426
427static inline BufferDesc *
429{
430 return &LocalBufferDescriptors[id];
431}
432
433static inline Buffer
435{
436 return (Buffer) (bdesc->buf_id + 1);
437}
438
439static inline ConditionVariable *
441{
442 return &(BufferIOCVArray[bdesc->buf_id]).cv;
443}
444
445/*
446 * Functions for acquiring/releasing a shared buffer header's spinlock. Do
447 * not apply these to local buffers!
448 */
449extern uint64 LockBufHdr(BufferDesc *desc);
450
451/*
452 * Unlock the buffer header.
453 *
454 * This can only be used if the caller did not modify BufferDesc.state. To
455 * set/unset flag bits or change the refcount use UnlockBufHdrExt().
456 */
457static inline void
459{
461
463}
464
465/*
466 * Unlock the buffer header, while atomically adding the flags in set_bits,
467 * unsetting the ones in unset_bits and changing the refcount by
468 * refcount_change.
469 *
470 * Note that this approach would not work for usagecount, since we need to cap
471 * the usagecount at BM_MAX_USAGE_COUNT.
472 */
473static inline uint64
476 int refcount_change)
477{
478 for (;;)
479 {
481
483
487
488 if (refcount_change != 0)
490
492 buf_state))
493 {
494 return old_buf_state;
495 }
496 }
497}
498
500
501/* in bufmgr.c */
502
503/*
504 * Structure to sort buffers per file on checkpoints.
505 *
506 * This structure is allocated per buffer in shared memory, so it should be
507 * kept as small as possible.
508 */
509typedef struct CkptSortItem
510{
511 Oid tsId;
515 int buf_id;
517
519
520/* ResourceOwner callbacks to hold buffer I/Os and pins */
523
524/* Convenience wrappers over ResourceOwnerRemember/Forget */
525static inline void
527{
529}
530static inline void
532{
534}
535static inline void
537{
539}
540static inline void
542{
544}
545
546/*
547 * Internal buffer management routines
548 */
549/* bufmgr.c */
550extern void WritebackContextInit(WritebackContext *context, int *max_pending);
554
555extern void TrackNewBufferPin(Buffer buf);
556
557/* solely to make it easier to write tests */
558extern bool StartBufferIO(BufferDesc *buf, bool forInput, bool nowait);
560 bool forget_owner, bool release_aio);
561
562
563/* freelist.c */
566 uint64 *buf_state, bool *from_ring);
567extern bool StrategyRejectBuffer(BufferAccessStrategy strategy,
568 BufferDesc *buf, bool from_ring);
569
571extern void StrategyNotifyBgWriter(int bgwprocno);
572
573extern Size StrategyShmemSize(void);
574extern void StrategyInitialize(bool init);
575
576/* buf_table.c */
577extern Size BufTableShmemSize(int size);
578extern void InitBufTable(int size);
580extern int BufTableLookup(BufferTag *tagPtr, uint32 hashcode);
581extern int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id);
582extern void BufTableDelete(BufferTag *tagPtr, uint32 hashcode);
583
584/* localbuf.c */
586extern void UnpinLocalBuffer(Buffer buffer);
587extern void UnpinLocalBufferNoOwner(Buffer buffer);
589 ForkNumber forkNum,
590 BlockNumber blockNum);
592 BlockNumber blockNum, bool *foundPtr);
595 uint32 flags,
598 Buffer *buffers,
600extern void MarkLocalBufferDirty(Buffer buffer);
603extern bool StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool nowait);
606extern void DropRelationLocalBuffers(RelFileLocator rlocator,
607 ForkNumber *forkNum, int nforks,
609extern void DropRelationAllLocalBuffers(RelFileLocator rlocator);
610extern void AtEOXact_LocalBuffers(bool isCommit);
611
612#endif /* BUFMGR_INTERNALS_H */
static bool pg_atomic_compare_exchange_u64(volatile pg_atomic_uint64 *ptr, uint64 *expected, uint64 newval)
Definition atomics.h:522
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
Definition atomics.h:467
static uint64 pg_atomic_fetch_sub_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
Definition atomics.h:541
uint32 BlockNumber
Definition block.h:31
#define InvalidBlockNumber
Definition block.h:33
int Buffer
Definition buf.h:23
void FlushLocalBuffer(BufferDesc *bufHdr, SMgrRelation reln)
Definition localbuf.c:183
PGDLLIMPORT const ResourceOwnerDesc buffer_resowner_desc
Definition bufmgr.c:278
static void InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator, ForkNumber forkNum, BlockNumber blockNum)
static uint32 BufTableHashPartition(uint32 hashcode)
static LWLock * BufMappingPartitionLockByIndex(uint32 index)
void BufTableDelete(BufferTag *tagPtr, uint32 hashcode)
Definition buf_table.c:148
void UnpinLocalBuffer(Buffer buffer)
Definition localbuf.c:841
int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc)
Definition freelist.c:321
static ForkNumber BufTagGetForkNum(const BufferTag *tag)
#define BUF_REFCOUNT_ONE
static ConditionVariable * BufferDescriptorGetIOCV(const BufferDesc *bdesc)
bool StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool nowait)
Definition localbuf.c:523
static uint64 UnlockBufHdrExt(BufferDesc *desc, uint64 old_buf_state, uint64 set_bits, uint64 unset_bits, int refcount_change)
void AtEOXact_LocalBuffers(bool isCommit)
Definition localbuf.c:1003
int BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
Definition buf_table.c:90
BufferDesc * StrategyGetBuffer(BufferAccessStrategy strategy, uint64 *buf_state, bool *from_ring)
Definition freelist.c:174
static bool BufferTagsEqual(const BufferTag *tag1, const BufferTag *tag2)
static RelFileNumber BufTagGetRelNumber(const BufferTag *tag)
static void UnlockBufHdr(BufferDesc *desc)
static bool BufTagMatchesRelFileLocator(const BufferTag *tag, const RelFileLocator *rlocator)
bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount)
Definition localbuf.c:805
static void BufTagSetRelForkDetails(BufferTag *tag, RelFileNumber relnumber, ForkNumber forknum)
void InitBufTable(int size)
Definition buf_table.c:51
PGDLLIMPORT const ResourceOwnerDesc buffer_io_resowner_desc
Definition bufmgr.c:269
void StrategyInitialize(bool init)
Definition freelist.c:401
static void ResourceOwnerRememberBufferIO(ResourceOwner owner, Buffer buffer)
uint64 LockBufHdr(BufferDesc *desc)
Definition bufmgr.c:7097
#define BM_LOCKED
void MarkLocalBufferDirty(Buffer buffer)
Definition localbuf.c:491
#define BUFFERDESC_PAD_TO_SIZE
PGDLLIMPORT WritebackContext BackendWritebackContext
Definition buf_init.c:25
static void ResourceOwnerForgetBufferIO(ResourceOwner owner, Buffer buffer)
Size BufTableShmemSize(int size)
Definition buf_table.c:41
uint32 BufTableHashCode(BufferTag *tagPtr)
Definition buf_table.c:78
void DropRelationAllLocalBuffers(RelFileLocator rlocator)
Definition localbuf.c:702
void ScheduleBufferTagForWriteback(WritebackContext *wb_context, IOContext io_context, BufferTag *tag)
Definition bufmgr.c:7269
void InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced)
Definition localbuf.c:605
int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id)
Definition buf_table.c:118
static void ClearBufferTag(BufferTag *tag)
static void ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer)
void WritebackContextInit(WritebackContext *context, int *max_pending)
Definition bufmgr.c:7257
void StrategyNotifyBgWriter(int bgwprocno)
Definition freelist.c:358
struct buftag BufferTag
static void ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer)
void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint64 set_flag_bits, bool release_aio)
Definition localbuf.c:562
PGDLLIMPORT BufferDescPadded * BufferDescriptors
Definition buf_init.c:22
PrefetchBufferResult PrefetchLocalBuffer(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum)
Definition localbuf.c:72
PGDLLIMPORT ConditionVariableMinimallyPadded * BufferIOCVArray
Definition buf_init.c:24
BlockNumber ExtendBufferedRelLocal(BufferManagerRelation bmr, ForkNumber fork, uint32 flags, uint32 extend_by, BlockNumber extend_upto, Buffer *buffers, uint32 *extended_by)
Definition localbuf.c:346
void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context)
Definition bufmgr.c:7319
PGDLLIMPORT CkptSortItem * CkptBufferIds
Definition buf_init.c:26
IOContext IOContextForStrategy(BufferAccessStrategy strategy)
Definition freelist.c:747
void UnpinLocalBufferNoOwner(Buffer buffer)
Definition localbuf.c:848
void DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber *forkNum, int nforks, BlockNumber *firstDelBlock)
Definition localbuf.c:665
static LWLock * BufMappingPartitionLock(uint32 hashcode)
void TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint64 set_flag_bits, bool forget_owner, bool release_aio)
Definition bufmgr.c:6937
bool StartBufferIO(BufferDesc *buf, bool forInput, bool nowait)
Definition bufmgr.c:6879
static RelFileLocator BufTagGetRelFileLocator(const BufferTag *tag)
Size StrategyShmemSize(void)
Definition freelist.c:380
uint64 WaitBufHdrUnlocked(BufferDesc *buf)
Definition bufmgr.c:7145
PGDLLIMPORT BufferDesc * LocalBufferDescriptors
Definition localbuf.c:47
static BufferDesc * GetLocalBufferDescriptor(uint32 id)
static BufferDesc * GetBufferDescriptor(uint32 id)
void TrackNewBufferPin(Buffer buf)
Definition bufmgr.c:3416
bool StrategyRejectBuffer(BufferAccessStrategy strategy, BufferDesc *buf, bool from_ring)
Definition freelist.c:787
static Buffer BufferDescriptorGetBuffer(const BufferDesc *bdesc)
BufferDesc * LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum, bool *foundPtr)
Definition localbuf.c:119
#define PGDLLIMPORT
Definition c.h:1328
#define Assert(condition)
Definition c.h:873
uint64_t uint64
Definition c.h:547
uint32_t uint32
Definition c.h:546
size_t Size
Definition c.h:619
LWLockPadded * MainLWLockArray
Definition lwlock.c:161
#define BUFFER_MAPPING_LWLOCK_OFFSET
Definition lwlock.h:102
#define NUM_BUFFER_PARTITIONS
Definition lwlock.h:91
#define WRITEBACK_MAX_PENDING_FLUSHES
static char buf[DEFAULT_XLOG_SEG_SIZE]
IOContext
Definition pgstat.h:285
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
#define InvalidOid
unsigned int Oid
static int fb(int x)
Oid RelFileNumber
Definition relpath.h:25
ForkNumber
Definition relpath.h:56
@ InvalidForkNumber
Definition relpath.h:57
#define InvalidRelFileNumber
Definition relpath.h:26
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition resowner.c:561
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition resowner.c:521
#define init()
int wait_backend_pgprocno
BufferTag tag
pg_atomic_uint64 state
proclist_head lock_waiters
PgAioWaitRef io_wref
ForkNumber forkNum
RelFileNumber relNumber
BlockNumber blockNum
RelFileNumber relNumber
PendingWriteback pending_writebacks[WRITEBACK_MAX_PENDING_FLUSHES]
BlockNumber blockNum
RelFileNumber relNumber
ForkNumber forkNum
Definition type.h:96
char pad[BUFFERDESC_PAD_TO_SIZE]
BufferDesc bufferdesc
LWLock lock
Definition lwlock.h:70

◆ BM_LOCK_SHIFT

#define BM_LOCK_SHIFT    (BUF_FLAG_SHIFT + BUF_FLAG_BITS)

Definition at line 77 of file buf_internals.h.

◆ BM_LOCK_VAL_EXCLUSIVE

#define BM_LOCK_VAL_EXCLUSIVE    (UINT64CONST(1) << (BM_LOCK_SHIFT + MAX_BACKENDS_BITS + 1))

Definition at line 83 of file buf_internals.h.

◆ BM_LOCK_VAL_SHARE_EXCLUSIVE

#define BM_LOCK_VAL_SHARE_EXCLUSIVE    (UINT64CONST(1) << (BM_LOCK_SHIFT + MAX_BACKENDS_BITS))

Definition at line 81 of file buf_internals.h.

◆ BM_LOCK_VAL_SHARED

#define BM_LOCK_VAL_SHARED    (UINT64CONST(1) << (BM_LOCK_SHIFT))

Definition at line 79 of file buf_internals.h.

◆ BM_LOCK_WAKE_IN_PROGRESS

#define BM_LOCK_WAKE_IN_PROGRESS   BUF_DEFINE_FLAG(11)

Definition at line 128 of file buf_internals.h.

◆ BM_LOCKED

#define BM_LOCKED   BUF_DEFINE_FLAG( 0)

Definition at line 106 of file buf_internals.h.

◆ BM_MAX_USAGE_COUNT

#define BM_MAX_USAGE_COUNT   5

Definition at line 145 of file buf_internals.h.

◆ BM_PERMANENT

#define BM_PERMANENT   BUF_DEFINE_FLAG( 9)

Definition at line 124 of file buf_internals.h.

◆ BM_PIN_COUNT_WAITER

#define BM_PIN_COUNT_WAITER   BUF_DEFINE_FLAG( 7)

Definition at line 120 of file buf_internals.h.

◆ BM_TAG_VALID

#define BM_TAG_VALID   BUF_DEFINE_FLAG( 3)

Definition at line 112 of file buf_internals.h.

◆ BM_VALID

#define BM_VALID   BUF_DEFINE_FLAG( 2)

Definition at line 110 of file buf_internals.h.

◆ BUF_DEFINE_FLAG

#define BUF_DEFINE_FLAG (   flagno)     (UINT64CONST(1) << (BUF_FLAG_SHIFT + (flagno)))

Definition at line 102 of file buf_internals.h.

◆ BUF_FLAG_BITS

#define BUF_FLAG_BITS   12

Definition at line 51 of file buf_internals.h.

◆ BUF_FLAG_MASK

#define BUF_FLAG_MASK    (((UINT64CONST(1) << BUF_FLAG_BITS) - 1) << BUF_FLAG_SHIFT)

Definition at line 73 of file buf_internals.h.

◆ BUF_FLAG_SHIFT

#define BUF_FLAG_SHIFT    (BUF_REFCOUNT_BITS + BUF_USAGECOUNT_BITS)

Definition at line 71 of file buf_internals.h.

◆ BUF_LOCK_BITS

#define BUF_LOCK_BITS   (18+2)

Definition at line 52 of file buf_internals.h.

◆ BUF_REFCOUNT_BITS

#define BUF_REFCOUNT_BITS   18

Definition at line 49 of file buf_internals.h.

◆ BUF_REFCOUNT_MASK

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

Definition at line 59 of file buf_internals.h.

◆ BUF_REFCOUNT_ONE

#define BUF_REFCOUNT_ONE   1

Definition at line 58 of file buf_internals.h.

◆ BUF_STATE_GET_REFCOUNT

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

Definition at line 90 of file buf_internals.h.

◆ BUF_STATE_GET_USAGECOUNT

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

Definition at line 92 of file buf_internals.h.

◆ BUF_USAGECOUNT_BITS

#define BUF_USAGECOUNT_BITS   4

Definition at line 50 of file buf_internals.h.

◆ BUF_USAGECOUNT_MASK

#define BUF_USAGECOUNT_MASK    (((UINT64CONST(1) << BUF_USAGECOUNT_BITS) - 1) << (BUF_USAGECOUNT_SHIFT))

Definition at line 65 of file buf_internals.h.

◆ BUF_USAGECOUNT_ONE

#define BUF_USAGECOUNT_ONE    (UINT64CONST(1) << BUF_REFCOUNT_BITS)

Definition at line 67 of file buf_internals.h.

◆ BUF_USAGECOUNT_SHIFT

#define BUF_USAGECOUNT_SHIFT    BUF_REFCOUNT_BITS

Definition at line 63 of file buf_internals.h.

◆ BUFFERDESC_PAD_TO_SIZE

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

Definition at line 382 of file buf_internals.h.

Typedef Documentation

◆ BufferDesc

◆ BufferDescPadded

◆ BufferTag

◆ CkptSortItem

◆ PendingWriteback

◆ WritebackContext

Function Documentation

◆ AtEOXact_LocalBuffers()

void AtEOXact_LocalBuffers ( bool  isCommit)
extern

Definition at line 1003 of file localbuf.c.

1004{
1006}
static void CheckForLocalBufferLeaks(void)
Definition localbuf.c:970

References CheckForLocalBufferLeaks().

Referenced by AtEOXact_Buffers().

◆ BufferDescriptorGetBuffer()

◆ BufferDescriptorGetIOCV()

static ConditionVariable * BufferDescriptorGetIOCV ( const BufferDesc bdesc)
inlinestatic

Definition at line 441 of file buf_internals.h.

442{
443 return &(BufferIOCVArray[bdesc->buf_id]).cv;
444}

References BufferIOCVArray, and fb().

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

◆ BufferTagsEqual()

static bool BufferTagsEqual ( const BufferTag tag1,
const BufferTag tag2 
)
inlinestatic

Definition at line 223 of file buf_internals.h.

224{
225 return (tag1->spcOid == tag2->spcOid) &&
226 (tag1->dbOid == tag2->dbOid) &&
227 (tag1->relNumber == tag2->relNumber) &&
228 (tag1->blockNum == tag2->blockNum) &&
229 (tag1->forkNum == tag2->forkNum);
230}

References fb().

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

◆ BufMappingPartitionLock()

◆ BufMappingPartitionLockByIndex()

static LWLock * BufMappingPartitionLockByIndex ( uint32  index)
inlinestatic

◆ BufTableDelete()

void BufTableDelete ( BufferTag tagPtr,
uint32  hashcode 
)
extern

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, fb(), HASH_REMOVE, hash_search_with_hash_value(), and SharedBufHash.

Referenced by InvalidateBuffer(), and InvalidateVictimBuffer().

◆ BufTableHashCode()

uint32 BufTableHashCode ( BufferTag tagPtr)
extern

Definition at line 78 of file buf_table.c.

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

References fb(), get_hash_value(), and SharedBufHash.

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

◆ BufTableHashPartition()

static uint32 BufTableHashPartition ( uint32  hashcode)
inlinestatic

Definition at line 249 of file buf_internals.h.

250{
251 return hashcode % NUM_BUFFER_PARTITIONS;
252}

References NUM_BUFFER_PARTITIONS.

Referenced by BufMappingPartitionLock().

◆ BufTableInsert()

int BufTableInsert ( BufferTag tagPtr,
uint32  hashcode,
int  buf_id 
)
extern

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:198
@ HASH_ENTER
Definition hsearch.h:114

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

Referenced by BufferAlloc(), and ExtendBufferedRelShared().

◆ BufTableLookup()

int BufTableLookup ( BufferTag tagPtr,
uint32  hashcode 
)
extern

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 fb(), HASH_FIND, hash_search_with_hash_value(), BufferLookupEnt::id, and SharedBufHash.

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

◆ BufTableShmemSize()

Size BufTableShmemSize ( int  size)
extern

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

◆ BufTagGetRelFileLocator()

◆ BufTagGetRelNumber()

static RelFileNumber BufTagGetRelNumber ( const BufferTag tag)
inlinestatic

Definition at line 172 of file buf_internals.h.

173{
174 return tag->relNumber;
175}

References buftag::relNumber.

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

◆ BufTagMatchesRelFileLocator()

◆ BufTagSetRelForkDetails()

static void BufTagSetRelForkDetails ( BufferTag tag,
RelFileNumber  relnumber,
ForkNumber  forknum 
)
inlinestatic

Definition at line 184 of file buf_internals.h.

186{
187 tag->relNumber = relnumber;
188 tag->forkNum = forknum;
189}

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

Referenced by ClearBufferTag(), and InitBufferTag().

◆ ClearBufferTag()

◆ DropRelationAllLocalBuffers()

void DropRelationAllLocalBuffers ( RelFileLocator  rlocator)
extern

Definition at line 702 of file localbuf.c.

703{
704 int i;
705
706 for (i = 0; i < NLocBuffer; i++)
707 {
710
712
713 if ((buf_state & BM_TAG_VALID) &&
714 BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator))
715 {
717 }
718 }
719}
#define BM_TAG_VALID
int i
Definition isn.c:77
void InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced)
Definition localbuf.c:605
int NLocBuffer
Definition localbuf.c:45

References BM_TAG_VALID, BufTagMatchesRelFileLocator(), fb(), GetLocalBufferDescriptor(), i, InvalidateLocalBuffer(), NLocBuffer, and pg_atomic_read_u64().

Referenced by DropRelationsAllBuffers().

◆ DropRelationLocalBuffers()

void DropRelationLocalBuffers ( RelFileLocator  rlocator,
ForkNumber forkNum,
int  nforks,
BlockNumber firstDelBlock 
)
extern

Definition at line 665 of file localbuf.c.

667{
668 int i;
669 int j;
670
671 for (i = 0; i < NLocBuffer; i++)
672 {
675
677
678 if (!(buf_state & BM_TAG_VALID) ||
679 !BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator))
680 continue;
681
682 for (j = 0; j < nforks; j++)
683 {
684 if (BufTagGetForkNum(&bufHdr->tag) == forkNum[j] &&
685 bufHdr->tag.blockNum >= firstDelBlock[j])
686 {
688 break;
689 }
690 }
691 }
692}
int j
Definition isn.c:78

References BM_TAG_VALID, BufTagGetForkNum(), BufTagMatchesRelFileLocator(), fb(), GetLocalBufferDescriptor(), i, InvalidateLocalBuffer(), j, NLocBuffer, and pg_atomic_read_u64().

Referenced by DropRelationBuffers().

◆ ExtendBufferedRelLocal()

BlockNumber ExtendBufferedRelLocal ( BufferManagerRelation  bmr,
ForkNumber  fork,
uint32  flags,
uint32  extend_by,
BlockNumber  extend_upto,
Buffer buffers,
uint32 extended_by 
)
extern

Definition at line 346 of file localbuf.c.

353{
356
357 /* Initialize local buffers if first request in this session */
358 if (LocalBufHash == NULL)
360
362
363 for (uint32 i = 0; i < extend_by; i++)
364 {
367
368 buffers[i] = GetLocalVictimBuffer();
369 buf_hdr = GetLocalBufferDescriptor(-buffers[i] - 1);
371
372 /* new buffers are zero-filled */
374 }
375
377
379 {
380 /*
381 * In contrast to shared relations, nothing could change the relation
382 * size concurrently. Thus we shouldn't end up finding that we don't
383 * need to do anything.
384 */
386
388 }
389
390 /* Fail if relation is already at maximum possible length */
394 errmsg("cannot extend relation %s beyond %u blocks",
395 relpath(BMR_GET_SMGR(bmr)->smgr_rlocator, fork).str,
397
398 for (uint32 i = 0; i < extend_by; i++)
399 {
400 int victim_buf_id;
402 BufferTag tag;
404 bool found;
405
406 victim_buf_id = -buffers[i] - 1;
408
409 /* in case we need to pin an existing buffer below */
411
412 InitBufferTag(&tag, &BMR_GET_SMGR(bmr)->smgr_rlocator.locator, fork,
413 first_block + i);
414
416 hash_search(LocalBufHash, &tag, HASH_ENTER, &found);
417 if (found)
418 {
421
423
427
428 /*
429 * Clear the BM_VALID bit, do StartLocalBufferIO() and proceed.
430 */
436
437 /* no need to loop for local buffers */
438 StartLocalBufferIO(existing_hdr, true, false);
439 }
440 else
441 {
443
445
446 victim_buf_hdr->tag = tag;
447
449
451
453
455 }
456 }
457
459
460 /* actually extend relation */
462
465
466 for (uint32 i = 0; i < extend_by; i++)
467 {
468 Buffer buf = buffers[i];
471
473
477 }
478
480
482
483 return first_block;
484}
static void pg_atomic_unlocked_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:494
#define MaxBlockNumber
Definition block.h:35
#define BM_DIRTY
#define BM_JUST_DIRTIED
#define BUF_USAGECOUNT_ONE
#define BM_VALID
bool track_io_timing
Definition bufmgr.c:176
void * Block
Definition bufmgr.h:26
#define BMR_GET_SMGR(bmr)
Definition bufmgr.h:118
#define MemSet(start, val, len)
Definition c.h:1013
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition dynahash.c:952
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ereport(elevel,...)
Definition elog.h:150
const char * str
BufferUsage pgBufferUsage
Definition instrument.c:20
void UnpinLocalBuffer(Buffer buffer)
Definition localbuf.c:841
bool StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool nowait)
Definition localbuf.c:523
static HTAB * LocalBufHash
Definition localbuf.c:53
#define LocalBufHdrGetBlock(bufHdr)
Definition localbuf.c:42
bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount)
Definition localbuf.c:805
static void InitLocalBuffers(void)
Definition localbuf.c:728
void LimitAdditionalLocalPins(uint32 *additional_pins)
Definition localbuf.c:323
static Buffer GetLocalVictimBuffer(void)
Definition localbuf.c:224
@ IOOBJECT_TEMP_RELATION
Definition pgstat.h:278
@ IOCONTEXT_NORMAL
Definition pgstat.h:289
@ IOOP_EXTEND
Definition pgstat.h:314
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
int64 local_blks_written
Definition instrument.h:33

References Assert, BM_DIRTY, BM_JUST_DIRTIED, BM_TAG_VALID, BM_VALID, BMR_GET_SMGR, buf, BUF_USAGECOUNT_ONE, BufferDescriptorGetBuffer(), CurrentResourceOwner, ereport, errcode(), errmsg(), ERROR, fb(), GetLocalBufferDescriptor(), GetLocalVictimBuffer(), HASH_ENTER, hash_search(), i, InitBufferTag(), InitLocalBuffers(), InvalidBlockNumber, IOCONTEXT_NORMAL, IOOBJECT_TEMP_RELATION, IOOP_EXTEND, LimitAdditionalLocalPins(), BufferUsage::local_blks_written, LocalBufHash, LocalBufHdrGetBlock, MaxBlockNumber, MemSet, pg_atomic_read_u64(), pg_atomic_unlocked_write_u64(), pgBufferUsage, pgstat_count_io_op_time(), pgstat_prepare_io_time(), PinLocalBuffer(), relpath, ResourceOwnerEnlarge(), smgrnblocks(), smgrzeroextend(), StartLocalBufferIO(), str, track_io_timing, and UnpinLocalBuffer().

Referenced by ExtendBufferedRelCommon().

◆ FlushLocalBuffer()

void FlushLocalBuffer ( BufferDesc bufHdr,
SMgrRelation  reln 
)
extern

Definition at line 183 of file localbuf.c.

184{
187
189
190 /*
191 * Try to start an I/O operation. There currently are no reasons for
192 * StartLocalBufferIO to return false, so we raise an error in that case.
193 */
194 if (!StartLocalBufferIO(bufHdr, false, false))
195 elog(ERROR, "failed to start write IO on local buffer");
196
197 /* Find smgr relation for buffer */
198 if (reln == NULL)
201
203
205
206 /* And write... */
209 bufHdr->tag.blockNum,
210 localpage,
211 false);
212
213 /* Temporary table I/O does not use Buffer Access Strategies */
216
217 /* Mark not-dirty */
218 TerminateLocalBufferIO(bufHdr, true, 0, false);
219
221}
void PageSetChecksumInplace(Page page, BlockNumber blkno)
Definition bufpage.c:1541
PageData * Page
Definition bufpage.h:81
ProcNumber MyProcNumber
Definition globals.c:90
int32 * LocalRefCount
Definition localbuf.c:49
void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint64 set_flag_bits, bool release_aio)
Definition localbuf.c:562
@ IOOP_WRITE
Definition pgstat.h:316
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, BufferDescriptorGetBuffer(), BufTagGetForkNum(), BufTagGetRelFileLocator(), elog, ERROR, fb(), 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(), TerminateLocalBufferIO(), and track_io_timing.

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

◆ GetBufferDescriptor()

static BufferDesc * GetBufferDescriptor ( uint32  id)
inlinestatic

Definition at line 423 of file buf_internals.h.

424{
425 return &(BufferDescriptors[id]).bufferdesc;
426}

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(), BufferIsLockedByMe(), BufferIsLockedByMeInMode(), 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(), LockBufferForCleanup(), LockBufferInternal(), MarkBufferDirty(), MarkBufferDirtyHint(), MarkDirtyAllUnpinnedBuffers(), MarkDirtyRelUnpinnedBuffers(), MarkDirtyUnpinnedBuffer(), pg_buffercache_os_pages_internal(), pg_buffercache_pages(), pg_buffercache_summary(), pg_buffercache_usage_counts(), read_rel_block_ll(), ReadBuffersCanStartIOOnce(), ReadRecentBuffer(), ReleaseAndReadBuffer(), ReleaseBuffer(), ResOwnerReleaseBuffer(), StartReadBuffersImpl(), StrategyGetBuffer(), SyncOneBuffer(), TrackNewBufferPin(), UnlockBuffer(), and ZeroAndLockBuffer().

◆ GetLocalBufferDescriptor()

◆ InitBufferTag()

◆ InitBufTable()

void InitBufTable ( int  size)
extern

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}
#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:334
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 ( BufferDesc bufHdr,
bool  check_unreferenced 
)
extern

Definition at line 605 of file localbuf.c.

606{
608 int bufid = -buffer - 1;
611
612 /*
613 * It's possible that we started IO on this buffer before e.g. aborting
614 * the transaction that created a table. We need to wait for that IO to
615 * complete before removing / reusing the buffer.
616 */
617 if (pgaio_wref_valid(&bufHdr->io_wref))
618 {
619 PgAioWaitRef iow = bufHdr->io_wref;
620
622 Assert(!pgaio_wref_valid(&bufHdr->io_wref));
623 }
624
626
627 /*
628 * We need to test not just LocalRefCount[bufid] but also the BufferDesc
629 * itself, as the latter is used to represent a pin by the AIO subsystem.
630 * This can happen if AIO is initiated and then the query errors out.
631 */
632 if (check_unreferenced &&
634 elog(ERROR, "block %u of %s is still referenced (local %d)",
635 bufHdr->tag.blockNum,
638 BufTagGetForkNum(&bufHdr->tag)).str,
640
641 /* Remove entry from hashtable */
644 if (!hresult) /* shouldn't happen */
645 elog(ERROR, "local buffer hash table corrupted");
646 /* Mark buffer invalid */
647 ClearBufferTag(&bufHdr->tag);
651}
bool pgaio_wref_valid(PgAioWaitRef *iow)
Definition aio.c:971
void pgaio_wref_wait(PgAioWaitRef *iow)
Definition aio.c:991
#define BUF_STATE_GET_REFCOUNT(state)
#define relpathbackend(rlocator, backend, forknum)
Definition relpath.h:141

References Assert, BUF_STATE_GET_REFCOUNT, BufferDescriptorGetBuffer(), BufTagGetForkNum(), BufTagGetRelFileLocator(), ClearBufferTag(), elog, ERROR, fb(), HASH_REMOVE, hash_search(), LocalBufHash, LocalRefCount, MyProcNumber, pg_atomic_read_u64(), pg_atomic_unlocked_write_u64(), pgaio_wref_valid(), pgaio_wref_wait(), and relpathbackend.

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

◆ IOContextForStrategy()

IOContext IOContextForStrategy ( BufferAccessStrategy  strategy)
extern

Definition at line 747 of file freelist.c.

748{
749 if (!strategy)
750 return IOCONTEXT_NORMAL;
751
752 switch (strategy->btype)
753 {
754 case BAS_NORMAL:
755
756 /*
757 * Currently, GetAccessStrategy() returns NULL for
758 * BufferAccessStrategyType BAS_NORMAL, so this case is
759 * unreachable.
760 */
762 return IOCONTEXT_NORMAL;
763 case BAS_BULKREAD:
764 return IOCONTEXT_BULKREAD;
765 case BAS_BULKWRITE:
766 return IOCONTEXT_BULKWRITE;
767 case BAS_VACUUM:
768 return IOCONTEXT_VACUUM;
769 }
770
771 elog(ERROR, "unrecognized BufferAccessStrategyType: %d", strategy->btype);
773}
@ 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:341
@ IOCONTEXT_VACUUM
Definition pgstat.h:290
@ IOCONTEXT_BULKREAD
Definition pgstat.h:286
@ IOCONTEXT_BULKWRITE
Definition pgstat.h:287
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 ( WritebackContext wb_context,
IOContext  io_context 
)
extern

Definition at line 7319 of file bufmgr.c.

7320{
7322 int i;
7323
7324 if (wb_context->nr_pending == 0)
7325 return;
7326
7327 /*
7328 * Executing the writes in-order can make them a lot faster, and allows to
7329 * merge writeback requests to consecutive blocks into larger writebacks.
7330 */
7331 sort_pending_writebacks(wb_context->pending_writebacks,
7332 wb_context->nr_pending);
7333
7335
7336 /*
7337 * Coalesce neighbouring writes, but nothing else. For that we iterate
7338 * through the, now sorted, array of pending flushes, and look forward to
7339 * find all neighbouring (or identical) writes.
7340 */
7341 for (i = 0; i < wb_context->nr_pending; i++)
7342 {
7346 int ahead;
7347 BufferTag tag;
7349 Size nblocks = 1;
7350
7351 cur = &wb_context->pending_writebacks[i];
7352 tag = cur->tag;
7354
7355 /*
7356 * Peek ahead, into following writeback requests, to see if they can
7357 * be combined with the current one.
7358 */
7359 for (ahead = 0; i + ahead + 1 < wb_context->nr_pending; ahead++)
7360 {
7361
7362 next = &wb_context->pending_writebacks[i + ahead + 1];
7363
7364 /* different file, stop */
7366 BufTagGetRelFileLocator(&next->tag)) ||
7367 BufTagGetForkNum(&cur->tag) != BufTagGetForkNum(&next->tag))
7368 break;
7369
7370 /* ok, block queued twice, skip */
7371 if (cur->tag.blockNum == next->tag.blockNum)
7372 continue;
7373
7374 /* only merge consecutive writes */
7375 if (cur->tag.blockNum + 1 != next->tag.blockNum)
7376 break;
7377
7378 nblocks++;
7379 cur = next;
7380 }
7381
7382 i += ahead;
7383
7384 /* and finally tell the kernel to write the data to storage */
7386 smgrwriteback(reln, BufTagGetForkNum(&tag), tag.blockNum, nblocks);
7387 }
7388
7389 /*
7390 * Assume that writeback requests are only issued for buffers containing
7391 * blocks of permanent relations.
7392 */
7394 IOOP_WRITEBACK, io_start, wb_context->nr_pending, 0);
7395
7396 wb_context->nr_pending = 0;
7397}
static int32 next
Definition blutils.c:225
struct cursor * cur
Definition ecpg.c:29
@ IOOBJECT_RELATION
Definition pgstat.h:277
@ IOOP_WRITEBACK
Definition pgstat.h:311
#define INVALID_PROC_NUMBER
Definition procnumber.h:26
#define RelFileLocatorEquals(locator1, locator2)
void smgrwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks)
Definition smgr.c:805

References buftag::blockNum, BufTagGetForkNum(), BufTagGetRelFileLocator(), cur, fb(), i, INVALID_PROC_NUMBER, IOOBJECT_RELATION, IOOP_WRITEBACK, next, 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 
)
extern

Definition at line 119 of file localbuf.c.

121{
122 BufferTag newTag; /* identity of requested block */
126 int bufid;
127 bool found;
128
129 InitBufferTag(&newTag, &smgr->smgr_rlocator.locator, forkNum, blockNum);
130
131 /* Initialize local buffers if first request in this session */
132 if (LocalBufHash == NULL)
134
136
137 /* See if the desired buffer already exists */
140
141 if (hresult)
142 {
143 bufid = hresult->id;
146
148 }
149 else
150 {
152
154 bufid = -victim_buffer - 1;
156
159 if (found) /* shouldn't happen */
160 elog(ERROR, "local buffer hash table corrupted");
161 hresult->id = bufid;
162
163 /*
164 * it's all ours now.
165 */
166 bufHdr->tag = newTag;
167
172
173 *foundPtr = false;
174 }
175
176 return bufHdr;
177}
#define BUF_USAGECOUNT_MASK
#define BUF_FLAG_MASK
RelFileLocator locator
RelFileLocatorBackend smgr_rlocator
Definition smgr.h:38

References Assert, BM_TAG_VALID, BUF_FLAG_MASK, BUF_USAGECOUNT_MASK, BUF_USAGECOUNT_ONE, BufferTagsEqual(), CurrentResourceOwner, elog, ERROR, fb(), GetLocalBufferDescriptor(), GetLocalVictimBuffer(), HASH_ENTER, HASH_FIND, hash_search(), InitBufferTag(), InitLocalBuffers(), LocalBufHash, RelFileLocatorBackend::locator, pg_atomic_read_u64(), pg_atomic_unlocked_write_u64(), PinLocalBuffer(), ResourceOwnerEnlarge(), and SMgrRelationData::smgr_rlocator.

Referenced by PinBufferForBlock().

◆ LockBufHdr()

uint64 LockBufHdr ( BufferDesc desc)
extern

Definition at line 7097 of file bufmgr.c.

7098{
7100
7102
7103 while (true)
7104 {
7105 /*
7106 * Always try once to acquire the lock directly, without setting up
7107 * the spin-delay infrastructure. The work necessary for that shows up
7108 * in profiles and is rarely necessary.
7109 */
7111 if (likely(!(old_buf_state & BM_LOCKED)))
7112 break; /* got lock */
7113
7114 /* and then spin without atomic operations until lock is released */
7115 {
7117
7119
7120 while (old_buf_state & BM_LOCKED)
7121 {
7124 }
7126 }
7127
7128 /*
7129 * Retry. The lock might obviously already be re-acquired by the time
7130 * we're attempting to get it again.
7131 */
7132 }
7133
7134 return old_buf_state | BM_LOCKED;
7135}
static uint64 pg_atomic_fetch_or_u64(volatile pg_atomic_uint64 *ptr, uint64 or_)
Definition atomics.h:560
#define BufferIsLocal(buffer)
Definition buf.h:37
#define likely(x)
Definition c.h:411
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:753

References Assert, BM_LOCKED, BufferDescriptorGetBuffer(), BufferIsLocal, fb(), finish_spin_delay(), init_local_spin_delay, likely, perform_spin_delay(), pg_atomic_fetch_or_u64(), pg_atomic_read_u64(), and BufferDesc::state.

Referenced by AbortBufferIO(), apw_dump_now(), buffer_stage_common(), BufferAlloc(), BufferGetLSNAtomic(), BufferLockDequeueSelf(), BufferLockQueueSelf(), BufferLockWakeup(), BufferSync(), ConditionalLockBufferForCleanup(), create_toy_buffer(), DropDatabaseBuffers(), DropRelationBuffers(), DropRelationsAllBuffers(), EvictAllUnpinnedBuffers(), EvictRelUnpinnedBuffers(), EvictUnpinnedBuffer(), ExtendBufferedRelShared(), FindAndDropRelationBuffers(), FlushBuffer(), FlushDatabaseBuffers(), FlushRelationBuffers(), FlushRelationsAllBuffers(), GetVictimBuffer(), InvalidateBuffer(), InvalidateVictimBuffer(), IsBufferCleanupOK(), LockBufferForCleanup(), MarkBufferDirtyHint(), MarkDirtyAllUnpinnedBuffers(), MarkDirtyRelUnpinnedBuffers(), MarkDirtyUnpinnedBuffer(), pg_buffercache_os_pages_internal(), pg_buffercache_pages(), StartBufferIO(), SyncOneBuffer(), TerminateBufferIO(), UnlockBuffers(), WaitIO(), and WakePinCountWaiter().

◆ MarkLocalBufferDirty()

void MarkLocalBufferDirty ( Buffer  buffer)
extern

Definition at line 491 of file localbuf.c.

492{
493 int bufid;
496
497 Assert(BufferIsLocal(buffer));
498
499#ifdef LBDEBUG
500 fprintf(stderr, "LB DIRTY %d\n", buffer);
501#endif
502
503 bufid = -buffer - 1;
504
506
508
510
511 if (!(buf_state & BM_DIRTY))
513
515
517}
#define fprintf(file, fmt, msg)
Definition cubescan.l:21
int64 local_blks_dirtied
Definition instrument.h:32

References Assert, BM_DIRTY, BufferIsLocal, fb(), fprintf, GetLocalBufferDescriptor(), BufferUsage::local_blks_dirtied, LocalRefCount, pg_atomic_read_u64(), pg_atomic_unlocked_write_u64(), and pgBufferUsage.

Referenced by MarkBufferDirty(), and MarkBufferDirtyHint().

◆ PinLocalBuffer()

bool PinLocalBuffer ( BufferDesc buf_hdr,
bool  adjust_usagecount 
)
extern

Definition at line 805 of file localbuf.c.

806{
809 int bufid = -buffer - 1;
810
812
813 if (LocalRefCount[bufid] == 0)
814 {
817 if (adjust_usagecount &&
819 {
821 }
823
824 /*
825 * See comment in PinBuffer().
826 *
827 * If the buffer isn't allocated yet, it'll be marked as defined in
828 * GetLocalBufferStorage().
829 */
832 }
836
837 return buf_state & BM_VALID;
838}
#define BM_MAX_USAGE_COUNT
#define BUF_STATE_GET_USAGECOUNT(state)
static int NLocalPinnedBuffers
Definition localbuf.c:56
#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, fb(), LocalBufHdrGetBlock, LocalRefCount, NLocalPinnedBuffers, pg_atomic_read_u64(), pg_atomic_unlocked_write_u64(), ResourceOwnerRememberBuffer(), and VALGRIND_MAKE_MEM_DEFINED.

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

◆ PrefetchLocalBuffer()

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

Definition at line 72 of file localbuf.c.

74{
75 PrefetchBufferResult result = {InvalidBuffer, false};
76 BufferTag newTag; /* identity of requested block */
78
79 InitBufferTag(&newTag, &smgr->smgr_rlocator.locator, forkNum, blockNum);
80
81 /* Initialize local buffers if first request in this session */
82 if (LocalBufHash == NULL)
84
85 /* See if the desired buffer already exists */
88
89 if (hresult)
90 {
91 /* Yes, so nothing to do */
92 result.recent_buffer = -hresult->id - 1;
93 }
94 else
95 {
96#ifdef USE_PREFETCH
97 /* Not in buffers, so initiate prefetch */
98 if ((io_direct_flags & IO_DIRECT_DATA) == 0 &&
99 smgrprefetch(smgr, forkNum, blockNum, 1))
100 {
101 result.initiated_io = true;
102 }
103#endif /* USE_PREFETCH */
104 }
105
106 return result;
107}
#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

References fb(), HASH_FIND, hash_search(), 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 532 of file buf_internals.h.

533{
535}

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

Referenced by UnpinBuffer(), and UnpinLocalBuffer().

◆ ResourceOwnerForgetBufferIO()

static void ResourceOwnerForgetBufferIO ( ResourceOwner  owner,
Buffer  buffer 
)
inlinestatic

◆ ResourceOwnerRememberBuffer()

static void ResourceOwnerRememberBuffer ( ResourceOwner  owner,
Buffer  buffer 
)
inlinestatic

◆ ResourceOwnerRememberBufferIO()

static void ResourceOwnerRememberBufferIO ( ResourceOwner  owner,
Buffer  buffer 
)
inlinestatic

Definition at line 537 of file buf_internals.h.

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

Referenced by StartBufferIO().

◆ ScheduleBufferTagForWriteback()

void ScheduleBufferTagForWriteback ( WritebackContext wb_context,
IOContext  io_context,
BufferTag tag 
)
extern

Definition at line 7269 of file bufmgr.c.

7271{
7272 PendingWriteback *pending;
7273
7274 /*
7275 * As pg_flush_data() doesn't do anything with fsync disabled, there's no
7276 * point in tracking in that case.
7277 */
7279 !enableFsync)
7280 return;
7281
7282 /*
7283 * Add buffer to the pending writeback array, unless writeback control is
7284 * disabled.
7285 */
7286 if (*wb_context->max_pending > 0)
7287 {
7289
7290 pending = &wb_context->pending_writebacks[wb_context->nr_pending++];
7291
7292 pending->tag = *tag;
7293 }
7294
7295 /*
7296 * Perform pending flushes if the writeback limit is exceeded. This
7297 * includes the case where previously an item has been added, but control
7298 * is now disabled.
7299 */
7300 if (wb_context->nr_pending >= *wb_context->max_pending)
7302}
void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context)
Definition bufmgr.c:7319
bool enableFsync
Definition globals.c:129

References Assert, enableFsync, fb(), IO_DIRECT_DATA, io_direct_flags, IssuePendingWritebacks(), PendingWriteback::tag, and WRITEBACK_MAX_PENDING_FLUSHES.

Referenced by GetVictimBuffer(), and SyncOneBuffer().

◆ StartBufferIO()

bool StartBufferIO ( BufferDesc buf,
bool  forInput,
bool  nowait 
)
extern

Definition at line 6879 of file bufmgr.c.

6880{
6882
6884
6885 for (;;)
6886 {
6888
6890 break;
6892 if (nowait)
6893 return false;
6894 WaitIO(buf);
6895 }
6896
6897 /* Once we get here, there is definitely no I/O active on this buffer */
6898
6899 /* Check if someone else already did the I/O */
6900 if (forInput ? (buf_state & BM_VALID) : !(buf_state & BM_DIRTY))
6901 {
6903 return false;
6904 }
6905
6908 0);
6909
6912
6913 return true;
6914}
#define BM_IO_IN_PROGRESS
uint64 LockBufHdr(BufferDesc *desc)
Definition bufmgr.c:7097
static void WaitIO(BufferDesc *buf)
Definition bufmgr.c:6800

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

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

◆ StartLocalBufferIO()

bool StartLocalBufferIO ( BufferDesc bufHdr,
bool  forInput,
bool  nowait 
)
extern

Definition at line 523 of file localbuf.c.

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

References BM_DIRTY, BM_VALID, fb(), pg_atomic_read_u64(), pgaio_wref_valid(), and pgaio_wref_wait().

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

◆ StaticAssertDecl() [1/4]

StaticAssertDecl ( )

◆ StaticAssertDecl() [2/4]

StaticAssertDecl ( BUF_REFCOUNT_BITS+BUF_USAGECOUNT_BITS+BUF_FLAG_BITS+BUF_LOCK_BITS<=  64,
"parts of buffer state space need to be <= 64"   
)

◆ StaticAssertDecl() [3/4]

StaticAssertDecl ( MAX_BACKENDS_BITS<=  BUF_LOCK_BITS - 2,
"MAX_BACKENDS_BITS needs to be <= BUF_LOCK_BITS - 2"   
)

◆ StaticAssertDecl() [4/4]

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

◆ StrategyGetBuffer()

BufferDesc * StrategyGetBuffer ( BufferAccessStrategy  strategy,
uint64 buf_state,
bool from_ring 
)
extern

Definition at line 174 of file freelist.c.

175{
177 int bgwprocno;
178 int trycounter;
179
180 *from_ring = false;
181
182 /*
183 * If given a strategy object, see whether it can select a buffer. We
184 * assume strategy objects don't need buffer_strategy_lock.
185 */
186 if (strategy != NULL)
187 {
188 buf = GetBufferFromRing(strategy, buf_state);
189 if (buf != NULL)
190 {
191 *from_ring = true;
192 return buf;
193 }
194 }
195
196 /*
197 * If asked, we need to waken the bgwriter. Since we don't want to rely on
198 * a spinlock for this we force a read from shared memory once, and then
199 * set the latch based on that value. We need to go through that length
200 * because otherwise bgwprocno might be reset while/after we check because
201 * the compiler might just reread from memory.
202 *
203 * This can possibly set the latch of the wrong process if the bgwriter
204 * dies in the wrong moment. But since PGPROC->procLatch is never
205 * deallocated the worst consequence of that is that we set the latch of
206 * some arbitrary process.
207 */
209 if (bgwprocno != -1)
210 {
211 /* reset bgwprocno first, before setting the latch */
213
214 /*
215 * Not acquiring ProcArrayLock here which is slightly icky. It's
216 * actually fine because procLatch isn't ever freed, so we just can
217 * potentially set the wrong process' (or no process') latch.
218 */
219 SetLatch(&GetPGProcByNumber(bgwprocno)->procLatch);
220 }
221
222 /*
223 * We count buffer allocation requests so that the bgwriter can estimate
224 * the rate of buffer consumption. Note that buffers recycled by a
225 * strategy object are intentionally not counted here.
226 */
228
229 /* Use the "clock sweep" algorithm to find a free buffer */
231 for (;;)
232 {
235
237
238 /*
239 * Check whether the buffer can be used and pin it if so. Do this
240 * using a CAS loop, to avoid having to lock the buffer header.
241 */
243 for (;;)
244 {
246
247 /*
248 * If the buffer is pinned or has a nonzero usage_count, we cannot
249 * use it; decrement the usage_count (unless pinned) and keep
250 * scanning.
251 */
252
254 {
255 if (--trycounter == 0)
256 {
257 /*
258 * We've scanned all the buffers without making any state
259 * changes, so all the buffers are pinned (or were when we
260 * looked at them). We could hope that someone will free
261 * one eventually, but it's probably better to fail than
262 * to risk getting stuck in an infinite loop.
263 */
264 elog(ERROR, "no unpinned buffers available");
265 }
266 break;
267 }
268
269 /* See equivalent code in PinBuffer() */
271 {
273 continue;
274 }
275
277 {
279
282 {
284 break;
285 }
286 }
287 else
288 {
289 /* pin the buffer if the CAS succeeds */
291
294 {
295 /* Found a usable buffer */
296 if (strategy != NULL)
297 AddBufferToRing(strategy, buf);
299
301
302 return buf;
303 }
304 }
305 }
306 }
307}
static uint32 pg_atomic_fetch_add_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
Definition atomics.h:366
pg_noinline uint64 WaitBufHdrUnlocked(BufferDesc *buf)
Definition bufmgr.c:7145
void TrackNewBufferPin(Buffer buf)
Definition bufmgr.c:3416
#define unlikely(x)
Definition c.h:412
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:737
#define INT_ACCESS_ONCE(var)
Definition freelist.c:24
static BufferDesc * GetBufferFromRing(BufferAccessStrategy strategy, uint64 *buf_state)
Definition freelist.c:658
int NBuffers
Definition globals.c:142
void SetLatch(Latch *latch)
Definition latch.c:290
#define GetPGProcByNumber(n)
Definition proc.h:446
pg_atomic_uint32 numBufferAllocs
Definition freelist.c:47

References AddBufferToRing(), BufferStrategyControl::bgwprocno, BM_LOCKED, buf, BUF_REFCOUNT_ONE, BUF_STATE_GET_REFCOUNT, BUF_STATE_GET_USAGECOUNT, BUF_USAGECOUNT_ONE, BufferDescriptorGetBuffer(), ClockSweepTick(), elog, ERROR, fb(), GetBufferDescriptor(), GetBufferFromRing(), GetPGProcByNumber, INT_ACCESS_ONCE, NBuffers, BufferStrategyControl::numBufferAllocs, pg_atomic_compare_exchange_u64(), pg_atomic_fetch_add_u32(), pg_atomic_read_u64(), SetLatch(), StrategyControl, TrackNewBufferPin(), unlikely, and WaitBufHdrUnlocked().

Referenced by GetVictimBuffer().

◆ StrategyInitialize()

void StrategyInitialize ( bool  init)
extern

Definition at line 401 of file freelist.c.

402{
403 bool found;
404
405 /*
406 * Initialize the shared buffer lookup hashtable.
407 *
408 * Since we can't tolerate running out of lookup table entries, we must be
409 * sure to specify an adequate table size here. The maximum steady-state
410 * usage is of course NBuffers entries, but BufferAlloc() tries to insert
411 * a new entry before deleting the old. In principle this could be
412 * happening in each partition concurrently, so we could need as many as
413 * NBuffers + NUM_BUFFER_PARTITIONS entries.
414 */
416
417 /*
418 * Get or create the shared strategy control block
419 */
421 ShmemInitStruct("Buffer Strategy Status",
422 sizeof(BufferStrategyControl),
423 &found);
424
425 if (!found)
426 {
427 /*
428 * Only done once, usually in postmaster
429 */
430 Assert(init);
431
433
434 /* Initialize the clock-sweep pointer */
436
437 /* Clear statistics */
440
441 /* No pending notification */
443 }
444 else
445 Assert(!init);
446}
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
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition shmem.c:389
#define SpinLockInit(lock)
Definition spin.h:57
pg_atomic_uint32 nextVictimBuffer
Definition freelist.c:40
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)
extern

Definition at line 358 of file freelist.c.

359{
360 /*
361 * We acquire buffer_strategy_lock just to ensure that the store appears
362 * atomic to StrategyGetBuffer. The bgwriter should call this rather
363 * infrequently, so there's no performance penalty from being safe.
364 */
366 StrategyControl->bgwprocno = bgwprocno;
368}
#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,
BufferDesc buf,
bool  from_ring 
)
extern

Definition at line 787 of file freelist.c.

788{
789 /* We only do this in bulkread mode */
790 if (strategy->btype != BAS_BULKREAD)
791 return false;
792
793 /* Don't muck with behavior of normal buffer-replacement strategy */
794 if (!from_ring ||
795 strategy->buffers[strategy->current] != BufferDescriptorGetBuffer(buf))
796 return false;
797
798 /*
799 * Remove the dirty buffer from the ring; necessary to prevent infinite
800 * loop if all ring members are dirty.
801 */
802 strategy->buffers[strategy->current] = InvalidBuffer;
803
804 return true;
805}
Buffer buffers[FLEXIBLE_ARRAY_MEMBER]
Definition freelist.c:83

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

Referenced by GetVictimBuffer().

◆ StrategyShmemSize()

Size StrategyShmemSize ( void  )
extern

Definition at line 380 of file freelist.c.

381{
382 Size size = 0;
383
384 /* size of lookup hash table ... see comment in StrategyInitialize */
386
387 /* size of the shared replacement strategy control block */
388 size = add_size(size, MAXALIGN(sizeof(BufferStrategyControl)));
389
390 return size;
391}
Size BufTableShmemSize(int size)
Definition buf_table.c:41
#define MAXALIGN(LEN)
Definition c.h:826
Size add_size(Size s1, Size s2)
Definition shmem.c:495

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

Referenced by BufferManagerShmemSize().

◆ StrategySyncStart()

int StrategySyncStart ( uint32 complete_passes,
uint32 num_buf_alloc 
)
extern

Definition at line 321 of file freelist.c.

322{
323 uint32 nextVictimBuffer;
324 int result;
325
328 result = nextVictimBuffer % NBuffers;
329
330 if (complete_passes)
331 {
333
334 /*
335 * Additionally add the number of wraparounds that happened before
336 * completePasses could be incremented. C.f. ClockSweepTick().
337 */
338 *complete_passes += nextVictimBuffer / NBuffers;
339 }
340
341 if (num_buf_alloc)
342 {
344 }
346 return result;
347}
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition atomics.h:237
static uint32 pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)
Definition atomics.h:330

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

Referenced by BgBufferSync().

◆ TerminateBufferIO()

void TerminateBufferIO ( BufferDesc buf,
bool  clear_dirty,
uint64  set_flag_bits,
bool  forget_owner,
bool  release_aio 
)
extern

Definition at line 6937 of file bufmgr.c.

6939{
6942 int refcount_change = 0;
6943
6945
6948
6949 /* Clear earlier errors, if this IO failed, it'll be marked again */
6951
6954
6955 if (release_aio)
6956 {
6957 /* release ownership by the AIO subsystem */
6959 refcount_change = -1;
6960 pgaio_wref_clear(&buf->io_wref);
6961 }
6962
6966
6967 if (forget_owner)
6970
6972
6973 /*
6974 * Support LockBufferForCleanup()
6975 *
6976 * We may have just released the last pin other than the waiter's. In most
6977 * cases, this backend holds another pin on the buffer. But, if, for
6978 * example, this backend is completing an IO issued by another backend, it
6979 * may be time to wake the waiter.
6980 */
6983}
void pgaio_wref_clear(PgAioWaitRef *iow)
Definition aio.c:964
#define BM_PIN_COUNT_WAITER
#define BM_IO_ERROR
#define BM_CHECKPOINT_NEEDED
static void WakePinCountWaiter(BufferDesc *buf)
Definition bufmgr.c:3324
void ConditionVariableBroadcast(ConditionVariable *cv)

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

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

◆ TerminateLocalBufferIO()

void TerminateLocalBufferIO ( BufferDesc bufHdr,
bool  clear_dirty,
uint64  set_flag_bits,
bool  release_aio 
)
extern

Definition at line 562 of file localbuf.c.

564{
565 /* Only need to adjust flags */
567
568 /* BM_IO_IN_PROGRESS isn't currently used for local buffers */
569
570 /* Clear earlier errors, if this IO failed, it'll be marked again */
572
573 if (clear_dirty)
575
576 if (release_aio)
577 {
578 /* release pin held by IO subsystem, see also buffer_stage_common() */
581 pgaio_wref_clear(&bufHdr->io_wref);
582 }
583
586
587 /* local buffers don't track IO using resowners */
588
589 /* local buffers don't use the IO CV, as no other process can see buffer */
590
591 /* local buffers don't use BM_PIN_COUNT_WAITER, so no need to wake */
592}

References Assert, BUF_REFCOUNT_ONE, BUF_STATE_GET_REFCOUNT, fb(), pg_atomic_read_u64(), pg_atomic_unlocked_write_u64(), and pgaio_wref_clear().

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

◆ TrackNewBufferPin()

void TrackNewBufferPin ( Buffer  buf)
externinline

Definition at line 3416 of file bufmgr.c.

3417{
3419
3421 ref->data.refcount++;
3422
3424
3425 /*
3426 * This is the first pin for this page by this backend, mark its page as
3427 * defined to valgrind. While the page contents might not actually be
3428 * valid yet, we don't currently guarantee that such pages are marked
3429 * undefined or non-accessible.
3430 *
3431 * It's not necessarily the prettiest to do this here, but otherwise we'd
3432 * need this block of code in multiple places.
3433 */
3435 BLCKSZ);
3436}
static PrivateRefCountEntry * NewPrivateRefCountEntry(Buffer buffer)
Definition bufmgr.c:373
#define BufHdrGetBlock(bufHdr)
Definition bufmgr.c:73

References buf, BufHdrGetBlock, CurrentResourceOwner, fb(), GetBufferDescriptor(), NewPrivateRefCountEntry(), ResourceOwnerRememberBuffer(), and VALGRIND_MAKE_MEM_DEFINED.

Referenced by GetBufferFromRing(), PinBuffer(), PinBuffer_Locked(), and StrategyGetBuffer().

◆ UnlockBufHdr()

◆ UnlockBufHdrExt()

◆ UnpinLocalBuffer()

void UnpinLocalBuffer ( Buffer  buffer)
extern

◆ UnpinLocalBufferNoOwner()

void UnpinLocalBufferNoOwner ( Buffer  buffer)
extern

◆ WaitBufHdrUnlocked()

uint64 WaitBufHdrUnlocked ( BufferDesc buf)
extern

◆ WritebackContextInit()

void WritebackContextInit ( WritebackContext context,
int max_pending 
)
extern

Definition at line 7257 of file bufmgr.c.

7258{
7259 Assert(*max_pending <= WRITEBACK_MAX_PENDING_FLUSHES);
7260
7261 context->max_pending = max_pending;
7262 context->nr_pending = 0;
7263}

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 25 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 269 of file bufmgr.c.

270{
271 .name = "buffer io",
272 .release_phase = RESOURCE_RELEASE_BEFORE_LOCKS,
273 .release_priority = RELEASE_PRIO_BUFFER_IOS,
274 .ReleaseResource = ResOwnerReleaseBufferIO,
275 .DebugPrint = ResOwnerPrintBufferIO
276};
static void ResOwnerReleaseBufferIO(Datum res)
Definition bufmgr.c:7402
static char * ResOwnerPrintBufferIO(Datum res)
Definition bufmgr.c:7410
#define RELEASE_PRIO_BUFFER_IOS
Definition resowner.h:62
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition resowner.h:54

Referenced by ResourceOwnerForgetBufferIO(), and ResourceOwnerRememberBufferIO().

◆ buffer_resowner_desc

PGDLLIMPORT const ResourceOwnerDesc buffer_resowner_desc
extern

Definition at line 278 of file bufmgr.c.

279{
280 .name = "buffer",
281 .release_phase = RESOURCE_RELEASE_BEFORE_LOCKS,
282 .release_priority = RELEASE_PRIO_BUFFER_PINS,
283 .ReleaseResource = ResOwnerReleaseBuffer,
284 .DebugPrint = ResOwnerPrintBuffer
285};
static void ResOwnerReleaseBuffer(Datum res)
Definition bufmgr.c:7424
static char * ResOwnerPrintBuffer(Datum res)
Definition bufmgr.c:7460
#define RELEASE_PRIO_BUFFER_PINS
Definition resowner.h:63

Referenced by ResourceOwnerForgetBuffer(), and ResourceOwnerRememberBuffer().

◆ BufferDescriptors

PGDLLIMPORT BufferDescPadded* BufferDescriptors
extern

Definition at line 22 of file buf_init.c.

Referenced by BufferManagerShmemInit(), and GetBufferDescriptor().

◆ BufferIOCVArray

Definition at line 24 of file buf_init.c.

Referenced by BufferDescriptorGetIOCV(), and BufferManagerShmemInit().

◆ CkptBufferIds

PGDLLIMPORT CkptSortItem* CkptBufferIds
extern

Definition at line 26 of file buf_init.c.

Referenced by BufferManagerShmemInit(), and BufferSync().

◆ LocalBufferDescriptors

PGDLLIMPORT BufferDesc* LocalBufferDescriptors
extern

Definition at line 47 of file localbuf.c.

Referenced by GetLocalBufferDescriptor(), and InitLocalBuffers().