
current commands; instead, store current-status information in shared memory. This substantially reduces the overhead of stats_command_string and also ensures that pg_stat_activity is fully up to date at all times. Per my recent proposal.
204 lines
5.3 KiB
C
204 lines
5.3 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* ipci.c
|
|
* POSTGRES inter-process communication initialization code.
|
|
*
|
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
*
|
|
* IDENTIFICATION
|
|
* $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.84 2006/06/19 01:51:21 tgl Exp $
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#include "postgres.h"
|
|
|
|
#include "access/clog.h"
|
|
#include "access/multixact.h"
|
|
#include "access/nbtree.h"
|
|
#include "access/subtrans.h"
|
|
#include "access/twophase.h"
|
|
#include "access/xlog.h"
|
|
#include "miscadmin.h"
|
|
#include "pgstat.h"
|
|
#include "postmaster/bgwriter.h"
|
|
#include "postmaster/postmaster.h"
|
|
#include "storage/bufmgr.h"
|
|
#include "storage/freespace.h"
|
|
#include "storage/ipc.h"
|
|
#include "storage/lock.h"
|
|
#include "storage/lwlock.h"
|
|
#include "storage/pg_sema.h"
|
|
#include "storage/pg_shmem.h"
|
|
#include "storage/pmsignal.h"
|
|
#include "storage/proc.h"
|
|
#include "storage/procarray.h"
|
|
#include "storage/sinval.h"
|
|
#include "storage/spin.h"
|
|
|
|
|
|
/*
|
|
* CreateSharedMemoryAndSemaphores
|
|
* Creates and initializes shared memory and semaphores.
|
|
*
|
|
* This is called by the postmaster or by a standalone backend.
|
|
* It is also called by a backend forked from the postmaster in the
|
|
* EXEC_BACKEND case. In the latter case, the shared memory segment
|
|
* already exists and has been physically attached to, but we have to
|
|
* initialize pointers in local memory that reference the shared structures,
|
|
* because we didn't inherit the correct pointer values from the postmaster
|
|
* as we do in the fork() scenario. The easiest way to do that is to run
|
|
* through the same code as before. (Note that the called routines mostly
|
|
* check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
|
|
* This is a bit code-wasteful and could be cleaned up.)
|
|
*
|
|
* If "makePrivate" is true then we only need private memory, not shared
|
|
* memory. This is true for a standalone backend, false for a postmaster.
|
|
*/
|
|
void
|
|
CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
|
|
{
|
|
if (!IsUnderPostmaster)
|
|
{
|
|
PGShmemHeader *seghdr;
|
|
Size size;
|
|
int numSemas;
|
|
|
|
/*
|
|
* Size of the Postgres shared-memory block is estimated via
|
|
* moderately-accurate estimates for the big hogs, plus 100K for the
|
|
* stuff that's too small to bother with estimating.
|
|
*
|
|
* We take some care during this phase to ensure that the total size
|
|
* request doesn't overflow size_t. If this gets through, we don't
|
|
* need to be so careful during the actual allocation phase.
|
|
*/
|
|
size = 100000;
|
|
size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
|
|
sizeof(ShmemIndexEnt)));
|
|
size = add_size(size, BufferShmemSize());
|
|
size = add_size(size, LockShmemSize());
|
|
size = add_size(size, ProcGlobalShmemSize());
|
|
size = add_size(size, XLOGShmemSize());
|
|
size = add_size(size, CLOGShmemSize());
|
|
size = add_size(size, SUBTRANSShmemSize());
|
|
size = add_size(size, TwoPhaseShmemSize());
|
|
size = add_size(size, MultiXactShmemSize());
|
|
size = add_size(size, LWLockShmemSize());
|
|
size = add_size(size, ProcArrayShmemSize());
|
|
size = add_size(size, BackendStatusShmemSize());
|
|
size = add_size(size, SInvalShmemSize());
|
|
size = add_size(size, FreeSpaceShmemSize());
|
|
size = add_size(size, BgWriterShmemSize());
|
|
size = add_size(size, BTreeShmemSize());
|
|
#ifdef EXEC_BACKEND
|
|
size = add_size(size, ShmemBackendArraySize());
|
|
#endif
|
|
|
|
/* might as well round it off to a multiple of a typical page size */
|
|
size = add_size(size, 8192 - (size % 8192));
|
|
|
|
elog(DEBUG3, "invoking IpcMemoryCreate(size=%lu)",
|
|
(unsigned long) size);
|
|
|
|
/*
|
|
* Create the shmem segment
|
|
*/
|
|
seghdr = PGSharedMemoryCreate(size, makePrivate, port);
|
|
|
|
InitShmemAccess(seghdr);
|
|
|
|
/*
|
|
* Create semaphores
|
|
*/
|
|
numSemas = ProcGlobalSemas();
|
|
numSemas += SpinlockSemas();
|
|
PGReserveSemaphores(numSemas, port);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* We are reattaching to an existing shared memory segment. This
|
|
* should only be reached in the EXEC_BACKEND case, and even then only
|
|
* with makePrivate == false.
|
|
*/
|
|
#ifdef EXEC_BACKEND
|
|
Assert(!makePrivate);
|
|
#else
|
|
elog(PANIC, "should be attached to shared memory already");
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Set up shared memory allocation mechanism
|
|
*/
|
|
if (!IsUnderPostmaster)
|
|
InitShmemAllocation();
|
|
|
|
/*
|
|
* Now initialize LWLocks, which do shared memory allocation and are
|
|
* needed for InitShmemIndex.
|
|
*/
|
|
if (!IsUnderPostmaster)
|
|
CreateLWLocks();
|
|
|
|
/*
|
|
* Set up shmem.c index hashtable
|
|
*/
|
|
InitShmemIndex();
|
|
|
|
/*
|
|
* Set up xlog, clog, and buffers
|
|
*/
|
|
XLOGShmemInit();
|
|
CLOGShmemInit();
|
|
SUBTRANSShmemInit();
|
|
TwoPhaseShmemInit();
|
|
MultiXactShmemInit();
|
|
InitBufferPool();
|
|
|
|
/*
|
|
* Set up lock manager
|
|
*/
|
|
InitLocks();
|
|
|
|
/*
|
|
* Set up process table
|
|
*/
|
|
if (!IsUnderPostmaster)
|
|
InitProcGlobal();
|
|
CreateSharedProcArray();
|
|
CreateSharedBackendStatus();
|
|
|
|
/*
|
|
* Set up shared-inval messaging
|
|
*/
|
|
CreateSharedInvalidationState();
|
|
|
|
/*
|
|
* Set up free-space map
|
|
*/
|
|
InitFreeSpaceMap();
|
|
|
|
/*
|
|
* Set up interprocess signaling mechanisms
|
|
*/
|
|
PMSignalInit();
|
|
BgWriterShmemInit();
|
|
|
|
/*
|
|
* Set up other modules that need some shared memory space
|
|
*/
|
|
BTreeShmemInit();
|
|
|
|
#ifdef EXEC_BACKEND
|
|
|
|
/*
|
|
* Alloc the win32 shared backend array
|
|
*/
|
|
if (!IsUnderPostmaster)
|
|
ShmemBackendArrayAllocation();
|
|
#endif
|
|
}
|