태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

'memory_target'에 해당되는 글 1건

  1. 2009.03.25 오라클 11g의 automatic memory management(AMM)에 대한 아름다운 Test Case (7)

오라클 11g의 automatic memory management(AMM)에 대한 아름다운 Test Case

오라클 2009.03.25 19:19
오라클 11g는 SGA뿐 아니라 PGA까지 포함하는 강력한 자동 메모리 관리(Automatic Memory Management:AMM) 기능을 제공한다.

앞으로는 오라클에 얼마만큼의 메모리를 써라~고 지정만 해주면 된다는 것을 의미한다. 멋진 일이긴 하지만, 실제 적용할 때는 염두에 두어야 할 몇가지 함정들이 있을 것이다.

간단해 보이지만, AMM의 속성을 잘 알 수 있는 Test Case를 만들어 보겠다.

  • Memory Target, Memory Max Target 값을 200M로 설정한다.
  • DB Cache와 Shared Pool 간의 경합을 시뮬레이션하기 위해, logical reads와 hard parse를 혼합해서 과도하게 발생시킨다.
  • 이 상황에서, PGA aggregate target 의 변화가 발생하는지 체크한다.


*.memory_target=200m
*.memory_max_target=200m

declare
  pat1     varchar2(1000);
  pat2     varchar2(1000);
  va       number;
begin
  select ksppstvl into pat1
    from sys.xm$ksppi i, sys.xm$ksppcv v   -- synonym of x$ table
    where i.indx = v.indx
    and i.ksppinm = '__pga_aggregate_target';

  for idx in 1 .. 1000000 loop

    -- Mixed workloads of heavy logical reads and hard parse
    execute immediate
       'select count(*) from t3 where 10 = mod('||idx||',10)+1' into va;

    if mod(idx, 100) = 0 then
      sys.dbms_system.ksdwrt(2, idx || 'th execution');

      for p in (select ksppinm, ksppstvl
          from sys.xm$ksppi i, sys.xm$ksppcv v
          where i.indx = v.indx
          and i.ksppinm in
           ('__shared_pool_size', '__db_cache_size',
              '__pga_aggregate_target'))  
             loop

          sys.dbms_system.ksdwrt(2, p.ksppinm || ' = ' || p.ksppstvl);
      end loop;

      select ksppstvl into pat2
      from sys.xm$ksppi i, sys.xm$ksppcv v
      where i.indx = v.indx
      and i.ksppinm = '__pga_aggregate_target';

      -- Do I have PGA aggregate target change?
      if pat1 <>  pat2 then
        sys.dbms_system.ksdwrt(2, 'yep, I got it! pat1=' || pat1 ||', pat2='||pat2);
        exit;
      end if;
    end if;
  end loop;
end;
/


결과는 아래와 같다. (alert log 파일)

100th execution
__shared_pool_size = 92274688
__db_cache_size = 16777216
__pga_aggregate_target = 83886080
200th execution
__shared_pool_size = 92274688
__db_cache_size = 16777216
__pga_aggregate_target = 83886080
300th execution
__shared_pool_size = 88080384
__db_cache_size = 20971520
__pga_aggregate_target = 83886080
400th execution
__shared_pool_size = 92274688
__db_cache_size = 16777216
__pga_aggregate_target = 83886080
500th execution
__shared_pool_size = 88080384
__db_cache_size = 20971520
__pga_aggregate_target = 83886080
600th execution
__shared_pool_size = 92274688
__db_cache_size = 20971520
__pga_aggregate_target = 83886080
700th execution
__shared_pool_size = 92274688
__db_cache_size = 20971520
__pga_aggregate_target = 83886080
800th execution
__shared_pool_size = 92274688
__db_cache_size = 20971520
__pga_aggregate_target = 83886080
900th execution
__shared_pool_size = 92274688
__db_cache_size = 20971520
__pga_aggregate_target = 83886080
1000th execution
__shared_pool_size = 92274688
__db_cache_size = 20971520
__pga_aggregate_target = 83886080
1100th execution
__shared_pool_size = 92274688
__db_cache_size = 20971520
__pga_aggregate_target = 83886080

1200th execution
__shared_pool_size = 92274688
__db_cache_size = 37748736
__pga_aggregate_target = 58720256
yep, I got it! pat1=83886080, pat2=58720256


기대했던대로, Oracle은 부하에 따라 Buffer Cache의 크기와 Shared Pool의 크기를 주거니 받거니 하면서 변경하는 것을 볼 수 있다.

그런데, 1200번째 실행에서는 갑자기 PGA aggregate target 영역에서 메모리를 훔쳐서 Buffer Cache로 가져다쓴다. 이 역시 AMM(Automatic Memory Management)에서는 충분히 발생가능한 일이다.

문제는 어떤 특정 상황에서는 위험이 발생할 수 있다는 것이다. PGA aggregate target가 바뀐다는 것은 Hash/Sort관련 Operation의 Cost가 변경된다는 것을 의미한다. 따라서 갑자기 실행 계획이 바뀌는 것과 같은 위험한 상황이 발생 할 수도 있다. PGA Aggregate Target이 변하면 Hash/Sort의 성능 자체에도 영향을 주게 된다.

조금 극단적인 Test Case라고 할 수 있지만, 이런 현상이 논리적인 빈틈이나 버그로 인해 끔찍한 결과를 초래할 수 있다는 것은 경험으로 잘 알 고 있을 것이다.

오라클 11g가 좀 더 대중화되면, 이런 유형의 문제에 대한 실사례를 접할 수 있을 것이다.


