前文,我们分析了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压缩造成的内存消耗问题确实是一个有挑战的课题,感兴趣的同学们可以深入探讨!

GPDB OOM问题相关推荐

  1. oom 如何避免 高并发_【转载】如何避免OOM?看Greenplum的最佳实践

    导致数据库 OOM 报错的原因可能有: 数据库节点内存不足 操作系统内存相关的内核参数配置不当 数据倾斜,导致某些查询时,某个 SEGMENT 需要申请的内存超大 查询倾斜,例如某些聚合.窗口函数的分 ...

  2. linux内核oom,linux OOM killer分析

    基本概念 Linux 内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽而内核会把该进程杀 ...

  3. java并发读取相同的文件_高效读取大文件,再也不用担心 OOM 了!

    最近阿粉接到一个需求,需要从文件读取数据,然后经过业务处理之后存储到数据库中.这个需求,说实话不是很难,阿粉很快完成了第一个版本. 内存读取 第一个版本,阿粉采用内存读取的方式,所有的数据首先读读取到 ...

  4. java程序员遇到的问题_Java 程序员平时最常遇到的故障:系统OOM (一)

    作为 Java 程序员而言,先不考虑自己系统外部依赖的缓存.消息队列.数据库等等东西挂掉,就我们自己系统本身而言,最常见的挂掉的原因是什么? 其实就是系统OOM,也就是所谓的内存溢出! 什么是内存溢出 ...

  5. MyBatis中使用流式查询避免数据量过大导致OOM

    欢迎关注方志朋的博客,回复"666"获面试宝典 今天mybatis查询数据库中大量的数据,程序抛出: java.lang.OutOfMemoryError: Java heap s ...

  6. mysql sys库 oom_MySQL 5.6因为OOM导致数据库重启

    MySQL 5.6因为OOM导致数据库重启 发布时间:2020-08-09 08:29:53 来源:ITPUB博客 阅读:89 作者:feelpurple 线上的一套MySQL 5.6的从库,因为OO ...

  7. 百度二面:一个线程OOM了,其它线程还能运行吗?

    由于面试官仅提到OOM,但 Java 的OOM又分很多类型: 堆溢出("java.lang.OutOfMemoryError: Java heap space") 永久代溢出(&q ...

  8. 面试官:哪些场景会产生OOM?怎么解决?

    这个面试题是一个朋友在面试的时候碰到的,什么时候会抛出OutOfMemery异常呢?初看好像挺简单的,其实深究起来考察的是对整个JVM的了解,而且这个问题从网上可以翻到一些乱七八糟的答案,其实在总结下 ...

  9. 震惊!线上四台机器同一时间全部 OOM,到底发生了什么?

    来自:码海 案发现场 昨天晚上突然短信收到 APM (即 Application Performance Management 的简称,我们内部自己搭建了这样一套系统来对应用的性能.可靠性进行线上的监 ...

最新文章

  1. jvm十三:类加载器命名空间
  2. C++ 宽字符(wchar_t)与窄字符(char)的转换
  3. iphonex适配游戏_Cocos Creator 适配怎么做?
  4. linux Pci字符驱动基本加载流程
  5. 用Java控制小电灯-树莓派PI4J
  6. mybatis日期范围查询_15. Django 2.1.7 模型 条件查询、模糊查询、空查询、比较查询、范围查询、日期查询...
  7. WXS是小程序的一套脚本语言
  8. 【原】[webkit移动开发笔记]之空链接是使用javascript:void(0)还是使用#none
  9. mysql 与 mycat集成读写分离
  10. MVC中Action参数绑定的过程
  11. centos如何界面操作mysql_【mysql】centos7下mysql的安装以及基本操作
  12. WinRAR去广告方法
  13. edem颗粒替换_Altair EDEM Professional 2020.2安装教程(附替换补丁)
  14. 使用FFmpeg命令对音视频进行基础的编辑
  15. 机顶盒装linux教程,一种Linux机顶盒焦点控制方法与流程
  16. ThinkPHP微信小说小程序源码-自带采集带安装教程
  17. 二度理解Java web中的核心知识
  18. iOS端屏幕录制ReplayKit
  19. 网络营销试卷(参考答案及评分标准)
  20. centos6.8服务器中了挖矿程序病毒的解决方法

热门文章

  1. 信通院“5G+工业互联网”产业政策分析
  2. 千鸟弹幕机器人_千鸟熊猫TV直播弹幕机器人软件2.83
  3. Cowardly refusing to save to a terminal. Use the -o flag or redirect
  4. 读懂SAP Leonardo物联网平台
  5. 金融期货开户有什么用(期货开户支持哪些银行)
  6. 红楼梦第一回最后部分
  7. HTML 20 实体字符
  8. 【Android App】人脸识别中借助摄像头和OpenCV实时检测人脸讲解及实战(附源码和演示 超详细)
  9. 基于单片机无线传输测温DS18B20传感器设计(毕设课设)
  10. Linux命令之more(11)