赣州制作网站企业,怎么制作一个个人网站,一个人看的免费直播大全,网站建设开拓该行业的难点疑动态共享内存是AntDB数据库通信的重要手段#xff0c;本文主要阐述AntDB-T数据库动态共享内存的实现原理、实现方式与使用方法。 AntDB-T数据库是一款企业级通用分布式关系型数据库#xff0c;其数据库内核是基于进程模型实现的#xff0c;因此进程间通信#xff08;IPC本文主要阐述AntDB-T数据库动态共享内存的实现原理、实现方式与使用方法。 AntDB-T数据库是一款企业级通用分布式关系型数据库其数据库内核是基于进程模型实现的因此进程间通信IPC是实现分布式架构间进行任务协作和数据共享的关键。
实现进程间通信的方式有多种例如管道、消息队列、信号量、共享内存等。在程序运行过程中AntDB-T数据库为了实现进程之间更高效的通信和数据传输采用了共享内存的方式。例如AntDB-T数据库在并发任务需要创建多个工作进程的情况下工作进程与后端进程之间的通信和数据传输将通过动态创建的共享内存来实现。 一AntDB-T动态共享内存实现原理
那接下来本部分内容就为各位小伙伴慢慢解析AntDB-T数据库动态共享内存的原理。 AntDB-T动态共享内存是什么
动态共享内存dynamic shared memory简称 DSM在数据库运行期间可以动态创建出来的共享内存动态共享内存允许AntDB-T在运行时动态地分配和释放内存从而提高系统的性能和可伸缩性。 AntDB-T中动态共享内存实现方式
在AntDB-T中动态共享内存的实现方式有多种由dynamic_shared_memory_type参数控制默认是posix是指使用shm_open分配的POSIX shared memory。 图1dynamic_shared_memory_type 配置参数 dynamic_shared_memory_type参数定义如下表 参数名称 dynamic_shared_memory_type 数据类型 enum 默认值 posix 取值范围 {posix,sysv,mmap,windows} 其中posix,sysv,mmap适用于Linux平台 windows适用于Windows平台 参数含义 指定PostgreSQL使用的dynamic shared memory的实现方式。 posix是指使用shm_open分配的POSIX shared memory; sysv是指使用shmget分配的System V shared memory windows是指Windows shared memory mmap是指使用存在的data directory中的memory-mapped files模拟的shared memory。 通常不鼓励使用mmap值这在任何平台上都不是默认值因为操作系统可能会反复将修改过的页面写回磁盘从而增加系统I/O负载但是当pg_dynshmem子目录存储在RAM磁盘上或者其他共享内存工具不可用时它可能对调试有用。 是否可session级修改 否 修改后何时生效 重启AntDB-T instance生效 启用动态内存共享之后当AntDB-T数据库启动后会在/dev/shm目录下有所体现,关了AntDB-T数据库之后这些文件就没有了 图2AntDB-T数据库启动后/dev/shm目录情况 图3AntDB-T数据库关闭后/dev/shm目录情况 AntDB-T为什么要引入动态共享内存
动态共享内存可以在运行时动态地分配和释放内存从而使得内存管理更加灵活和高效并且动态共享内存还可以实现延迟初始化lazy initialization和重新配置reconfiguration等特性从而提高了系统的性能和可伸缩性。 在实际AntDB-T数据库中动态共享内存在很多地方会用到举个例子比如动态共享内存在并行中会用到因为对于并行查询而言执行时创建的DN worker进程与 DN leader进程通过共享内存实现数据交互。但这部分内存无法像普通的共享内存那样在系统启动时预先分配毕竟直到真正执行时才知道有多少 DN worker进程以及需要分配多少内存。动态共享内存即在执行时动态创建用于 DN leader与 DN worker间通信执行完成后释放。 二AntDB-T动态共享内存实现方式
下面将针对动态共享内存机制进行源码说明。本次以AntDB-T的代码为例来解析动态共享内存的实现方式。
在AntDB-T源码中dsm.c、dsm_impl.c文件提供了动态共享内存的功能实现了共享内存的动态申请和释放。动态共享内存通过一个handletypedef uint32 dsm_handle;与一块内存进行映射这个handle是一个32位无符号整数。在创建动态共享内存时需要指定一个handle作为标识符而访问动态共享内存时也是通过这个handle进行访问。不同进程之间通过传递handle来告知对方动态共享内存的位置其他进程则通过handle来访问该动态共享内存。
1.基础数据结构
dsm_control_header和dsm_control_item是动态共享内存里最基础的2个数据结构。定义如下图所示 图4dsm_control_header和dsm_control_item数据结构
dsm_control_header是动态共享内存的控制结构头dsm_control_item记录每个分配的动态共享内存的状态字段nitems表示动态共享内存当前已经使用的数量字段maxitems表示动态共享内存的最大数量字段refcnt表示 /* 2 active, 1 moribund, 0 gone */字段impl_private_pm_handle表示仅在Windows上需要字段pinned表示是否固定动态共享内存段dsm_handle表示动态共享内存段的名字。
dsm_segment表示申请的一个共享内存段对于动态共享内存的api来说这是代表共享内存的最小单位定义如下图所示 图5dsm_segment数据结构
每个后端进程都可以通过使用dsm_segment来访问共享内存dsm_segment包含了内存分配和释放等操作所需的信息并提供了一组函数来管理和操作共享内存每个会话session可以有一个或多个dsm_segment。其中字段mapped_address代表需要返回的当前映射共享内存的起始地址字段resowner表示该动态共享内存段资源所有者control_slot表示在控制动态共享内存段dsm_control_header里面的第几个item。
2.初始化AntDB-T动态共享内存DSM
在 postmaster 主进程启动时调用dsm_postmaster_startup(PGShmemHeader *shim)函数进行动态共享内存相关的初始化其主要逻辑如下 1)计算 dsm_control 结构所需要的内存大小
1计算所需共享内存的最大数量maxitems
maxitemsPG_DYNSHMEM_FIXED_SLOTS PG_DYNSHMEM_SLOTS_PER_BACKEND * MaxBackends 645* MaxBackends
其中PG_DYNSHMEM_FIXED_SLOTS为64PG_DYNSHMEM_SLOTS_PER_BACKEND为5
该值maxitems与 MaxBackends大小有关MaxBackends为最大的backend进程的数量和配置的最大连接数max_connections、autovacuum worker进程的最大个数(autovacuum_max_workers)、并发进程的最大数量max_worker_processes、wal sender process的最大数量有关。
2根据maxitems计算dsm_control 结构所需要的内存大小segsize
segsize dsm_control_bytes_needed(maxitems);
其中函数dsm_control_bytes_needed定义
static uint64dsm_control_bytes_needed(uint32 nitems){ return offsetof(dsm_control_header, item) sizeof(dsm_control_item) * (uint64) nitems;}
2)调用 dsm_impl_op() 函数该函数根据dynamic_shared_memory_type参数调用不同的接口创建用于dsm_control 结构的动态共享内存地址赋值给 dsm_control 变量该变量的类型为 dsm_control_header 。
3)初始化 magic、nitems、maxitems变量其中maxitems 表示AntDB-T该DN节点所有进程能够申请的动态共享内存的最大数量nitems 表示当前已使用的动态共享内存数量每一次动态共享内存申请对应一个 dsm_control_item。
其函数大致调用关系如下
main(int argc, char *argv[])PostmasterMain(int argc, char *argv[])reset_shared(void)CreateSharedMemoryAndSemaphores(void)dsm_postmaster_startup(PGShmemHeader *shim) 3. 清理AntDB-T动态共享内存DSM
在 postmaster 主进程关闭时会调用 dsm_postmaster_shutdown() 函数进行 dsm 的清理这个函数是在初始化动态共享内存dsm_postmaster_startup()时就指定了on_shmem_exit(dsm_postmaster_shutdown, PointerGetDatum(shim)) 清理动态共享内存的主要逻辑首先检查动态共享内存段是否已经损坏如果损坏了就记录错误日志直接返回如果没有损害时就遍历 dsm_control-nitems 数组对其中正在使用的 item 对应的动态共享内存DSM进行销毁 最后再销毁 dsm_control 自身对应的 动态共享内存DSM 内存 。 三AntDB-T动态共享内存实践分享 使用动态共享内存之前需要先对其进行创建。AntDB-T启动时已经初始化好了动态共享内存后面使用的时候只需要创建动态共享内存挂载动态共享内存解除挂载动态共享内存销毁共享内存。AntDB-T数据库使用动态共享内存的地方有很多下面举个最简单的并行查询的例子来解说下如何使用动态共享内存举例的表字段和并行查询的执行计划如下图所示 图6AntDB-T 并行查询的例子
可以从上图的执行计划里面明确看到有使用到了并行查询并且并行的worker个数是2。先进行简单的并行查询的原理介绍图如下所示DN backend主进程拉起从进程DN backend主进程在处理时发现需要进行并行处理就会在启动从进程时会调用 LaunchParallelWorkers 函数这个函数会调用RegisterDynamicBackgroundWorker 此时会给 Postmaster 进程发一个信号请求 Postmaster 进程启动一个 background 进程Postmaster 进程收到信号后就会启动一个新后台进程来处理查询。 图7AntDB-T 并行查询的流程
在 AntDB-T 的源码中上述SQL例子在并行查询中使用动态共享内存DSM其主要逻辑如下
1.DN backend主进程在判断需要进行并行处理时就会初始化并行执行计划ExecInitParallelPlan在ExecInitParallelPlan函数中会评估共享内存大小通过使用shm_toc_estimate_chunk、shm_toc_estimate_keys宏定义向estimate中增加数据结构可以多次调用然后使用shm_toc_estimate得出需要创建的动态共享内存的总大小最后调用 dsm_create()函数 创建动态共享内存DSM。创建并行的工作进程时将动态共享内存DSM对应的 handle 作为参数传递给 并行的worker 进程其调用关系如下
ExecGather(PlanState *pstate)ExecInitParallelPlan(PlanState *planstate, EState *estate, Bitmapset *sendParams, int nworkers, int64 tuples_needed)InitializeParallelDSM(ParallelContext *pcxt)dsm_create(Size size, int flags)LaunchParallelWorkers(ParallelContext *pcxt)worker.bgw_main_arg UInt32GetDatum(dsm_segment_handle(pcxt-seg)); 2.并行的子进程DN worker 进程先调用 dsm_attach() 函数挂载到动态共享内存然后调用函数ParallelQueryMain处理查询业务该函数里面使用了动态共享内存当并行的子进程执行结束时会调用 dsm_detach() 函数解除挂载的 dsm 共享内存其大致的调用关系如下
ParallelWorkerMain(Datum main_arg)seg dsm_attach(DatumGetUInt32(main_arg));ParallelQueryMain(dsm_segment *seg, shm_toc *toc)area dsa_attach_in_place(area_space, seg);dsa_detach(area)dsm_detach(area-segment_maps[i].segment); 总结
本文主要讲述了AntDB-T动态共享内存的基本概念、引入动态共享内存带来的能力提升、基本数据结构、动态共享内存机制原理和使用方法。限于篇幅动态共享内存的其他函数接口比如dsm_pin_mapping、dsm_unpin_mapping、dsm_pin_segment、其他使用动态共享内存的场景、动态共享内存中涉及的锁等相关内容没有涉及小伙伴们请持续关注AntDB数据库公众号。 关于AntDB数据库
AntDB数据库始于2008年在运营商的核心系统上为全国24个省份的10亿多用户提供在线服务具备高性能、弹性扩展、高可靠等产品特性峰值每秒可处理百万笔电信核心交易保障系统持续稳定运行近十年并在通信、金融、交通、能源、物联网等行业成功商用落地。