圈子推荐
查看所有吧>>
活跃用户
    AtlasDB内存上下文的意义

    在程序中,为了更好的控制变量的生命周期,我们会在堆区,而不是栈区来开辟空间,因为栈区只适合开辟临时变量,只有在堆区开辟空间才能延续变量的生存周期;在PG这种复杂的,多进程的程序中,对堆区的申请,管理,与释放有着巨大的挑战:

    内存泄漏与越界的风险

    在多层的,复杂的步骤中,如果没有及时甚至忘记释放内存,对空间利用来说是相当不利的,当一个复杂的程序走完时,我们甚至不知道应该释放哪些空间;并且还要去管理开辟的内存,因为我们后面不知道它到底有多大,要使用变量去记录,防止访问越界。

    利用效率的问题

    在正常使用标准Cmalloc时,系统会自行寻找合适的位置去开辟空间,当多次进行

    malloc或者free时,可能会产生内存碎片,降低利用率,也就是说,在分配以及释放空间时,情况往往不是完全可控的。

    在这种情况下,为了能够解决上述问题,使得对内存空间的操作更加高效,规整,需要有一个对象,专门去管理内存空间,这个对象,在逻辑上将内存空间分成了树状结构,在某个过程可以对应一个结点,便于对此过程的空间进行分配与回收,提升效率,这应该是内存上下文的意义。


    TopMemoryContext

    内存上下文树的顶级结点,是追溯其它上下文的起点,在进程中从来不会被删除或重置,其生命周期与进程一致;并且要避免在此上下文中开辟空间,也不能将其设为当前上下文。

    PostmasterContext

    守护进程(postmaster)的正常工作的内存上下文结点,当一个后端进程被唤起时,可以由被唤起的后端进程来释放一些守护进程创建此后端进程产生的一些副本。

    ErrorContext

    是永久存在的,进入此上下文空间可进行错误恢复操作,当恢复完成时,此上下文的内容会被重置。

    要注意的是,守护进程只存在TopMemoryContextPostmasterContext以及ErrorContext,其它的顶级上下文结点,在后端进程被唤起时才会设置。

     

    CacheMemoryContext

    relcache, catcache相关模块的永久的存储地点,也不可以被删除或者重置,除了调试监测的目的,可以视其为TopMemoryContext

    MessageContext

    存储从前端获取的命令,生命周期与当前命令一致,在PostgresMain的主循环的顶部会被重置,其子结点会被删除。

    TopTransactionContext

    此结点的生命周期与顶级事务的生命周期一致,在顶级事务完成后,此上下文会被重置,子节点会被删除,一般情况下会在CurTransactionContext中开辟空间,涉及到多个子事务的控制信息的存储时,才会用到这里。

    CurTransactionContext

    此上下文结点的信息的生存周期与当前事务的生存周期一致,特别情况,在顶级事务提交时也会用到,当在操作顶级事务时,此指针指向的与TopTransactionContext一致,但是到了子事务中,此指针将指向一个子上下文结点。如果一个子事务终止,其CurTransactionContext也会在终止程序完成后被消除,但是子事务提交时,其CurTransactionContext会保持到顶级事务提交。


    • 分享到:
    排序方式:回复时间 共有4条评论

    十亿少女的梦 发表于 2020-06-01 16:28 1 楼

    改为mysql那种线程模式,这一数据的共享就不是问题了。 by the way, 数据库日志记录shared buffer error, 导致了数据库重启,这个与进程机制有关否

    | 回复

    神奇大叶子 发表于 2020-06-02 15:17 2 楼

    内存上下文是全部进程共享一套,还是一个进程是独立的一套?

    | 回复

    呼哈哈呼 发表于 2020-06-02 15:36 3 楼

    应该不止这些吧,为了方便不同的进程操作内存,不会乱吧

    | 回复

    于贵阳 发表于 2020-06-04 15:47 4 楼

    回复@神奇大叶子 :肯定共用啊,不然有什么意义

    | 回复