HybridDB · 源码分析 · MemoryContext 内存管理和内存异常分析-阿里云开发者社区

开发者社区> db匠> 正文

HybridDB · 源码分析 · MemoryContext 内存管理和内存异常分析

简介: 背景 最近排查和解决了几处 HybridDB for PostgreSQL 内存泄漏的BUG。觉得有一定通用性。 这期分享给大家一些实现细节和小技巧。 阿里云上的 HybridDB for PostgreSQL 是基于 PostgreSQL 开发,定位于 OLAP 场景的 MPP 架构数据库集群。它不少的内部机制沿用了 PostgreSQL 的实现。其中就包括了内存管理机制 MemoryCont
+关注继续查看

背景

最近排查和解决了几处 HybridDB for PostgreSQL 内存泄漏的BUG。觉得有一定通用性。
这期分享给大家一些实现细节和小技巧。

阿里云上的 HybridDB for PostgreSQL 是基于 PostgreSQL 开发,定位于 OLAP 场景的 MPP 架构数据库集群。它不少的内部机制沿用了 PostgreSQL 的实现。其中就包括了内存管理机制 MemoryContext。

一:PostgreSQL 内存管理机制

PostgreSQL 对内存的使用方式主要分两大块

1. shared_buffer 和同类 buffer。 简单的说 shared_buffer 用于存放数据页面对应数据文件中的 block,这部分内存是 PostgreSQL 中各进程共享。这部分不在本文讨论。
2. MemoryContext 以功能为单位组织起来的树形数据结构,不同的阶段使用不同的 MemoryContext。

1. MemoryContext 的作用

简单的说 MemoryContext 的存在是为了更清晰的管理内存

  • 合理管理碎片小内存。频繁的向 OS 申请和释放内存效率是很差的。MemoryContext 会以 trunk 为单位向 OS 申请成块的内存,并管理起来。当程序需求小内存时从 trunk 中分配,用完后归还给对应的 MemoryContext ,并不归还给 OS。
  • 赋予内存功能和生命周期属性
    • 以功能为单位管理内存。不同功能和阶段使用对应的 MemoryContext。
    • TopTransactionContext:一个事务的生命周期,事务管理相关数据放在 TopTransactionContext,当一个事务提交时该上下文被整个释放。
    • ExprContext PostgreSQL 以行为单位处理数据,每一行数据的表达式计算都会在 ExprContext 完成,每处理完一行都会重置对应的 ExprContext。
  • 树形的 MemoryContext 结构
    • 不同功能间的 MemoryContext 是以为树为单位组织起来的
    • 每个数据库后端进程顶层是 TopMemoryContext
    • TopMemoryContext 下有很多子 Context
      • 缓存相关的 CacheMemoryContext;
      • 本地锁相关的 LOCALLOCK hash;
      • 当前事务相关的 TopTransactionContext
      • 注意 CacheMemoryContext 为何不属于 TopTransactionContext,那是由于 Cache 是独立于事务存在的,事务提交不影响 Cache 的存在。
    • 删除或重置一个 MemoryContext,它的子 MemoryContext 也一并被删除或重置。

2. 不同模块的 MemoryContext

你可能明白了,实现不同的模块时,对待内存的方式可能区别很大。
比如:

1. 执行器在做表达式计算时,一些诸如字符串类型数据处理的函数,大多会比较随意的使用 palloc 分配内存,但直到函数返回,却并没有释放它们。
2. 在处理缓存模块处理数据时,却倍加小心的释放内存。

这是由于:

1. 执行器对数据的处理是以行为单位,都在 ExprContext 中,每处理完一行,会重置 ExprContext,以此释放相关的内存。
2. 缓存的生命周期很长,不会定期重置整个 MemoryContext。哪怕少量的内存泄漏,积攒的后果都很严重。这部分的实现容易出问题,也不好排查。

3. 常见的内存问题

虽然有很好的内存管理机制,但进程中内存间没有强隔离,也可能出现内存问题。

造成内存泄漏的原因很大可能是:

