Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * ipci.c
4 : : * POSTGRES inter-process communication initialization code.
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/ipc/ipci.c
12 : : *
13 : : *-------------------------------------------------------------------------
14 : : */
15 : : #include "postgres.h"
16 : :
17 : : #include "access/clog.h"
18 : : #include "access/commit_ts.h"
19 : : #include "access/multixact.h"
20 : : #include "access/nbtree.h"
21 : : #include "access/subtrans.h"
22 : : #include "access/syncscan.h"
23 : : #include "access/transam.h"
24 : : #include "access/twophase.h"
25 : : #include "access/xlogprefetcher.h"
26 : : #include "access/xlogrecovery.h"
27 : : #include "access/xlogwait.h"
28 : : #include "commands/async.h"
29 : : #include "miscadmin.h"
30 : : #include "pgstat.h"
31 : : #include "postmaster/autovacuum.h"
32 : : #include "postmaster/bgworker_internals.h"
33 : : #include "postmaster/bgwriter.h"
34 : : #include "postmaster/walsummarizer.h"
35 : : #include "replication/logicallauncher.h"
36 : : #include "replication/origin.h"
37 : : #include "replication/slot.h"
38 : : #include "replication/slotsync.h"
39 : : #include "replication/walreceiver.h"
40 : : #include "replication/walsender.h"
41 : : #include "storage/aio_subsys.h"
42 : : #include "storage/bufmgr.h"
43 : : #include "storage/dsm.h"
44 : : #include "storage/dsm_registry.h"
45 : : #include "storage/ipc.h"
46 : : #include "storage/pg_shmem.h"
47 : : #include "storage/pmsignal.h"
48 : : #include "storage/predicate.h"
49 : : #include "storage/proc.h"
50 : : #include "storage/procarray.h"
51 : : #include "storage/procsignal.h"
52 : : #include "storage/sinvaladt.h"
53 : : #include "utils/guc.h"
54 : : #include "utils/injection_point.h"
55 : : #include "utils/wait_event.h"
56 : :
57 : : /* GUCs */
58 : : int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;
59 : :
60 : : shmem_startup_hook_type shmem_startup_hook = NULL;
61 : :
62 : : static Size total_addin_request = 0;
63 : :
64 : : static void CreateOrAttachShmemStructs(void);
65 : :
66 : : /*
67 : : * RequestAddinShmemSpace
68 : : * Request that extra shmem space be allocated for use by
69 : : * a loadable module.
70 : : *
71 : : * This may only be called via the shmem_request_hook of a library that is
72 : : * loaded into the postmaster via shared_preload_libraries. Calls from
73 : : * elsewhere will fail.
74 : : */
75 : : void
7091 tgl@sss.pgh.pa.us 76 :CBC 17 : RequestAddinShmemSpace(Size size)
77 : : {
1402 rhaas@postgresql.org 78 [ - + ]: 17 : if (!process_shmem_requests_in_progress)
1402 rhaas@postgresql.org 79 [ # # ]:UBC 0 : elog(FATAL, "cannot request additional shared memory outside shmem_request_hook");
7091 tgl@sss.pgh.pa.us 80 :CBC 17 : total_addin_request = add_size(total_addin_request, size);
81 : 17 : }
82 : :
83 : : /*
84 : : * CalculateShmemSize
85 : : * Calculates the amount of shared memory needed.
86 : : */
87 : : Size
129 heikki.linnakangas@i 88 :GNC 2147 : CalculateShmemSize(void)
89 : : {
90 : : Size size;
91 : :
92 : : /*
93 : : * Size of the Postgres shared-memory block is estimated via moderately-
94 : : * accurate estimates for the big hogs, plus 100K for the stuff that's too
95 : : * small to bother with estimating.
96 : : *
97 : : * We take some care to ensure that the total size request doesn't
98 : : * overflow size_t. If this gets through, we don't need to be so careful
99 : : * during the actual allocation phase.
100 : : */
1651 michael@paquier.xyz 101 :CBC 2147 : size = 100000;
102 : 2147 : size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
103 : : sizeof(ShmemIndexEnt)));
104 : 2147 : size = add_size(size, dsm_estimate_size());
786 nathan@postgresql.or 105 : 2147 : size = add_size(size, DSMRegistryShmemSize());
563 heikki.linnakangas@i 106 : 2147 : size = add_size(size, BufferManagerShmemSize());
107 : 2147 : size = add_size(size, LockManagerShmemSize());
1651 michael@paquier.xyz 108 : 2147 : size = add_size(size, PredicateLockShmemSize());
109 : 2147 : size = add_size(size, ProcGlobalShmemSize());
1438 tmunro@postgresql.or 110 : 2147 : size = add_size(size, XLogPrefetchShmemSize());
828 heikki.linnakangas@i 111 : 2147 : size = add_size(size, VarsupShmemSize());
1651 michael@paquier.xyz 112 : 2147 : size = add_size(size, XLOGShmemSize());
1488 heikki.linnakangas@i 113 : 2147 : size = add_size(size, XLogRecoveryShmemSize());
1651 michael@paquier.xyz 114 : 2147 : size = add_size(size, CLOGShmemSize());
115 : 2147 : size = add_size(size, CommitTsShmemSize());
116 : 2147 : size = add_size(size, SUBTRANSShmemSize());
117 : 2147 : size = add_size(size, TwoPhaseShmemSize());
118 : 2147 : size = add_size(size, BackgroundWorkerShmemSize());
119 : 2147 : size = add_size(size, MultiXactShmemSize());
120 : 2147 : size = add_size(size, LWLockShmemSize());
121 : 2147 : size = add_size(size, ProcArrayShmemSize());
122 : 2147 : size = add_size(size, BackendStatusShmemSize());
563 heikki.linnakangas@i 123 : 2147 : size = add_size(size, SharedInvalShmemSize());
1651 michael@paquier.xyz 124 : 2147 : size = add_size(size, PMSignalShmemSize());
125 : 2147 : size = add_size(size, ProcSignalShmemSize());
126 : 2147 : size = add_size(size, CheckpointerShmemSize());
127 : 2147 : size = add_size(size, AutoVacuumShmemSize());
128 : 2147 : size = add_size(size, ReplicationSlotsShmemSize());
129 : 2147 : size = add_size(size, ReplicationOriginShmemSize());
130 : 2147 : size = add_size(size, WalSndShmemSize());
131 : 2147 : size = add_size(size, WalRcvShmemSize());
816 rhaas@postgresql.org 132 : 2147 : size = add_size(size, WalSummarizerShmemSize());
1651 michael@paquier.xyz 133 : 2147 : size = add_size(size, PgArchShmemSize());
134 : 2147 : size = add_size(size, ApplyLauncherShmemSize());
135 : 2147 : size = add_size(size, BTreeShmemSize());
136 : 2147 : size = add_size(size, SyncScanShmemSize());
137 : 2147 : size = add_size(size, AsyncShmemSize());
1439 andres@anarazel.de 138 : 2147 : size = add_size(size, StatsShmemSize());
626 noah@leadboat.com 139 : 2147 : size = add_size(size, WaitEventCustomShmemSize());
783 michael@paquier.xyz 140 : 2147 : size = add_size(size, InjectionPointShmemSize());
760 akapila@postgresql.o 141 : 2147 : size = add_size(size, SlotSyncShmemSize());
363 andres@anarazel.de 142 : 2147 : size = add_size(size, AioShmemSize());
132 akorotkov@postgresql 143 :GNC 2147 : size = add_size(size, WaitLSNShmemSize());
82 msawada@postgresql.o 144 : 2147 : size = add_size(size, LogicalDecodingCtlShmemSize());
145 : :
146 : : /* include additional requested shmem from preload libraries */
1651 michael@paquier.xyz 147 :CBC 2147 : size = add_size(size, total_addin_request);
148 : :
149 : : /* might as well round it off to a multiple of a typical page size */
150 : 2147 : size = add_size(size, 8192 - (size % 8192));
151 : :
152 : 2147 : return size;
153 : : }
154 : :
155 : : #ifdef EXEC_BACKEND
156 : : /*
157 : : * AttachSharedMemoryStructs
158 : : * Initialize a postmaster child process's access to shared memory
159 : : * structures.
160 : : *
161 : : * In !EXEC_BACKEND mode, we inherit everything through the fork, and this
162 : : * isn't needed.
163 : : */
164 : : void
165 : : AttachSharedMemoryStructs(void)
166 : : {
167 : : /* InitProcess must've been called already */
168 : : Assert(MyProc != NULL);
169 : : Assert(IsUnderPostmaster);
170 : :
171 : : /*
172 : : * In EXEC_BACKEND mode, backends don't inherit the number of fast-path
173 : : * groups we calculated before setting the shmem up, so recalculate it.
174 : : */
175 : : InitializeFastPathLocks();
176 : :
177 : : CreateOrAttachShmemStructs();
178 : :
179 : : /*
180 : : * Now give loadable modules a chance to set up their shmem allocations
181 : : */
182 : : if (shmem_startup_hook)
183 : : shmem_startup_hook();
184 : : }
185 : : #endif
186 : :
187 : : /*
188 : : * CreateSharedMemoryAndSemaphores
189 : : * Creates and initializes shared memory and semaphores.
190 : : */
191 : : void
833 heikki.linnakangas@i 192 : 1152 : CreateSharedMemoryAndSemaphores(void)
193 : : {
194 : : PGShmemHeader *shim;
195 : : PGShmemHeader *seghdr;
196 : : Size size;
197 : :
198 [ - + ]: 1152 : Assert(!IsUnderPostmaster);
199 : :
200 : : /* Compute the size of the shared-memory block */
129 heikki.linnakangas@i 201 :GNC 1152 : size = CalculateShmemSize();
833 heikki.linnakangas@i 202 [ + + ]:CBC 1152 : elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
203 : :
204 : : /*
205 : : * Create the shmem segment
206 : : */
207 : 1152 : seghdr = PGSharedMemoryCreate(size, &shim);
208 : :
209 : : /*
210 : : * Make sure that huge pages are never reported as "unknown" while the
211 : : * server is running.
212 : : */
213 [ - + ]: 1150 : Assert(strcmp("unknown",
214 : : GetConfigOption("huge_pages_status", false, false)) != 0);
215 : :
216 : : /*
217 : : * Set up shared memory allocation mechanism
218 : : */
44 heikki.linnakangas@i 219 :GNC 1150 : InitShmemAllocator(seghdr);
220 : :
221 : : /* Initialize subsystems */
833 heikki.linnakangas@i 222 :CBC 1150 : CreateOrAttachShmemStructs();
223 : :
224 : : /* Initialize dynamic shared memory facilities. */
225 : 1150 : dsm_postmaster_startup(shim);
226 : :
227 : : /*
228 : : * Now give loadable modules a chance to set up their shmem allocations
229 : : */
230 [ + + ]: 1150 : if (shmem_startup_hook)
231 : 15 : shmem_startup_hook();
232 : 1150 : }
233 : :
234 : : /*
235 : : * Initialize various subsystems, setting up their data structures in
236 : : * shared memory.
237 : : *
238 : : * This is called by the postmaster or by a standalone backend.
239 : : * It is also called by a backend forked from the postmaster in the
240 : : * EXEC_BACKEND case. In the latter case, the shared memory segment
241 : : * already exists and has been physically attached to, but we have to
242 : : * initialize pointers in local memory that reference the shared structures,
243 : : * because we didn't inherit the correct pointer values from the postmaster
244 : : * as we do in the fork() scenario. The easiest way to do that is to run
245 : : * through the same code as before. (Note that the called routines mostly
246 : : * check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
247 : : * This is a bit code-wasteful and could be cleaned up.)
248 : : */
249 : : static void
250 : 1150 : CreateOrAttachShmemStructs(void)
251 : : {
252 : : /*
253 : : * Now initialize LWLocks, which do shared memory allocation and are
254 : : * needed for InitShmemIndex.
255 : : */
4430 rhaas@postgresql.org 256 : 1150 : CreateLWLocks();
257 : :
258 : : /*
259 : : * Set up shmem.c index hashtable
260 : : */
8933 tgl@sss.pgh.pa.us 261 : 1150 : InitShmemIndex();
262 : :
2053 tmunro@postgresql.or 263 : 1150 : dsm_shmem_init();
786 nathan@postgresql.or 264 : 1150 : DSMRegistryShmemInit();
265 : :
266 : : /*
267 : : * Set up xlog, clog, and buffers
268 : : */
828 heikki.linnakangas@i 269 : 1150 : VarsupShmemInit();
9238 tgl@sss.pgh.pa.us 270 : 1150 : XLOGShmemInit();
1438 tmunro@postgresql.or 271 : 1150 : XLogPrefetchShmemInit();
1488 heikki.linnakangas@i 272 : 1150 : XLogRecoveryShmemInit();
8968 tgl@sss.pgh.pa.us 273 : 1150 : CLOGShmemInit();
4120 alvherre@alvh.no-ip. 274 : 1150 : CommitTsShmemInit();
7927 tgl@sss.pgh.pa.us 275 : 1150 : SUBTRANSShmemInit();
7626 276 : 1150 : MultiXactShmemInit();
563 heikki.linnakangas@i 277 : 1150 : BufferManagerShmemInit();
278 : :
279 : : /*
280 : : * Set up lock manager
281 : : */
282 : 1150 : LockManagerShmemInit();
283 : :
284 : : /*
285 : : * Set up predicate lock manager
286 : : */
287 : 1150 : PredicateLockShmemInit();
288 : :
289 : : /*
290 : : * Set up process table
291 : : */
7375 tgl@sss.pgh.pa.us 292 [ + - ]: 1150 : if (!IsUnderPostmaster)
293 : 1150 : InitProcGlobal();
563 heikki.linnakangas@i 294 : 1150 : ProcArrayShmemInit();
295 : 1150 : BackendStatusShmemInit();
5224 rhaas@postgresql.org 296 : 1150 : TwoPhaseShmemInit();
4625 297 : 1150 : BackgroundWorkerShmemInit();
298 : :
299 : : /*
300 : : * Set up shared-inval messaging
301 : : */
563 heikki.linnakangas@i 302 : 1150 : SharedInvalShmemInit();
303 : :
304 : : /*
305 : : * Set up interprocess signaling mechanisms
306 : : */
6158 tgl@sss.pgh.pa.us 307 : 1150 : PMSignalShmemInit();
6071 308 : 1150 : ProcSignalShmemInit();
5058 simon@2ndQuadrant.co 309 : 1150 : CheckpointerShmemInit();
6968 alvherre@alvh.no-ip. 310 : 1150 : AutoVacuumShmemInit();
4426 rhaas@postgresql.org 311 : 1150 : ReplicationSlotsShmemInit();
3973 andres@anarazel.de 312 : 1150 : ReplicationOriginShmemInit();
5903 heikki.linnakangas@i 313 : 1150 : WalSndShmemInit();
314 : 1150 : WalRcvShmemInit();
816 rhaas@postgresql.org 315 : 1150 : WalSummarizerShmemInit();
1826 fujii@postgresql.org 316 : 1150 : PgArchShmemInit();
3342 peter_e@gmx.net 317 : 1150 : ApplyLauncherShmemInit();
760 akapila@postgresql.o 318 : 1150 : SlotSyncShmemInit();
319 : :
320 : : /*
321 : : * Set up other modules that need some shared memory space
322 : : */
7251 tgl@sss.pgh.pa.us 323 : 1150 : BTreeShmemInit();
6855 324 : 1150 : SyncScanShmemInit();
5871 325 : 1150 : AsyncShmemInit();
1439 andres@anarazel.de 326 : 1150 : StatsShmemInit();
626 noah@leadboat.com 327 : 1150 : WaitEventCustomShmemInit();
783 michael@paquier.xyz 328 : 1150 : InjectionPointShmemInit();
363 andres@anarazel.de 329 : 1150 : AioShmemInit();
132 akorotkov@postgresql 330 :GNC 1150 : WaitLSNShmemInit();
82 msawada@postgresql.o 331 : 1150 : LogicalDecodingCtlShmemInit();
10841 scrappy@hub.org 332 :CBC 1150 : }
333 : :
334 : : /*
335 : : * InitializeShmemGUCs
336 : : *
337 : : * This function initializes runtime-computed GUCs related to the amount of
338 : : * shared memory required for the current configuration.
339 : : */
340 : : void
1649 michael@paquier.xyz 341 : 995 : InitializeShmemGUCs(void)
342 : : {
343 : : char buf[64];
344 : : Size size_b;
345 : : Size size_mb;
346 : : Size hp_size;
347 : :
348 : : /*
349 : : * Calculate the shared memory size and round up to the nearest megabyte.
350 : : */
129 heikki.linnakangas@i 351 :GNC 995 : size_b = CalculateShmemSize();
1649 michael@paquier.xyz 352 :CBC 995 : size_mb = add_size(size_b, (1024 * 1024) - 1) / (1024 * 1024);
353 : 995 : sprintf(buf, "%zu", size_mb);
1376 tgl@sss.pgh.pa.us 354 : 995 : SetConfigOption("shared_memory_size", buf,
355 : : PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
356 : :
357 : : /*
358 : : * Calculate the number of huge pages required.
359 : : */
1636 michael@paquier.xyz 360 : 995 : GetHugePageSize(&hp_size, NULL);
361 [ + - ]: 995 : if (hp_size != 0)
362 : : {
363 : : Size hp_required;
364 : :
51 nathan@postgresql.or 365 :GNC 995 : hp_required = size_b / hp_size;
366 [ + - ]: 995 : if (size_b % hp_size != 0)
367 : 995 : hp_required = add_size(hp_required, 1);
1636 michael@paquier.xyz 368 :CBC 995 : sprintf(buf, "%zu", hp_required);
1376 tgl@sss.pgh.pa.us 369 : 995 : SetConfigOption("shared_memory_size_in_huge_pages", buf,
370 : : PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
371 : : }
372 : :
129 heikki.linnakangas@i 373 :GNC 995 : sprintf(buf, "%d", ProcGlobalSemas());
597 nathan@postgresql.or 374 :CBC 995 : SetConfigOption("num_os_semaphores", buf, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
1649 michael@paquier.xyz 375 : 995 : }
|