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_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
 
typedef enum StartBufferIOResult StartBufferIOResult
 

Enumerations

enum  StartBufferIOResult { BUFFER_IO_ALREADY_DONE , BUFFER_IO_IN_PROGRESS , BUFFER_IO_READY_FOR_IO }
 

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 (int id)
 
static BufferDescGetLocalBufferDescriptor (int 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)
 
StartBufferIOResult StartBufferIO (Buffer buffer, bool forInput, bool wait, PgAioWaitRef *io_wref)
 
StartBufferIOResult StartSharedBufferIO (BufferDesc *buf, bool forInput, bool wait, PgAioWaitRef *io_wref)
 
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)
 
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)
 
StartBufferIOResult StartLocalBufferIO (BufferDesc *bufHdr, bool forInput, bool wait, PgAioWaitRef *io_wref)
 
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 121 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_LOCK_HAS_WAITERS

#define BM_LOCK_HAS_WAITERS   BUF_DEFINE_FLAG(10)

Definition at line 125 of file buf_internals.h.

◆ BM_LOCK_MASK

Definition at line 85 of file buf_internals.h.

161{
162 Oid spcOid; /* tablespace oid */
163 Oid dbOid; /* database oid */
164 RelFileNumber relNumber; /* relation file number */
165 ForkNumber forkNum; /* fork number */
166 BlockNumber blockNum; /* blknum relative to begin of reln */
167} BufferTag;
168
169static inline RelFileNumber
171{
172 return tag->relNumber;
173}
174
175static inline ForkNumber
176BufTagGetForkNum(const BufferTag *tag)
177{
178 return tag->forkNum;
179}
180
181static inline void
183 ForkNumber forknum)
184{
185 tag->relNumber = relnumber;
186 tag->forkNum = forknum;
187}
188
189static inline RelFileLocator
191{
192 RelFileLocator rlocator;
193
194 rlocator.spcOid = tag->spcOid;
195 rlocator.dbOid = tag->dbOid;
196 rlocator.relNumber = BufTagGetRelNumber(tag);
197
198 return rlocator;
199}
200
201static inline void
203{
204 tag->spcOid = InvalidOid;
205 tag->dbOid = InvalidOid;
208}
209
210static inline void
211InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator,
212 ForkNumber forkNum, BlockNumber blockNum)
213{
214 tag->spcOid = rlocator->spcOid;
215 tag->dbOid = rlocator->dbOid;
216 BufTagSetRelForkDetails(tag, rlocator->relNumber, forkNum);
217 tag->blockNum = blockNum;
218}
219
220static inline bool
222{
223 return (tag1->spcOid == tag2->spcOid) &&
224 (tag1->dbOid == tag2->dbOid) &&
225 (tag1->relNumber == tag2->relNumber) &&
226 (tag1->blockNum == tag2->blockNum) &&
227 (tag1->forkNum == tag2->forkNum);
228}
229
230static inline bool
232 const RelFileLocator *rlocator)
233{
234 return (tag->spcOid == rlocator->spcOid) &&
235 (tag->dbOid == rlocator->dbOid) &&
236 (BufTagGetRelNumber(tag) == rlocator->relNumber);
237}
238
239
240/*
241 * The shared buffer mapping table is partitioned to reduce contention.
242 * To determine which partition lock a given tag requires, compute the tag's
243 * hash code with BufTableHashCode(), then apply BufMappingPartitionLock().
244 * NB: NUM_BUFFER_PARTITIONS must be a power of 2!
245 */
246static inline uint32
248{
249 return hashcode % NUM_BUFFER_PARTITIONS;
250}
251
252static inline LWLock *
254{
256 BufTableHashPartition(hashcode)].lock;
257}
258
259static inline LWLock *
261{
263}
264
265/*
266 * BufferDesc -- shared descriptor/state data for a single shared buffer.
267 *
268 * The state of the buffer is controlled by the, drumroll, state variable. It
269 * only may be modified using atomic operations. The state variable combines
270 * various flags, the buffer's refcount and usage count. See comment above
271 * BUF_REFCOUNT_BITS for details about the division. This layout allow us to
272 * do some operations in a single atomic operation, without actually acquiring
273 * and releasing the spinlock; for instance, increasing or decreasing the
274 * refcount.
275 *
276 * One of the aforementioned flags is BM_LOCKED, used to implement the buffer
277 * header lock. See the following paragraphs, as well as the documentation for
278 * individual fields, for more details.
279 *
280 * The identity of the buffer (BufferDesc.tag) can only be changed by the
281 * backend holding the buffer header lock.
282 *
283 * If the lock is held by another backend, neither additional buffer pins may
284 * be established (we would like to relax this eventually), nor can flags be
285 * set/cleared. These operations either need to acquire the buffer header
286 * spinlock, or need to use a CAS loop, waiting for the lock to be released if
287 * it is held. However, existing buffer pins may be released while the buffer
288 * header spinlock is held, using an atomic subtraction.
289 *
290 * If we have the buffer pinned, its tag can't change underneath us, so we can
291 * examine the tag without locking the buffer header. Also, in places we do
292 * one-time reads of the flags without bothering to lock the buffer header;
293 * this is generally for situations where we don't expect the flag bit being
294 * tested to be changing.
295 *
296 * We can't physically remove items from a disk page if another backend has
297 * the buffer pinned. Hence, a backend may need to wait for all other pins
298 * to go away. This is signaled by storing its own pgprocno into
299 * wait_backend_pgprocno and setting flag bit BM_PIN_COUNT_WAITER. At present,
300 * there can be only one such waiter per buffer.
301 *
302 * The content of buffers is protected via the buffer content lock,
303 * implemented as part of the buffer state. Note that the buffer header lock
304 * is *not* used to control access to the data in the buffer! We used to use
305 * an LWLock to implement the content lock, but having a dedicated
306 * implementation of content locks allows us to implement some otherwise hard
307 * things (e.g. race-freely checking if AIO is in progress before locking a
308 * buffer exclusively) and enables otherwise impossible optimizations
309 * (e.g. unlocking and unpinning a buffer in one atomic operation).
310 *
311 * We use this same struct for local buffer headers, but the locks are not
312 * used and not all of the flag bits are useful either. To avoid unnecessary
313 * overhead, manipulations of the state field should be done without actual
314 * atomic operations (i.e. only pg_atomic_read_u64() and
315 * pg_atomic_unlocked_write_u64()).
316 *
317 * Be careful to avoid increasing the size of the struct when adding or
318 * reordering members. Keeping it below 64 bytes (the most common CPU
319 * cache line size) is fairly important for performance.
320 *
321 * Per-buffer I/O condition variables are currently kept outside this struct in
322 * a separate array. They could be moved in here and still fit within that
323 * limit on common systems, but for now that is not done.
324 */
325typedef struct BufferDesc
326{
327 /*
328 * ID of page contained in buffer. The buffer header spinlock needs to be
329 * held to modify this field.
330 */
332
333 /*
334 * Buffer's index number (from 0). The field never changes after
335 * initialization, so does not need locking.
336 */
337 int buf_id;
338
339 /*
340 * State of the buffer, containing flags, refcount and usagecount. See
341 * BUF_* and BM_* defines at the top of this file.
342 */
344
345 /*
346 * Backend of pin-count waiter. The buffer header spinlock needs to be
347 * held to modify this field.
348 */
350
351 PgAioWaitRef io_wref; /* set iff AIO is in progress */
352
353 /*
354 * List of PGPROCs waiting for the buffer content lock. Protected by the
355 * buffer header spinlock.
356 */
358} BufferDesc;
359
360/*
361 * Concurrent access to buffer headers has proven to be more efficient if
362 * they're cache line aligned. So we force the start of the BufferDescriptors
363 * array to be on a cache line boundary and force the elements to be cache
364 * line sized.
365 *
366 * XXX: As this is primarily matters in highly concurrent workloads which
367 * probably all are 64bit these days, and the space wastage would be a bit
368 * more noticeable on 32bit systems, we don't force the stride to be cache
369 * line sized on those. If somebody does actual performance testing, we can
370 * reevaluate.
371 *
372 * Note that local buffer descriptors aren't forced to be aligned - as there's
373 * no concurrent access to those it's unlikely to be beneficial.
374 *
375 * We use a 64-byte cache line size here, because that's the most common
376 * size. Making it bigger would be a waste of memory. Even if running on a
377 * platform with either 32 or 128 byte line sizes, it's good to align to
378 * boundaries and avoid false sharing.
379 */
380#define BUFFERDESC_PAD_TO_SIZE (SIZEOF_VOID_P == 8 ? 64 : 1)
381
382typedef union BufferDescPadded
383{
387
388/*
389 * The PendingWriteback & WritebackContext structure are used to keep
390 * information about pending flush requests to be issued to the OS.
391 */
392typedef struct PendingWriteback
393{
394 /* could store different types of pending flushes here */
397
398/* struct forward declared in bufmgr.h */
399typedef struct WritebackContext
400{
401 /* pointer to the max number of writeback requests to coalesce */
402 int *max_pending;
403
404 /* current number of pending writeback requests */
405 int nr_pending;
406
407 /* pending requests */
410
411/* in buf_init.c */
415
416/* in localbuf.c */
418
419
420static inline BufferDesc *
422{
423 Assert(id >= 0 && id < NBuffers);
424
425 return &(BufferDescriptors[id]).bufferdesc;
426}
427
428static inline BufferDesc *
430{
431 return &LocalBufferDescriptors[id];
432}
433
434static inline Buffer
436{
437 return (Buffer) (bdesc->buf_id + 1);
438}
439
440static inline ConditionVariable *
442{
443 return &(BufferIOCVArray[bdesc->buf_id]).cv;
444}
445
446/*
447 * Functions for acquiring/releasing a shared buffer header's spinlock. Do
448 * not apply these to local buffers!
449 */
450extern uint64 LockBufHdr(BufferDesc *desc);
451
452/*
453 * Unlock the buffer header.
454 *
455 * This can only be used if the caller did not modify BufferDesc.state. To
456 * set/unset flag bits or change the refcount use UnlockBufHdrExt().
457 */
458static inline void
460{
462
464}
465
466/*
467 * Unlock the buffer header, while atomically unsetting the ones in
468 * unset_bits, adding the flags in set_bits, and changing the refcount by
469 * refcount_change. If a flag is both cleared and added, it will end up being
470 * set.
471 *
472 * Note that this approach would not trivially work for usagecount, since we
473 * need to cap the usagecount at BM_MAX_USAGE_COUNT.
474 */
475static inline uint64
478 int refcount_change)
479{
480 for (;;)
481 {
483
485
486 /*
487 * Set bits after clearing bits, so that a cleared and re-added flag
488 * survives.
489 */
493
494 if (refcount_change != 0)
496
498 buf_state))
499 {
500 return old_buf_state;
501 }
502 }
503}
504
506
507/* in bufmgr.c */
508
509/*
510 * Structure to sort buffers per file on checkpoints.
511 *
512 * This structure is allocated per buffer in shared memory, so it should be
513 * kept as small as possible.
514 */
515typedef struct CkptSortItem
516{
517 Oid tsId;
521 int buf_id;
523
525
526/* ResourceOwner callbacks to hold buffer I/Os and pins */
529
530/* Convenience wrappers over ResourceOwnerRemember/Forget */
531static inline void
533{
535}
536static inline void
538{
540}
541static inline void
543{
545}
546static inline void
548{
550}
551
552/*
553 * Internal buffer management routines
554 */
555/* bufmgr.c */
556extern void WritebackContextInit(WritebackContext *context, int *max_pending);
560
561extern void TrackNewBufferPin(Buffer buf);
562
563/*
564 * Return value for StartBufferIO / StartSharedBufferIO / StartLocalBufferIO.
565 *
566 * When preparing a buffer for I/O and setting BM_IO_IN_PROGRESS, the buffer
567 * may already have I/O in progress or the I/O may have been done by another
568 * backend. See the documentation of StartSharedBufferIO for more details.
569 */
570typedef enum StartBufferIOResult
571{
576
577/* the following are exposed to make it easier to write tests */
578extern StartBufferIOResult StartBufferIO(Buffer buffer, bool forInput, bool wait,
579 PgAioWaitRef *io_wref);
581 PgAioWaitRef *io_wref);
583 bool forget_owner, bool release_aio);
584
585
586/* freelist.c */
589 uint64 *buf_state, bool *from_ring);
590extern bool StrategyRejectBuffer(BufferAccessStrategy strategy,
591 BufferDesc *buf, bool from_ring);
592
594extern void StrategyNotifyBgWriter(int bgwprocno);
595
596/* buf_table.c */
598extern int BufTableLookup(BufferTag *tagPtr, uint32 hashcode);
599extern int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id);
600extern void BufTableDelete(BufferTag *tagPtr, uint32 hashcode);
601
602/* localbuf.c */
604extern void UnpinLocalBuffer(Buffer buffer);
605extern void UnpinLocalBufferNoOwner(Buffer buffer);
607 ForkNumber forkNum,
608 BlockNumber blockNum);
610 BlockNumber blockNum, bool *foundPtr);
613 uint32 flags,
616 Buffer *buffers,
618extern void MarkLocalBufferDirty(Buffer buffer);
622 bool wait, PgAioWaitRef *io_wref);
625extern void DropRelationLocalBuffers(RelFileLocator rlocator,
626 ForkNumber *forkNum, int nforks,
628extern void DropRelationAllLocalBuffers(RelFileLocator rlocator);
629extern void AtEOXact_LocalBuffers(bool isCommit);
630
631#endif /* BUFMGR_INTERNALS_H */
static bool pg_atomic_compare_exchange_u64(volatile pg_atomic_uint64 *ptr, uint64 *expected, uint64 newval)
Definition atomics.h:517
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
Definition atomics.h:462
static uint64 pg_atomic_fetch_sub_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
Definition atomics.h:536
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:294
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:154
void UnpinLocalBuffer(Buffer buffer)
Definition localbuf.c:865
int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc)
Definition freelist.c:331
static ForkNumber BufTagGetForkNum(const BufferTag *tag)
#define BUF_REFCOUNT_ONE
static ConditionVariable * BufferDescriptorGetIOCV(const BufferDesc *bdesc)
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:1027
StartBufferIOResult StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool wait, PgAioWaitRef *io_wref)
Definition localbuf.c:532
int BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
Definition buf_table.c:96
BufferDesc * StrategyGetBuffer(BufferAccessStrategy strategy, uint64 *buf_state, bool *from_ring)
Definition freelist.c:184
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:829
static void BufTagSetRelForkDetails(BufferTag *tag, RelFileNumber relnumber, ForkNumber forknum)
static BufferDesc * GetLocalBufferDescriptor(int id)
PGDLLIMPORT const ResourceOwnerDesc buffer_io_resowner_desc
Definition bufmgr.c:285
static void ResourceOwnerRememberBufferIO(ResourceOwner owner, Buffer buffer)
uint64 LockBufHdr(BufferDesc *desc)
Definition bufmgr.c:7567
#define BM_LOCKED
void MarkLocalBufferDirty(Buffer buffer)
Definition localbuf.c:500
#define BUFFERDESC_PAD_TO_SIZE
StartBufferIOResult
@ BUFFER_IO_IN_PROGRESS
@ BUFFER_IO_ALREADY_DONE
@ BUFFER_IO_READY_FOR_IO
PGDLLIMPORT WritebackContext BackendWritebackContext
Definition buf_init.c:27
static void ResourceOwnerForgetBufferIO(ResourceOwner owner, Buffer buffer)
uint32 BufTableHashCode(BufferTag *tagPtr)
Definition buf_table.c:84
StartBufferIOResult StartSharedBufferIO(BufferDesc *buf, bool forInput, bool wait, PgAioWaitRef *io_wref)
Definition bufmgr.c:7290
void DropRelationAllLocalBuffers(RelFileLocator rlocator)
Definition localbuf.c:726
void ScheduleBufferTagForWriteback(WritebackContext *wb_context, IOContext io_context, BufferTag *tag)
Definition bufmgr.c:7739
void InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced)
Definition localbuf.c:629
int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id)
Definition buf_table.c:124
static void ClearBufferTag(BufferTag *tag)
static void ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer)
void WritebackContextInit(WritebackContext *context, int *max_pending)
Definition bufmgr.c:7727
void StrategyNotifyBgWriter(int bgwprocno)
Definition freelist.c:368
struct buftag BufferTag
StartBufferIOResult StartBufferIO(Buffer buffer, bool forInput, bool wait, PgAioWaitRef *io_wref)
Definition bufmgr.c:7370
static void ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer)
void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint64 set_flag_bits, bool release_aio)
Definition localbuf.c:586
PGDLLIMPORT BufferDescPadded * BufferDescriptors
Definition buf_init.c:24
PrefetchBufferResult PrefetchLocalBuffer(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum)
Definition localbuf.c:72
PGDLLIMPORT ConditionVariableMinimallyPadded * BufferIOCVArray
Definition buf_init.c:26
BlockNumber ExtendBufferedRelLocal(BufferManagerRelation bmr, ForkNumber fork, uint32 flags, uint32 extend_by, BlockNumber extend_upto, Buffer *buffers, uint32 *extended_by)
Definition localbuf.c:355
void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context)
Definition bufmgr.c:7789
PGDLLIMPORT CkptSortItem * CkptBufferIds
Definition buf_init.c:28
IOContext IOContextForStrategy(BufferAccessStrategy strategy)
Definition freelist.c:712
void UnpinLocalBufferNoOwner(Buffer buffer)
Definition localbuf.c:872
void DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber *forkNum, int nforks, BlockNumber *firstDelBlock)
Definition localbuf.c:689
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:7407
static RelFileLocator BufTagGetRelFileLocator(const BufferTag *tag)
uint64 WaitBufHdrUnlocked(BufferDesc *buf)
Definition bufmgr.c:7615
PGDLLIMPORT BufferDesc * LocalBufferDescriptors
Definition localbuf.c:47
void TrackNewBufferPin(Buffer buf)
Definition bufmgr.c:3535
bool StrategyRejectBuffer(BufferAccessStrategy strategy, BufferDesc *buf, bool from_ring)
Definition freelist.c:752
static Buffer BufferDescriptorGetBuffer(const BufferDesc *bdesc)
static BufferDesc * GetBufferDescriptor(int id)
BufferDesc * LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum, bool *foundPtr)
Definition localbuf.c:119
#define PGDLLIMPORT
Definition c.h:1478
#define Assert(condition)
Definition c.h:1002
uint64_t uint64
Definition c.h:684
uint32_t uint32
Definition c.h:683
int NBuffers
Definition globals.c:144
LWLockPadded * MainLWLockArray
Definition lwlock.c:150
#define BUFFER_MAPPING_LWLOCK_OFFSET
Definition lwlock.h:94
#define NUM_BUFFER_PARTITIONS
Definition lwlock.h:83
#define WRITEBACK_MAX_PENDING_FLUSHES
static char buf[DEFAULT_XLOG_SEG_SIZE]
IOContext
Definition pgstat.h:289
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
#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:571
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition resowner.c:531
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:97
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 127 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 144 of file buf_internals.h.

