PostgreSQL启动过程中的那些事七:初始化共享内存和信号十五:shmem中初始化ProcSignal

       这一节 pg 初始化非 postmaster 进程间发送信号用到的相关结构,在共享内存里通过信号交互,通过 ProcSignalShmemInit 例程实现 。主要是初始化了 MaxBackends + NUM_AUXPROCTYPES =164 (默认是100+64 个,可以设置) ProcSignalSlot 结构的数组,以供非 postmaster 进程之间互动互操作。

 

1 先上个图,看一下函数调用过程梗概,中间略过部分细节


初始化 ProcSingal 方法调用流程图

 

2 初始化 xlog 相关结构

话说 main()-> ->PostmasterMain()-> ->reset_shared() -> CreateSharedMemoryAndSemaphores()> -> ProcSignalShmemInit() ,调用 ShmemInitStruct() 在其中 调用 hash_search() 在哈希表索引 "ShmemIndex" 中查找 "ProcSignalSlots" ,如果没有,就在 shmemIndex 中给 "ProcSignalSlots" 分一个 HashElement ShmemIndexEnt entry ,在其中的 Entry 中写上 "ProcSignalSlots" 。返回 ShmemInitStruct() ,再调用 ShmemAlloc() 在共享内存上给 "ProcSignalSlots" 相关结构(见下面“ ProcSignalSlots 相关结构图” )分配空间,设置 entry (在这儿及ShmemIndexEnt 类型变量)的成员 location 指向该空间, size 成员记录该空间大小 最后返回 ProcSignalShmemInit () ,让 ProcSignalSlot * 类型静态 全局变量 ProcSignalSlots 指向 所分配内存 ,初始化ProcSingalSlot 结构类型的成员值为0

相关结构定义和图见下面:

 

每一个想要接受信号的进程把自己的PID 注册到 ProcSignalSlots 数组。为了分配槽简单,也为了避免在知道要发给信号的进程ID 的情况下搜索数组,这个数组有一个backend 进程ID 构成的索引。

typedef struct

{

    pid_t       pss_pid ;

    sig_atomic_t pss_signalFlags [ NUM_PROCSIGNALS ];

} ProcSignalSlot ;

 

信号在各操作系统中是不同的。下面是各系统的信号类型PGSemaphoreData 的定义。

POSIX 标准的 PGSemaphoreData 的定义:

typedef sem_t PGSemaphoreData;

SYSV 标准的 PGSemaphoreData 的定义:

typedef struct PGSemaphoreData

{

    int         semId;          /* semaphore set identifier */

    int         semNum;         /* semaphore number within set */

} PGSemaphoreData;

Windows 系统 PGSemaphoreData 的定义:

typedef HANDLE PGSemaphoreData;

 

初始化完 ProcSignalSlots 相关结构 的共享内存结构图

       为了精简上图,把创建 shmem 的哈希表索引 "ShmemIndex" 时创建的 HCTL 结构删掉了,这个结构的作用是记录创建可扩展哈希表的相关信息,不过这个结构在 "ShmemIndex" 创建完成后也会由于出了对象作用域而消失。增加了左边灰色底的部分,描述 共享内存 /shmem 里各变量物理布局概览,由下往上,由低地址到高地址。 图中黄色的索引项就是本节新增加的索引项。

ProcSignalSlots 相关结构图

猜你喜欢

转载自beigang.iteye.com/blog/1461977
今日推荐