신고
Trackbacks 5 : Comments 7
  1. oracler 2009.03.31 22:54 신고 Modify/Delete Reply

    끄응...이 글과 상관없는 걸 질문해도 될련지요. 염치불구하고.. 쩝

    1. clob, blob 처럼 lob 타입이 컬럼으로 있는 테이블에 대량의 데이타(1000만건 이상)
    을 insert 할때는 현저하게 느려지는데 성능 개선 방법이 있는지요.
    lob 타입컬럼을 빼고 insert 하는 경우와 lob 타입 컬럼을 포함해서
    insert 하는것이 성능 차이가 아주 많이 납니다. 10배 100 이상 극단적으로..

    2. lob 타입 컬럼에 대해서는 테이블생성시 자동으로 인덱스가 만들어지는데 (SYS_XX)
    이 lob type 인덱스를 수작업으로 제거하거나 재생성할수 있는지요.
    위 1번에서 대량 데이타 insert 시 미리 index 제거하고 하는데
    이 lob type 컬럼 인덱스는 처리를 못했습니다.
    이 인덱스때문에 insert 가 느린건지는 알수없네요.

    3. lob type 의 인덱스는 사이즈가 다른 btree 인덱스에 비해 아주 작더군요.
    이게 무슨 메커니즘으로 작동되는지 궁금합니다.
    꼭 있어야 하는건지. (하긴 꼭 있어야 하니깐 자동으로 만들어지겠지만)

    미리 감사드립니다.

  2. 욱짜 2009.04.01 08:16 신고 Modify/Delete Reply

    번거로우시겠지만, 이 질문을 다른 분들도 공유할 수 있도록 http://ask.ex-em.com 에 올려주시겠습니까?

  3. oracler 2009.04.01 23:52 신고 Modify/Delete Reply

    인덱스 문제가 아니었군요 cache 는 메모리 소진문제로 사용못할거 같네요. nocache 로 놓고 logging nologging 을 확인해봐야 할듯합니다.. 감사합니다.

  4. 욱짜 2009.04.02 08:34 신고 Modify/Delete Reply

    넵. 다양한 옵션을 테스트하셔서 최적의 설정을 찾으시는 것이 가장 좋은 방법일 듯 합니다.

    한가지 아이디어는 Insert시에는 cache 속성을 켰다가 Insert가 끝나면 cache 속성을 끄는 것도 생각해 볼 수 있습니다.

  5. oracler 2009.04.07 00:19 신고 Modify/Delete Reply

    대용량 DML 튜닝은 쿼리와는 다를거 같은데요.

    cache / logging 옵션 alter 도 있긴한데..
    이처럼 대용량 insert 시에 더 무서운것이 아카이브의 변수가 있습니다.

    blob 컬럼 1000만건 insert 처럼 대용량 insert 의 경우엔
    데이타 볼륨 자체가 매우커서 DB 아카이브 상태가 다른 일반적인 insert 보다 훨씬 더 큽니다.

    exem 답변은 cache 가 답인듯으로 받아들여질수 있는데
    insert 그것만 따지면 빠르겠지만 다른 쿼리들이나 시스템 영향 주는것 생각하면
    blob 컬럼에 대한 cache 옵션은 대다수의 경우엔
    일반적인 답으로서는 고려하면 안될듯한 옵션이고
    그런 DB 전체적 관점에서 부작용까지 같이 언급을 해주시면 좋겠습니다.

    성능 튜닝이 insert 등 DML 에 촛점을 맞춘 경우는 드물었던것 같습니다.
    DML 로 접어들면 select 때와는 다르게 고려할 변수가 상당히 많죠.
    사실 대부분이 "성능"하면 Query (SELECT) 를 먼저 생각하는데, 고객은 그런것 모르고 오로지 응답만을 봅니다.

    운영DB 는 아카이브겠지만 구축환경은 대부분 노아카이브입니다.
    DML 의 성능관점에서 보면 SQL 트레이스 뜨는것보다
    이런 환경적인 튜닝요소가 더 중요할수 있다는겁니다.

  6. 욱짜 2009.04.07 08:25 신고 Modify/Delete Reply

    이 의견도 Ask Exem에 남겨주시면 더 좋을텐데요. ^^

    DML 튜닝은 Query 튜닝과는 또 다른 요소들이 많죠. 특히 주의할 것이 말씀하신 것처럼 Redo 양을 튜닝하는 것입니다. Redo를 최적화하기 위해 다양한 기법을 사용할 수 있습니다.

    시스템마다 CPU 성능, Memory 크기, Storage 성능, 환경설정이 다르고 DML Pattern마다 Logical Reads와 Redo가 생성되는 패턴이 다르기 때문에 "DML 튜닝은 이렇게 하라"는 법칙을 만들기는 거의 불가능합니다. 몇 가지 중요한 법칙은 기억하되 개별 DML은 모두 다른 문제로 인식하고 튜닝을 하는 것이 정답일 것 같습니다.

    DML 튜닝에 있어서도 SQL*Trace는 중요한 역할을 합니다. 만일 Redo 양에 문제가 있다면 log file parallel write나 log file switch 관련 대기 현상이 기록될 겁니다. 지나친 Data File I/O가 문제라면 free buffer space나 db file parallel write같은 대기 현상이 나타날 것이구요. 단, Redo의 양이나 기타 중요한 정보들은 SQL*Trace에는 나타나지 않기 때문에 저 같은 경우는 SQL*Trace와 함께 제가 구현한 일종의 Session Monitoring Script를 사용합니다. Session Stats, Time Model, Wait Event, Latch Activity 등의 정보를 종합적으로 봐서 튜닝 요소를 찾는 방법을 선호합니다. 이런 다양한 정보들을 수집해야만 좀 더 과학적인 튜닝이 가능합니다.

  7. 이재현 2011.06.02 17:46 Modify/Delete Reply

    관리자의 승인을 기다리고 있는 댓글입니다

Write a comment

티스토리 툴바