◆ BM_PERMANENT

#define BM_PERMANENT   BUF_DEFINE_FLAG( 9)

Definition at line 123 of file buf_internals.h.

◆ BM_PIN_COUNT_WAITER

#define BM_PIN_COUNT_WAITER   BUF_DEFINE_FLAG( 7)

Definition at line 119 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 381 of file buf_internals.h.

Typedef Documentation

◆ BufferDesc

◆ BufferDescPadded

◆ BufferTag

◆ CkptSortItem

◆ PendingWriteback

◆ StartBufferIOResult

◆ WritebackContext

Enumeration Type Documentation

◆ StartBufferIOResult

Enumerator
BUFFER_IO_ALREADY_DONE 
BUFFER_IO_IN_PROGRESS 
BUFFER_IO_READY_FOR_IO 

Definition at line 571 of file buf_internals.h.

Function Documentation

◆ AtEOXact_LocalBuffers()

void AtEOXact_LocalBuffers ( bool  isCommit)
extern

Definition at line 1027 of file localbuf.c.

1028{
1030}
static void CheckForLocalBufferLeaks(void)
Definition localbuf.c:994

References CheckForLocalBufferLeaks().

Referenced by AtEOXact_Buffers().

◆ BufferDescriptorGetBuffer()

◆ BufferDescriptorGetIOCV()

