PostgreSQL dsm 动态共享内存管理机制

  • 源码版本:PG 13.3
  • 源码文件:dsm.c dsm_impl.c

PostgreSQL 是基于进程模型的数据库内核实现,进程之间的通信、数据传输通常需要借助共享内存实现。在程序运行过程中,比如并发任务需要创建多个工作进程,工作进程与 backend 进程之间的通信、数据传输需要通过动态创建的共享内存实现。在 PG 源码中,dsm (dynamic shared memory)模块就是动态共享内存,实现了共享内存的动态申请,动态释放。

dsm 内存实际上就是通过一个 handle 与一块内存进行映射,handle 是一个 unsigned int 的 32 位整数。创建 dsm 时指定一个 handle,访问 dsm 时也是通过这个 handle 进行访问。不同进程之间通过传递 handle 来告诉对方 dsm 内存在哪里,其他进程通过 handle 进行 dsm 的访问。

1. 初始化 dsm

在 postmaster 主进程启动时,调用 dsm_postmaster_startup() 函数,进行 dsm 相关的初始化,主要逻辑如下:

  1. 计算 dsm control 结构所需要的内存大小,该值与 MaxBackends 大小有关
  2. 调用 dsm_impl_op() 函数创建用于 dsm control 结构的 dsm 共享内存,赋值给 dsm_control 变量,该变量的类型为 dsm_control_header
  3. 初始化 maxitems 和 nitems,maxitems 表示 PG 所有进程能够申请的 dsm 最大数量,nitems 表示当前已使用的数量,每一次 dsm 申请,对应一个 dsm_control_item

dsm_control_header 结构如下:

typedef struct dsm_control_header { uint32 magic; uint32 nitems; uint32 maxitems; dsm_control_item item[FLEXIBLE_ARRAY_MEMBER]; } dsm_control_header;