Oracle/Admin2013. 4. 16. 09:57

 

 

 

오라클 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가 좀 더 대중화되면, 이런 유형의 문제에 대한 실사례를 접할 수 있을 것이다.

 

출처 : http://ukja.tistory.com/216

Posted by 자수성가한 부자