1、如果在出現問題時,能正常連接到CN或DN,可以到連接到對應的報錯節點,通過如下查詢定位到會話前10個消耗內存最大的會話的PID信息,確認問題會話,然後通過pid查詢pg_stat_activity找到對應的會話SQL,然後優化SQL:
select split_part(sessid, '.'::text, 2) AS pid,contextname,sum(totalsize)/1024/1024 TotalMB,sum(freesize)/1024/1024 FreeMB,COUNT(*) FROM gs_session_memory_detail group by sessid,contextname order by TotalMB desc limit 10;
select client_addr,query from pg_stat_activity where pid=?;
但是該方法通常在出現問題時,節點無法正常連接,所以釋放後連接,無法找到對應會話,需要結合其他方法。
2、內存不足問題需要首先檢查下內存資源池使用情況,看看是否是動態內存使用不足,檢查,相關參數配置情況,是否內存分配過小:
select * from gs_total_memory_detail;
show max_process_memory;
show shared_buffers;
show cstore_buffers;
show work_mem;
其中會話的動態內存無法配置,大致可以計算為max_process_memory-shared_buffers -cstore_buffers為會話動態分配內存池大小,所以提升動態會話內存只有通過擴大max_process_memory或者縮小(shared_buffers或cstore_buffers)兩種方式增加擴大動態內存,非列存庫cstore_buffers最小可以調整到16MB.
3、檢查操作系統層面的物理內存分片資源是否能夠擴容:
free -g
儘量不要使用交換內存,內存充足情況儘量給DN節點充足的內存。
4、檢查節點線程池是否打開。
show enable_thread_pool
5、監控動態會話內存使用情況:可以設置告警80%:
select round((max(case when memorytype = 'dynamic_used_memory' then memorymbytes end)::numeric/nullif(max(case when memorytype = 'max_dynamic_memory' then memorymbytes end),0)::numeric) * 100,2) as dynamic_memory_usage_pct from gs_total_memory_detail;