static ConditionVariable * BufferDescriptorGetIOCV ( const BufferDesc bdesc)
inlinestatic

Definition at line 442 of file buf_internals.h.

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

References BufferIOCVArray, and fb().

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

◆ BufferTagsEqual()

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

Definition at line 222 of file buf_internals.h.

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}

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 154 of file buf_table.c.

155{
157
160 tagPtr,
161 hashcode,
163 NULL);
164
165 if (!result) /* shouldn't happen */
166 elog(ERROR, "shared buffer hash table corrupted");
167}
static HTAB * SharedBufHash
Definition buf_table.c:34
uint32 result
void * hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, uint32 hashvalue, HASHACTION action, bool *foundPtr)
Definition dynahash.c:902
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
@ HASH_REMOVE
Definition hsearch.h:110

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

Referenced by InvalidateBuffer(), and InvalidateVictimBuffer().

◆ BufTableHashCode()

uint32 BufTableHashCode ( BufferTag tagPtr)
extern

Definition at line 84 of file buf_table.c.

85{
87}
uint32 get_hash_value(HTAB *hashp, const void *keyPtr)
Definition dynahash.c:845

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 248 of file buf_internals.h.

249{
250 return hashcode % NUM_BUFFER_PARTITIONS;
251}

References NUM_BUFFER_PARTITIONS.

Referenced by BufMappingPartitionLock().

◆ BufTableInsert()

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

Definition at line 124 of file buf_table.c.

125{
127 bool found;
128
129 Assert(buf_id >= 0); /* -1 is reserved for not-in-table */
130 Assert(tagPtr->blockNum != P_NEW); /* invalid tag */
131
134 tagPtr,
135 hashcode,
137 &found);
138
139 if (found) /* found something already in the table */
140 return result->id;
141
142 result->id = buf_id;
143
144 return -1;
145}
#define P_NEW
Definition bufmgr.h:200
@ HASH_ENTER
Definition hsearch.h:109

