PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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
84 * clock sweeps 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 * Note: Buffer header lock (BM_LOCKED flag) must be held to examine or change
215 * tag, state or wait_backend_pgprocno fields. In general, buffer header lock
216 * is a spinlock which is combined with flags, refcount and usagecount into
217 * single atomic variable. This layout allow us to do some operations in a
218 * single atomic operation, without actually acquiring and releasing spinlock;
219 * for instance, increase or decrease refcount. buf_id field never changes
220 * after initialization, so does not need locking. freeNext is protected by
221 * the buffer_strategy_lock not buffer header lock. The LWLock can take care
222 * of itself. The buffer header lock is *not* used to control access to the
223 * data in the buffer!
224 *
225 * It's assumed that nobody changes the state field while buffer header lock
226 * is held. Thus buffer header lock holder can do complex updates of the
227 * state variable in single write, simultaneously with lock release (cleaning
228 * BM_LOCKED flag). On the other hand, updating of state without holding
229 * buffer header lock is restricted to CAS, which ensures that BM_LOCKED flag
230 * is not set. Atomic increment/decrement, OR/AND etc. are not allowed.
231 *
232 * An exception is that if we have the buffer pinned, its tag can't change
233 * underneath us, so we can examine the tag without locking the buffer header.
234 * Also, in places we do one-time reads of the flags without bothering to
235 * lock the buffer header; this is generally for situations where we don't
236 * expect the flag bit being tested to be changing.
237 *
238 * We can't physically remove items from a disk page if another backend has
239 * the buffer pinned. Hence, a backend may need to wait for all other pins
240 * to go away. This is signaled by storing its own pgprocno into
241 * wait_backend_pgprocno and setting flag bit BM_PIN_COUNT_WAITER. At present,
242 * there can be only one such waiter per buffer.
243 *
244 * We use this same struct for local buffer headers, but the locks are not
245 * used and not all of the flag bits are useful either. To avoid unnecessary
246 * overhead, manipulations of the state field should be done without actual
247 * atomic operations (i.e. only pg_atomic_read_u32() and
248 * pg_atomic_unlocked_write_u32()).
249 *
250 * Be careful to avoid increasing the size of the struct when adding or
251 * reordering members. Keeping it below 64 bytes (the most common CPU
252 * cache line size) is fairly important for performance.
253 *
254 * Per-buffer I/O condition variables are currently kept outside this struct in
255 * a separate array. They could be moved in here and still fit within that
256 * limit on common systems, but for now that is not done.
257 */
258typedef struct BufferDesc
260 BufferTag tag; /* ID of page contained in buffer */
261 int buf_id; /* buffer's index number (from 0) */
262
263 /* state of the tag, containing flags, refcount and usagecount */
266 int wait_backend_pgprocno; /* backend of pin-count waiter */
267 int freeNext; /* link in freelist chain */
269 PgAioWaitRef io_wref; /* set iff AIO is in progress */
270 LWLock content_lock; /* to lock access to buffer contents */
271} BufferDesc;
272
273/*
274 * Concurrent access to buffer headers has proven to be more efficient if
275 * they're cache line aligned. So we force the start of the BufferDescriptors
276 * array to be on a cache line boundary and force the elements to be cache
277 * line sized.
278 *
279 * XXX: As this is primarily matters in highly concurrent workloads which
280 * probably all are 64bit these days, and the space wastage would be a bit
281 * more noticeable on 32bit systems, we don't force the stride to be cache
282 * line sized on those. If somebody does actual performance testing, we can
283 * reevaluate.
284 *
285 * Note that local buffer descriptors aren't forced to be aligned - as there's
286 * no concurrent access to those it's unlikely to be beneficial.
287 *
288 * We use a 64-byte cache line size here, because that's the most common
289 * size. Making it bigger would be a waste of memory. Even if running on a
290 * platform with either 32 or 128 byte line sizes, it's good to align to
291 * boundaries and avoid false sharing.
292 */
293#define BUFFERDESC_PAD_TO_SIZE (SIZEOF_VOID_P == 8 ? 64 : 1)
295typedef union BufferDescPadded
300
301/*
302 * The PendingWriteback & WritebackContext structure are used to keep
303 * information about pending flush requests to be issued to the OS.
304 */
305typedef struct PendingWriteback
306{
307 /* could store different types of pending flushes here */
310
311/* struct forward declared in bufmgr.h */
312typedef struct WritebackContext
313{
314 /* pointer to the max number of writeback requests to coalesce */
315 int *max_pending;
316
317 /* current number of pending writeback requests */
318 int nr_pending;
319
320 /* pending requests */
323
324/* in buf_init.c */
328
329/* in localbuf.c */
331
332
333static inline BufferDesc *
335{
336 return &(BufferDescriptors[id]).bufferdesc;
337}
338
339static inline BufferDesc *
341{
342 return &LocalBufferDescriptors[id];
343}
344
345static inline Buffer
347{
348 return (Buffer) (bdesc->buf_id + 1);
349}
350
351static inline ConditionVariable *
353{
354 return &(BufferIOCVArray[bdesc->buf_id]).cv;
355}
356
357static inline LWLock *
359{
360 return (LWLock *) (&bdesc->content_lock);
361}
362
363/*
364 * The freeNext field is either the index of the next freelist entry,
365 * or one of these special values:
366 */
367#define FREENEXT_END_OF_LIST (-1)
368#define FREENEXT_NOT_IN_LIST (-2)
369
370/*
371 * Functions for acquiring/releasing a shared buffer header's spinlock. Do
372 * not apply these to local buffers!
373 */
374extern uint32 LockBufHdr(BufferDesc *desc);
375
376static inline void
377UnlockBufHdr(BufferDesc *desc, uint32 buf_state)
378{
380 pg_atomic_write_u32(&desc->state, buf_state & (~BM_LOCKED));
381}
382
383/* in bufmgr.c */
384
385/*
386 * Structure to sort buffers per file on checkpoints.
387 *
388 * This structure is allocated per buffer in shared memory, so it should be
389 * kept as small as possible.
390 */
391typedef struct CkptSortItem
399
401
402/* ResourceOwner callbacks to hold buffer I/Os and pins */
405
406/* Convenience wrappers over ResourceOwnerRemember/Forget */
407static inline void
409{
411}
412static inline void
414{
416}
417static inline void
419{
421}
422static inline void
424{
426}
427
428/*
429 * Internal buffer management routines
430 */
431/* bufmgr.c */
432extern void WritebackContextInit(WritebackContext *context, int *max_pending);
433extern void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context);
434extern void ScheduleBufferTagForWriteback(WritebackContext *wb_context,
435 IOContext io_context, BufferTag *tag);
436
437/* solely to make it easier to write tests */
438extern bool StartBufferIO(BufferDesc *buf, bool forInput, bool nowait);
439extern void TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint32 set_flag_bits,
440 bool forget_owner, bool release_aio);
441
442
443/* freelist.c */
446 uint32 *buf_state, bool *from_ring);
447extern void StrategyFreeBuffer(BufferDesc *buf);
448extern bool StrategyRejectBuffer(BufferAccessStrategy strategy,
449 BufferDesc *buf, bool from_ring);
450
451extern int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc);
452extern void StrategyNotifyBgWriter(int bgwprocno);
453
454extern Size StrategyShmemSize(void);
455extern void StrategyInitialize(bool init);
456extern bool have_free_buffer(void);
457
458/* buf_table.c */
459extern Size BufTableShmemSize(int size);
460extern void InitBufTable(int size);
461extern uint32 BufTableHashCode(BufferTag *tagPtr);
462extern int BufTableLookup(BufferTag *tagPtr, uint32 hashcode);
463extern int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id);
464extern void BufTableDelete(BufferTag *tagPtr, uint32 hashcode);
465
466/* localbuf.c */
467extern bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount);
468extern void UnpinLocalBuffer(Buffer buffer);
469extern void UnpinLocalBufferNoOwner(Buffer buffer);
471 ForkNumber forkNum,
472 BlockNumber blockNum);
474 BlockNumber blockNum, bool *foundPtr);
476 ForkNumber fork,
477 uint32 flags,
478 uint32 extend_by,
479 BlockNumber extend_upto,
480 Buffer *buffers,
481 uint32 *extended_by);
482extern void MarkLocalBufferDirty(Buffer buffer);
483extern void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty,
484 uint32 set_flag_bits, bool release_aio);
485extern bool StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool nowait);
486extern void FlushLocalBuffer(BufferDesc *bufHdr, SMgrRelation reln);
487extern void InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced);
488extern void DropRelationLocalBuffers(RelFileLocator rlocator,
489 ForkNumber forkNum,
490 BlockNumber firstDelBlock);
491extern void DropRelationAllLocalBuffers(RelFileLocator rlocator);
492extern void AtEOXact_LocalBuffers(bool isCommit);
493
494#endif /* BUFMGR_INTERNALS_H */
#define pg_write_barrier()
Definition: atomics.h:157
static void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:276
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:182
static void InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator, ForkNumber forkNum, BlockNumber blockNum)
struct CkptSortItem CkptSortItem
static uint32 BufTableHashPartition(uint32 hashcode)
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:832
int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc)
Definition: freelist.c:394
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)
static ConditionVariable * BufferDescriptorGetIOCV(const BufferDesc *bdesc)
bool StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool nowait)
Definition: localbuf.c:521
#define BUF_FLAG_BITS
Definition: buf_internals.h:46
struct BufferDesc BufferDesc
void AtEOXact_LocalBuffers(bool isCommit)
Definition: localbuf.c:993
static void UnlockBufHdr(BufferDesc *desc, uint32 buf_state)
bool have_free_buffer(void)
Definition: freelist.c:175
void DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber firstDelBlock)
Definition: localbuf.c:663
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 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:796
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:474
#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:489
#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:693
void TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint32 set_flag_bits, bool forget_owner, bool release_aio)
Definition: bufmgr.c:6102
void ScheduleBufferTagForWriteback(WritebackContext *wb_context, IOContext io_context, BufferTag *tag)
Definition: bufmgr.c:6413
void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint32 set_flag_bits, bool release_aio)
Definition: localbuf.c:560
void InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced)
Definition: localbuf.c:603
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:6401
void StrategyNotifyBgWriter(int bgwprocno)
Definition: freelist.c:431
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:71
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:345
void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context)
Definition: bufmgr.c:6463
PGDLLIMPORT CkptSortItem * CkptBufferIds
Definition: buf_init.c:25
IOContext IOContextForStrategy(BufferAccessStrategy strategy)
Definition: freelist.c:800
void UnpinLocalBufferNoOwner(Buffer buffer)
Definition: localbuf.c:839
static LWLock * BufMappingPartitionLock(uint32 hashcode)
BufferDesc * StrategyGetBuffer(BufferAccessStrategy strategy, uint32 *buf_state, bool *from_ring)
Definition: freelist.c:196
bool StartBufferIO(BufferDesc *buf, bool forInput, bool nowait)
Definition: bufmgr.c:6045
static RelFileLocator BufTagGetRelFileLocator(const BufferTag *tag)
Size StrategyShmemSize(void)
Definition: freelist.c:453
PGDLLIMPORT BufferDesc * LocalBufferDescriptors
Definition: localbuf.c:46
PGDLLIMPORT const ResourceOwnerDesc buffer_pin_resowner_desc
Definition: bufmgr.c:244
uint32 LockBufHdr(BufferDesc *desc)
Definition: bufmgr.c:6259
static BufferDesc * GetLocalBufferDescriptor(uint32 id)
static BufferDesc * GetBufferDescriptor(uint32 id)
void StrategyFreeBuffer(BufferDesc *buf)
Definition: freelist.c:363
bool StrategyRejectBuffer(BufferAccessStrategy strategy, BufferDesc *buf, bool from_ring)
Definition: freelist.c:840
static Buffer BufferDescriptorGetBuffer(const BufferDesc *bdesc)
BufferDesc * LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum, bool *foundPtr)
Definition: localbuf.c:118
#define PGDLLIMPORT
Definition: c.h:1291
uint32_t uint32
Definition: c.h:502
size_t Size
Definition: c.h:576
int init
Definition: isn.c:79
LWLockPadded * MainLWLockArray
Definition: lwlock.c:202
#define BUFFER_MAPPING_LWLOCK_OFFSET
Definition: lwlock.h:104
#define NUM_BUFFER_PARTITIONS
Definition: lwlock.h:93
#define WRITEBACK_MAX_PENDING_FLUSHES
static char * buf
Definition: pg_test_fsync.c:72
IOContext
Definition: pgstat.h:282
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:217
#define InvalidOid
Definition: postgres_ext.h:35
unsigned int Oid
Definition: postgres_ext.h:30
#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:564
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:524
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