当 GaussDB 的动态内存打满时,可以通过以下步骤进行分析:
1. 获取内存统计信息
首先,需要获取 GaussDB 进程的内存统计信息,包括实时内存统计信息和内存上下文占用大小。
实时内存统计信息: 查询 GaussDB Kernel 进程的总内存统计信息,可以使用以下 SQL 语句:
sql复制 select * from pv_total_memory_detail;
复制这将显示 GaussDB 进程的内存使用情况,包括最大动态内存、已用动态内存、动态内存峰值等信息。
内存上下文占用大小: 查看数据库进程全局的内存上下文占用大小,可以使用以下 SQL 语句:
sql复制 select contextname, sum(totalsize)/1024/1024 sum, sum(freesize)/1024/1024, count(*) count from pg_shared_memory_detail group by contextname order by sum desc limit 10;
复制这将显示内存上下文的占用情况,帮助确定哪些内存上下文占用了较多的内存。
2. 分析内存占用分类
根据获取的内存统计信息,可以分析内存占用的分类,确定是哪一部分内存导致了动态内存打满。
全局内存上下文占用较高: 如果
dynamic_used_memory
较大,而dynamic_used_shrctx
较小,则可以确认是线程和 session 上的内存占用较多。如果dynamic_used_memory
和dynamic_used_shrctx
相差不大,则可以确认是全局内存上下文使用的动态内存较大。线程级内存上下文占用较高: 如果线程级内存上下文占用较高,可以使用以下 SQL 语句查看线程级内存上下文的占用情况:
sql复制 select contextname, sum(totalsize)/1024/1024 sum, sum(freesize)/1024/1024, count(*) count from gs_thread_memory_context group by contextname order by sum desc limit 10;
复制session 级内存上下文占用较高: 如果 session 级内存上下文占用较高,可以使用以下 SQL 语句查看 session 级内存上下文的占用情况:
sql复制 select contextname, sum(totalsize)/1024/1024 sum, sum(freesize)/1024/1024, count(*) count from pv_session_memory_context group by contextname order by sum desc limit 10;
复制
3. 查看历史内存使用详情
可以使用 gs_get_history_memory_detail
视图查看 GaussDB 在过去所有时间段的内存使用超过 90% 时的内存使用详情:
select * from gs_get_history_memory_detail(NULL) order by memory_info desc limit 10;
复制
这将显示历史内存使用情况,帮助确定内存打满的具体时间点和原因。
4. 解决方案
根据分析结果,可以采取以下解决方案:
内存堆积导致内存满: 如果出现内存堆积长时间不释放的情况,可以通过做主备切换来降低内存的使用。
业务原因导致内存满: 如果是由于业务原因导致内存满,可以修改客户端作业,降低并发数或者修改 SQL 语句,使其在执行时不占用大量内存。建议联系华为工程师协助给出详细的解决方案。
other 内存缓存过多导致内存满: 如果是由于业务场景导致的 other 内存缓存过高,可以通过调整执行计划相关的参数或者从客户端侧调整业务来解决内存过高的问题。建议联系华为工程师协助给出详细的解决方案。