对PostgreSQL中后台进程内存挂载的初步学习

开始

从 CreateSharedMemoryAndSemaphores 开始:

对于 Postmaster 的各个子进程而言,内存结构在 Postmaster 中已经建立,只是需要挂到各子进程自己的本地变量上。

/*                            * CreateSharedMemoryAndSemaphores                            *        Creates and initializes shared memory and semaphores.                    *                            * This is called by the postmaster or by a standalone backend.                            * It is also called by a backend forked from the postmaster in the                            * EXEC_BACKEND case.  In the latter case, the shared memory segment                            * already exists and has been physically attached to, but we have to                            * initialize pointers in local memory that reference the shared structures,                            * because we didn't inherit the correct pointer values from the postmaster                            * as we do in the fork() scenario.  The easiest way to do that is to run                            * through the same code as before.  (Note that the called routines mostly                            * check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.                            * This is a bit code-wasteful and could be cleaned up.)                            *                            * If "makePrivate" is true then we only need private memory, not shared                            * memory.    This is true for a standalone backend, false for a postmaster.                        */                            
void                            
CreateSharedMemoryAndSemaphores(bool makePrivate, int port)                            
{                            ……                        /*                        * Set up shmem.c index hashtable                        */                        InitShmemIndex();                        /*                        * Set up xlog, clog, and buffers                        */                        XLOGShmemInit();                        CLOGShmemInit();                        SUBTRANSShmemInit();                        MultiXactShmemInit();                        InitBufferPool();                        /*                        * Set up lock manager                        */                        InitLocks();                        /*                        * Set up predicate lock manager                        */                        InitPredicateLocks();                        /*                        * Set up process table                        */                        if (!IsUnderPostmaster)                        InitProcGlobal();                    CreateSharedProcArray();                        CreateSharedBackendStatus();                        TwoPhaseShmemInit();                        /*                        * Set up shared-inval messaging                        */                        CreateSharedInvalidationState();                        /*                        * Set up interprocess signaling mechanisms                        */                        PMSignalShmemInit();                        ProcSignalShmemInit();                        CheckpointerShmemInit();                        AutoVacuumShmemInit();                        WalSndShmemInit();                        WalRcvShmemInit();                        /*                        * Set up other modules that need some shared memory space                        */                        BTreeShmemInit();                        SyncScanShmemInit();                        AsyncShmemInit();                        #ifdef EXEC_BACKEND                        /*                    * Alloc the win32 shared backend array                    */                    if (!IsUnderPostmaster)                    ShmemBackendArrayAllocation();                #endif                        /*                        * Now give loadable modules a chance to set up their shmem allocations                        */                        if (shmem_startup_hook)                        shmem_startup_hook();                    
}                            

接着看 InitShmemIndex

/*                    *    InitShmemIndex() --- set up or attach to shmem index table.                */                    
void                    
InitShmemIndex(void)                    
{                    HASHCTL        info;        int        hash_flags;        /*                * Create the shared memory shmem index.                *                * Since ShmemInitHash calls ShmemInitStruct, which expects the ShmemIndex                * hashtable to exist already, we have a bit of a circularity problem in                * initializing the ShmemIndex itself.                The special "ShmemIndex" hash* table name will tell ShmemInitStruct to fake it.                */                info.keysize = SHMEM_INDEX_KEYSIZE;                info.entrysize = sizeof(ShmemIndexEnt);                hash_flags = HASH_ELEM;                ShmemIndex = ShmemInitHash("ShmemIndex",                SHMEM_INDEX_SIZE, SHMEM_INDEX_SIZE,&info, hash_flags);
}                    

然后是 ShmemInitHash,重点要关注 hash_flag 的设置

