了解和诊断ORA-600[729] space leak错误

如果自己搞不定可以找诗檀软件专业ORACLE数据库修复团队成员帮您恢复!

诗檀软件专业数据库修复团队

服务热线 : 13764045638 QQ号:47079569 邮箱:service@parnassusdata.com

 

目标

这篇文章的目的是帮助Oracle客户了解ORA-600[729] UGA内存泄露问题。本文将帮助你了解内存泄漏问题是什么以及内存泄露时应当怎么做。

解决方案

什么是空间(内存)泄漏?

当Oracle试图释放被分配给进程的内存时,常出现内存泄漏。当Oracle释放被分配给用户进程的堆时,会话注销过程中会发现内存泄漏。

当用户连接到Oracle,创建一个用户进程同时分配堆。每个进程都将有自己的内存堆。

内存被分成若干堆,每堆由一个或多个扩展组成。每个扩展包含一系列连续的存储块,这些块可以是自由的也可以是被分配的。通用堆管理器在FREE LISTS 和 LRU LISTS的帮助下,分配并释放内存块,。

块类型如下:

  1. FREE
    2. FREEABLE
    3. RECREATABLE
    4. PERMANENT
    5. FREEABLE WITH MARK并不强制每个扩展只能包含一种类型的组块。扩展区可以包含不同类型的块。当进程需要内存块时,根据需要将它们进行分配。Oracle在内部跟踪分配给进程的内存量。

进程终止时,所有分配给进程的内存会自动释放。内存被释放时,被分配的堆也被释放。一般情况下,当堆被释放,进程判定为被分配的块只有 PERMANENT块和自由列表上的FREE块。如果该进程发现仍有剩余FREEABLE 或RECREATABLE 块存在,则该进程没有正常释放内存。这种情况被认为是空间泄漏。
Oracle通常为SGA堆,UGA堆,Large Pool堆和PGA堆执行内存泄露检查。内存泄漏错误会导致在BACKGROUND_DUMP_DESTINATION或USER_DUMP_DESTINATION中生成跟踪文件。

空格泄漏问题一般会捕获跟踪信息和堆转储。

在alert.log中,该错误会被报告为:

Errors in file d:\oracle\admin\testdb\bdump\yourfilenamehere.trc:

ORA-00600: internal error code, arguments: [729], [560], [space leak], [], [], [], [], []

操作系统以及Oracle进程头信息之后,你会在跟踪文件中看到以下信息:

*** 2006-10-03 18:43:11.598
*** SESSION ID:(34.50354) 2006-10-03 18:43:11.597
******** ERROR: UGA memory leak detected 560 ********

上面几行告诉我们,这种内存泄漏来自UGA,泄漏的字节数是560。
******************************************************
HEAP DUMP heap name=”session heap” desc=0xaef81d0
extent sz=0xffb8 alt=32767 het=32767 rec=0 flg=3 opc=3
parent=0xaeb63e0 owner=0x7a4b7078 nex=(nil) xsz=0xffb8

以上几行将转储描述为带描述符0xaef81d0的会话堆。

下面的转储中,可以看到没有释放的块是块4085a350。这是一个重新创建的块,大小为560个字节,正是错误ORA-00600[729]所报告的泄露的字节数,[560],[space_leak]。

分析内存泄漏问题时,确定FREEABLE和RECREATABLE块。理想状况下,它们应等于错误所报告的泄漏的内存总字节数。

看下面的内存转储,就会发现FREEABLE和RECREATABLE块的总字节等于560,这是泄露的内存字节数。

EXTENT 0 addr=0x407cf048
Chunk 407cf050 sz= 65456 free ” “
EXTENT 1 addr=0x408a0048
Chunk 408a0050 sz= 65456 free ” “
EXTENT 2 addr=0x40890048
Chunk 40890050 sz= 65456 free ” “
EXTENT 3 addr=0x40850048
Chunk 40850050 sz= 41728 free ” “
Chunk 4085a350 sz= 560 recreate “bind var heap ” latch=(nil)
EXTENT 4 addr=0x407df048
Chunk 407df050 sz= 65456 free ” “
EXTENT 5 addr=0x40f91048
Chunk 40f91050 sz= 65456 free ” “
EXTENT 6 addr=0x40880048
Chunk 40880050 sz= 65456 free ” “
EXTENT 7 addr=0x40870048
Chunk 40870050 sz= 65456 free ” “

如何处理内存泄露?

步骤1.查看alert.log以验证错误并获取跟踪文件的信息。

alert.log会报告类似于下列错误:

Sat Dec 02 21:52:17 2006
Errors in file d:\oracle\admin\testdb\udump\testdb_ora_5928.trc:
ORA-00600: internal error code, arguments: [729], [152], [space leak], [], [], [], [], []

a. 第一个方括号内的数字[729]是内存泄露问题的常见参数。
b. 第二个数字[152]是由错误导致的泄漏的字节数。

  1. 第三个参数往往是是[空间泄漏]。

步骤 2. 打开相关的跟踪文件。

操作系统和Oracle进程的头信息之下,你会看到以下信息:

*** 2006-12-13 02:01:13.859
*** SESSION ID:(54.11635) 2006-12-13 02:01:13.859
******** ERROR: UGA memory leak detected 152 ********
******************************************************

上述错误状态:

a.内存从UGA区域泄露

b.再次在文本中报告泄漏数(152字节)。

步骤3.会话注销期间验证泄漏。

a.搜索跟踪文件来“调用堆栈跟踪”。如果“opilof”在堆栈中被引用,会话注销期间就会出错。本节内容与以下内容类似:

—– Call Stack Trace —–
calling call entry argument values in hex
location type point (? means dubious value)
——————– ——– ——————– —————————-
ksedmp()+184 ? ksedst() 800000010000B938 ?
ksfdmp()+32 ? ksedmp() 800003FFBFFF6418 ?
kgeriv()+152 ? ksfdmp() 20000000B168 ?
kgesiv()+132 ? kgeriv() 40000000000002D9 ?
ksesic2()+124 ? kgesiv() 000000000 ?
ksmuhe()+1040 ? ksesic2() 000000000 ?
ksmugf()+400 ? ksmuhe() 000000000 ?
ksuxds()+2692 ? ksmugf() 800003FFBFFF4020 ?
ksudel()+104 ? ksuxds() 8000000100131B38 ?
opilof()+876 ? ksudel() 800003FFBFFF5808 ?
opiodr()+2416 ? opilof() 0650AB9D8 ?
ttcpip()+1320 ? opiodr() 8000000100004790 ?
opitsk()+1260 ? ttcpip() 000000100 ?
opiino()+1484 ? opitsk() 8000000100138268 ?
opiodr()+2416 ? opiino() 000001560 ?
opidrv()+752 ? opiodr() 800003FFBFFF0870 ?
sou2o()+40 ? opidrv() 000000000 ?
main()+228 ? sou2o() 000000000 ?

  1. 会话状态对象若具有以下的标志信息,则表明会话已经被删除:
    SO: 7000000abdd9290, type: 4, owner: 7000000ab97a2b8, flag: INIT/-/-/0x00
    (session) sid: 617 trans: 0, creator: 7000000ab97a2b8, flag: (100041) USR/- BSY/-/-/DEL/-/-
    DID: 0000-0000-00000000, short-term DID: 0000-0000-00000000
  2. 使用专用服务器还是多线程服务器?

a.如果使用的是专用服务器,退出进程后该错误就不再产生影响。该错误导致的结果微不足道,不会有任何实际问题。此泄漏是在UGA。

b.如果使用多线程服务器(MTS)和/或XA事务进程管理器/监测器,泄漏的内存是在SGA区域。此时审查alert.log 以找出其他错误,如ORA-4030或ORA-4031就尤为重要,以确保SGA没有出现额外的资源相关的问题

  1. 可以无视泄漏吗?

a.是否有其他错误?如果同一时间没有其它错误,这种情况下错误很少出现,可以被安全忽略。有一个经验法则,小于90000字节的泄漏被认为是无关紧要的。在这种情况下,解决方案是设置事件10262(见下文)。

  1. 泄漏是在SGA中吗?检查alert.log是否有其他错误,如ORA-4030和ORA-4031,以确保共享池或操作系统内存中没有其他问题。

c.给定任务中错误重复出现了吗?如果是,应进一步调查,因为泄漏可能是一个已知的漏洞。

参考Note 31056.1–  ORA-600[729] UGA Space Leak

寻找已知的错误和修复列表。

设置事件 10262:

确定泄漏的字节数是最小值,且没有发现其他错误,你可以选择忽略这些错误。90000个字节以内的泄漏是在容许范围内。

若泄露的字节量在容许范围内,又不想在alert.log文件中报错,那么设置事件10262。这样若泄漏在指定的字节数以内, alert log 文件上就不会报错ORA-600[729]。

a.在 init.ora 参数文件中设置下列事件. 此示例禁止报错小于90000字节的空间泄漏:

event = “10262 trace name context forever, level 90000”

  1. 停止并重新启动数据库

如果水平值设置为1,就禁用空间泄漏检查。不建议这么做,因为会错过大的内存泄漏。

如果事件值设定为大于1,该事件中指定字节数以内的空间泄漏都将被忽略。

是否出现漏洞?

有很多漏洞可能会导致该问题。此时最普遍的是:

1.
搜索跟踪文件,寻找:
‘XDB’ and kgbt’

如果找到了,该漏洞可能是:
Bug 7499301 – Memory leak in XDB / ORA-600 [729] Note 7499301.8

该问题在下列版本中已修复
12.1.0.1 (基础版)
11.2.0.2 (服务器补丁集)

2.
搜索跟踪文件,寻找:
kllcqgf:kllsltb

该漏洞可能是:
Bug 14385220 – Private memory leak of “kllcqgf:kllsltb” memory (ORA-600 [729] / ORA-600 [723]
note 14385220.8

这不可能是个大泄漏。如果是个小错误,如上所述,可以通过设置事件10262 进行掩饰。

该问题在12.2 (未来版) 中得到修复

3.
搜索跟踪文件,寻找:
“kxs-role”

该漏洞可能是:
Bug 9474750 – ORA-600 [729] space leak of “kxs-krole” memory Note 9474750.8
该问题在下列版本中得到修复

12.1.0.1 (基础版)
11.2.0.2 (服务器补丁集)

4.
搜索跟踪文件,寻找:
‘hssh’
‘horkmal’
‘ncoxdc’

如果找到一个或全部,该漏洞可能是:
Bug 9365381 – ORA-600 [729] having called an external procedure followed by PMON dump Note 9365381.8

该问题在下列版本中已得到修复
12.1.0.1 (基础版)
11.2.0.3 (服务器补丁集)

5.
欲知已修复错误的完整列表,请参考下面的文档:
Note 31056.1 ORA-600 [729] “UGA Space Leak”

 

6.

请注意,从11.2.0.4版起,ORA-600[729]被外部错误’ORA-10260:limit size (<nnnnn>) of the PGA heap set by event 10261 exceeded’代替

 

 

关注刘相兵的新浪微博

扫码加入微信Oracle小密圈,了解Oracle最新技术下载分享资源

Speak Your Mind

沪公网安备 31010802001379号

TEL/電話+86 13764045638
Email service@parnassusdata.com
QQ 47079569