1. 在较长生存周期的 MemoryContext 中正常处理流程中没有释放内存。
2. 由于发生了异常,跳转到在异常处理阶段没有释放内存。
3. 没有使用内存管理机制,使用 OS 调用 malloc,free 处理内存(某些实现不合理的插件中可能出现)。
4. 在不正确的 MemoryContext 分配了内存,导致内存泄漏或数据丢失。
5. 写内存越界,这是最难找的问题,很容易造成数据库崩溃。

4. 问题排查小技巧

针对内存泄漏,常用两种方法排查

1. valgrind 最常见的大杀器,开发人员都懂的。这里就不详细介绍了。

2. 使用 GDB 也能大致定位问题

2.1 这是一段脚本,我们把它保存成文本文件(pg_debug_cmd)

define sum_context_blocks
set $context = $arg0
set $block = ((AllocSet) $context)->blocks
set $size = 0
while ($block)
set $size = $size + (((AllocBlock) $block)->endptr - ((char *) $block))
set $block = ((AllocBlock) $block)->next
end
printf "%s: %d\n",((MemoryContext)$context)->name, $size
end

define walk_contexts
set $parent_$arg0 = ($arg1)
set $indent_$arg0 = ($arg0)
set $i_$arg0 = $indent_$arg0
while ($i_$arg0)
printf " "
set $i_$arg0 = $i_$arg0 - 1
end
sum_context_blocks $parent_$arg0
set $child_$arg0 = ((MemoryContext) $parent_$arg0)->firstchild
set $indent_$arg0 = $indent_$arg0 + 1
while ($child_$arg0)
walk_contexts $indent_$arg0 $child_$arg0
set $child_$arg0 = ((MemoryContext) $child_$arg0)->nextchild
end
end

walk_contexts 0 TopMemoryContext

2.2 获得疑似内存泄漏的进程PID,定时触发执行下面的 shell

gdb -p $PID < pg_debug_cmd > memchek/MemoryContextInfo_$(time).log

2.3 分析日志文件

日志文件以 MemoryContext 树的形式展示了一个时间点该进程的内存分配情况。根据时间的积累,可以很容易判断出哪一些 MemoryContext 可能存在异常,从而为内存泄漏指明一个方向。

(gdb)
TopMemoryContext: 149616
 pgstat TabStatusArray lookup hash table: 8192
 TopTransactionContext: 8192
 TableSpace cache: 8192
 Type information cache: 24480
 Operator lookup cache: 24576
 MessageContext: 32768
 Operator class cache: 8192
 smgr relation table: 24576
 TransactionAbortContext: 32768
 Portal hash: 8192
 PortalMemory: 8192
  PortalHeapMemory: 1024
   ExecutorState: 24576
    SRF multi-call context: 1024
    ExprContext: 0
    ExprContext: 0
    ExprContext: 0
 Relcache by OID: 24576
 CacheMemoryContext: 1040384
  pg_toast_2619_index: 1024
  ....
  pg_authid_rolname_index: 1024
 WAL record construction: 49776
 PrivateRefCount: 8192
 MdSmgr: 8192
 LOCALLOCK hash: 8192
 Timezones: 104128
 ErrorContext: 8192

最后,文章的参考资料中也提供了一种类似的方法,供各位参考。

总结

PostgreSQL 内存管理机制的实现比较复杂,但用起来确却很简单,有一种特别的美感,推荐大家了解一下。

