Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit eee5abc

Browse files
committed
Refactor EXEC_BACKEND code so that postmaster child processes reattach
to shared memory as soon as possible, ie, right after read_backend_variables. The effective difference from the original code is that this happens before instead of after read_nondefault_variables(), which loads GUC information and is apparently capable of expanding the backend's memory allocation more than you'd think it should. This should fix the failure-to-attach-to-shared-memory reports we've been seeing on Windows. Also clean up a few bits of unnecessarily grotty EXEC_BACKEND code.
1 parent e14018d commit eee5abc

File tree

7 files changed

+178
-123
lines changed

7 files changed

+178
-123
lines changed

src/backend/port/sysv_shmem.c

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Portions Copyright (c) 1994, Regents of the University of California
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/port/sysv_shmem.c,v 1.40 2004/11/09 21:30:13 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/port/sysv_shmem.c,v 1.41 2004/12/29 21:35:58 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -142,11 +142,7 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, uint32 size)
142142
on_shmem_exit(IpcMemoryDelete, Int32GetDatum(shmid));
143143

144144
/* OK, should be able to attach to the segment */
145-
#ifdef EXEC_BACKEND
146-
memAddress = shmat(shmid, UsedShmemSegAddr, PG_SHMAT_FLAGS);
147-
#else
148145
memAddress = shmat(shmid, NULL, PG_SHMAT_FLAGS);
149-
#endif
150146

151147
if (memAddress == (void *) -1)
152148
elog(FATAL, "shmat(id=%d) failed: %m", shmid);
@@ -279,7 +275,7 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2)
279275
*
280276
* Create a shared memory segment of the given size and initialize its
281277
* standard header. Also, register an on_shmem_exit callback to release
282-
* the storage. For an exec'ed backend, it just attaches.
278+
* the storage.
283279
*
284280
* Dead Postgres segments are recycled if found, but we do not fail upon
285281
* collision with non-Postgres shmem segments. The idea here is to detect and
@@ -303,30 +299,6 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
303299
struct stat statbuf;
304300
#endif
305301

306-
#ifdef EXEC_BACKEND
307-
/* If Exec case, just attach and return the pointer */
308-
if (UsedShmemSegAddr != NULL && !makePrivate && IsUnderPostmaster)
309-
{
310-
void *origUsedShmemSegAddr = UsedShmemSegAddr;
311-
312-
#ifdef __CYGWIN__
313-
/* cygipc (currently) appears to not detach on exec. */
314-
PGSharedMemoryDetach();
315-
UsedShmemSegAddr = origUsedShmemSegAddr;
316-
#endif
317-
elog(DEBUG3, "Attaching to %p", UsedShmemSegAddr);
318-
hdr = PGSharedMemoryAttach((IpcMemoryKey) UsedShmemSegID, &shmid);
319-
if (hdr == NULL)
320-
elog(FATAL, "could not attach to proper memory at fixed address: shmget(key=%d, addr=%p) failed: %m",
321-
(int) UsedShmemSegID, UsedShmemSegAddr);
322-
if (hdr != origUsedShmemSegAddr)
323-
elog(FATAL, "attaching to shared mem returned unexpected address (got %p, expected %p)",
324-
hdr, UsedShmemSegAddr);
325-
UsedShmemSegAddr = hdr;
326-
return hdr;
327-
}
328-
#endif
329-
330302
/* Room for a header? */
331303
Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
332304

@@ -424,6 +396,49 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
424396
return hdr;
425397
}
426398

399+
#ifdef EXEC_BACKEND
400+
401+
/*
402+
* PGSharedMemoryReAttach
403+
*
404+
* Re-attach to an already existing shared memory segment. In the non
405+
* EXEC_BACKEND case this is not used, because postmaster children inherit
406+
* the shared memory segment attachment via fork().
407+
*
408+
* UsedShmemSegID and UsedShmemSegAddr are implicit parameters to this
409+
* routine. The caller must have already restored them to the postmaster's
410+
* values.
411+
*/
412+
void
413+
PGSharedMemoryReAttach(void)
414+
{
415+
IpcMemoryId shmid;
416+
void *hdr;
417+
void *origUsedShmemSegAddr = UsedShmemSegAddr;
418+
419+
Assert(UsedShmemSegAddr != NULL);
420+
Assert(IsUnderPostmaster);
421+
422+
#ifdef __CYGWIN__
423+
/* cygipc (currently) appears to not detach on exec. */
424+
PGSharedMemoryDetach();
425+
UsedShmemSegAddr = origUsedShmemSegAddr;
426+
#endif
427+
428+
elog(DEBUG3, "Attaching to %p", UsedShmemSegAddr);
429+
hdr = (void *) PGSharedMemoryAttach((IpcMemoryKey) UsedShmemSegID, &shmid);
430+
if (hdr == NULL)
431+
elog(FATAL, "could not reattach to shared memory (key=%d, addr=%p): %m",
432+
(int) UsedShmemSegID, UsedShmemSegAddr);
433+
if (hdr != origUsedShmemSegAddr)
434+
elog(FATAL, "reattaching to shared memory returned unexpected address (got %p, expected %p)",
435+
hdr, origUsedShmemSegAddr);
436+
437+
UsedShmemSegAddr = hdr; /* probably redundant */
438+
}
439+
440+
#endif /* EXEC_BACKEND */
441+
427442
/*
428443
* PGSharedMemoryDetach
429444
*

src/backend/postmaster/postmaster.c

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.440 2004/11/17 08:30:09 neilc Exp $
40+
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.441 2004/12/29 21:36:03 tgl Exp $
4141
*
4242
* NOTES
4343
*
@@ -1584,10 +1584,8 @@ processCancelRequest(Port *port, void *pkt)
15841584
int backendPID;
15851585
long cancelAuthCode;
15861586
Backend *bp;
1587-
15881587
#ifndef EXEC_BACKEND
15891588
Dlelem *curr;
1590-
15911589
#else
15921590
int i;
15931591
#endif
@@ -3152,10 +3150,31 @@ SubPostmasterMain(int argc, char *argv[])
31523150

31533151
MyProcPid = getpid(); /* reset MyProcPid */
31543152

