Oracle应急处理:Oracle 内存泄漏但系统可telnet登陆

0 阅读3分钟

小亦平台会持续给大家科普一些Oracle数据库的应急处理方案,运维朋友们可以在应急处理方案专栏查看更多案例。

问题概述

场景描述:操作系统可以telnet但系统出现内存大量换页时,paging space利用率持续增长,此时可能出现可以登陆数据库和无法登陆数据库两种情况,此时适用该场景。

问题分析

内存泄漏是指应用程序或进程在分配内存后未能正确释放,导致可用内存逐渐减少的现象。在 Oracle 环境中:

  1. PGA/SGA 泄漏: Oracle 后台进程或用户会话持续占用内存且不释放,常见于 PGA 内存管理异常(如大量排序操作未释放)、SGA 组件(如 buffer cache、shared pool)异常增长。

  2. 系统级影响: 当物理内存耗尽时,操作系统开始使用 paging space (交换空间/虚拟内存) 进行换页操作,导致 paging space利用率持续增长。这会引发严重的性能下降,表现为:

  • 系统响应迟缓
  • 进程调度延迟
  • 数据库操作挂起或响应极慢
  1. 两种状态:
  • 可登录数据库: 数据库实例仍在运行但性能极差,部分功能可能受限。
  • 无法登录数据库: 数据库实例因内存压力已挂起或无响应。

解决方案

  1. 信息收集
  • 无法登陆数据库时
由于数据库挂起,因此需要分两步走,先按照场景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

说明:上述命令中的53687091710为固定的关键字,不需要修改


同时收集操作系统信息(可选,时间允许情况下进行)


root用户登陆,从操作系统命令判断出消耗大量内存的进程号


#svmon -Pt -t 20

#ps aux|head -1;ps aux|grep -v grep|sort -n +4

#truss --p XX  ----XX为进程号,收集10秒即可ctrl+c取消
  1. 杀掉个别前台进程或者重新启动实例
如果是个别前台进程占用大量内存导致,则杀掉该进程

否则登陆数据库时使用下面方法正常重启实例

$sqlplus "/as sysdba"

SQL>shutdown immediate;

SQL>startup;
  • 无法登陆使用上述方法重启时则
ps --ef|grep ora_pmon

kill -9 "pmon进程的操作系统进程" 

点击即刻前往小亦知识库查看应急预案完整版:www.ces-xiaoyi.com.cn/#/welcome/k…

运维工作中遇到难题?立即提交工单:www.ces-xiaoyi.com.cn/#/workOrder… 小亦平台工程师火速响应,助您快速修复故障!