PostgreSQL的内存管理机制十二:共享内存/shmem分配

pg 的内存除了 AllocSet/MemoryContext 外,另一个主要部分就是共享内存(shared memory )。这一节讨论共享内存(简写shmem )的分配。

pg reset_shared () 这个函数里, 计算数据缓冲、xlogclog 、共享进程、子事务、并发控制、轻量级锁、backend 进程等需要的共享内存, 调用 shmget() 函数在堆上分配, PGShmemHeader * 类型的 ShmemSegHdr 变量的index 成员指向调用hash_create() 创建的共享内存索引——可扩展 哈希表索引 "ShmemIndex" totalSize 成员中记录分配的shmem 大小。

有了共享内存和共享内存索引,再加上一个共享内存锁(关于此锁及pg 中的其它锁,是一个需要很多字才能讨论清楚的点,以后专门讨论),就可以分配共享内存了。

分配共享内存时,先把要分配内存的结构做对齐处理,然后回去共享内存锁,接着判断要分配的内存大小,大于8k 的需要做块对齐,从共享内存的空闲共享内存偏移量处分配所需大小内存,判断所分配内存是否 超过了共享内存的末尾地址,如果超过,释放锁,报错 "out of shared memory" ,如果没有超过, 释放锁,设置新的 空闲共享内存偏移量,返回分配的共享内存地址。

 

 

PostgreSQL的内存管理机制十二:共享内存/shmem分配_第1张图片

 

共享内存分配流程图

 

    到这儿貌似共享内存分配很简单,已经讨论完,其实不然,通常分配共享内存时还需要在共享内存索引表"ShmemIndex" 加一个索引,为了清楚,再把这个索引图放到下面,复习一下。

PostgreSQL的内存管理机制十二:共享内存/shmem分配_第2张图片

共享内存及其索引 "ShmemIndex" 结构图

 

下面举个在shmem 上分配xlog 相关内存的例子,串一下分配的过程。

XLOGSHmemInit() 分配xlog 相关内存 ,初始化控制文件 data/global/pg_control 相关数据结构及事务日志 xlog 相关数据结构,在 XLOGSHmemInit() 函数里,首先在 shmem 的哈希表索引 "ShmemIndex" 上给控制文件 pg_control 增加一个 HashElement ShmemIndexEnt entry ), shmem 里根据 ControlFileData 大小调用 ShmemAlloc() 分配内存空间,使 ShmemIndexEnt 的成员 location 指向该空间, size 成员记录该空间大小

XLOGSHmemInit() 调用 ShmemInitStruct() 在其中 调用 hash_search() 在哈希表索引 "ShmemIndex" 中查找 "XLOG Ctl" ,如果没有,就在 shmemIndex 中给 "XLOG Ctl" 分一个 HashElement ShmemIndexEnt entry ,在其中的 Entry 中写上 "XLOG Ctl" 。返回 ShmemInitStruct() ,再调用ShmemAlloc() 在共享内存上给"XLOG Ctl" 相关结构(见下面“ XLog 相关结构图” )分配空间,设置 entry (在这儿及ShmemIndexEnt 类型变量)的成员 location 指向该空间, size 成员记录该空间大小 最后返回 XLOGShmemInit() ,让 XLogCtlData * 类型静态 全局变量 XLogCtl 指向在shmem 里给"XLOG Ctl" 相关结构分配的内存地址。

增加了xlog 相关结构在 "ShmemIndex" 中的索引及在共享内存/shmem 中分配了内存的xlog 相关结构对象的结构如下。

 
PostgreSQL的内存管理机制十二:共享内存/shmem分配_第3张图片

增加了xlog 相关机构索引的共享内存索引 "ShmemIndex" 结构图

 

 

PostgreSQL的内存管理机制十二:共享内存/shmem分配_第4张图片

 

控制文件结构图

       上图中 ControlFileData 结构中的 XLogRecPtr CheckPoint 不是指针,因此应该用右边的相应结构图代替,把这两个合进去有点费劲,将就着看吧。

 

 

PostgreSQL的内存管理机制十二:共享内存/shmem分配_第5张图片

 

XLog 相关结构图

 

你可能感兴趣的:(PostgreSQL内核)