SGA에서 shared pool 과 buffer cache 가 커졌다 작아졌다 난리부르스를 출 때...
확인은
select *
from (
select INST_ID,
COMPONENT,
OPER_TYPE,
OPER_MODE,
PARAMETER,
INITIAL_SIZE,
TARGET_SIZE,
FINAL_SIZE,
(final_size-initial_size)/1024/1024 as delta_mb,
STATUS,
START_TIME,
END_TIME
from GV$SGA_RESIZE_OPS
where inst_id=1
order by inst_id, END_TIME desc)
where rownum <= 50
만약 buffer cache 가 GROW 하고 shared pool이 줄어들 때 shared pool 쪽에서 library cache pin 이 일어날 수 있다. 잘못하면 이거 안풀리고 DB가 Hang까지 갈 수 있다.
왜 이런 일이 일어날까? 10g 에서부터 buffer cache 가 커지면 shared pool 의 영역을 일부 뺏어와서 쓰게 된다. 이 영역을 KGH: NO ACCESS 영역이라고 한다.
Resizing the SGA « Oracle Scratchpad 참고
오라클은 KGH: NO ACCESS 영역을 찜해놓고, 그 안에 있는 LCO를 바로 clean out 하지는 않는다. 그렇게 하기도 어렵고 대단히 무리한 CPU Operation 이 될 수 있기 때문이다. 그래서 영역을 일단 찜하고 그 안에 있는 LCO들이 unpin되면 그 영역을 buffer cache로 점진적으로 가져온다. 이럴 때 위의 쿼리에서 OPER_MODE 가 DEFFERED 로 찍힌다.
그러면 왜 library cache pin이 일어날까?
이건 추측인데... 메모리를 KGH: NO ACCESS 로 표시할 때 그 안에 들어가있는 LCO 들에 대해서 어떤 플래그를 달아야 하는데, 그 때 pin 이 걸리는게 아닐까 싶다. 확인할 길은 없다. 물론 영역 크기가 크면 자주 호출되는 LCO 가 걸려들 가능성이 높을거고 그때 pin 이 걸리겠지.
또 하나 관찰한 흥미로운 증상은, SGA Max > SGA Target 일 때 SGA resize가 더욱 빈번하게 일어난다는 거다. 거의 1~2분에 한번씩 일어나서 오라클 버그로 의심했으나
Simple Is Beautiful | SHARED POOL中KGH: NOACCESS占用大量内存的问题分析 참고
우리가 쓰는 10.2.0.3 에서는 패치가 되었다고 Oracle SR 결과 확인이 되었다. 그래서 궁여지책으로 SGA Max = SGA Target 으로 맞추고 나니 증상이 훨씬 덜해졌다. 이건 또 왜 이런걸까??
그리고.. SGA Max > SGA Target 으로 설정해놓고 몇G의 여유분을 놔둔다 하더라도 쎈 배치가 돌거나 어떤 일이 생기면 SGA Target을 넘어서서까지 메모리를 할당을 하는 것 같다. PGA도 pga_aggregate_target을 넘어서서 할당을 하는데 (v$pga_target_advice뷰의 over allocation참조) SGA Target도 마찬가지인듯. 그리고 Target을 넘어서서 메모리를 사용하고 나면 자동적으로 Target까지 shrink 를 시도하는게 아닌가 한다.
살펴보니 추측투성이네~
결론은...
ASSM쓸거면 SGA Max = SGA Target으로 해놓자.
이다.
Posted by maceo