References Assert, fb(), HASH_ENTER, hash_search_with_hash_value(), P_NEW, result, and SharedBufHash.

Referenced by BufferAlloc(), and ExtendBufferedRelShared().

◆ BufTableLookup()

int BufTableLookup ( BufferTag tagPtr,
uint32  hashcode 
)
extern

Definition at line 96 of file buf_table.c.

97{
99
102 tagPtr,
103 hashcode,
104 HASH_FIND,
105 NULL);
106
107 if (!result)
108 return -1;
109
110 return result->id;
111}
@ HASH_FIND
Definition hsearch.h:108

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

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

◆ BufTagGetForkNum()

◆ BufTagGetRelFileLocator()

◆ BufTagGetRelNumber()

static RelFileNumber BufTagGetRelNumber ( const BufferTag tag)
inlinestatic

Definition at line 171 of file buf_internals.h.

172{
173 return tag->relNumber;
174}

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 183 of file buf_internals.h.

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

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

Referenced by ClearBufferTag(), and InitBufferTag().

◆ ClearBufferTag()

◆ DropRelationAllLocalBuffers()

void DropRelationAllLocalBuffers ( RelFileLocator  rlocator)
extern

Definition at line 726 of file localbuf.c.

727{
728 int i;
729
730 for (i = 0; i < NLocBuffer; i++)
731 {
734
736
737 if ((buf_state & BM_TAG_VALID) &&
738 BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator))
739 {
741 }
742 }
743}
#define BM_TAG_VALID
int i
Definition isn.c:77
void InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced)
Definition localbuf.c:629
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 689 of file localbuf.c.

691{
692 int i;
693 int j;
694
695 for (i = 0; i < NLocBuffer; i++)
696 {
699
701
702 if (!(buf_state & BM_TAG_VALID) ||
703 !BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator))
704 continue;
705
706 for (j = 0; j < nforks; j++)
707 {
708 if (BufTagGetForkNum(&bufHdr->tag) == forkNum[j] &&
709 bufHdr->tag.blockNum >= firstDelBlock[j])
710 {
712 break;
713 }
714 }
715 }
716}
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 355 of file localbuf.c.

362{
365
366 /* Initialize local buffers if first request in this session */
367 if (LocalBufHash == NULL)
369
371
372 for (uint32 i = 0; i < extend_by; i++)
373 {
376
377 buffers[i] = GetLocalVictimBuffer();
378 buf_hdr = GetLocalBufferDescriptor(-buffers[i] - 1);
380
381 /* new buffers are zero-filled */
383 }
384
386
388 {
389 /*
390 * In contrast to shared relations, nothing could change the relation
391 * size concurrently. Thus we shouldn't end up finding that we don't
392 * need to do anything.
393 */
395
397 }
398
399 /* Fail if relation is already at maximum possible length */
403 errmsg("cannot extend relation %s beyond %u blocks",
404 relpath(BMR_GET_SMGR(bmr)->smgr_rlocator, fork).str,
406
407 for (uint32 i = 0; i < extend_by; i++)
408 {
409 int victim_buf_id;
411 BufferTag tag;
413 bool found;
414
415 victim_buf_id = -buffers[i] - 1;
417
418 /* in case we need to pin an existing buffer below */
420
421 InitBufferTag(&tag, &BMR_GET_SMGR(bmr)->smgr_rlocator.locator, fork,
422 first_block + i);
423
425 hash_search(LocalBufHash, &tag, HASH_ENTER, &found);
426 if (found)
427 {
430
432
436
437 /*
438 * Clear the BM_VALID bit, do StartLocalBufferIO() and proceed.
439 */
445
446 /* no need to loop for local buffers */
448 }
449 else
450 {
452
454
455 victim_buf_hdr->tag = tag;
456
458
460
462
464 }
465 }
466
468
469 /* actually extend relation */
471
474
475 for (uint32 i = 0; i < extend_by; i++)
476 {
477 Buffer buf = buffers[i];
480
482
486 }
487
489
491
492 return first_block;
493}
static void pg_atomic_unlocked_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:489
#define MaxBlockNumber
Definition block.h:35
#define BM_DIRTY
#define BUF_USAGECOUNT_ONE
#define BM_VALID
bool track_io_timing
Definition bufmgr.c:192
void * Block
Definition bufmgr.h:26
#define BMR_GET_SMGR(bmr)
Definition bufmgr.h:118
#define MemSet(start, val, len)
Definition c.h:1147
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition dynahash.c:889
int errcode(int sqlerrcode)
Definition elog.c:875
#define ereport(elevel,...)
Definition elog.h:152
const char * str
BufferUsage pgBufferUsage
Definition instrument.c:25
void UnpinLocalBuffer(Buffer buffer)
Definition localbuf.c:865
static HTAB * LocalBufHash
Definition localbuf.c:53
#define LocalBufHdrGetBlock(bufHdr)
Definition localbuf.c:42
StartBufferIOResult StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool wait, PgAioWaitRef *io_wref)
Definition localbuf.c:532
bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount)
Definition localbuf.c:829
static void InitLocalBuffers(void)
Definition localbuf.c:752
void LimitAdditionalLocalPins(uint32 *additional_pins)
Definition localbuf.c:332
static Buffer GetLocalVictimBuffer(void)
Definition localbuf.c:225
static char * errmsg
@ IOOBJECT_TEMP_RELATION
Definition pgstat.h:282
@ IOCONTEXT_NORMAL
Definition pgstat.h:293
@ IOOP_EXTEND
Definition pgstat.h:318
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:459
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_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 anything other than
193 * BUFFER_IO_READY_FOR_IO, so we raise an error in that case.
194 */
196 elog(ERROR, "failed to start write IO on local buffer");
197
198 /* Find smgr relation for buffer */
199 if (reln == NULL)
202
203 PageSetChecksum(localpage, bufHdr->tag.blockNum);
204
206
207 /* And write... */
210 bufHdr->tag.blockNum,
211 localpage,
212 false);
213
214 /* Temporary table I/O does not use Buffer Access Strategies */
217
218 /* Mark not-dirty */
219 TerminateLocalBufferIO(bufHdr, true, 0, false);
220
222}
void PageSetChecksum(Page page, BlockNumber blkno)
Definition bufpage.c:1518
PageData * Page
Definition bufpage.h:81
ProcNumber MyProcNumber
Definition globals.c:92
int32 * LocalRefCount
Definition localbuf.c:49
void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint64 set_flag_bits, bool release_aio)
Definition localbuf.c:586
@ IOOP_WRITE
Definition pgstat.h:320
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, BUFFER_IO_READY_FOR_IO, BufferDescriptorGetBuffer(), BufTagGetForkNum(), BufTagGetRelFileLocator(), elog, ERROR, fb(), IOCONTEXT_NORMAL, IOOBJECT_TEMP_RELATION, IOOP_WRITE, BufferUsage::local_blks_written, LocalBufHdrGetBlock, LocalRefCount, MyProcNumber, PageSetChecksum(), pgBufferUsage, pgstat_count_io_op_time(), pgstat_prepare_io_time(), smgropen(), smgrwrite(), StartLocalBufferIO(), TerminateLocalBufferIO(), and track_io_timing.

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

◆ GetBufferDescriptor()

