原 GreenPlum 6中启用资源组后,报错 ERROR: insufficient memory reserved for statement (execHHashagg.c:1400)
Tags: 原创故障处理GreenPlum资源组内存不足enable_hashagg
现象
在GP6中,启用资源组后,查询报错:
1 2 3 4 5 6 7 8 | SELECT current_database(),bdinspname,bdirelname,bdirelpages,bdiexppages,( case when position('moderate' in bdidiag)>0 then 1 when position('significant' in bdidiag)>0 then 2 else 0 end) as bloat_state FROM gp_toolkit.gp_bloat_diag ORDER BY bloat_state desc |
可以确保内存足够,该查询只返回5条数据:
而且,去掉最后的ORDER BY bloat_state desc
后可以正常查询:
分析
通过如下的SQL语句可以查看到历史报错insufficient memory reserved for statement 信息:
1 2 3 4 5 6 7 8 | SELECT * FROM gpmetrics.gpcc_pg_log_history d where d.logtime >= '2025-01-03 09:50' and d.logtime <= '2025-01-10 10:50' and logseverity not in ('LOG') AND logmessage like '%memory%' order by d.logtime ; |
基本报错都是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | insufficient memory reserved for statement (execHHashagg.c:1400) insufficient memory reserved for statement (execHHashagg.c:845) Stack trace: 1 0xc05a17 postgres errstart (elog.c:557) 2 0xc088ae postgres elog_finish (elog.c:1728) 3 0x9169ff postgres <symbol not found> (execHHashagg.c:845) 4 0x8e47cc postgres ExecAgg (nodeAgg.c:1170) 5 0x8ca945 postgres ExecProcNode (execProcnode.c:1121) 6 0x8fde16 postgres <symbol not found> (tuptable.h:159) 7 0x8d88f9 postgres ExecScan (execScan.c:84) 8 0x8caa05 postgres ExecProcNode (execProcnode.c:1067) 9 0x8ec9b9 postgres ExecHashJoin (tuptable.h:159) 10 0x8ca975 postgres ExecProcNode (execProcnode.c:1106) 11 0x8ec9b9 postgres ExecHashJoin (tuptable.h:159) 12 0x8ca975 postgres ExecProcNode (execProcnode.c:1106) 13 0x8ea2dc postgres MultiExecHash (tuptable.h:159) 14 0x8cac90 postgres MultiExecProcNode (execProcnode.c:1276) 15 0x8ec442 postgres ExecHashJoin (nodeHashjoin.c:238) 16 0x8ca975 postgres ExecProcNode (execProcnode.c:1106) 17 0x8fde16 postgres <symbol not found> (tuptable.h:159) 18 0x8d88f9 postgres ExecScan (execScan.c:84) 19 0x8caa05 postgres ExecProcNode (execProcnode.c:1067) 20 0x8fa618 postgres ExecSort (tuptable.h:159) 21 0x8ca955 postgres ExecProcNode (execProcnode.c:1117) 22 0x8c1b29 postgres <symbol not found> (tuptable.h:159) 23 0x8c23be postgres standard_ExecutorRun (execMain.c:3168) 24 0x8c2595 postgres ExecutorRun (execMain.c:992) 25 0xaa0217 postgres <symbol not found> (pquery.c:1170) 26 0xaa22a1 postgres PortalRun (pquery.c:1017) 27 0xa9c260 postgres <symbol not found> (postgres.c:1855) 28 0xa9f336 postgres PostgresMain (postgres.c:5334) 29 0x6b5ef8 postgres <symbol not found> (postmaster.c:4500) 30 0xa23016 postgres PostmasterMain (postmaster.c:1517) |
其实从最后的execHHashagg.c
可以看到是hashagg导致的。
解决
在会话级别设置:
1 | SET enable_hashagg =0; |
参数enable_hashagg介绍
enable_hashagg
是 Greenplum 数据库中的一个 优化器 GUC(Grand Unified Configuration)参数,用于控制查询优化器是否启用 哈希聚合(Hash Aggregation) 策略。
哈希聚合(Hash Aggregation)是什么?
Hash Aggregation
是数据库在执行聚合操作(如 GROUP BY
或聚合函数)时的一种实现方式。它会将输入数据通过哈希表进行分组,从而高效地计算聚合结果。
- 优点:
- 在数据量较小、内存足够时,
Hash Aggregation
通常比基于排序的聚合(Sort Aggregation
或Group Aggregation
)速度更快。 - 适合处理高并发查询或小型数据集。
- 在数据量较小、内存足够时,
- 缺点:
- 如果数据量很大,超出了可用内存,哈希表会溢出到磁盘,导致性能急剧下降。
- 当内存限制较严格时(如启用资源组),可能会因为内存不足而报错。
enable_hashagg 参数的作用
- 启用 (
ON
):- 优化器会优先选择使用
Hash Aggregation
实现聚合操作。 - 默认情况下,该参数是开启的。
- 优化器会优先选择使用
- 禁用 (
OFF
):- 优化器将不会选择
Hash Aggregation
,改为使用基于排序的聚合方式(Sort Aggregation
或Group Aggregation
)。 - 对于内存紧张或数据量较大的场景,关闭
Hash Aggregation
可能会更稳定。
- 优化器将不会选择
使用场景和调整建议
1. 默认情况
- 如果没有内存不足或性能问题,建议保持
enable_hashagg
为默认值ON
。
2. 数据量大或内存不足时
在处理大表的聚合查询时,如果
1Hash Aggregation本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信dbaup66,谢谢!