4. 메모리 구조

3가지 주요 메모리 구조
  • 시스템 글로벌 영역 (SGA, System Global Area)
  • 프로세스 글로벌 영역 (PGA, Process Global Area)
  • 사용자 글로벌 영역 (UGA, User Global Area)


메모리 관리 방법
  • 수동으로 관리하는 방법
  • 자동으로 관리하는 방법
    • DBA가 SGA와 PGA 메모리 영역과 관련된 두가지 파라메터를 설정하는 것
    • 오라클 11g 이상에서 사용하는 방법으로 MEMORY_TARGET 파라미터만 설정하여 사용하는 것.


4.1 프로세스 글로벌 영역과 사용자 글로벌 영역

PGA: Process Global Area
  • 특정 프로세스에 할당한 고유한 메모리의 일부분
  • 단일 운영체제 프로세스 또는 쓰레드와 관련된 메모리
  • 시스템 내의 어떠한 다른 프로세스 나 스레드들에도 침범 당하거나 간섭받지 않는다.
  • C 함수인 malloc()이나 memmap()을 통해 할당됨.
  • 시스템의 운영 시간 동안 증가되거나 축소가 가능
  • SGA 영역내에 절대 위치 하지 않는다.
  • 쿼리 실행에 필요한 작업에 사용됨.


UGA: User Global Area
  • 세션의 고유 영역
  • 특정 세션이 항상 접근할 수 있어야 하는 메모리
  • 데이터베이스의 접속 방식에 따라 위치가 달라짐. (shared mode : sga내에 존재 dedicated mode : pga내에 존재)


PGA내의 non-UGA 메모리 관리 방식
  • 수동 PGA 관리 방법 : 각 프로세스 별로 얼만큼 사용할지 설정
  • 자동 PGA 관리 방법 : 인스턴스 전체에 대해 얼마나 많은 메모리를 사용할지 설정
    • PGA_AGGREGATE_TARGET : 오라클에 PGA 메모리를 얼마나 사용할 것인가를 알려주는 방법
    • MEMORY_TARGET : 데이터베이스 인스턴스가 SGA와 PAG에서 사용할 총 메모리량을 엄라로 할것인가를 알려주는 기법, PGA의 크기는 오라클이 알아서 설정함.
    • 자세한 정보 : http://wiki.ex-em.com/index.php/PGA_AGGREGATE_TARGET


WORKAREA_SIZE_POLICY
  • PGA 메모리 관리 시 이 파라메터를 통해 통제되며 세션 수준에서 변경이 가능
  • 오라클 9i 릴리즈 2 이상에서는 AUTO 지금 그 이하는 MANUAL


4.1.1 수동 PGA 메모리 관리

수동 관리시 필요한 파라메터
  • SORT_AREA_SIZE : 디스크에 쓰기 이전 정보를 정렬하는데 사용될 메모리 총량
  • SORT_AREA_RETAINED_SIZE : 정렬작업이 완료된 후에 정렬한 데이터를 유지하기 위해 사용될 메모리 양
  • HASH_AREA_SIZE : 서버 프로세스가 해시 테이블을 저장하는 데 사용하는 메모리의 양.


  • SORT_AREA_SIZE가 512K, SORT_AREA_RETAINED_SIZE가 256K라면 데이터를 정렬할때 512K 까지 메모리를 사용하고, 완료하고 나면 256K로 줄어들고, 256K보다 크면 디스크로 내려쓴다.


UGA/PGA 메모리 사용량 테스트*


--run_query.sql
connect /
set serveroutput off
set echo on
column sid new_val SID
select sid from v$mystat where rownum = 1;
alter session set workarea_size_policy=manual;
alter session set sort_area_size = &1;
prompt run @reset_stat &SID and @watch_stat in another session here!
pause
set termout off
select * from t order by 1,2,3,4;
set termout on
prompt run @watch_stat in another session here!
Pause
and then run:

--2.관찰을 위한 작은 테이블을 리셋하고 SQL*Plus 변수에 SID를 설정
--reset_stat.sql
drop table sess_stats;
create table sess_stats
( name varchar2(64), value number, diff number);
variable sid number
exec :sid :=&1


--3.스크립트에 세션의 통계값을 INSERT하고 이후에 통계값을 갱신하기 위해 
MERGE SQL문을 생성
--watch_stat.sql
merge into sess_stats
using
(
select a.name, b.value from v$statname a, v$sesstat b
where a.statistic# = b.statistic#
and b.sid = :sid
and (a.name like '%ga %' or a.name like '%direct temp%')
) curr_stats
on (sess_stats.name = curr_stats.name)
when matched then
update set diff = curr_stats.value - sess_stats.value,
value = curr_stats.value
when not matched then
insert (name, value, diff)
values (curr_stats.name, curr_stats.value, null)
/
select name,
case when name like '%ga %'
then round(value/1024,0)
else value
end kbytes_writes,
case when name like '%ga %'
then round(diff / 1024,0)
else value
end diff_kbytes_writes
from sess_stats
order by name;



