UGA MEMORY LEAK 에러인 ORA-600[729] ERROR에 대한 이해

Oracle 2010. 9. 20. 12:45
PURPOSE

이 문서는 오라클 shadow 프로세스에게 할당되었던 메모리를 free 하는 과정에서 만날 수 있는
memory leak problem 에 대해서 소개하고자 한다. 메모리 leak dump 는 주로 session 이 logoff하는
과정에서 만날 수 있는 것으로서 user process에게 할당되었다가 사용된 heap을
ORACLE 서버가 free할 때 발생하는 것이다.

Problem Description

alert log 및 트레이스 화일에는 이와 같은 에러가 남게 된다.

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


Explanation

Heap dump의 내용과 어떤 경우에 이런 에러가 발생하는지에 대해 좀 더 자세히 알아보기로 한다.

Oracle이 process를 종료하면, 점유하였던 메모리와 release되는 memory를 비교하여
size가 정확히 일치하지 않으면 ora-600[729] 에러를 발생시키고, shutdown 시에 SGA 등을
모두 release하고 일부 메모리 영역이 여전히 남아있으면 ora-600[730]을 report하게 된다.

User가 oracle에 접속하면 user process가 생성이 되고, 각 user process마다 heap이 할당된다.
모든 프로세스들은 자신의 memory heap을 갖게 된다.
Heap을 구성하는 각 extent는 연속적인 chunk로 이루어져 있는데, 이러한 chunk들은 각각
다음과 같은 type들을 가질 수 있다.

1. FREE : free chunk는 heap manager가 다시 할당할 수 있는 비어있는 부분.
Free 영역은 할당된 chunk가 해제가 된 상태로 이것은 인접한 free chunk들과
merge한 다음에 Free list에 등록된다.

2. FREEABLE : freeable은 flush를 시켜서 다시 merge를 할 수 있는 후보.
SYS.X$KSMSP를 조회하면 freeable space에 대한 조각을 확인할 수 있다.

3. RECREATABLE : memory chunk가 heap에 할당될 때, chunk의 내용이 재생성가능한 것으로
명시할 수 있다. 이러한 option으로 생성되면, 이 chunk는 사용 중이지 않을 때 명시적으로
'unpinned'될 수 있다. 사용자가 heap으로부터 space를 요청할 때 공간이 없으면,
이러한 unpinned 혹은 recreatable chunk를 해제하고 사용할 수 있다.
Unpinned chunk는 LRU list에 존재하게 되어 무엇을 가장 먼저 비게 할 것인지 결정할 수
있으며, 이러한 방법은 row cache나 library cache에 이용된다.

4. PERMANENT : 이 영역은 일단 할당되면 해제되지 않는 메모리 부분인데, 각 heap descriptor는
이러한 permanent chunk 부분을 가리키는 pointer를 갖고 있다.
이 permanent chunk는 두 부분으로 나누어지는데, 앞 부분은 이미 permanent로 할당된
메모리 부분이고, 뒷 부분은 아직 할당되지 않은 reserved area 이다.
Chunk의 header에는 어느 부분부터가 reserved area의 시작인지 나타내는 pointer가 있다.
실제 permanent 메모리는 프로세스가 종료하여 heap 자체가 해제되면 그 영역도 해제가 된다.

5. FREEABLE WITH MARK

Permanent 메모리 영역을 해제할 때 완전히 free 시키지 않고, Freeable with MARK 상태로
두었다가 다시 restore 하기도 하는데, 이 chunk type은 oracle 10g 에서는 널리 알려져
있지는 않다.

[ Extent의 할당과 해제 ]

연속된 chunk들의 집합을 extent라고 한다.
즉, heap에 포함되어 있는 extent들의 집합 안에서 요청한 크기의 조각을 할당받게 된다.
만약 이 때 발견하지 못하면, heap manager는 새로운 extent를 요청하여 이것을 heap에 추가한다.

각 extent는 오직 한 종류의 chunk type만 갖는 것이 아니고, 다양한 type의 chunk를 가질 수 있다.
프로세스가 memory chunk를 요청할 때 heap manager는 필요한 size 만큼의 공간을 할당해 준다.
프로세스가 종료하면 프로세스에게 할당되었던 모든 메모리는 자동으로 release가 된다.
프로세스 종료(logoff) 시 RECREATABLE chunk와 FREEABLE chunk는 FREELIST 로 등록되었다고
판단을 하고, 메모리가 release될 때 아직 남아 있는 할당된 heap들은 free가 되는데,
ORACLE server 입장에서는 일반적으로 heap이 free가 될 때 PERMANENT chunk로 할당된 chunk와
freelist 상에 있는 FREE chunk들을 free시킬 대상으로 삼는다.

프로세스가 FREEABLE 혹은 RECREATABLE type 으로 남아 있는 chunk를 발견한 경우는
해당 프로세스가 memory deallcation 을 제대로 수행하지 않았다는 것을 의미하게 된다.
이러한 상황을 space leak 이라 부른다.
오라클은 일반적으로 SGA heap, UGA heap, Large pool heap, 그리고, PGA heap에 대해
space leak을 check한다. Space leak error는 BACKGROUND_DUMP_DEST 또는
USER_DUMP_DEST 내에 trace file 안에 남게 된다.

Symptoms

Space leak problem은 일반적으로 trace information과 heap dump를 capture하여 떨어뜨리게 된다.
OS와 ORACLE process header 정보 다음에 trace file 내에 이와 같은 정보를 볼 수 있다.

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

바로 위 라인을 보면 이 memory leak 은 UGA 영역에서 발생한 것이고, leak이 일어난 size는
560 bytes임을 알 수 있다.

