小亦平台會持續給大家科普一些Oracle數據庫的應急處理方案,運維朋友們可以在往期文章中查看更多案例。
問題概述
場景描述:操作系統可以telnet但系統出現內存大量換頁時,paging space利用率持續增長,此時可能出現可以登陸數據庫和無法登陸數據庫兩種情況,此時適用該場景。
問題分析
內存泄漏是指應用程序或進程在分配內存後未能正確釋放,導致可用內存逐漸減少的現象。在 Oracle 環境中:
- PGA/SGA 泄漏: Oracle 後台進程或用户會話持續佔用內存且不釋放,常見於 PGA 內存管理異常(如大量排序操作未釋放)、SGA 組件(如 buffer cache、shared pool)異常增長。
- 系統級影響: 當物理內存耗盡時,操作系統開始使用 paging space (交換空間/虛擬內存) 進行換頁操作,導致 paging space利用率持續增長。這會引發嚴重的性能下降,表現為:
- 系統響應遲緩
- 進程調度延遲
- 數據庫操作掛起或響應極慢
- 兩種狀態:
- 可登錄數據庫: 數據庫實例仍在運行但性能極差,部分功能可能受限。
- 無法登錄數據庫: 數據庫實例因內存壓力已掛起或無響應。
解決方案
- 信息收集
- 無法登陸數據庫時
由於數據庫掛起,因此需要分兩步走,先按照場景2收集造成掛起的信息,再按照下列步驟收集導致內存泄漏的關鍵信息。
root用户登陸,從操作系統命令判斷出消耗大量內存的進程號
#svmon -Pg -t 20
#svmon -Pt -t 20
#ps aux|head -1;ps aux|grep -v grep|sort -n +4
然後oracle用户登陸使用-prelim參數繞過無法登陸數據庫的問題,收集前3個最佔用內存的進程
$sqlplus -prelim "/as sysdba"
SQL>oradebug setospid XX ---> XX為操作系統進程號
SQL>oradebug dump heapdump 536870917
SQL>oradebug dump processstate 10
SQL>oradebug tracefile_name
SQL>oradebug short_stack
SQL>oradebug short_stack
説明:上述命令中的536870917和10為固定的關鍵字,不需要修改
同時收集操作系統信息(可選,時間允許情況下進行)
root用户登陸,從操作系統命令判斷出消耗大量內存的進程號
#svmon -Pg -t 20
#svmon -Pt -t 20
#ps aux|head -1;ps aux|grep -v grep|sort -n +4
#truss --p XX ----XX為進程號
- 可以登陸數據庫時
oracle用户,登陸數據庫收集前3個最佔用內存的操作系統進程號
$sqlplus "/as sysdba"
select * from gv$pgastat;
select a.sid,
a.serial#,
a.status,
b.spid,
a.username,
a.sql_id,
a.last_call_et,
round(b.PGA_USED_MEM/1024/1024,0) PGA_USED_MEM_M ,
round(b.PGA_ALLOC_MEM/1024/1024,0) PGA_ALLOC_MEM_M,
round(b.PGA_MAX_MEM/1024/1024,0) PGA_MAX_MEM_M
from v$session a, v$process b
where
a.paddr = b.addr
and PGA_ALLOC_MEM / 1024 / 1024 > 200
order by b.PGA_ALLOC_MEM;
-----------此處顯示的結果為進程佔用內存從小到大的排序,查看第三列spid即可獲得操作系統進程號
-----------下面的SQL語句查詢出了這些進程正在執行的SQL語句,即可找到泄漏點
select a.sid,
a.serial#,
a.status,
b.spid,
a.username,
a.last_call_et,
round(b.PGA_USED_MEM/1024/1024,0) PGA_USED_MEM_M ,
round(b.PGA_ALLOC_MEM/1024/1024,0) PGA_ALLOC_MEM_M,
round(b.PGA_MAX_MEM/1024/1024,0) PGA_MAX_MEM_M,
a.program,a.machine,a.username,
c.sql_text
from v$session a, v$process b, v$sqltext c
where a.paddr = b.addr
and a.sql_id = c.sql_id
and b.PGA_ALLOC_MEM / 1024 / 1024 > 200
order by a.sid,a.serial#,c.piece;
SQL>oradebug setospid XX -->
XX為操作系統進程號,依次收集最佔用內存的前幾個進程
SQL>oradebug dump heapdump 536870917
SQL>oradebug dump processstate 10
SQL>oradebug tracefile_name
SQL>oradebug short_stack
SQL>oradebug short_stack
説明:上述命令中的536870917和10為固定的關鍵字,不需要修改
同時收集操作系統信息(可選,時間允許情況下進行)
root用户登陸,從操作系統命令判斷出消耗大量內存的進程號
#svmon -Pt -t 20
#ps aux|head -1;ps aux|grep -v grep|sort -n +4
#truss --p XX ----XX為進程號,收集10秒即可ctrl+c取消
- 殺掉個別前台進程或者重新啓動實例
如果是個別前台進程佔用大量內存導致,則殺掉該進程
否則登陸數據庫時使用下面方法正常重啓實例
$sqlplus "/as sysdba"
SQL>shutdown immediate;
SQL>startup;
- 無法登陸使用上述方法重啓時則
ps --ef|grep ora_pmon
kill -9 "pmon進程的操作系統進程"
點擊即刻前往小亦知識庫查看應急預案完整版:https://www.ces-xiaoyi.com.cn/#/welcome/knowledge/panel/detai...
運維工作中遇到難題?立即提交工單:https://www.ces-xiaoyi.com.cn/#/workOrder?marketing_code=arti...小亦平台工程師火速響應,助您快速修復故障!