/*                                * ShmemInitHash -- Create and initialize, or attach to, a                                *        shared memory hash table.                        *                                * We assume caller is doing some kind of synchronization                                * so that two processes don't try to create/initialize the same                                * table at once.  (In practice, all creations are done in the postmaster                                * process; child processes should always be attaching to existing tables.)                                *                                * max_size is the estimated maximum number of hashtable entries.  This is                                * not a hard limit, but the access efficiency will degrade if it is                                * exceeded substantially (since it's used to compute directory size and                                * the hash table buckets will get overfull).                                *                                * init_size is the number of hashtable entries to preallocate.  For a table                                * whose maximum size is certain, this should be equal to max_size; that                                * ensures that no run-time out-of-shared-memory failures can occur.                                *                                * Note: before Postgres 9.0, this function returned NULL for some failure                                * cases.  Now, it always throws error instead, so callers need not check                                * for NULL.                                */                                
HTAB *                                
ShmemInitHash(const char *name, /* table string name for shmem index */                                long init_size,    /* initial table size */                long max_size,    /* max size of the table */                HASHCTL *infoP,    /* info about key and bucket size */                int hash_flags)    /* info about infoP */                
{                                bool       found;                        void       *location;                        /*                            * Hash tables allocated in shared memory have a fixed directory; it can't                            * grow or other backends wouldn't be able to find it. So, make sure we                            * make it big enough to start with.                            *                            * The shared memory allocator must be specified too.                            */                            infoP->dsize = infoP->max_dsize = hash_select_dirsize(max_size);                            infoP->alloc = ShmemAlloc;                            hash_flags |= HASH_SHARED_MEM | HASH_ALLOC | HASH_DIRSIZE;                            /* look it up in the shmem index */                            location = ShmemInitStruct(name,                            hash_get_shared_size(infoP, hash_flags),                &found);                /*                            * if it already exists, attach to it rather than allocate and initialize                            * new space                            */                            if (found)                            hash_flags |= HASH_ATTACH;                        /* Pass location of hashtable header to hash_create */                            infoP->hctl = (HASHHDR *) location;                            return hash_create(name, init_size, infoP, hash_flags);                            
}                                

再下来:

/*                            * hash_create -- create a new dynamic hash table                            *                            *    tabname: a name for the table (for debugging purposes)                        *    nelem: maximum number of elements expected                        *    *info: additional table parameters, as indicated by flags                        *    flags: bitmask indicating which parameters to take from *info                        *                            * Note: for a shared-memory hashtable, nelem needs to be a pretty good                            * estimate, since we can't expand the table on the fly.  But an unshared                            * hashtable can be expanded on-the-fly, so it's better for nelem to be                            * on the small side and let the table grow if it's exceeded.  An overly                            * large nelem will penalize hash_seq_search speed without buying much.                            */                            
HTAB *                            
hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)                            
{                            ……                        if (flags & HASH_SHARED_MEM)                        {                        /*                    * ctl structure and directory are preallocated for shared memory                    * tables.    Note that HASH_DIRSIZE and HASH_ALLOC had better be set as                * well.                    */                    hashp->hctl = info->hctl;                    hashp->dir = (HASHSEGMENT *) (((char *) info->hctl) + sizeof(HASHHDR));                    hashp->hcxt = NULL;                    hashp->isshared = true;                    /* hash table already exists, we're just attaching to it */                     if (flags & HASH_ATTACH)                    {                    /* make local copies of some heavily-used values */                hctl = hashp->hctl;                hashp->keysize = hctl->keysize;                hashp->ssize = hctl->ssize;                hashp->sshift = hctl->sshift;                return hashp;                }                    }                        else                        {                        ……                    }                        ……                        return hashp;                        
}                            

[作者:技术者高健@博客园  mail: luckyjackgao@gmail.com ]

结束

转载于:https://www.cnblogs.com/gaojian/archive/2012/11/06/2757116.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/422114.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

四阶龙格积分法 matlab,matlab控制系统计算机仿真实验-完整版