static BufferDesc * GetBufferDescriptor ( int  id)
inlinestatic

Definition at line 422 of file buf_internals.h.

423{
424 Assert(id >= 0 && id < NBuffers);
425
426 return &(BufferDescriptors[id]).bufferdesc;
427}

References Assert, BufferDescriptors, and NBuffers.

Referenced by AbortBufferIO(), apw_dump_now(), buffer_call_start_io(), buffer_call_terminate_io(), buffer_readv_complete_one(), buffer_stage_common(), BufferAlloc(), BufferBeginSetHintBits(), BufferGetBlockNumber(), BufferGetLSNAtomic(), BufferGetTag(), BufferIsDirty(), BufferIsLockedByMe(), BufferIsLockedByMeInMode(), BufferIsPermanent(), BufferManagerShmemInit(), BufferSetHintBits16(), BufferSync(), CheckReadBuffersOperation(), ConditionalLockBuffer(), ConditionalLockBufferForCleanup(), create_toy_buffer(), DebugPrintBufferRefcount(), DropDatabaseBuffers(), DropRelationBuffers(), DropRelationsAllBuffers(), EvictAllUnpinnedBuffers(), EvictRelUnpinnedBuffers(), EvictUnpinnedBuffer(), ExtendBufferedRelShared(), FindAndDropRelationBuffers(), FlushDatabaseBuffers(), FlushOneBuffer(), FlushRelationBuffers(), FlushRelationsAllBuffers(), GetBufferFromRing(), invalidate_one_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(), ReadRecentBuffer(), ReleaseAndReadBuffer(), ReleaseBuffer(), ResOwnerReleaseBuffer(), StartBufferIO(), StartReadBuffersImpl(), StrategyGetBuffer(), SyncOneBuffer(), TrackNewBufferPin(), UnlockBuffer(), UnlockReleaseBuffer(), WaitReadBuffers(), and ZeroAndLockBuffer().

◆ GetLocalBufferDescriptor()

◆ InitBufferTag()

◆ InvalidateLocalBuffer()

void InvalidateLocalBuffer ( BufferDesc bufHdr,
bool  check_unreferenced 
)
extern

Definition at line 629 of file localbuf.c.

630{
632 int bufid = -buffer - 1;
635
636 /*
637 * It's possible that we started IO on this buffer before e.g. aborting
638 * the transaction that created a table. We need to wait for that IO to
639 * complete before removing / reusing the buffer.
640 */
641 if (pgaio_wref_valid(&bufHdr->io_wref))
642 {
643 PgAioWaitRef iow = bufHdr->io_wref;
644
646 Assert(!pgaio_wref_valid(&bufHdr->io_wref));
647 }
648
650
651 /*
652 * We need to test not just LocalRefCount[bufid] but also the BufferDesc
653 * itself, as the latter is used to represent a pin by the AIO subsystem.
654 * This can happen if AIO is initiated and then the query errors out.
655 */
656 if (check_unreferenced &&
658 elog(ERROR, "block %u of %s is still referenced (local %d)",
659 bufHdr->tag.blockNum,
662 BufTagGetForkNum(&bufHdr->tag)).str,
664
665 /* Remove entry from hashtable */
668 if (!hresult) /* shouldn't happen */
669 elog(ERROR, "local buffer hash table corrupted");
670 /* Mark buffer invalid */
671 ClearBufferTag(&bufHdr->tag);
675}
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_one_block(), and modify_rel_block().

◆ IOContextForStrategy()

IOContext IOContextForStrategy ( BufferAccessStrategy  strategy)
extern

Definition at line 712 of file freelist.c.

713{
714 if (!strategy)
715 return IOCONTEXT_NORMAL;
716
717 switch (strategy->btype)
718 {
719 case BAS_NORMAL:
720
721 /*
722 * Currently, GetAccessStrategy() returns NULL for
723 * BufferAccessStrategyType BAS_NORMAL, so this case is
724 * unreachable.
725 */
727 return IOCONTEXT_NORMAL;
728 case BAS_BULKREAD:
729 return IOCONTEXT_BULKREAD;
730 case BAS_BULKWRITE:
731 return IOCONTEXT_BULKWRITE;
732 case BAS_VACUUM:
733 return IOCONTEXT_VACUUM;
734 }
735
736 elog(ERROR, "unrecognized BufferAccessStrategyType: %d", strategy->btype);
738}
@ 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:426
@ IOCONTEXT_VACUUM
Definition pgstat.h:294
@ IOCONTEXT_BULKREAD
Definition pgstat.h:290
@ IOCONTEXT_BULKWRITE
Definition pgstat.h:291
BufferAccessStrategyType btype
Definition freelist.c:77

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(), ReadBuffer_common(), StartReadBuffersImpl(), and WaitReadBuffers().

◆ IssuePendingWritebacks()

void IssuePendingWritebacks ( WritebackContext wb_context,
IOContext  io_context 
)
extern

Definition at line 7789 of file bufmgr.c.

7790{
7792 int i;
7793
7794 if (wb_context->nr_pending == 0)
7795 return;
7796
7797 /*
7798 * Executing the writes in-order can make them a lot faster, and allows to
7799 * merge writeback requests to consecutive blocks into larger writebacks.
7800 */
7801 sort_pending_writebacks(wb_context->pending_writebacks,
7802 wb_context->nr_pending);
7803
7805
7806 /*
7807 * Coalesce neighbouring writes, but nothing else. For that we iterate
7808 * through the, now sorted, array of pending flushes, and look forward to
7809 * find all neighbouring (or identical) writes.
7810 */
7811 for (i = 0; i < wb_context->nr_pending; i++)
7812 {
7816 int ahead;
7817 BufferTag tag;
7819 Size nblocks = 1;
7820
7821 cur = &wb_context->pending_writebacks[i];
7822 tag = cur->tag;
7824
7825 /*
7826 * Peek ahead, into following writeback requests, to see if they can
7827 * be combined with the current one.
7828 */
7829 for (ahead = 0; i + ahead + 1 < wb_context->nr_pending; ahead++)
7830 {
7831
7832 next = &wb_context->pending_writebacks[i + ahead + 1];
7833
7834 /* different file, stop */
7836 BufTagGetRelFileLocator(&next->tag)) ||
7837 BufTagGetForkNum(&cur->tag) != BufTagGetForkNum(&next->tag))
7838 break;
7839
7840 /* ok, block queued twice, skip */
7841 if (cur->tag.blockNum == next->tag.blockNum)
7842 continue;
7843
7844 /* only merge consecutive writes */
7845 if (cur->tag.blockNum + 1 != next->tag.blockNum)
7846 break;
7847
7848 nblocks++;
7849 cur = next;
7850 }
7851
7852 i += ahead;
7853
7854 /* and finally tell the kernel to write the data to storage */
7856 smgrwriteback(reln, BufTagGetForkNum(&tag), tag.blockNum, nblocks);
7857 }
7858
7859 /*
7860 * Assume that writeback requests are only issued for buffers containing
7861 * blocks of permanent relations.
7862 */
7864 IOOP_WRITEBACK, io_start, wb_context->nr_pending, 0);
7865
7866 wb_context->nr_pending = 0;
7867}
static int32 next
Definition blutils.c:225
size_t Size
Definition c.h:748
struct cursor * cur
Definition ecpg.c:29
@ IOOBJECT_RELATION
Definition pgstat.h:281
@ IOOP_WRITEBACK
Definition pgstat.h:315
#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 7567 of file bufmgr.c.

