小亦平台会持续给大家科普一些运维过程中常见的问题解决案例,运维朋友们可以在常见问题及解决方案专栏查看更多案例。
1. 问题概述
数据库版本:505.2.RC1
数据库模式:集中式单机
用户给的部署环境配置是32C64G(1:2)的比例,能安装上但是在高并发下会报错内存不够
报错:
Current thread memory info, current role is: 1, max_mem is: 24561, thrd_beyondChunk is: 0, currMem is: 24561.
----debug_query_id=0, Current used memory reaching the database memory limitation. Current thread is consuming about 6 MB, allocating 8192 bytes.
2024-10-21 14:39:19.342 dn_6001 oper_dc bipq 172.20.37.70 140161374414592 0[0:0#0] 0 PostgreSQL JDBC Driver 0 [BACKEND] ERROR: memory is temporarily unavailable
2024-10-21 14:39:19.342 dn_6001 oper_dc bipq 172.20.37.70 140161374414592 0[0:0#0] 0 PostgreSQL JDBC Driver 0 [BACKEND] DETAIL: Failed on request of size 8192 bytes under queryid 0 in inval.cpp:949.
2. 问题分析
如果出现集群内存不足或者长时间内存占用处于较高状态的情况,一般是由以下几种原因造成的。
- 内存堆积 当SQL语句执行过程中临时内存未及时释放时,会导致内存堆积。
- 并发过高导致内存占用过高 客户端向server端建立的连接数过多,导致server端创建了大量的session,占用大量内存,这种场景下会出现内存出现占用较高的情况。
- 单条SQL语句内存占用较高 对于部分SQL语句,执行过程中会使用大量的内存,导致内存出现短暂性上涨,如复杂的存储过程语句,执行时内存占用可能达到几十GB大小。
- 内存缓存过多 GaussDB引入了jemalloc开源库来管理内存管理,但是jemalloc在面对大量的内存碎片时会存在内存持续缓存不释放的问题,导致数据库进程使用的内存远远超过了实际使用的内存,具体表现为使用内存视图pv_total_memory_detail查询时,other_used_memory占用过大。如下所示。
查看试图:
select * from pg_total_memory_detail;
nodename | memorytype | memorymbytes
----------+-------------------------+--------------
dn_6001 | max_process_memory | 51200
dn_6001 | process_used_memory | 22047
dn_6001 | max_dynamic_memory | 43494
dn_6001 | dynamic_used_memory | 43244
dn_6001 | dynamic_peak_memory | 43190
- max_dynamic_memory动态内存溢出
- max_dynamic_memory(内核最大能分配的动态内存) 和 dynamic_used_memory(内核已使用内存) 非常接近
3. 解决方案与优化建议
优化措施:
- 扩容内存用户现在给的配置是1:2的配置,gauss推荐1:8,最低1:4
- 最终扩容为32c 128g(满足 32C:128G=1:4 的最低要求)
- 加大max_process_memory
- max_dynamic_memory = max_process_memory- max_cstore_memory - udf_reserved_memory - max_shared_memory ;
优化结果: