GPDB OOM问题

简介: GPDB OOM问题

前文,我们分析了gp_vmem_protect_limit参数的意义,仅统计gp_malloc中申请的,它并没有统计共享内存的部分,所以仍旧有操作系统OOM的风险,详情:GPDB中gp_vmem_protect_limit参数的意义但经测试验证,仍不足以对上GP占用的内存总额。这样,也就是说仍有其他内存没有被gp_vmem_protect_limit统计进去。猜想,仍有malloc函数申请的内存没有统计进去,继续在该函数上打断点,进行跟踪。经排查,发现大部分额外的malloc都是压缩、解压缩函数中调用的,也就是zstd库函数。
最开始猜想,是因为GP列存压缩表的压缩导致,但是业务的SQL不涉及修改,都是查询。那这个压缩来自哪里?查看堆栈发现是排序、HASH AGG和HASH JOIN中的。我们将HASH AGG和HASH JOIN关闭掉,发现有效果,但是最后因为磁盘空间不够保存退出了,排序的临时文件有点大。那么继续更进一步,查看堆栈,分析压缩使用场景。发现,排序、hash agg、hash join的临时文件需要压缩:调用的函数为BufFilePledgeSequential,我们查看该函数:


有个参数gp_workfile_compression控制是否压缩:如果有很多溢出文件,则设置gp_workfile_compression来压缩这些溢出文件。压缩溢出文件可能有助于避免IO操作导致磁盘子系统过载:Specifies whether the temporary files created, when a hash aggregation or hash join operation spills to disk, are compressed。

那么我们将这个参数关闭,将临时文件全部软连接到一个大盘中,这样使用同样的执行计划,仅临时文件是否压缩不同。这样,将SQL成功跑完,但是中间跟踪过程,临时文件非常大。所以业务中压缩是必须的。


hash agg和hash join中的临时文件压缩导致内存过大,且内存的申请在zstd库函数中,并不是GP代码中,所以并没有被gp_vmem_protect_limit跟踪到

另查到姚总早期分享的内容:https://www.infoq.cn/article/iAdFEBtb1Y0MOJlvrScU?utm_source=related_read_bottom


执行器优化:目前 Greenplum 使用 zstd 压缩 AO 数据和临时数据,zstd造成的一个问题是内存消耗较大,如何优化操作大量压缩文件时的内存消耗是一个很有挑战的课题。有关更多细节可以参考这个讨论(最后部分有简单的问题重现方法)。链接地址:https://github.com/greenplum-db/gpdb/pull/6508


临时解决方案可以通过限制gp_workfile_limit_files_per_query、gp_workfile_limit_per_query、gp_workfile_limit_per_segment等参数来控制一个查询中临时文件个数,从而规避zstd压缩占用的内存。另外,若zstd压缩接口的参数中有可以统计其申请内存的成员变量,那么可以通过修改代码,将这部分内存也统计到gp_vmem_protect_limit参数中,不过估计改动影响会比较大,zstd是第三方库,首先需要了解它的内存申请及管理机制,其次若压缩、解压缩接口中没有相关统计参数,那么就需要尝试修改zstd库,这造成的影响就更大了。zstd压缩造成的内存消耗问题确实是一个有挑战的课题,感兴趣的同学们可以深入探讨!

目录
相关文章
|
7月前
|
缓存 Java 开发工具
OOM out of memory 内存溢出
OOM out of memory 内存溢出
94 1
|
关系型数据库 分布式数据库 PostgreSQL
GPDB如何使用valgrind进行内存检测
GPDB如何使用valgrind进行内存检测
87 0
|
SQL 监控 数据库
GPDB-内核特性-资源组内存管理机制-1
GPDB-内核特性-资源组内存管理机制-1
103 0
|
SQL NoSQL Java
GPDB-疑难杂症-使用资源组入库OOM
GPDB-疑难杂症-使用资源组入库OOM
79 0
|
存储 算法 关系型数据库
PostgreSQL 垃圾回收参数优化之 - maintenance_work_mem , autovacuum_work_mem
PostgreSQL 垃圾回收参数优化之 - maintenance_work_mem , autovacuum_work_mem
3511 1
|
监控 关系型数据库 PostgreSQL
PostgreSQL bgwriter,walwriter,backend process 写磁盘的实时监控
标签 PostgreSQL , 背景 数据库有两大块buffer,wal buffer和shared buffer。 wal buffer是预写日志缓冲区。 shared buffer是数据页缓冲区。
2664 0
|
SQL 算法 关系型数据库
100G内存下,MySQL查询200G大表会OOM么?
我的主机内存只有100G,现在要全表扫描一个200G大表,会不会把DB主机的内存用光? 逻辑备份时,可不就是做整库扫描吗?若这样就会把内存吃光,逻辑备份不是早就挂了? 所以大表全表扫描,看起来应该没问题。这是为啥呢?
100G内存下,MySQL查询200G大表会OOM么?
|
算法 Java 编译器
troubleshoot之:GC调优到底是什么
troubleshoot之:GC调优到底是什么
troubleshoot之:GC调优到底是什么
|
前端开发 Java Android开发
JVM garbage collector thrashing and after running out of JVM memory
React Native Android 项目使用 ./gradlew assembleRelease 命令打包报错
554 0
JVM garbage collector thrashing and after running out of JVM memory
JVM 报 GC Overhead limit exceeded 是什么意思?
JVM 报 GC Overhead limit exceeded 是什么意思?