PostgreSQL Source Code git master
buf_internals.h
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * buf_internals.h
4 * Internal definitions for buffer manager and the buffer replacement
5 * strategy.
6 *
7 *
8 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
10 *
11 * src/include/storage/buf_internals.h
12 *
13 *-------------------------------------------------------------------------
14 */
15#ifndef BUFMGR_INTERNALS_H
16#define BUFMGR_INTERNALS_H
17
18#include "pgstat.h"
19#include "port/atomics.h"
20#include "storage/aio_types.h"
21#include "storage/buf.h"
22#include "storage/bufmgr.h"
24#include "storage/lwlock.h"
25#include "storage/procnumber.h"
26#include "storage/shmem.h"
27#include "storage/smgr.h"
28#include "storage/spin.h"
29#include "utils/relcache.h"
30#include "utils/resowner.h"
31
32/*
33 * Buffer state is a single 32-bit variable where following data is combined.
34 *
35 * - 18 bits refcount
36 * - 4 bits usage count
37 * - 10 bits of flags
38 *
39 * Combining these values allows to perform some operations without locking
40 * the buffer header, by modifying them together with a CAS loop.
41 *
42 * The definition of buffer state components is below.
43 */
44#define BUF_REFCOUNT_BITS 18
45#define BUF_USAGECOUNT_BITS 4
46#define BUF_FLAG_BITS 10
47
49 "parts of buffer state space need to equal 32");
50
51#define BUF_REFCOUNT_ONE 1
52#define BUF_REFCOUNT_MASK ((1U << BUF_REFCOUNT_BITS) - 1)
53#define BUF_USAGECOUNT_MASK (((1U << BUF_USAGECOUNT_BITS) - 1) << (BUF_REFCOUNT_BITS))
54#define BUF_USAGECOUNT_ONE (1U << BUF_REFCOUNT_BITS)
55#define BUF_USAGECOUNT_SHIFT BUF_REFCOUNT_BITS
56#define BUF_FLAG_MASK (((1U << BUF_FLAG_BITS) - 1) << (BUF_REFCOUNT_BITS + BUF_USAGECOUNT_BITS))
57
58/* Get refcount and usagecount from buffer state */
59#define BUF_STATE_GET_REFCOUNT(state) ((state) & BUF_REFCOUNT_MASK)
60#define BUF_STATE_GET_USAGECOUNT(state) (((state) & BUF_USAGECOUNT_MASK) >> BUF_USAGECOUNT_SHIFT)
61
62/*
63 * Flags for buffer descriptors
64 *
65 * Note: BM_TAG_VALID essentially means that there is a buffer hashtable
66 * entry associated with the buffer's tag.
67 */
68#define BM_LOCKED (1U << 22) /* buffer header is locked */
69#define BM_DIRTY (1U << 23) /* data needs writing */
70#define BM_VALID (1U << 24) /* data is valid */
71#define BM_TAG_VALID (1U << 25) /* tag is assigned */
72#define BM_IO_IN_PROGRESS (1U << 26) /* read or write in progress */
73#define BM_IO_ERROR (1U << 27) /* previous I/O failed */
74#define BM_JUST_DIRTIED (1U << 28) /* dirtied since write started */
75#define BM_PIN_COUNT_WAITER (1U << 29) /* have waiter for sole pin */
76#define BM_CHECKPOINT_NEEDED (1U << 30) /* must write for checkpoint */
77#define BM_PERMANENT (1U << 31) /* permanent buffer (not unlogged,
78 * or init fork) */
79/*
80 * The maximum allowed value of usage_count represents a tradeoff between
81 * accuracy and speed of the clock-sweep buffer management algorithm. A
82 * large value (comparable to NBuffers) would approximate LRU semantics.
83 * But it can take as many as BM_MAX_USAGE_COUNT+1 complete cycles of the
84 * clock-sweep hand to find a free buffer, so in practice we don't want the
85 * value to be very large.
86 */
87#define BM_MAX_USAGE_COUNT 5
90 "BM_MAX_USAGE_COUNT doesn't fit in BUF_USAGECOUNT_BITS bits");
92 "MAX_BACKENDS_BITS needs to be <= BUF_REFCOUNT_BITS");
93
94/*
95 * Buffer tag identifies which disk block the buffer contains.
96 *
97 * Note: the BufferTag data must be sufficient to determine where to write the
98 * block, without reference to pg_class or pg_tablespace entries. It's
99 * possible that the backend flushing the buffer doesn't even believe the
100 * relation is visible yet (its xact may have started before the xact that
101 * created the rel). The storage manager must be able to cope anyway.
102 *
103 * Note: if there's any pad bytes in the struct, InitBufferTag will have
104 * to be fixed to zero them, since this struct is used as a hash key.
105 */
106typedef struct buftag
108 Oid spcOid; /* tablespace oid */
109 Oid dbOid; /* database oid */
110 RelFileNumber relNumber; /* relation file number */
111 ForkNumber forkNum; /* fork number */
112 BlockNumber blockNum; /* blknum relative to begin of reln */
113} BufferTag;
114
115static inline RelFileNumber
117{
118 return tag->relNumber;
119}
120
121static inline ForkNumber
122BufTagGetForkNum(const BufferTag *tag)
123{
124 return tag->forkNum;
125}
126
127static inline void
129 ForkNumber forknum)
130{
131 tag->relNumber = relnumber;
132 tag->forkNum = forknum;
133}
134
135static inline RelFileLocator
137{
138 RelFileLocator rlocator;
139
140 rlocator.spcOid = tag->spcOid;
141 rlocator.dbOid = tag->dbOid;
142 rlocator.relNumber = BufTagGetRelNumber(tag);
143
144 return rlocator;
145}
146
147static inline void
149{
150 tag->spcOid = InvalidOid;
151 tag->dbOid = InvalidOid;
154}
155
156static inline void
157InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator,
158 ForkNumber forkNum, BlockNumber blockNum)
159{
160 tag->spcOid = rlocator->spcOid;
161 tag->dbOid = rlocator->dbOid;
162 BufTagSetRelForkDetails(tag, rlocator->relNumber, forkNum);
163 tag->blockNum = blockNum;
164}
165
166static inline bool
167BufferTagsEqual(const BufferTag *tag1, const BufferTag *tag2)
168{
169 return (tag1->spcOid == tag2->spcOid) &&
170 (tag1->dbOid == tag2->dbOid) &&
171 (tag1->relNumber == tag2->relNumber) &&
172 (tag1->blockNum == tag2->blockNum) &&
173 (tag1->forkNum == tag2->forkNum);
174}
175
176static inline bool
178 const RelFileLocator *rlocator)
179{
180 return (tag->spcOid == rlocator->spcOid) &&
181 (tag->dbOid == rlocator->dbOid) &&
182 (BufTagGetRelNumber(tag) == rlocator->relNumber);
183}
184
185
186/*
187 * The shared buffer mapping table is partitioned to reduce contention.
188 * To determine which partition lock a given tag requires, compute the tag's
189 * hash code with BufTableHashCode(), then apply BufMappingPartitionLock().
190 * NB: NUM_BUFFER_PARTITIONS must be a power of 2!
191 */
192static inline uint32
194{
195 return hashcode % NUM_BUFFER_PARTITIONS;
196}
197
198static inline LWLock *
200{
202 BufTableHashPartition(hashcode)].lock;
203}
204
205static inline LWLock *
207{
209}
210
211/*
212 * BufferDesc -- shared descriptor/state data for a single shared buffer.
213 *
214 * The state of the buffer is controlled by the, drumroll, state variable. It
215 * only may be modified using atomic operations. The state variable combines
216 * various flags, the buffer's refcount and usage count. See comment above
217 * BUF_REFCOUNT_BITS for details about the division. This layout allow us to
218 * do some operations in a single atomic operation, without actually acquiring
219 * and releasing the spinlock; for instance, increasing or decreasing the
220 * refcount.
221 *
222 * One of the aforementioned flags is BM_LOCKED, used to implement the buffer
223 * header lock. See the following paragraphs, as well as the documentation for
224 * individual fields, for more details.
225 *
226 * The identity of the buffer (BufferDesc.tag) can only be changed by the
227 * backend holding the buffer header lock.
228 *
229 * If the lock is held by another backend, neither additional buffer pins may
230 * be established (we would like to relax this eventually), nor can flags be
231 * set/cleared. These operations either need to acquire the buffer header
232 * spinlock, or need to use a CAS loop, waiting for the lock to be released if
233 * it is held. However, existing buffer pins may be released while the buffer
234 * header spinlock is held, using an atomic subtraction.
235 *
236 * The LWLock can take care of itself. The buffer header lock is *not* used
237 * to control access to the data in the buffer!
238 *
239 * If we have the buffer pinned, its tag can't change underneath us, so we can
240 * examine the tag without locking the buffer header. Also, in places we do
241 * one-time reads of the flags without bothering to lock the buffer header;
242 * this is generally for situations where we don't expect the flag bit being
243 * tested to be changing.
244 *
245 * We can't physically remove items from a disk page if another backend has
246 * the buffer pinned. Hence, a backend may need to wait for all other pins
247 * to go away. This is signaled by storing its own pgprocno into
248 * wait_backend_pgprocno and setting flag bit BM_PIN_COUNT_WAITER. At present,
249 * there can be only one such waiter per buffer.
250 *
251 * We use this same struct for local buffer headers, but the locks are not
252 * used and not all of the flag bits are useful either. To avoid unnecessary
253 * overhead, manipulations of the state field should be done without actual
254 * atomic operations (i.e. only pg_atomic_read_u32() and
255 * pg_atomic_unlocked_write_u32()).
256 *
257 * Be careful to avoid increasing the size of the struct when adding or
258 * reordering members. Keeping it below 64 bytes (the most common CPU
259 * cache line size) is fairly important for performance.
260 *
261 * Per-buffer I/O condition variables are currently kept outside this struct in
262 * a separate array. They could be moved in here and still fit within that
263 * limit on common systems, but for now that is not done.
264 */
265typedef struct BufferDesc
266{
267 /*
268 * ID of page contained in buffer. The buffer header spinlock needs to be
269 * held to modify this field.
270 */
272
273 /*
274 * Buffer's index number (from 0). The field never changes after
275 * initialization, so does not need locking.
276 */
277 int buf_id;
278
279 /*
280 * State of the buffer, containing flags, refcount and usagecount. See
281 * BUF_* and BM_* defines at the top of this file.
282 */
284
285 /*
286 * Backend of pin-count waiter. The buffer header spinlock needs to be
287 * held to modify this field.
288 */
291 PgAioWaitRef io_wref; /* set iff AIO is in progress */
292 LWLock content_lock; /* to lock access to buffer contents */
293} BufferDesc;
294
295/*
296 * Concurrent access to buffer headers has proven to be more efficient if
297 * they're cache line aligned. So we force the start of the BufferDescriptors
298 * array to be on a cache line boundary and force the elements to be cache
299 * line sized.
300 *
301 * XXX: As this is primarily matters in highly concurrent workloads which
302 * probably all are 64bit these days, and the space wastage would be a bit
303 * more noticeable on 32bit systems, we don't force the stride to be cache
304 * line sized on those. If somebody does actual performance testing, we can
305 * reevaluate.
306 *
307 * Note that local buffer descriptors aren't forced to be aligned - as there's
308 * no concurrent access to those it's unlikely to be beneficial.
309 *
310 * We use a 64-byte cache line size here, because that's the most common
311 * size. Making it bigger would be a waste of memory. Even if running on a
312 * platform with either 32 or 128 byte line sizes, it's good to align to
313 * boundaries and avoid false sharing.
314 */
315#define BUFFERDESC_PAD_TO_SIZE (SIZEOF_VOID_P == 8 ? 64 : 1)
317typedef union BufferDescPadded
322
323/*
324 * The PendingWriteback & WritebackContext structure are used to keep
325 * information about pending flush requests to be issued to the OS.
326 */
327typedef struct PendingWriteback
328{
329 /* could store different types of pending flushes here */
332
333/* struct forward declared in bufmgr.h */
334typedef struct WritebackContext
335{
336 /* pointer to the max number of writeback requests to coalesce */
337 int *max_pending;
338
339 /* current number of pending writeback requests */
340 int nr_pending;
341
342 /* pending requests */
345
346/* in buf_init.c */
350
351/* in localbuf.c */
353
354
355static inline BufferDesc *
357{
358 return &(BufferDescriptors[id]).bufferdesc;
359}
360
361static inline BufferDesc *
363{
364 return &LocalBufferDescriptors[id];
365}
366
367static inline Buffer
369{
370 return (Buffer) (bdesc->buf_id + 1);
371}
372
373static inline ConditionVariable *
375{
376 return &(BufferIOCVArray[bdesc->buf_id]).cv;
377}
378
379static inline LWLock *
381{
382 return (LWLock *) (&bdesc->content_lock);
383}
384
385/*
386 * Functions for acquiring/releasing a shared buffer header's spinlock. Do
387 * not apply these to local buffers!
388 */
389extern uint32 LockBufHdr(BufferDesc *desc);
390
391/*
392 * Unlock the buffer header.
393 *
394 * This can only be used if the caller did not modify BufferDesc.state. To
395 * set/unset flag bits or change the refcount use UnlockBufHdrExt().
396 */
397static inline void
399{
401
403}
404
405/*
406 * Unlock the buffer header, while atomically adding the flags in set_bits,
407 * unsetting the ones in unset_bits and changing the refcount by
408 * refcount_change.
409 *
410 * Note that this approach would not work for usagecount, since we need to cap
411 * the usagecount at BM_MAX_USAGE_COUNT.
412 */
413static inline uint32
414UnlockBufHdrExt(BufferDesc *desc, uint32 old_buf_state,
415 uint32 set_bits, uint32 unset_bits,
416 int refcount_change)
417{
418 for (;;)
419 {
420 uint32 buf_state = old_buf_state;
421
422 Assert(buf_state & BM_LOCKED);
423
424 buf_state |= set_bits;
425 buf_state &= ~unset_bits;
426 buf_state &= ~BM_LOCKED;
427
428 if (refcount_change != 0)
429 buf_state += BUF_REFCOUNT_ONE * refcount_change;
430
431 if (pg_atomic_compare_exchange_u32(&desc->state, &old_buf_state,
432 buf_state))
433 {
434 return old_buf_state;
435 }
436 }
437}
438
440
441/* in bufmgr.c */
442
443/*
444 * Structure to sort buffers per file on checkpoints.
445 *
446 * This structure is allocated per buffer in shared memory, so it should be
447 * kept as small as possible.
448 */
449typedef struct CkptSortItem
457
459
460/* ResourceOwner callbacks to hold buffer I/Os and pins */
463
464/* Convenience wrappers over ResourceOwnerRemember/Forget */
465static inline void
467{
469}
470static inline void
472{
474}
475static inline void
477{
479}
480static inline void
482{
484}
485
486/*
487 * Internal buffer management routines
488 */
489/* bufmgr.c */
490extern void WritebackContextInit(WritebackContext *context, int *max_pending);
491extern void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context);
492extern void ScheduleBufferTagForWriteback(WritebackContext *wb_context,
493 IOContext io_context, BufferTag *tag);
494
495extern void TrackNewBufferPin(Buffer buf);
496
497/* solely to make it easier to write tests */
498extern bool StartBufferIO(BufferDesc *buf, bool forInput, bool nowait);
499extern void TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint32 set_flag_bits,
500 bool forget_owner, bool release_aio);
501
502
503/* freelist.c */
506 uint32 *buf_state, bool *from_ring);
507extern bool StrategyRejectBuffer(BufferAccessStrategy strategy,
508 BufferDesc *buf, bool from_ring);
509
510extern int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc);
511extern void StrategyNotifyBgWriter(int bgwprocno);
512
513extern Size StrategyShmemSize(void);
514extern void StrategyInitialize(bool init);
515
516/* buf_table.c */
517extern Size BufTableShmemSize(int size);
518extern void InitBufTable(int size);
519extern uint32 BufTableHashCode(BufferTag *tagPtr);
520extern int BufTableLookup(BufferTag *tagPtr, uint32 hashcode);
521extern int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id);
522extern void BufTableDelete(BufferTag *tagPtr, uint32 hashcode);
523
524/* localbuf.c */
525extern bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount);
526extern void UnpinLocalBuffer(Buffer buffer);
527extern void UnpinLocalBufferNoOwner(Buffer buffer);
529 ForkNumber forkNum,
530 BlockNumber blockNum);
532 BlockNumber blockNum, bool *foundPtr);
534 ForkNumber fork,
535 uint32 flags,
536 uint32 extend_by,
537 BlockNumber extend_upto,
538 Buffer *buffers,
539 uint32 *extended_by);
540extern void MarkLocalBufferDirty(Buffer buffer);
541extern void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty,
542 uint32 set_flag_bits, bool release_aio);
543extern bool StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool nowait);
544extern void FlushLocalBuffer(BufferDesc *bufHdr, SMgrRelation reln);
545extern void InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced);
546extern void DropRelationLocalBuffers(RelFileLocator rlocator,
547 ForkNumber *forkNum, int nforks,
548 BlockNumber *firstDelBlock);
549extern void DropRelationAllLocalBuffers(RelFileLocator rlocator);
550extern void AtEOXact_LocalBuffers(bool isCommit);
551
552#endif /* BUFMGR_INTERNALS_H */
static bool pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 *expected, uint32 newval)
Definition: atomics.h:347
static uint32 pg_atomic_fetch_sub_u32(volatile pg_atomic_uint32 *ptr, int32 sub_)
Definition: atomics.h:379
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:237
uint32 BlockNumber
Definition: block.h:31
#define InvalidBlockNumber
Definition: block.h:33
int Buffer
Definition: buf.h:23
#define BM_MAX_USAGE_COUNT
Definition: buf_internals.h:86
void FlushLocalBuffer(BufferDesc *bufHdr, SMgrRelation reln)
Definition: localbuf.c:183
static void InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator, ForkNumber forkNum, BlockNumber blockNum)
struct CkptSortItem CkptSortItem
static uint32 BufTableHashPartition(uint32 hashcode)
uint32 WaitBufHdrUnlocked(BufferDesc *buf)
Definition: bufmgr.c:6294
static LWLock * BufMappingPartitionLockByIndex(uint32 index)
void BufTableDelete(BufferTag *tagPtr, uint32 hashcode)
Definition: buf_table.c:148
union BufferDescPadded BufferDescPadded
void UnpinLocalBuffer(Buffer buffer)
Definition: localbuf.c:841
int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc)
Definition: freelist.c:321
StaticAssertDecl(BUF_REFCOUNT_BITS+BUF_USAGECOUNT_BITS+BUF_FLAG_BITS==32, "parts of buffer state space need to equal 32")
static ForkNumber BufTagGetForkNum(const BufferTag *tag)
#define BUF_REFCOUNT_ONE
Definition: buf_internals.h:51
static ConditionVariable * BufferDescriptorGetIOCV(const BufferDesc *bdesc)
bool StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool nowait)
Definition: localbuf.c:523
#define BUF_FLAG_BITS
Definition: buf_internals.h:46
struct BufferDesc BufferDesc
void AtEOXact_LocalBuffers(bool isCommit)
Definition: localbuf.c:1003
int BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
Definition: buf_table.c:90
static bool BufferTagsEqual(const BufferTag *tag1, const BufferTag *tag2)
static RelFileNumber BufTagGetRelNumber(const BufferTag *tag)
static LWLock * BufferDescriptorGetContentLock(const BufferDesc *bdesc)
static void UnlockBufHdr(BufferDesc *desc)
static bool BufTagMatchesRelFileLocator(const BufferTag *tag, const RelFileLocator *rlocator)
#define BUF_REFCOUNT_BITS
Definition: buf_internals.h:44
struct WritebackContext WritebackContext
bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount)
Definition: localbuf.c:805
struct PendingWriteback PendingWriteback
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:235
void StrategyInitialize(bool init)
Definition: freelist.c:401
static uint32 UnlockBufHdrExt(BufferDesc *desc, uint32 old_buf_state, uint32 set_bits, uint32 unset_bits, int refcount_change)
#define BUF_USAGECOUNT_BITS
Definition: buf_internals.h:45
static void ResourceOwnerRememberBufferIO(ResourceOwner owner, Buffer buffer)
#define BM_LOCKED
Definition: buf_internals.h:68
void MarkLocalBufferDirty(Buffer buffer)
Definition: localbuf.c:491
#define BUFFERDESC_PAD_TO_SIZE
PGDLLIMPORT WritebackContext BackendWritebackContext
Definition: buf_init.c:24
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 TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint32 set_flag_bits, bool forget_owner, bool release_aio)
Definition: bufmgr.c:6104
void ScheduleBufferTagForWriteback(WritebackContext *wb_context, IOContext io_context, BufferTag *tag)
Definition: bufmgr.c:6418
void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint32 set_flag_bits, bool release_aio)
Definition: localbuf.c:562
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:6406
void StrategyNotifyBgWriter(int bgwprocno)
Definition: freelist.c:358
struct buftag BufferTag
static void ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer)
PGDLLIMPORT BufferDescPadded * BufferDescriptors
Definition: buf_init.c:21
PrefetchBufferResult PrefetchLocalBuffer(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum)
Definition: localbuf.c:72
PGDLLIMPORT ConditionVariableMinimallyPadded * BufferIOCVArray
Definition: buf_init.c:23
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:6468
PGDLLIMPORT CkptSortItem * CkptBufferIds
Definition: buf_init.c:25
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)
BufferDesc * StrategyGetBuffer(BufferAccessStrategy strategy, uint32 *buf_state, bool *from_ring)
Definition: freelist.c:174
bool StartBufferIO(BufferDesc *buf, bool forInput, bool nowait)
Definition: bufmgr.c:6046
static RelFileLocator BufTagGetRelFileLocator(const BufferTag *tag)
Size StrategyShmemSize(void)
Definition: freelist.c:380
PGDLLIMPORT BufferDesc * LocalBufferDescriptors
Definition: localbuf.c:47
PGDLLIMPORT const ResourceOwnerDesc buffer_pin_resowner_desc
Definition: bufmgr.c:244
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:6264
static BufferDesc * GetLocalBufferDescriptor(uint32 id)
static BufferDesc * GetBufferDescriptor(uint32 id)
void TrackNewBufferPin(Buffer buf)
Definition: bufmgr.c:3303
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:1320
uint32_t uint32
Definition: c.h:543
size_t Size
Definition: c.h:615
Assert(PointerIsAligned(start, uint64))
int init
Definition: isn.c:79
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
Definition: pg_test_fsync.c:72
IOContext
Definition: pgstat.h:285
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:222
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
#define MAX_BACKENDS_BITS
Definition: procnumber.h:38
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
LWLock content_lock
int wait_backend_pgprocno
BufferTag tag
pg_atomic_uint32 state
PgAioWaitRef io_wref
ForkNumber forkNum
RelFileNumber relNumber
BlockNumber blockNum
Definition: lwlock.h:42
RelFileNumber relNumber
PendingWriteback pending_writebacks[WRITEBACK_MAX_PENDING_FLUSHES]
BlockNumber blockNum
RelFileNumber relNumber
ForkNumber forkNum
Oid spcOid
Definition: type.h:96
char pad[BUFFERDESC_PAD_TO_SIZE]
BufferDesc bufferdesc
LWLock lock
Definition: lwlock.h:70