7568{
7570
7572
7573 while (true)
7574 {
7575 /*
7576 * Always try once to acquire the lock directly, without setting up
7577 * the spin-delay infrastructure. The work necessary for that shows up
7578 * in profiles and is rarely necessary.
7579 */
7581 if (likely(!(old_buf_state & BM_LOCKED)))
7582 break; /* got lock */
7583
7584 /* and then spin without atomic operations until lock is released */
7585 {
7587
7589
7590 while (old_buf_state & BM_LOCKED)
7591 {
7594 }
7596 }
7597
7598 /*
7599 * Retry. The lock might obviously already be re-acquired by the time
7600 * we're attempting to get it again.
7601 */
7602 }
7603
7604 return old_buf_state | BM_LOCKED;
7605}
static uint64 pg_atomic_fetch_or_u64(volatile pg_atomic_uint64 *ptr, uint64 or_)
Definition atomics.h:555
#define BufferIsLocal(buffer)
Definition buf.h:37
#define likely(x)
Definition c.h:496
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:749

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(), FlushDatabaseBuffers(), FlushRelationBuffers(), FlushRelationsAllBuffers(), InvalidateBuffer(), InvalidateVictimBuffer(), IsBufferCleanupOK(), LockBufferForCleanup(), MarkDirtyAllUnpinnedBuffers(), MarkDirtyRelUnpinnedBuffers(), MarkDirtyUnpinnedBuffer(), MarkSharedBufferDirtyHint(), pg_buffercache_os_pages_internal(), pg_buffercache_pages(), StartSharedBufferIO(), SyncOneBuffer(), TerminateBufferIO(), UnlockBuffers(), WaitIO(), and WakePinCountWaiter().

◆ MarkLocalBufferDirty()

void MarkLocalBufferDirty ( Buffer  buffer)
extern

Definition at line 500 of file localbuf.c.

501{
502 int bufid;
505
506 Assert(BufferIsLocal(buffer));
507
508#ifdef LBDEBUG
509 fprintf(stderr, "LB DIRTY %d\n", buffer);
510#endif
511
512 bufid = -buffer - 1;
513
515
517
519
520 if (!(buf_state & BM_DIRTY))
522
524
526}
#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 BufferSetHintBits16(), MarkBufferDirty(), and MarkBufferDirtyHint().

◆ PinLocalBuffer()

bool PinLocalBuffer ( BufferDesc buf_hdr,
bool  adjust_usagecount 
)
extern

Definition at line 829 of file localbuf.c.

830{
833 int bufid = -buffer - 1;
834
836
837 if (LocalRefCount[bufid] == 0)
838 {
841 if (adjust_usagecount &&
843 {
845 }
847
848 /*
849 * See comment in PinBuffer().
850 *
851 * If the buffer isn't allocated yet, it'll be marked as defined in
852 * GetLocalBufferStorage().
853 */
856 }
860
861 return buf_state & BM_VALID;
862}
#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{
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:172
#define IO_DIRECT_DATA
Definition fd.h:54
bool smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks)
Definition smgr.c:678

References fb(), HASH_FIND, hash_search(), InitBufferTag(), InitLocalBuffers(), InvalidBuffer, IO_DIRECT_DATA, io_direct_flags, LocalBufHash, RelFileLocatorBackend::locator, result, SMgrRelationData::smgr_rlocator, and smgrprefetch().

Referenced by PrefetchBuffer().

◆ ResourceOwnerForgetBuffer()

static void ResourceOwnerForgetBuffer ( ResourceOwner  owner,
Buffer  buffer 
)
inlinestatic

◆ 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

◆ ScheduleBufferTagForWriteback()

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

Definition at line 7739 of file bufmgr.c.

7741{
7742 PendingWriteback *pending;
7743
7744 /*
7745 * As pg_flush_data() doesn't do anything with fsync disabled, there's no
7746 * point in tracking in that case.
7747 */
7749 !enableFsync)
7750 return;
7751
7752 /*
7753 * Add buffer to the pending writeback array, unless writeback control is
7754 * disabled.
7755 */
7756 if (*wb_context->max_pending > 0)
7757 {
7759
7760 pending = &wb_context->pending_writebacks[wb_context->nr_pending++];
7761
7762 pending->tag = *tag;
7763 }
7764
7765 /*
7766 * Perform pending flushes if the writeback limit is exceeded. This
7767 * includes the case where previously an item has been added, but control
7768 * is now disabled.
7769 */
7770 if (wb_context->nr_pending >= *wb_context->max_pending)
7772}
void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context)
Definition bufmgr.c:7789
bool enableFsync
Definition globals.c:131

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

Referenced by GetVictimBuffer(), and SyncOneBuffer().

◆ StartBufferIO()

StartBufferIOResult StartBufferIO ( Buffer  buffer,
bool  forInput,
bool  wait,
PgAioWaitRef io_wref 
)
extern

Definition at line 7370 of file bufmgr.c.

7371{
7373
7374 if (BufferIsLocal(buffer))
7375 {
7376 buf_hdr = GetLocalBufferDescriptor(-buffer - 1);
7377
7378 return StartLocalBufferIO(buf_hdr, forInput, wait, io_wref);
7379 }
7380 else
7381 {
7382 buf_hdr = GetBufferDescriptor(buffer - 1);
7383
7384 return StartSharedBufferIO(buf_hdr, forInput, wait, io_wref);
7385 }
7386}
StartBufferIOResult StartSharedBufferIO(BufferDesc *buf, bool forInput, bool wait, PgAioWaitRef *io_wref)
Definition bufmgr.c:7290

References PrivateRefCountEntry::buffer, BufferIsLocal, fb(), GetBufferDescriptor(), GetLocalBufferDescriptor(), StartLocalBufferIO(), and StartSharedBufferIO().

Referenced by AsyncReadBuffers().

◆ StartLocalBufferIO()

StartBufferIOResult StartLocalBufferIO ( BufferDesc bufHdr,
bool  forInput,
bool  wait,
PgAioWaitRef io_wref 
)
extern

Definition at line 532 of file localbuf.c.

533{
535
536 /*
537 * With AIO the buffer could have IO in progress, e.g. when there are two
538 * scans of the same relation. Either wait for the other IO (if wait =
539 * true and io_wref == NULL) or return BUFFER_IO_IN_PROGRESS;
540 */
541 if (pgaio_wref_valid(&bufHdr->io_wref))
542 {
543 PgAioWaitRef buf_wref = bufHdr->io_wref;
544
545 if (io_wref != NULL)
546 {
547 /* We've already asynchronously started this IO, so join it */
548 *io_wref = buf_wref;
550 }
551
552 /*
553 * For temp buffers we should never need to wait in
554 * StartLocalBufferIO() when called with io_wref == NULL while there
555 * are staged IOs, as it's not allowed to call code that is not aware
556 * of AIO while in batch mode.
557 */
559
560 if (!wait)
562
564 }
565
566 /* Once we get here, there is definitely no I/O active on this buffer */
567
568 /* Check if someone else already did the I/O */
571 {
573 }
574
575 /* BM_IO_IN_PROGRESS isn't currently used for local buffers */
576
577 /* local buffers don't track IO using resowners */
578
580}
bool pgaio_have_staged(void)
Definition aio.c:1117

References Assert, BM_DIRTY, BM_VALID, BUFFER_IO_ALREADY_DONE, BUFFER_IO_IN_PROGRESS, BUFFER_IO_READY_FOR_IO, fb(), pg_atomic_read_u64(), pgaio_have_staged(), pgaio_wref_valid(), and pgaio_wref_wait().

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