MALTAB 仿真实验指导书实验一实验题目:欧拉法&梯形法的MATLAB 实现实验目的:1.熟练掌握MATLAB 的使用方法2.牢记欧拉法、梯形法的计算过程3.熟悉欧拉法、梯形法以及实现二阶动态响应的程序编写 实验内容:已知被控对象的系数矩阵分别为A[-…

前端学习(590):调试javascript的流程

vs 安装live server插件 第一种方式 第二种方式 使用alert 断点调试debugger 断点调试 断点调试 设置断点

统一管理MOSS2010用户头像

我们都知道MOSS 2010里面的“我的网站”里面有一个上传照片功能,通过那里用户可以方便的上传自己的照片。也可以通过在AD里面上传用户的头像,通过MOSS的 User Profile Service Application 服务进行同步,实现MOSS,Outlook,Lync 头像的统一管理…

开博第一篇-ios

最近在工作之余学习了ios上的编程,感觉3G时代了,自己应该会些时代的东西! 由于是java出身,所以开始看objective-c时很别扭,但慢慢的看的话还是蛮有趣的! 最初买了本ios的编程教程,有点老&#x…

php代码质量怎么提高,如何提高PHP代码的质量?第一部分 自动化工具

重复的代码是不好的,每个人都知道。有时我们错误地创建了这样的代码,我们从来没有注意到它。有时我们这样做是因为我们懒惰。最好是配备一个工具,它可以在构建时提示这个问题。PHPCPD - PHP复制/粘贴检测器。通过运行以下命令来安装它&#x…

第二周周四DailyReporting——PM(李忠)

这几天不知道怎么的,项目一直进展缓慢,心里有些着急,下面是几个总结: (1)数据库来的时候,我们的能否承受大数据的考验; (2)组员这几天都有些闲,不…

matlab多缝夫琅禾费,常见的多缝夫琅禾费衍射.ppt

常见的多缝夫琅禾费衍射* * 5.8 多缝夫琅禾费衍射 所谓多缝是指在一块不透光的屏上,刻有 N 条等间距、等宽度的通光狭缝。夫琅禾费多缝衍射的装置如图所示。其每条狭缝均平行于 y1 方向,沿 x1 方向的缝宽为 a,相邻狭缝的间距为 d,…

php 判断心跳包报错,第29问:MySQL 的复制心跳说它不想跳了

问题最近年末,你们的数据库常常跑批量大事务,会发现复制忽然断开,报错“心跳与本地信息不兼容”: 会是什么缘由?php 实验咱们先来复现一下,再进行分析。html宽油,作一对主从数据库:m…

Linux 常用测试命令

1. cpu info: 2. memory info 3. 下载测试:这里有测试下载文件:wget http://cachefly.cachefly.net/100mb.test 4. 磁盘性能:命令:dd if/dev/zero oftest bs64k count4k oflagdsync 5. cpu负载信息命令:uptime解释: 3个…

php上操作redis,PHP操作redis

$redis new Redis();$redis->connect(localhost, 6379);lget/lindex$redis->lget(arg1, arg2);arg1: list的名字arg2: 获取list值的index,可以是小于零的数,表示从tail到headlinsert$redis->linsert(arg1, arg2, arg3, arg4);arg1: list的名字…

解决未知的服务器标记“asp:ListView”。

在.net 2.0后,微软后续出现了.net 3.0, .net 3.5,记不清是那个版本后,asp.net控件里面就有了asp:ListView这个控件,这个控件运行效率高,配置灵活非常好用,但是在使用的时候,需要在Web.config中进行配置一下…

python求二叉树高度,求二叉树的高度(深度)和宽度

定义二叉树节点public class TreeNode{int val;TreeNode left null;TreeNode right null;public TreeNode(int val){this.val val;}}求二叉树的深度使用递归,分别求出左子树的深度、右子树的深度,两个深度的较大值1public int maxDepth(TreeNode root…

操作系统的版本概况

基于MS-DOS的操作系统: Windows 1.0 Windows 2.0 Windows 3.x Windows 95 Windows 98 Windows ME 基于NT的操作系统: Windows NT 3.x Windows NT 4.0 Windows 2000 Windows XP Windows Vista Windows Server 2003 基于CE的操…

PHP中的stdClass 【转】

如果所有的Class都应该存在于一个默认的层级中的话,那么最顶层应该是最为一般的Class,也就是说极为抽象的,每一个下层的Class均比其上层的Class(即父类)更加专门化。基于该思想,在PHP中,这个顶层…