最近工作中遇到了Oracle进程大量占用系统内存,直到内存占用逼近系统全部内存然后导致系统奔溃的情况。
先说明一下环境。
Windows 2008 服务器,Oracle 10.2.0.4.0 企业版,服务器有16G内存,oracle.exe的内存占用到15.9G导致服务器崩溃。
发现问题时,使用 以下sql查询发现 一个oracle 的会话占用了大量的内存。
SELECT server "连接类型",  s.username,  oSUSEr, NAME,  VALUE/1024/1024 "占用内存MB",  s.SID "会话ID", s.serial#,  spid "操作系统进程ID", p.PGA_USED_MEM,  p.PGA_ALLOC_MEM,  p.PGA_FREEABLE_MEM, p.PGA_MAX_MEM FROM v$session s, v$sesstat st, v$statname sn, v$process p WHERE st.SID = s.SID AND st.statistic# = sn.statistic# AND sn.NAME LIKE 'session pga memory' AND p.addr = s.paddr ORDER BY VALUE DESC
此会话的PGA_USED_MEM,  PGA_ALLOC_MEM,  PGA_FREEABLE_MEM, PGA_MAX_MEM 等值可以达到4G左右,可以断定是会话的问题。 经查虽然我们在oracle中限定了PGA的大小也就是配置了PGA_AGGREGATE_TARGET ,但是PGA_AGGREGATE_TARGET作为一个Target Oracle只会做的尽量不超过此值,并不保证一定不超过。 情况很明显某个会话大量执行没有结束占用了内存。 下面可以通过各种方法查明回来的来源。
我通过Oracle 的EM企业管理器发现,有5条SQL大量的占用了数据库和CPU时间。于是读取SQL的内容逐一执行发现。其中一条SQL执行长达4个小时无法结束。在执行的同时由于需要保存临时结果占用了大量内存。
下一步就是联系相关开发修正SQL问题解决。
 
此次还有一点不明白,Oracle应该可以限制某个会话的内存上限,但是不知为何没有成功限制。