GaussDB动态内存高故障处理
- 故障现象
单个或者多个节点出现动态内存使用率超过阈值,动态内存快速上涨等现象,或者业务执行SQL报错:ERROR:memory is temporarily unavailable。
- 故障原因
可能原因有以下:
- 会话数上涨。
- SQL计划缓存增多。
- 内存泄漏。
- 参数设置不合理。
- 处理方法
步骤 1 登录DN节点,分别查看DN内存使用情况。
gsql -d postgres -p 40000 -U user -W password -r
select * from pg_total_memory_detail;

如上图,为当前DN的内存使用情况.
说明:
1. 分布式gsql连接DN,需要首先获取当前DN的端口号,集中式DN默认端口号为8000。
2. DN的端口号可通过cm_ctl query -Cvdp命令查询获取。
3. 如果连接备DN,需要gsql加“-m”参数。
步骤 2 当同节点的“dynamic_used_memory”大于“max_dynamic_memory”时会报内存不足,参考处理步骤1。
步骤 3 当同节点的“dynamic_used_memory”小于“max_dynamic_memory”但“dynamic_peak_memory”大于“max_dynamic_memory”时,说明曾经出现过内存不足的情况,参考处理步骤1。
步骤 4 若同节点的“dynamic_used_shrctx/max_dynamic_memory”大于80%时,请登录该节点执行以下命令查询“pg_shared_memory_detail”视图,查看使用内存较多的MemoryContext,参考处理步骤2。
分布式:
select * from pg_shared_memory_detail order by usedsize desc;
集中式:
select * from gs_shared_memory_detail order by usedsize desc;

说明:
1. 分布式gsql连接DN,需要首先获取当前DN的端口号,集中式DN默认端口号为8000。
2. DN的端口号可通过cm_ctl query -Cvdp命令查询获取。
3. 如果连接备DN,需要gsql加“-m”参数。
步骤 5 若同节点的“dynamic_used_shrctx/max_dynamic_memory”小于40%时,请登录该节点执行以下命令查询“pv_session_memory_detail”视图,查看使用内存较多的MemoryContext,参考处理步骤2。
分布式:
select * from pv_session_memory_detail;
集中式:
select * from gs_session_memory_detail;

说明
1. 分布式gsql连接DN,需要首先获取当前DN的端口号,集中式DN默认端口号为8000。
2. DN的端口号可通过cm_ctl query -Cvdp命令查询获取。
3. 如果连接备DN,需要gsql加“-m”参数。
步骤 6 若同节点的“other_used_memory/process_used_memory”大于50%时,请联系华为技术支持。
步骤 7 若同节点的“dynamic_used_memory/max_dynamic_memory”大于80%,请登录该节点执行以下命令查询视图,参考处理步骤2。
分布式:
查看具体占用内存较高的内存上下文
select contextname, sum(totalsize)/1024/1024 as total, sum(usedsize)/1024/1024,count(*) as used from pv_session_memory_detail group by 1 order by 2 desc limit 20;
查询占用动态内存较高的会话
select sessid, sum(totalsize)/1024/1024 as "totalsize MB", count(1) as count from pv_session_memory_context group by sessid order by 2 desc limit 10;
集中式:
查看具体占用内存较高的内存上下文
select contextname, sum(totalsize)/1024/1024 as total, sum(usedsize)/1024/1024,count(*) as used from gs_session_memory_detail group by 1 order by 2 desc limit 20;
查询占用动态内存较高的会话
select sessid, sum(totalsize)/1024/1024 as "totalsize MB", count(1) as count from gs_session_memory_context group by sessid order by 2 desc limit 10;
说明:
1. 分布式gsql连接DN,需要首先获取当前DN的端口号,集中式DN默认端口号为8000。
2. DN的端口号可通过cm_ctl query -Cvdp命令查询获取。
3. 如果连接备DN,需要gsql加“-m”参数。
4. sessid说明:
− 关闭线程池(enable_thread_pool = off)时该字段表示线程启动时间+session标识(字符串信息为timestamp.sessionid)。
− 开启线程池(enable_thread_pool = on)时,内存上下文是线程级别的,则对应的该字段表示线程启动时间+线程标识(字符串信息为timestamp.threadid)。
步骤 8 根据步骤7的sessid查询获取pid和sessionid。
若关闭线程池(enable_thread_pool = off),则执行以下SQL。
select pid,sessionid from pg_stat_activity where sessionid='$sessionid';
若开启线程池(enable_thread_pool = on),则执行以下SQL。
select pid,sessionid from pg_stat_activity where pid='$sessionid';
说明:
$sessionid为步骤7获取到的sessid后半部分,即“.“之后的部分。

如上图,sessionid为111630。
步骤 9 观察内存占用较大的上下文,若会话数不变,动态内存依然快速上涨,则可能为内存泄露,参考处理步骤3。
步骤 10 获取CN/DN的max_process_memory,shared_buffers参数值,若shared_buffers值过大,根据标准配置,重新设置该参数值,参考《开发指南》。
show max_process_memory;
show shared_buffers;
说明:
1. 分布式gsql连接DN,需要首先获取当前DN的端口号,集中式DN默认端口号为8000。
2. DN的端口号可通过cm_ctl query -Cvdp命令查询获取。
3. 如果连接备DN,需要gsql加“-m”参数。
须知:以上参数设置,需要重启集群生效,需谨慎评估。
步骤 11 当CachedPlan上下文内存占用较多(作用:SQL计划缓存,下一次查询时可以减少SQL执行计划的生成时间),需减少会话数、改写业务、减少SQL模板数以及在JDBC连接串配置较小的preparedStatementCacheQueries值,减少每个会话缓存的语句数量。
当SessionCacheMemoryContext上下文内存占用较多(作用:会话元数据缓存),需减少会话数、在enable_global_syscache为off的情况下,可以调小local_syscache_threshold,减少单个会话占用的缓存大小。
当TwoPhrase Cleaner上下文内存占用较多(作用:该内存是事务两阶段提交时,临时表自动清理所占用的内存),需修改gs_clean_timeout参数为0,禁止自动清理临时表,使TwoPhrase Cleaner不再增长。
须知:该操作为高危操作,执行前需联系华为技术支持确认。
步骤 12 请执行以下语句保留当前内存上下文上的内存申请详细信息(使用时根据实际内存上下文替换参数值),用于后续定位。
select gs_get_session_memctx_detail('$contextname');
说明:
$contextname为步骤7获取到的contextname列。
执行pg_terminate_session结束相应会话。
select pg_terminate_session('$pid', '$sessionid');
说明:
$pid或$sessionid为步骤8获取到的pid和sessionid。
须知:pg_terminate_session函数结束会话为高危操作,执行前需联系华为技术支持确认。
若kill会话之后仍然无法恢复,则重启DN进程。
kill -9 pid
说明:
pid为当前节点dn进程的pid,可通过ps -ux|grep dn|grep -v grep查询获取。
须知:kill操作为高危操作,执行前需联系华为技术支持确认。
步骤 13 若以上均不涉及,请联系华为技术支持。
----结束
- 点赞
- 收藏
- 关注作者
评论(0)