Heap은 연속된 chunk의 집합으로 이루어지고, heap이란 heap descriptor와 extent라고 불리는
메모리 조각의 집합으로 구성되며, 각 extent는 연속된 메모리 조각으로 정의가 된다.

******************************************************
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

위 dump에서 heap name은 SESSION HEAP 이고, Heap descriptor는 0xaef81d0 임을 알 수 있다.

아래의 extent 상세 정보를 보면 release되지 않은 chunk는 4085a350임을 나타낸다.
이것은 recreatable chunk이고, 그 size는 560 bytes이다. 이 수치는 [729], [560], [space leak]
에러에 나타난 bytes와 수치가 정확히 일치한다.

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 " "

메모리 leak issue를 분석할 때 FREEABLE과 RECREATABLE type의 chunk를 식별해야 한다.
그 수치는 에러의 arguments에 나타난 leak 현상을 보이는 memory bytes의 sum 과 일치해야 한다.

원인

ora-600[729] error는 memory leak 현상으로 발생하는 오라클 에러라 할 수 있다.
그러나, 이러한 현상은 정상적인 경우도 발생할 수 있으며, 지속적으로 반복적으로 발생하여
memory free 영역이 계속 줄어드는 현상으로 나타나지 않는 한, 특별히 문제 시 되지 않으며,
일정 사이즈 이하의 leak은 message로 나타나게 하지 않도록 조치할 수 있다.


Workaround

아래의 예는 2M 이하의 leak 발생 시 에러가 나지 않게 하는 것으로, 만약 100k정도나 1~2M 이하의
leak 문제가 보인다면 발생하지 않게 이와 같이 셋팅할 수 있다.

event="10262 trace name context forever, level 2000000"


Solution Description

Space leak 문제를 어떻게 다룰지에 대해 자세한 사항은 다음의 문서에서 안내하고 있다.

Step 1. alert log를 review하고, trace file 정보를 분석해야 한다.
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. argument [729]는 space leak 문제 발생 시 대표적인 에러 code이다.
b. argument [152]는 에러에 보고된 leak된 bytes의 수치이다.
c. argument [space leak] 는 항상 space leak 으로 나타난다.

Step 2. 연관된 트레이스 화일 분석

일반적인 trace information은 다음과 같다.

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

위 트레이스는 UGA로부터 leak된 메모리라는 것과 memory leak의 size가 152 bytes 라는 것을
의미한다.


Step 3. leak이 session logoff로부터 발생했다는 것을 확인한다.

Call Stack Trace 부분을 보면 opilof 가 stack 상에 보인다면 이것은 session logoff 시
발생했음을 알 수 있다.
실제 발생한 call stack trace의 예는 다음과 같다.

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 ?

Step 4. Dedicated Server인지, MTS 환경인지 확인한다.

1) 만약 Dedicated server 환경이라면 이 error의 impact은 process가 종료할 때 끝날 것이다.
사실 에러의 영향도는 거의 없고, 데이타베이스에 실질적인 문제는 없을 것이다.
2) MTS(Multi Threaded Server) 환경이거나 XA transaction process manager/monitor를 사용하는 환경이라면
leaked memory가 SGA 영역에 있을 것이다. 이 때에는 ora-4030, ora-4031 과 같은 다른 에러가 발생했는지
alert log를 보아야 한다.

Step 5. Leak problem을 무시할 수 있는가 ?

1) 이 물음에 대해서는 다른 에러는 없는지 우선 살펴보아야 한다. 만약 동시에 발생한 다른 에러가 전혀 없다면
이 에러는 무시해도 되고, 다시 재현하기가 쉽지 않은 case일 것이다. 무엇보다도 90,000 bytes 보다 작은
size의 leak은 중요하지 않다. 이에 대한 solution은 event 10262 를 셋팅하는 것이다.

2) 만약 leak이 SGA 내에 발생했는가?
ALERT log를 살펴보고, shared pool 이나 OS memory 와 관련한 추가적인 문제는 없는지 ORA-4030 또는
ORA-4031 발생 여부를 확인해야 한다.

3) 메모리 leak 현상이 특정 작업을 수행 시에 재현이 되는가?
만약 특정 작업 시에 재현이 된다면, leak 현상이 known bug인지 확인을 위해
추가적인 investigation이 필요한 경우이다.
다음 문서를 보면 known bug 와 fix된 version들을 확인할 수 있다.

Note 31056.1 ORA-600 [729] UGA Space Leak for a list of known bugs and fixes

Step 6. Event 10262 셋팅하기

만일 leak된 bytes 수치가 무시해도 될 만한 수치라는 것이 확인이 되면, 이 에러를
무시하기 위해 event를 걸 수 있다.

이 event를 셋팅을 하게 되면 90,000 bytes보다 작은 크기의 leak에 대해서는 alert log에 나타나지 않게 할 수 있다.

a. 다음과 같이 initSID.ora file에 event를 셋팅한다.

event="10262 trace name context forever, level 90000"

b. 데이타베이스를 restart해야 event가 효력을 미친다.

[ 참고 ]

만일 level 을 1로 하게 되면, space leak checking이 disable된다. 1로 하게 되면 매우
큰 사이즈의 memory leak을 놓칠 수 있으므로, 권장하지 않는다.
Level 을 1보다 큰 수로 하게 되면 event 안에 명시된 숫자보다 작은 memory leak에
대해서는 무시하도록 하는 역할을 한다.

Reference documents

<Note:403584.1> Understanding and Diagnosing ORA-600 [729] Space Leak Errors

출처 : http://j.mp/cRNlnc


Oracle 11gR1 11.1.0.6의 Memory Leak Bug와 연관하여, Memory Leak Error에 대한 이해를 돕기 위한

문서입니다.

:     

TISTORY에 Login하려면 여기를 누르세요.