Postgresql源码(90)共享内存申请CreateSharedMemoryAndSemaphores

Postgresql启动后申请两段内存,在启动时会判断系统支持情况,默认是使用mmap申请共享内存。

  • mmap申请匿名内存块,直接继承给子进程使用,头部放PGShmemHeader结构记录使用情况。
    • 《Linux内存映射函数mmap与匿名内存块》
  • ipc的共享内存,只申请PGSharedMemoryCreate大小。
    • 《Linux共享内存与子进程继承》

Postgresql的共享内存在9.2以后就是使用mmap申请的了,在少数情况下使用ipc的共享内存。

下面在CreateSharedMemoryAndSemaphores中初始化的数据结构,都是在父进程中初始化好,直接继承给子进程使用的。

mmap内存块使用情况:

0x2aaaaac00000[mmap] -----------------------          <-- ShmemSegHdr / ShmemBase
	                   PGShmemHeader
	                     int32    magic;
	                     pid_t    creatorPID;
	                     Size     totalsize;
	                     Size     freeoffset;
	                     dsm_handle  dsm_control;
	                     void     *index;
freeoffset=56     -> - - - - - - - - - - - -		      <-- sharedSemas(信号量:一个进程一个sem_t)
	                   PGSemaphoreData(128B)      
	                   PGSemaphoreData
	                   ...(2035+5)
	                   PGSemaphoreData
freeoffset=261176 -> - - - - - - - - - - - -          <-- ShmemLock(spinlock:一个slock_t)
                     slock_t(1B)                          (后面可以使用ShmemAlloc)
                     (只用1B但按8B对齐)                    (前面没锁只能用ShmemAllocUnlocked)
freeoffset=261184    - - - - - - - - - - - -          <-- ShmemVariableCache(关键全局计数器)
                     VariableCache
freeoffset=261376    - - - - - - - - - - - -          
	                   LWLOCK
	                   ...
freeoffset=288256	   - - - - - - - - - - - -          <-- ShmemIndex(key:48B/val:ShmemIndexEnt)
                     ShmemInitHash("ShmemIndex")          (共享内存索引哈希表)
                                                          (哈希表初始化好了,后面用ShmemInitStruct申请共享内存)
                                                          (前面使用ShmemAlloc申请)
                                                          (后面使用ShmemInitStruct调用ShmemAlloc申请)
freeoffset=298880    - - - - - - - - - - - -          <-- XLogCtl(XLOG和写BUFFER)
                     XLogCtlData
                     ...
freeoffset=4507136   - - - - - - - - - - - -          <-- ControlFile(控制文件)
                     ControlFileData
freeoffset=4507520   - - - - - - - - - - - -          <-- SharedStats
                     XLogPrefetchStats
freeoffset=4507648   - - - - - - - - - - - -
                     ...
                     ...
                     ...
                     ...
                     ...
	                   
0x2aaabea00000       ----------------------- [mmap]   <-- ShmemEnd
	                   ...

IPC的共享内存:

在当前例子中,IPC的共享内存只申请了一个PGShmemHeader的空间,没有其他空间可以使用。
0x7fc90a686000       ----------------------- [shmget] <-- InternalIpcMemoryCreate / UsedShmemSegAddr
	                        PGShmemHeader
	                 -----------------------

其中

  • freeoffset:在PGShmemHeader结构中记录空闲起始位置
  • ShmemLock
    • 这个步骤会申请一把spinlock
    • 在这个步骤前,只能使用ShmemAllocUnlocked无锁申请共享内存
    • 在这个步骤后,使用ShmemAlloc申请共享内存
  • ShmemIndex
    • 这个步骤会创建哈希表,key是48B的字符串,val就是共享内存的位置,相当于索引表。
    • 在这个步骤前,直接使用ShmemAlloc申请共享内存,调整freeoffset位置
    • 在这个步骤后,使用ShmemInitStruct申请共享内存,先在哈希表中创建一个索引条目,在使用ShmemAlloc调整freeoffset位置。

你可能感兴趣的:(pgsql,postgresql,数据库)