◆ StartSharedBufferIO()

StartBufferIOResult StartSharedBufferIO ( BufferDesc buf,
bool  forInput,
bool  wait,
PgAioWaitRef io_wref 
)
extern

Definition at line 7290 of file bufmgr.c.

7291{
7293
7295
7296 for (;;)
7297 {
7299
7301 break;
7302
7303 /* Join the existing IO */
7304 if (io_wref != NULL && pgaio_wref_valid(&buf->io_wref))
7305 {
7306 *io_wref = buf->io_wref;
7308
7309 return BUFFER_IO_IN_PROGRESS;
7310 }
7311 else if (!wait)
7312 {
7314 return BUFFER_IO_IN_PROGRESS;
7315 }
7316 else
7317 {
7318 /*
7319 * With wait = true, we always have to wait if the caller has
7320 * passed io_wref = NULL.
7321 *
7322 * Even with io_wref != NULL, we have to wait if the buffer's wait
7323 * ref is not valid but the IO is in progress, someone else
7324 * started IO but hasn't set the wait ref yet. We have no choice
7325 * but to wait until the IO completes.
7326 */
7328
7329 /*
7330 * If this backend currently has staged IO, submit it before
7331 * waiting for in-progress IO, to avoid potential deadlocks and
7332 * unnecessary delays.
7333 */
7335
7336 WaitIO(buf);
7337 }
7338 }
7339
7340 /* Once we get here, there is definitely no I/O active on this buffer */
7341
7342 /* Check if someone else already did the I/O */
7343 if (forInput ? (buf_state & BM_VALID) : !(buf_state & BM_DIRTY))
7344 {
7347 }
7348
7349 /*
7350 * No IO in progress and not already done; we will start IO. It's possible
7351 * that the IO was in progress but we're not done, because the IO errored
7352 * out. We'll do the IO ourselves.
7353 */
7356 0);
7357
7360
7362}
void pgaio_submit_staged(void)
Definition aio.c:1133
#define BM_IO_IN_PROGRESS
uint64 LockBufHdr(BufferDesc *desc)
Definition bufmgr.c:7567
static void WaitIO(BufferDesc *buf)
Definition bufmgr.c:7188

References BM_DIRTY, BM_IO_IN_PROGRESS, BM_VALID, buf, BUFFER_IO_ALREADY_DONE, BUFFER_IO_IN_PROGRESS, BUFFER_IO_READY_FOR_IO, BufferDescriptorGetBuffer(), CurrentResourceOwner, fb(), LockBufHdr(), pgaio_submit_staged(), pgaio_wref_valid(), ResourceOwnerEnlarge(), ResourceOwnerRememberBufferIO(), UnlockBufHdr(), UnlockBufHdrExt(), and WaitIO().

Referenced by buffer_call_start_io(), ExtendBufferedRelShared(), FlushBuffer(), read_rel_block_ll(), StartBufferIO(), 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 184 of file freelist.c.

185{
187 int bgwprocno;
188 int trycounter;
189
190 *from_ring = false;
191
192 /*
193 * If given a strategy object, see whether it can select a buffer. We
194 * assume strategy objects don't need buffer_strategy_lock.
195 */
196 if (strategy != NULL)
197 {
198 buf = GetBufferFromRing(strategy, buf_state);
199 if (buf != NULL)
200 {
201 *from_ring = true;
202 return buf;
203 }
204 }
205
206 /*
207 * If asked, we need to waken the bgwriter. Since we don't want to rely on
208 * a spinlock for this we force a read from shared memory once, and then
209 * set the latch based on that value. We need to go through that length
210 * because otherwise bgwprocno might be reset while/after we check because
211 * the compiler might just reread from memory.
212 *
213 * This can possibly set the latch of the wrong process if the bgwriter
214 * dies in the wrong moment. But since PGPROC->procLatch is never
215 * deallocated the worst consequence of that is that we set the latch of
216 * some arbitrary process.
217 */
219 if (bgwprocno != -1)
220 {
221 /* reset bgwprocno first, before setting the latch */
223
224 /*
225 * Not acquiring ProcArrayLock here which is slightly icky. It's
226 * actually fine because procLatch isn't ever freed, so we just can
227 * potentially set the wrong process' (or no process') latch.
228 */
229 SetLatch(&GetPGProcByNumber(bgwprocno)->procLatch);
230 }
231
232 /*
233 * We count buffer allocation requests so that the bgwriter can estimate
234 * the rate of buffer consumption. Note that buffers recycled by a
235 * strategy object are intentionally not counted here.
236 */
238
239 /* Use the "clock sweep" algorithm to find a free buffer */
241 for (;;)
242 {
245
247
248 /*
249 * Check whether the buffer can be used and pin it if so. Do this
250 * using a CAS loop, to avoid having to lock the buffer header.
251 */
253 for (;;)
254 {
256
257 /*
258 * If the buffer is pinned or has a nonzero usage_count, we cannot
259 * use it; decrement the usage_count (unless pinned) and keep
260 * scanning.
261 */
262
264 {
265 if (--trycounter == 0)
266 {
267 /*
268 * We've scanned all the buffers without making any state
269 * changes, so all the buffers are pinned (or were when we
270 * looked at them). We could hope that someone will free
271 * one eventually, but it's probably better to fail than
272 * to risk getting stuck in an infinite loop.
273 */
274 elog(ERROR, "no unpinned buffers available");
275 }
276 break;
277 }
278
279 /* See equivalent code in PinBuffer() */
281 {
283 continue;
284 }
285
287 {
289
292 {
294 break;
295 }
296 }
297 else
298 {
299 /* pin the buffer if the CAS succeeds */
301
304 {
305 /* Found a usable buffer */
306 if (strategy != NULL)
307 AddBufferToRing(strategy, buf);
309
311
312 return buf;
313 }
314 }
315 }
316 }
317}
static uint32 pg_atomic_fetch_add_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
Definition atomics.h:361
pg_noinline uint64 WaitBufHdrUnlocked(BufferDesc *buf)
Definition bufmgr.c:7615
void TrackNewBufferPin(Buffer buf)
Definition bufmgr.c:3535
#define unlikely(x)
Definition c.h:497
static BufferStrategyControl * StrategyControl
Definition freelist.c:59
static uint32 ClockSweepTick(void)
Definition freelist.c:110
static void AddBufferToRing(BufferAccessStrategy strategy, BufferDesc *buf)
Definition freelist.c:702
#define INT_ACCESS_ONCE(var)
Definition freelist.c:26
static BufferDesc * GetBufferFromRing(BufferAccessStrategy strategy, uint64 *buf_state)
Definition freelist.c:623
void SetLatch(Latch *latch)
Definition latch.c:290
#define GetPGProcByNumber(n)
Definition proc.h:506
pg_atomic_uint32 numBufferAllocs
Definition freelist.c:49

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

◆ StrategyNotifyBgWriter()

void StrategyNotifyBgWriter ( int  bgwprocno)
extern

Definition at line 368 of file freelist.c.

369{
370 /*
371 * We acquire buffer_strategy_lock just to ensure that the store appears
372 * atomic to StrategyGetBuffer. The bgwriter should call this rather
373 * infrequently, so there's no performance penalty from being safe.
374 */
376 StrategyControl->bgwprocno = bgwprocno;
378}
static void SpinLockRelease(volatile slock_t *lock)
Definition spin.h:62
static void SpinLockAcquire(volatile slock_t *lock)
Definition spin.h:56
slock_t buffer_strategy_lock
Definition freelist.c:35

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 752 of file freelist.c.

