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