SQL> @/oracle/test.sql 65536
SQL> column sid new_val SID
SQL> select sid from v$mystat where rownum = 1;

       SID
----------
      1038

SQL> alter session set workarea_size_policy=manual;

Session altered.

SQL> alter session set sort_area_size = &1;
old   1: alter session set sort_area_size = &1
new   1: alter session set sort_area_size = 65536

Session altered.

SQL> prompt run @/oracle/reset.sql &SID and @watch_stat in another session here!
run @/oracle/reset.sql       1038 and @watch_stat in another session here!
SQL> pause



SQL> @/oracle/reset.sql 1038

Table dropped.


Table created.


PL/SQL procedure successfully completed.

SQL> @/oracle/watch.sql

6 rows merged.


NAME                                                             KBYTES_WRITES
---------------------------------------------------------------- -------------
DIFF_KBYTES_WRITES
------------------
physical reads direct temporary tablespace                                   0
                 0

physical writes direct temporary tablespace                                  0
                 0

session pga memory                                                         585



NAME                                                             KBYTES_WRITES
---------------------------------------------------------------- -------------
DIFF_KBYTES_WRITES
------------------
session pga memory max                                                     585


session uga memory                                                         170


session uga memory max                                                     170



6 rows selected.

SQL>


_AREA_SIZE 설정시 기억해야 하는 사항
  • 메모리의 최대값을 제어한다.
  • 하나의 쿼리에 동시에 다수의 커서를 오픈할 수 있는데, 각각의 커서마다 SORT_AREA_RETIANED 영역이 필요하다. 즉, 이 설정은 세션별 제한이 아니라 작업 별 제한이다.
  • 이 메모리 영역은 요구할 경우에만 할당하는 방식이다.


4.1.2 자동 PGA 메모리 관리

자동 PAG 메모리 관리 방식의 장점
  • 각각의 파라메터들의 값을 무엇으로 할 것인지 고민하지 않아도 된다.
  • 전체 메모리를 전체 사용자가 활용하는 방식이라 작업 부하량의 변화를 고민하지 않아도 된다.
  • 사용할 전체 사이즈만 설정함으로서 자잘한 메모리 관리를 신경쓰지 않아도 된다.


자동 PGA 메모리 관리 설정 절차는 두 개의 인스턴스 초기화 파라미터에 적절한 값을 결정하는 것을 포함한다.
  • WORKAREA_SIZE_POLICY : 할당 대상 메모리량을 제어하기 위해 정렬 영역과 해시 영역 파라미터들을 MANUAL이나 AUTO로 설정할 수 있다.
  • PGA_AGGREGATE_TARGET : 데이터를 정렬하거나 해시작업을 수행하기 위해 사용하는 모든 작업영역에 대해 통틀어 얼마나 많은 메모리를 인스턴스에 할당할 것인가를 제어하는 파라메터


11g 부터는 MEMORY_TARGET 으로 제어한다.
  • WORKAREA_SIZE_POLICY가 AUTO 이고 PGA_AGGREGATE_TARAGET이 0이 아니면 PGA를 자동설정하는 것이다.
  • ALTER SESSION, ALTER SYSTEM 모두 가능하다.


메모리 할당방식 결정하기
자동으로 관리할 경우
  • PGA_AGGREGATE_TARGET의 최고의 한계값을 설정하는 것이다. 즉, 미리 할당하는 값은 아니다.
  • 하나의 세션은 PGA_AGGREGATE_TARGET의 약 5%만 사용이 가능하다. ( 수치는 항상 변할 수 있다.)
  • 동시 사용자가 늘어가면 각각 사용하는 PGA 메모리 양은 줄어든다.
  • 하나의 병렬 쿼리는 PGA_AGGREGATE_TARGET의 30% 까지만 사용이 가능하다.


PGA_AGGREGATE_TARGET을 사용한 메모리 제어
  • 인스턴스가 사용하는 PGA 메모리의 총량을 제어하기 위해서 PGA_AGGREGATE_TARGET을 사용할 수 있지만, 필요하다면 오라클은 그 값을 넘어 서곤 한다.


수동/자동 메모리 관리기법의 선택

  • 메모리 관리 시스템의 목표는 시스템의 메모리에 대한 요구가 늘어나거나 줄어듦에 따라 메모리를 서로 다르게 사용할 수 있게 하자는 것이다.
  • WORKARAE_SIZE_POLICY=AUTO로 설정하는 것은 바로 이런 목표를 달성하기 위한 최선의 길이다.
  • 특정 사용자에게 몰아줘야 하는 경우에는 ALTER SESSION 명령어를 사용하여 자동 메모리 기능을 disable하고, 수동으로 파라메터를 설정한다.