753{
754 /* We only do this in bulkread mode */
755 if (strategy->btype != BAS_BULKREAD)
756 return false;
757
758 /* Don't muck with behavior of normal buffer-replacement strategy */
759 if (!from_ring ||
760 strategy->buffers[strategy->current] != BufferDescriptorGetBuffer(buf))
761 return false;
762
763 /*
764 * Remove the dirty buffer from the ring; necessary to prevent infinite
765 * loop if all ring members are dirty.
766 */
767 strategy->buffers[strategy->current] = InvalidBuffer;
768
769 return true;
770}
Buffer buffers[FLEXIBLE_ARRAY_MEMBER]
Definition freelist.c:93

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

Referenced by GetVictimBuffer().

◆ StrategySyncStart()

int StrategySyncStart ( uint32 complete_passes,
uint32 num_buf_alloc 
)
extern

Definition at line 331 of file freelist.c.

332{
333 uint32 nextVictimBuffer;
334 int result;
335
338 result = nextVictimBuffer % NBuffers;
339
340 if (complete_passes)
341 {
343
344 /*
345 * Additionally add the number of wraparounds that happened before
346 * completePasses could be incremented. C.f. ClockSweepTick().
347 */
348 *complete_passes += nextVictimBuffer / NBuffers;
349 }
350
351 if (num_buf_alloc)
352 {
354 }
356 return result;
357}
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition atomics.h:232
static uint32 pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)
Definition atomics.h:325
pg_atomic_uint32 nextVictimBuffer
Definition freelist.c:42

References BufferStrategyControl::buffer_strategy_lock, BufferStrategyControl::completePasses, fb(), NBuffers, BufferStrategyControl::nextVictimBuffer, BufferStrategyControl::numBufferAllocs, pg_atomic_exchange_u32(), pg_atomic_read_u32(), result, 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 7407 of file bufmgr.c.

7409{
7412 int refcount_change = 0;
7413
7415
7418
7419 /* Clear earlier errors, if this IO failed, it'll be marked again */
7421
7422 if (clear_dirty)
7424
7425 if (release_aio)
7426 {
7427 /* release ownership by the AIO subsystem */
7429 refcount_change = -1;
7430 pgaio_wref_clear(&buf->io_wref);
7431 }
7432
7436
7437 if (forget_owner)
7440
7442
7443 /*
7444 * Support LockBufferForCleanup()
7445 *
7446 * We may have just released the last pin other than the waiter's. In most
7447 * cases, this backend holds another pin on the buffer. But, if, for
7448 * example, this backend is completing an IO issued by another backend, it
7449 * may be time to wake the waiter.
7450 */
7453}
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:3443
void ConditionVariableBroadcast(ConditionVariable *cv)

References Assert, BM_CHECKPOINT_NEEDED, BM_DIRTY, BM_IO_ERROR, BM_IO_IN_PROGRESS, 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 586 of file localbuf.c.

588{
589 /* Only need to adjust flags */
591
592 /* BM_IO_IN_PROGRESS isn't currently used for local buffers */
593
594 /* Clear earlier errors, if this IO failed, it'll be marked again */
596
597 if (clear_dirty)
599
600 if (release_aio)
601 {
602 /* release pin held by IO subsystem, see also buffer_stage_common() */
605 pgaio_wref_clear(&bufHdr->io_wref);
606 }
607
610
611 /* local buffers don't track IO using resowners */
612
613 /* local buffers don't use the IO CV, as no other process can see buffer */
614
615 /* local buffers don't use BM_PIN_COUNT_WAITER, so no need to wake */
616}

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

3536{
3538
3540 ref->data.refcount++;
3541
3543
3544 /*
3545 * This is the first pin for this page by this backend, mark its page as
3546 * defined to valgrind. While the page contents might not actually be
3547 * valid yet, we don't currently guarantee that such pages are marked
3548 * undefined or non-accessible.
3549 *
3550 * It's not necessarily the prettiest to do this here, but otherwise we'd
3551 * need this block of code in multiple places.
3552 */
3554 BLCKSZ);
3555}
static PrivateRefCountEntry * NewPrivateRefCountEntry(Buffer buffer)
Definition bufmgr.c:388
#define BufHdrGetBlock(bufHdr)
Definition bufmgr.c:76

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

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

◆ UnlockBufHdr()

◆ UnlockBufHdrExt()

static uint64 UnlockBufHdrExt ( BufferDesc desc,
uint64  old_buf_state,
uint64  set_bits,
uint64  unset_bits,
int  refcount_change 
)
inlinestatic

◆ 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 7727 of file bufmgr.c.

7728{
7729 Assert(*max_pending <= WRITEBACK_MAX_PENDING_FLUSHES);
7730
7731 context->max_pending = max_pending;
7732 context->nr_pending = 0;
7733}

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

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

Variable Documentation

◆ BackendWritebackContext

PGDLLIMPORT WritebackContext BackendWritebackContext
extern

Definition at line 27 of file buf_init.c.

Referenced by BufferManagerShmemAttach(), BufferManagerShmemInit(), and GetVictimBuffer().

◆ buffer_io_resowner_desc

PGDLLIMPORT const ResourceOwnerDesc buffer_io_resowner_desc
extern

Definition at line 285 of file bufmgr.c.

286{
287 .name = "buffer io",
288 .release_phase = RESOURCE_RELEASE_BEFORE_LOCKS,
289 .release_priority = RELEASE_PRIO_BUFFER_IOS,
290 .ReleaseResource = ResOwnerReleaseBufferIO,
291 .DebugPrint = ResOwnerPrintBufferIO
292};
static void ResOwnerReleaseBufferIO(Datum res)
Definition bufmgr.c:7872
static char * ResOwnerPrintBufferIO(Datum res)
Definition bufmgr.c:7880
#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 294 of file bufmgr.c.

295{
296 .name = "buffer",
297 .release_phase = RESOURCE_RELEASE_BEFORE_LOCKS,
298 .release_priority = RELEASE_PRIO_BUFFER_PINS,
299 .ReleaseResource = ResOwnerReleaseBuffer,
300 .DebugPrint = ResOwnerPrintBuffer
301};
static void ResOwnerReleaseBuffer(Datum res)
Definition bufmgr.c:7894
static char * ResOwnerPrintBuffer(Datum res)
Definition bufmgr.c:7930
#define RELEASE_PRIO_BUFFER_PINS
Definition resowner.h:63

Referenced by ResourceOwnerForgetBuffer(), and ResourceOwnerRememberBuffer().

◆ BufferDescriptors

PGDLLIMPORT BufferDescPadded* BufferDescriptors
extern

Definition at line 24 of file buf_init.c.

Referenced by BufferManagerShmemRequest(), and GetBufferDescriptor().

◆ BufferIOCVArray

Definition at line 26 of file buf_init.c.

Referenced by BufferDescriptorGetIOCV(), and BufferManagerShmemRequest().

◆ CkptBufferIds

PGDLLIMPORT CkptSortItem* CkptBufferIds
extern

Definition at line 28 of file buf_init.c.

Referenced by BufferManagerShmemRequest(), and BufferSync().

◆ LocalBufferDescriptors

PGDLLIMPORT BufferDesc* LocalBufferDescriptors
extern

Definition at line 47 of file localbuf.c.

Referenced by GetLocalBufferDescriptor(), and InitLocalBuffers().