PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-2026, 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/aio.h"
19#include "storage/bufmgr.h"
20#include "storage/proclist.h"
21#include "storage/shmem.h"
22#include "storage/subsystems.h"
23
29
30static void BufferManagerShmemRequest(void *arg);
31static void BufferManagerShmemInit(void *arg);
32static void BufferManagerShmemAttach(void *arg);
33
39
40/*
41 * Data Structures:
42 * buffers live in a freelist and a lookup data structure.
43 *
44 *
45 * Buffer Lookup:
46 * Two important notes. First, the buffer has to be
47 * available for lookup BEFORE an IO begins. Otherwise
48 * a second process trying to read the buffer will
49 * allocate its own copy and the buffer pool will
50 * become inconsistent.
51 *
52 * Buffer Replacement:
53 * see freelist.c. A buffer cannot be replaced while in
54 * use either by data manager or during IO.
55 *
56 *
57 * Synchronization/Locking:
58 *
59 * IO_IN_PROGRESS -- this is a flag in the buffer descriptor.
60 * It must be set when an IO is initiated and cleared at
61 * the end of the IO. It is there to make sure that one
62 * process doesn't start to use a buffer while another is
63 * faulting it in. see WaitIO and related routines.
64 *
65 * refcount -- Counts the number of processes holding pins on a buffer.
66 * A buffer is pinned during IO and immediately after a BufferAlloc().
67 * Pins must be released before end of transaction. For efficiency the
68 * shared refcount isn't increased if an individual backend pins a buffer
69 * multiple times. Check the PrivateRefCount infrastructure in bufmgr.c.
70 */
71
72
73/*
74 * Register shared memory area for the buffer pool.
75 */
76static void
78{
79 ShmemRequestStruct(.name = "Buffer Descriptors",
80 .size = NBuffers * sizeof(BufferDescPadded),
81 /* Align descriptors to a cacheline boundary. */
82 .alignment = PG_CACHE_LINE_SIZE,
83 .ptr = (void **) &BufferDescriptors,
84 );
85
86 ShmemRequestStruct(.name = "Buffer Blocks",
87 .size = NBuffers * (Size) BLCKSZ,
88 /* Align buffer pool on IO page size boundary. */
89 .alignment = PG_IO_ALIGN_SIZE,
90 .ptr = (void **) &BufferBlocks,
91 );
92
93 ShmemRequestStruct(.name = "Buffer IO Condition Variables",
95 /* Align descriptors to a cacheline boundary. */
96 .alignment = PG_CACHE_LINE_SIZE,
97 .ptr = (void **) &BufferIOCVArray,
98 );
99
100 /*
101 * The array used to sort to-be-checkpointed buffer ids is located in
102 * shared memory, to avoid having to allocate significant amounts of
103 * memory at runtime. As that'd be in the middle of a checkpoint, or when
104 * the checkpointer is restarted, memory allocation failures would be
105 * painful.
106 */
107 ShmemRequestStruct(.name = "Checkpoint BufferIds",
108 .size = NBuffers * sizeof(CkptSortItem),
109 .ptr = (void **) &CkptBufferIds,
110 );
111}
112
113/*
114 * Initialize shared buffer pool
115 *
116 * This is called once during shared-memory initialization (either in the
117 * postmaster, or in a standalone backend).
118 */
119static void
121{
122 /*
123 * Initialize all the buffer headers.
124 */
125 for (int i = 0; i < NBuffers; i++)
126 {
128
129 ClearBufferTag(&buf->tag);
130
131 pg_atomic_init_u64(&buf->state, 0);
132 buf->wait_backend_pgprocno = INVALID_PROC_NUMBER;
133
134 buf->buf_id = i;
135
136 pgaio_wref_clear(&buf->io_wref);
137
138 proclist_init(&buf->lock_waiters);
140 }
141
142 /* Initialize per-backend file flush context */
145}
146
147static void
149{
150 /* Initialize per-backend file flush context */
153}
void pgaio_wref_clear(PgAioWaitRef *iow)
Definition aio.c:964
static void pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:453
const ShmemCallbacks BufferManagerShmemCallbacks
Definition buf_init.c:34
CkptSortItem * CkptBufferIds
Definition buf_init.c:28
static void BufferManagerShmemAttach(void *arg)
Definition buf_init.c:148
char * BufferBlocks
Definition buf_init.c:25
WritebackContext BackendWritebackContext
Definition buf_init.c:27
static void BufferManagerShmemInit(void *arg)
Definition buf_init.c:120
static void BufferManagerShmemRequest(void *arg)
Definition buf_init.c:77
ConditionVariableMinimallyPadded * BufferIOCVArray
Definition buf_init.c:26
BufferDescPadded * BufferDescriptors
Definition buf_init.c:24
static ConditionVariable * BufferDescriptorGetIOCV(const BufferDesc *bdesc)
static void ClearBufferTag(BufferTag *tag)
static BufferDesc * GetBufferDescriptor(uint32 id)
void WritebackContextInit(WritebackContext *context, int *max_pending)
Definition bufmgr.c:7678
int backend_flush_after
Definition bufmgr.c:225
size_t Size
Definition c.h:689
void ConditionVariableInit(ConditionVariable *cv)
Datum arg
Definition elog.c:1322
int NBuffers
Definition globals.c:144
int i
Definition isn.c:77
#define PG_IO_ALIGN_SIZE
#define PG_CACHE_LINE_SIZE
static char buf[DEFAULT_XLOG_SEG_SIZE]
static int fb(int x)
static void proclist_init(proclist_head *list)
Definition proclist.h:29
#define INVALID_PROC_NUMBER
Definition procnumber.h:26
#define ShmemRequestStruct(...)
Definition shmem.h:176
ShmemRequestCallback request_fn
Definition shmem.h:133
const char * name