参考资料

  1. PostgreSQL Developer_FAQ

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Linux内存管理-高端内存(二)
在支持MMU的32位处理器平台上,Linux系统中的物理存储空间和虚拟存储空间的地址范围分别都是从0x00000000到0xFFFFFFFF,共4GB,但物理存储空间与虚拟存储空间布局完全不同。Linux运行在虚拟存储空间,并负责把系统中实际存在的远小于4GB的物理内存根据不同需求映射到整个4GB的虚拟存储空间中。
1055 0
关于bug分析与异常处理的一些思考
我将bug依据复现的难易程度分为:必现的bug,比较容易复现的bug,很难复现的bug。 对于必现的bug,我通常淡定地称为其不是bug,因为,通过不断地复现,不断地调试,这些bug通常都能被解决,被解决了,还是bug么? 对于比较容易复现的bug,所谓比较容易复现,就是通过不太复杂操作,尝试几次、十几次,现象就可出现的bug,因为复现操作变得复杂,所以,为了每次复现能够获得更多的信息,尽量多地增加调试信息,以期望问题复现后,极大地缩小问题原因的范围。
897 0
内存管理
其中介绍了虚拟内存的机制以及mmap系统调用的实现。mmap允许直接将设备内存映射到用户进程的地址空间中。物理内存的管理,包括缓存的分配及回收,请页机制,交换空间等。   1)交换模块(swap) 这个模块负责控制内存内容的换入换出,它通过替换机制,使得物理内存的页框(RAM页)中保留有效的逻辑页,即从主存中淘汰最近没被访问的逻辑页,保存近来访问过的逻辑页。
772 0
Java内存溢出OutOfMemoryError的产生与排查
在java的虚拟机异常中,有两个异常是大家比较关心的,一个是StackOverflowError,另一个是OutOfMemoryError。今天我们就来看看OutOfMemoryError是怎么产生的,以及如何去排查这个异常。
342 0
Linux系统内存管理之伙伴系统分析
 今天去面试,一位面试官提到了内存管理的伙伴系统,当时就懵了,因为根本就没有听说过。晚上回来在实验室查了一些资料,现总结如下:  1.伙伴系统概念   伙伴系统是一种经典的内存管理方法。Linux伙伴系统的引入为内核提供了一种用于分配一组连续的页而建立的一种高效的分配策略,并有效的解决了外碎片问题。
872 0
Rainbond 内置 ServiceMesh架构分析
在 Cloud Native 架构下,容器的使用给予了异构应用程序的更多可行性,kubernetes 增强的应用的横向扩容能力,用户可以快速的编排出复杂环境、复杂依赖关系的应用程序,同时开发者又无须过分关心应用程序的监控、扩展性、服务发现、负载均衡和分布式追踪这些繁琐的事情而专注于程序开发,赋予开发者更多的创造性。
1042 0
关于红旗5.0内存管理
红旗5.0是我最近试用的第三套linux发行版,昨天上这里看到有帖子说很吃内存,于是乎我也打开我的任务管理器,一看吓一跳!我的内存占用竟然达到近 1G!这个时候,我的红旗5.0已经开机近10小时,打开过很多程序,游览过很多网站,下载过很多东东,操作感觉并不慢,和开机时差不多,有些程序还比刚 开机时打开快很多。
851 0
VB源码之友升级了(系统内核的升级最近也要推出)
        以前有些懒,虽然用源码之友过程中出现了几次 VB IDE死机(害的要关闭VB IDE,如果没保存就惨了),不过一般免费用户遇不到,那是在专业版中提供的仅对函数内整理的功能。
597 0
Linux内存管理-高端内存(一)
高端内存是指物理地址大于 896M 的内存。对于这样的内存,无法在“内核直接映射空间”进行映射。 为什么?   因为“内核直接映射空间”最多只能从 3G 到 4G,只能直接映射 1G 物理内存,对于大于 1G 的物理内存,无能为力。
777 0
+关注
db匠
rds内核团队秘密研发的全自动卖萌机. 追加特效: 发数据库内核月报. 月报传送: http://mysql.taobao.org/monthly/
497
文章
0
问答
来源圈子
更多
阿里云数据库:帮用户承担一切数据库风险,给您何止是安心!支持关系型数据库:MySQL、SQL Server、PostgreSQL、PPAS(完美兼容Oracle)、自研PB级数据存储的分布式数据库Petadata、自研金融级云数据库OceanBase支持NoSQL数据库:MongoDB、Redis、Memcache更有褚霸、丁奇、德哥、彭立勋、玄惭、叶翔等顶尖数据库专家服务。
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载