3155-
/* Read in file-based context */
3153+
/* In EXEC_BACKEND case we will not have inherited these settings */
3154+
IsPostmasterEnvironment = true;
3155+
whereToSendOutput = None;
3156+
3157+
/* Setup essential subsystems (to ensure elog() behaves sanely) */
3158+
MemoryContextInit();
3159+
InitializeGUCOptions();
3160+
3161+
/* Read in the variables file */
31563162
memset(&port, 0, sizeof(Port));
31573163
read_backend_variables(argv[2], &port);
31583164

3165+
/* Check we got appropriate args */
3166+
if (argc < 3)
3167+
elog(FATAL, "invalid subpostmaster invocation");
3168+
3169+
/*
3170+
* If appropriate, physically re-attach to shared memory segment.
3171+
* We want to do this before going any further to ensure that we
3172+
* can attach at the same address the postmaster used.
3173+
*/
3174+
if (strcmp(argv[1], "-forkbackend") == 0 ||
3175+
strcmp(argv[1], "-forkboot") == 0)
3176+
PGSharedMemoryReAttach();
3177+
31593178
/*
31603179
* Start our win32 signal implementation. This has to be done
31613180
* after we read the backend variables, because we need to pick
@@ -3166,19 +3185,9 @@ SubPostmasterMain(int argc, char *argv[])
31663185
#endif
31673186

31683187
/* In EXEC_BACKEND case we will not have inherited these settings */
3169-
IsPostmasterEnvironment = true;
3170-
whereToSendOutput = None;
31713188
pqinitmask();
31723189
PG_SETMASK(&BlockSig);
31733190

3174-
/* Setup essential subsystems */
3175-
MemoryContextInit();
3176-
InitializeGUCOptions();
3177-
3178-
/* Check we got appropriate args */
3179-
if (argc < 3)
3180-
elog(FATAL, "invalid subpostmaster invocation");
3181-
31823191
/* Read in remaining GUC variables */
31833192
read_nondefault_variables();
31843193

@@ -3187,7 +3196,7 @@ SubPostmasterMain(int argc, char *argv[])
31873196
{
31883197
/* BackendRun will close sockets */
31893198

3190-
/* Attach process to shared segments */
3199+
/* Attach process to shared data structures */
31913200
CreateSharedMemoryAndSemaphores(false, MaxBackends, 0);
31923201

31933202
#ifdef USE_SSL
@@ -3208,7 +3217,7 @@ SubPostmasterMain(int argc, char *argv[])
32083217
/* Close the postmaster's sockets */
32093218
ClosePostmasterPorts(false);
32103219

3211-
/* Attach process to shared segments */
3220+
/* Attach process to shared data structures */
32123221
CreateSharedMemoryAndSemaphores(false, MaxBackends, 0);
32133222

32143223
BootstrapMain(argc - 2, argv + 2);
@@ -3259,6 +3268,7 @@ SubPostmasterMain(int argc, char *argv[])
32593268

32603269
return 1; /* shouldn't get here */
32613270
}
3271+
32623272
#endif /* EXEC_BACKEND */
32633273

32643274

@@ -3767,10 +3777,11 @@ read_inheritable_socket(SOCKET *dest, InheritableSocket *src)
37673777
static void
37683778
read_backend_variables(char *id, Port *port)
37693779
{
3780+
BackendParameters param;
3781+
37703782
#ifndef WIN32
37713783
/* Non-win32 implementation reads from file */
37723784
FILE *fp;
3773-
BackendParameters param;
37743785

37753786
/* Open file */
37763787
fp = AllocateFile(id, PG_BINARY_R);
@@ -3796,25 +3807,23 @@ read_backend_variables(char *id, Port *port)
37963807
id, strerror(errno));
37973808
exit(1);
37983809
}
3799-
3800-
restore_backend_variables(&param, port);
38013810
#else
38023811
/* Win32 version uses mapped file */
38033812
HANDLE paramHandle;
3804-
BackendParameters *param;
3813+
BackendParameters *paramp;
38053814

38063815
paramHandle = (HANDLE)atol(id);
3807-
param = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0);
3808-
if (!param)
3816+
paramp = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0);
3817+
if (!paramp)
38093818
{
38103819
write_stderr("could not map view of backend variables: error code %d\n",
38113820
(int) GetLastError());
38123821
exit(1);
38133822
}
38143823

3815-
restore_backend_variables(param, port);
3824+
memcpy(&param, paramp, sizeof(BackendParameters));
38163825

3817-
if (!UnmapViewOfFile(param))
3826+
if (!UnmapViewOfFile(paramp))
38183827
{
38193828
write_stderr("could not unmap view of backend variables: error code %d\n",
38203829
(int) GetLastError());
@@ -3828,6 +3837,8 @@ read_backend_variables(char *id, Port *port)
38283837
exit(1);
38293838
}
38303839
#endif
3840+
3841+
restore_backend_variables(&param, port);
38313842
}
38323843

38333844
/* Restore critical backend variables from the BackendParameters struct */
@@ -3930,6 +3941,7 @@ ShmemBackendArrayRemove(pid_t pid)
39303941
(errmsg_internal("could not find backend entry with pid %d",
39313942
(int) pid)));
39323943
}
3944+
39333945
#endif /* EXEC_BACKEND */
39343946

39353947

0 commit comments

Comments
 (0)