在pg启动的时候,会初始化共享内存,下面看下过程
在postmaster中使用下面的调用进入初始化过程
/*
* Set up shared memory and semaphores.
*/
reset_shared(PostPortNumber);
传入的是端口号,每次启动的时候,都是根据这个端口号来分配相同的IPC key,
CreateSharedMemoryAndSemaphores(false, port);
这个函数初始化共享内存和信号量
第一个参数是判断创建共享内存还是私有内存
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, PMSignalShmemSize());
size = add_size(size, BgWriterShmemSize());
size = add_size(size, AutoVacuumShmemSize());
size = add_size(size, BTreeShmemSize());
size = add_size(size, SyncScanShmemSize());
ifdef EXEC_BACKEND
size = add_size(size, ShmemBackendArraySize());
endif
开始初始化100k的大小,然后把各个部分需要的内存都加上
比如buffer size 的大小,有data page,buffer描述符,hash表
/*
* BufferShmemSize
*
* compute the size of shared memory for the buffer pool including
* data pages, buffer descriptors, hash tables, etc.
*/
Size
BufferShmemSize(void)
{
Size size = 0;
/* size of buffer descriptors */
size = add_size(size, mul_size(NBuffers, sizeof(BufferDesc)));
/* size of data pages */
size = add_size(size, mul_size(NBuffers, BLCKSZ));
/* size of stuff controlled by freelist.c */
size = add_size(size, StrategyShmemSize());
return size;
}
define BLCKSZ 8192默认8k
接着是创建共享内存段,初始化访问
/*
* Create the shmem segment
*/
seghdr = PGSharedMemoryCreate(size, makePrivate, port);
InitShmemAccess(seghdr);
在pgsharedmemorycreate中使用
/* Try to create new segment */
memAddress = InternalIpcMemoryCreate(NextShmemSegID, size);来创建新的共享内存段
* Attempt to create a new shared memory segment with the specified key.
* Will fail (return NULL) if such a segment already exists. If successful,
* attach t