PostgreSQL Source Code git master
buf_init.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * buf_init.c
4 * buffer manager initialization routines
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/storage/buffer/buf_init.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres.h"
16
18#include "storage/bufmgr.h"
19
25
26
27/*
28 * Data Structures:
29 * buffers live in a freelist and a lookup data structure.
30 *
31 *
32 * Buffer Lookup:
33 * Two important notes. First, the buffer has to be
34 * available for lookup BEFORE an IO begins. Otherwise
35 * a second process trying to read the buffer will
36 * allocate its own copy and the buffer pool will
37 * become inconsistent.
38 *
39 * Buffer Replacement:
40 * see freelist.c. A buffer cannot be replaced while in
41 * use either by data manager or during IO.
42 *
43 *
44 * Synchronization/Locking:
45 *
46 * IO_IN_PROGRESS -- this is a flag in the buffer descriptor.
47 * It must be set when an IO is initiated and cleared at
48 * the end of the IO. It is there to make sure that one
49 * process doesn't start to use a buffer while another is
50 * faulting it in. see WaitIO and related routines.
51 *
52 * refcount -- Counts the number of processes holding pins on a buffer.
53 * A buffer is pinned during IO and immediately after a BufferAlloc().
54 * Pins must be released before end of transaction. For efficiency the
55 * shared refcount isn't increased if an individual backend pins a buffer
56 * multiple times. Check the PrivateRefCount infrastructure in bufmgr.c.
57 */
58
59
60/*
61 * Initialize shared buffer pool
62 *
63 * This is called once during shared-memory initialization (either in the
64 * postmaster, or in a standalone backend).
65 */
66void
68{
69 bool foundBufs,
70 foundDescs,
71 foundIOCV,
72 foundBufCkpt;
73
74 /* Align descriptors to a cacheline boundary. */
76 ShmemInitStruct("Buffer Descriptors",
77 NBuffers * sizeof(BufferDescPadded),
78 &foundDescs);
79
80 /* Align buffer pool on IO page size boundary. */
81 BufferBlocks = (char *)
83 ShmemInitStruct("Buffer Blocks",
84 NBuffers * (Size) BLCKSZ + PG_IO_ALIGN_SIZE,
85 &foundBufs));
86
87 /* Align condition variables to cacheline boundary. */
89 ShmemInitStruct("Buffer IO Condition Variables",
91 &foundIOCV);
92
93 /*
94 * The array used to sort to-be-checkpointed buffer ids is located in
95 * shared memory, to avoid having to allocate significant amounts of
96 * memory at runtime. As that'd be in the middle of a checkpoint, or when
97 * the checkpointer is restarted, memory allocation failures would be
98 * painful.
99 */
101 ShmemInitStruct("Checkpoint BufferIds",
102 NBuffers * sizeof(CkptSortItem), &foundBufCkpt);
103
104 if (foundDescs || foundBufs || foundIOCV || foundBufCkpt)
105 {
106 /* should find all of these, or none of them */
107 Assert(foundDescs && foundBufs && foundIOCV && foundBufCkpt);
108 /* note: this path is only taken in EXEC_BACKEND case */
109 }
110 else
111 {
112 int i;
113
114 /*
115 * Initialize all the buffer headers.
116 */
117 for (i = 0; i < NBuffers; i++)
118 {
120
121 ClearBufferTag(&buf->tag);
122
123 pg_atomic_init_u32(&buf->state, 0);
124 buf->wait_backend_pgprocno = INVALID_PROC_NUMBER;
125
126 buf->buf_id = i;
127
128 /*
129 * Initially link all the buffers together as unused. Subsequent
130 * management of this list is done by freelist.c.
131 */
132 buf->freeNext = i + 1;
133
136
138 }
139
140 /* Correct last entry of linked list */
142 }
143
144 /* Init other shared buffer-management stuff */
145 StrategyInitialize(!foundDescs);
146
147 /* Initialize per-backend file flush context */
150}
151
152/*
153 * BufferManagerShmemSize
154 *
155 * compute the size of shared memory for the buffer pool including
156 * data pages, buffer descriptors, hash tables, etc.
157 */
158Size
160{
161 Size size = 0;
162
163 /* size of buffer descriptors */
164 size = add_size(size, mul_size(NBuffers, sizeof(BufferDescPadded)));
165 /* to allow aligning buffer descriptors */
166 size = add_size(size, PG_CACHE_LINE_SIZE);
167
168 /* size of data pages, plus alignment padding */
169 size = add_size(size, PG_IO_ALIGN_SIZE);
170 size = add_size(size, mul_size(NBuffers, BLCKSZ));
171
172 /* size of stuff controlled by freelist.c */
173 size = add_size(size, StrategyShmemSize());
174
175 /* size of I/O condition variables */
176 size = add_size(size, mul_size(NBuffers,
178 /* to allow aligning the above */
179 size = add_size(size, PG_CACHE_LINE_SIZE);
180
181 /* size of checkpoint sort array in bufmgr.c */
182 size = add_size(size, mul_size(NBuffers, sizeof(CkptSortItem)));
183
184 return size;
185}
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:221
CkptSortItem * CkptBufferIds
Definition: buf_init.c:24
Size BufferManagerShmemSize(void)
Definition: buf_init.c:159
char * BufferBlocks
Definition: buf_init.c:21
WritebackContext BackendWritebackContext
Definition: buf_init.c:23
void BufferManagerShmemInit(void)
Definition: buf_init.c:67
ConditionVariableMinimallyPadded * BufferIOCVArray
Definition: buf_init.c:22
BufferDescPadded * BufferDescriptors
Definition: buf_init.c:20
static ConditionVariable * BufferDescriptorGetIOCV(const BufferDesc *bdesc)
static LWLock * BufferDescriptorGetContentLock(const BufferDesc *bdesc)
#define FREENEXT_END_OF_LIST
static void ClearBufferTag(BufferTag *tag)
static BufferDesc * GetBufferDescriptor(uint32 id)
void WritebackContextInit(WritebackContext *context, int *max_pending)
Definition: bufmgr.c:5888
int backend_flush_after
Definition: bufmgr.c:176
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:775
size_t Size
Definition: c.h:576
void ConditionVariableInit(ConditionVariable *cv)
void StrategyInitialize(bool init)
Definition: freelist.c:474
Size StrategyShmemSize(void)
Definition: freelist.c:453
int NBuffers
Definition: globals.c:141
Assert(PointerIsAligned(start, uint64))
int i
Definition: isn.c:74
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:718
@ LWTRANCHE_BUFFER_CONTENT
Definition: lwlock.h:189
#define PG_IO_ALIGN_SIZE
#define PG_CACHE_LINE_SIZE
static char * buf
Definition: pg_test_fsync.c:72
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
Size add_size(Size s1, Size s2)
Definition: shmem.c:488
Size mul_size(Size s1, Size s2)
Definition: shmem.c:505
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:382