- 浏览: 231039 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
chenxliang:
2016年10月26、27日,上海浦东,Postgres中国用 ...
PostgreSQL的用户、角色和权限管理 -
gejiod:
最近出了SQL:2011標準,希望樓主也更新下
SQL2008标准 -
lincon77:
太长了,又是E文,要是有些例子可能好理解些
SQL2003标准 -
少主丶无翼:
很谢,找了很久
SQL2003标准 -
zeeeitch:
...
PostgreSQL启动过程中的那些事七:初始化共享内存和信号二十:shmem中初始化堆同步扫描、pg子进程相关结构
pg 现在要初始化另一块内存——共享内存 shared memory (以后 shared memory 有时会简写成 shmem ),在这块内存里, pg 存放数据、锁、各种 backend 进程等。
1 先上个图,看一下函数调用过程梗概,中间略过部分细节
初始化共享内存方法调用流程图
2 计算 shared memory 大小
话说 main()-> … ->PostmasterMain()-> … ->reset_shared() ,在 reset_shared () 这个函数里, pg 首先计算干 xxx 一堆事需要的内存大小 size ,然后分之。
首先我们看看都计算了哪些内存, 估算使用动态哈希表管理共享内存需要的内存;计算数据池及管理需要的内存(根据shared_buffer );计算锁表需要的共享内存;计算xlog 、clog 需要的共享内存;计算共享进程、子事务、并发控制、轻量级锁、backend 进程、后台写等需要的共享内存等,这些共享内存统统累加到size 。计算shared memory 共享内存代码如下:
size = 100000;
size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
sizeof (ShmemIndexEnt)));
size = add_size(size, BufferShmemSize());
size = add_size(size, LockShmemSize());
size = add_size(size, ProcGlobalShmemSize());
size = add_size(size, XLOGShmemSize());
size = add_size(size, CLOGShmemSize());
size = add_size(size, SUBTRANSShmemSize());
size = add_size(size, TwoPhaseShmemSize());
size = add_size(size, MultiXactShmemSize());
size = add_size(size, LWLockShmemSize());
size = add_size(size, ProcArrayShmemSize());
size = add_size(size, BackendStatusShmemSize());
size = add_size(size, SInvalShmemSize());
size = add_size(size, BgWriterShmemSize());
size = add_size(size, BTreeShmemSize());
size = add_size(size, SyncScanShmemSize());
size = add_size(size, ShmemBackendArraySize());
2 分配并初始化 shared memory
计算好需要的共享内存大小 size 后调用 PGSharedMemoryCreate() 函数分配共享内存。 PGSharedMemoryCreate() 函数创建给定大小的共享内存段并初始化一个 PGShmemHeader 结构类型标准头,且给释放内存注册回调函数。如果发现死 postgres 段就回收,但是和非 postgres 内存段碰撞后 pg 不会失败。这儿的想法是检测和重用崩溃的 postmaster 或 backend 进程已经分配的 key 。
PGSharedMemoryCreate () 分配内存是先根据 postmaster 进程端口号计算找一个空闲 IPC key 的起始值。接着调用 InternalIpcMemoryCreate() 函数, 尝试根据给定 IPC key 调用 shmget() 函数 创建共享内存段。如果给定 key 的内存段已经存在就失败返回 NULL 。如果成功,把该内存段 attach 到当前进程 postmaster 并返回该内存段地址。调用 on_shmem_exit() 函数注册 detach 和 delete 该段内存时的回调函数 IpcMemoryDelete() 和IpcMemoryDetach() 到on_shmem_exit_list 数组 。
on_shmem_exit() 函数注册函数到以 ONEXIT 结构为元素的数组on_shmem_exit_list[MAX_ON_EXITS] 中以供shmem_exit() 函数执行时调用。ONEXIT 结构结构定义见下面。
static struct ONEXIT
{
void (*function) (int code, Datum arg);
Datum arg;
} on_proc_exit_list[MAX_ON_EXITS], on_shmem_exit_list[MAX_ON_EXITS];
接着调用RecordSharedMemoryInLockFile() 函数把IPC key 和shmid 记录到postmaster.pid 文件,然后从InternalIpcMemoryCreate() 返回到 PGSharedMemoryCreate() 函数,再接着在分配到的共享内存的头部放一个 PGShmemHeader (结构定义见下面)结构实例并初始化其成员,使全局静态PGShmemHeader * 类型变量ShmemSegHdr 指到这个结构。然后调用PGReserveSemaphores() 函数分配存放信号的数组需要的内存到mySemSet 数组并用 on_shmem_exit() 函数注册 ReleaseSemaphores() 函数 到on_shmem_exit_list 数组,这个数组大小和backend 进程数有关。
typedef struct PGShmemHeader /* standard header for all Postgres shmem */
{
int32 magic; /* magic # to identify Postgres segments */
#define PGShmemMagic 679834894
pid_t creatorPID; /* PID of creating process */
Size totalsize; /* total size of segment */
Size freeoffset; /* offset to first free space */
void *index; /* pointer to ShmemIndex table */
#ifndef WIN32 /* Windows doesn't have useful inode#s */
dev_t device; /* device data directory is on */
ino_t inode; /* inode number of data directory */
#endif
} PGShmemHeader;
现在到了 InitShmemAllocation() 函数,调用SpinLockInit() 给该共享内存初始化spinlock 锁ShmemLock 以备shmem 分配时使用。再调用ShmemAlloc() (这个涉及到pg 的另一块内存——共享内存/shared memory/shmem 的管理机制,到pg 的内存管理机制时在讨论。共享内存占pg 整个使用内存的90% 以上)给事务管理器transaction manager 在shmem 上分配一个VariableCacheData 类型的空间赋给VariableCacheData * 类型变量ShmemVariableCache 以备后用。
接着调用CreateLWLocks() 计算需要的LWLock 锁(关于pg 中的锁到并发控制的时候再讨论)的数目,并根据计算的数目分配LWLock 数组需要的空间。每个内存块(根据设定,一般8k )需要两个LWLock ,还有clog 、subtrans 等需要的,这个数目会比较大,在我PC 上shared_buffer 是200MB 时这个数目是50,000+ 。
3 分配并初始化 shmem 索引 "ShmemIndex" ——可扩展哈希表
下来调用InitShmemIndex() 初始化一个pg 的可扩展哈希表(见pg 中的数据结构一) "ShmemIndex" 作为共享内存/shared memory/shmem 的索引。Pg 基于该索引表 "ShmemIndex" 管理shmem 内存。这里就是HTAB 、HASHHDR 、HashSegment 、HashBucket 、HashElemen 等等一堆招呼,可扩展哈希表 "ShmemIndex" 诞生了。其中的HTAB 在TopMemoryContext 里,其它在shmem 里, "ShmemIndex" 哈希表里存的是ShmemIndexEnt 类型实例,记录shmem 里每个内存块的名字、大小及偏移信息。按默认信息创建的 "ShmemIndex" 哈希表可以管理64M 以上个内存片段(每个哈希桶的开链表按1 个元素计算),结构见下图。
typedef struct
{
char key[SHMEM_INDEX_KEYSIZE]; /* string name */
void *location; /* location in shared mem */
Size size; /* # bytes allocated for the structure */
} ShmemIndexEnt;
static PGShmemHeader *ShmemSegHdr; /* shared mem segment header */
共享内存及其索引 "ShmemIndex" 结构图
这一节就到这儿吧。
发表评论
-
PostgreSQL服务过程中的那些事三:pg服务进程中的内存上下文
2012-12-31 15:07 2065题外话:年底了,就以这篇博文结束2012 ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询六:执行器执行
2012-11-07 20:13 1824话说 查询“ select c ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询五:规划成plantree
2012-10-31 20:37 1733话说 查询“ select cname, comp ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询四:分析重写成querytree
2012-10-24 19:27 1437话说 查询“ select cname, comp ... -
postgresql 小技巧
2012-10-16 19:36 1382Note : #PostgreSQL and ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询三:获取内存快照
2012-10-16 19:31 1762话说 查询“ select cname, comp ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询二:SQL解析为parsetree
2012-10-09 19:50 1532话说 查询“ select cname, comp fr ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询一:开启事务
2012-09-25 19:55 1887在《 PostgreSQL 服务过程中的那些事二: ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程一.八:加载DB基础设施,完成服务进程初始化
2012-09-18 21:02 1805话说调用 InitPostgres ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程一.七:初始化portal管理环境
2012-09-11 19:58 1631话说调用 In ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程一.六:初始化系统表缓存catcache
2012-09-04 20:51 1856话说调用 InitPostgres ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程一.五:初始化relcache管理环境
2012-08-28 20:47 1314话说调用 InitPostgres ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程三:初始化relcache管理环境
2012-08-28 20:46 0<!-- [if gte mso 9]><x ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询梗概
2012-08-21 21:04 1258话说客户端发起请求, pg 服务器为该请求启动一个 ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程二:建立连接完成
2012-08-13 18:50 15773 这节主要讨论 pg 服务进程 pos ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程一
2012-08-08 14:42 5687到pg 服务进程了,打算搞一个完整但简单的查询例子,从 ... -
PostgreSQL启动过程中的那些事十九:walwriter进程二
2012-08-03 16:53 13813 这节主要讨论 walwrit ... -
PostgreSQL启动过程中的那些事十九:walwriter进程一
2012-08-01 17:26 1614话说 main()->Po ... -
PostgreSQL启动过程中的那些事十八:bgwriter进程二
2012-07-27 07:25 14323 这节主要讨论 bgwr ... -
PostgreSQL启动过程中的那些事十八:bgwriter进程一
2012-07-23 20:18 1642话说 main()->Postm ...
相关推荐
在这个“共享内存实现代码shmem”的示例中,我们将深入探讨如何在编程中创建、写入和读取共享内存。 首先,我们要知道在Unix-like系统(如Linux)中,共享内存主要通过`sys/shm.h`头文件中的函数来操作,比如`...
1. **引入锁机制**:为了解决并发访问的问题,可以在创建和删除共享内存时引入自旋锁或读写锁,保证在保存和恢复过程中的数据一致性。 2. **内存映射和物理分布**:需要记录每个共享内存段的物理地址和映射信息,...
py_boost_shmem 在boost :: interprocess和Python的mmap之间映射共享内存的示例。 我在将python(使用mmap模块)中的共享内存连接到使用boost :: interprocess创建的C ++中的共享内存时遇到问题。 我开始工作了,想...
标题“shmem_fs.rar_memory”涉及的是Linux内核中的共享内存(Shared Memory)子系统,尤其是与内存管理相关的部分。共享内存是一种高效的进程间通信(IPC, Inter-Process Communication)机制,它允许多个进程直接...
libandroid-shmem 在使用ashmem在Android上进行System V共享内存(shmget,shmat,shmdt和shmctl)仿真。 它创建的共享内存段将在创建过程销毁它们或死时自动销毁,这与System V共享内存行为不同。 基于先前工作。...
利用信号量实现的共享内存同步实验,详看博客
下面通过一个示例来展示如何使用`multiprocessing`模块中的`RawArray`对象创建一个共享内存数组,并将其转换为NumPy数组格式: ```python import ctypes import multiprocessing as mp import numpy as np # 创建...
glance的Memory Report中,Text、Data、Stack和Shmem分别代表程序的可执行代码、动态分配的数据、局部变量和共享内存。"Other"则涵盖了非以上四类的内存,比如MEMMAP(内存映射,包括动态链接库的代码和数据部分)、...
共享内存的基础实验代码,详看博客http://blog.csdn.net/mybelief321
shmaps持久共享内存键值存储,支持自定义STL容器和TTL。提出的解决方案使您可以在共享内存段中组织多个独立的映射(键-值)存储。基于boost / interprocess和libcuckoo无锁映射。局限性:您不能将STL容器用于键或值...
详情看博客http://blog.csdn.net/mybelief321/article/details/9170041
- `src/backend/utils/misc/pg_shmem.c`文件中实现了共享内存的相关功能,这对于多进程之间的通信非常重要。 #### 五、PostgreSQL与MySQL对比 **1. PostgreSQL文件目录组织**: - 整体代码结构清晰,遵循了良好的...
中,文章列举了几个关键的读写函数,如`REG_RD/REG_WR`用于读取和写入PCI内存地址,`bnx2_reg_rd_ind()/bnx2_reg_wr_ind()`用于基于端口索引的读写操作,`Bnx2_shmem_rd()/bnx2_shmem_wr()`访问MCP的共享内存,以及`...
- **SHMEM**: 共享内存,用于实现虚拟化环境中不同操作系统之间的数据交换。 #### 三、配置步骤详解 ##### 1. 安装WindRiver Workbench (on host) - 在主机上安装WindRiver Workbench,安装过程中可参考默认配置...
本文介绍在nginx的代码中与共享内存相关的功能,包括ngx_shmem与ngx_slab的使用与注意事项,但不包括ngx_slab中实现的内存管理算法。 ngx_shmem的使用 ngx_shmem.c/h文件只是对mmap()/munmap()系统调用或者shmget()...
在Java开发过程中,调试是确保程序正确性和性能优化的关键步骤之一。通过合理设置Java调试参数,开发者可以在开发、测试甚至生产环境中对Java应用程序进行远程调试,这对于定位问题、理解程序运行时的行为至关重要。...
"dt_shmem"使用共享内存,适用于同一主机上的进程间通信;"dt_pipe"则通过命名管道进行通信,同样适用于本地调试场景。 当开发者在调试Java应用时,可以通过指定-JDWP选项来配置JDWP Transport,例如: ``` java -...
- **SHMEM_MAGIC**:提供更大的共享内存空间,特别适用于需要大量共享内存的应用场景,比如分布式计算环境。 综上所述,HP-UX中的内存管理机制提供了灵活的内存布局选择,以适应不同类型的可执行文件和应用程序的...
在PostgreSQL初始化时,它会检查全局函数指针ClientAuthentication_hook是否被设置,如果已经设置,则在客户端认证过程中执行它。 此外,还有一些钩子是专门为了优化查询性能而设计的。例如,explain_get_index_...