|
▒ System Global Area (SGA)
거의 모든 오라클 프로세서가 Access하는 대규모 공유 메모리 Segment이다.
▒ Process Global Area (PGA)
하나의 프로세스 또는 쓰레드를 위한 개별적인 메모리로서 다른 프로세스 / 쓰레드에서는 Access할 수 없다.
이 메모리는 일반적으로 C의 runtime 함수인 malloc()이나 memmap()을 통해서 할당되며, 시스템의 운영 시간 동안 증가되거나
축소된다.
▒ User Global Area (UGA)
사용자 Session의 고유 영역이며, 특정 Session이 항상 접근할 수 있어야 하는 메모리이다.
(Shared Server 모드일 경우에는 SGA, Dedicated Server 모드일 경우에는 PGA)
Shared Server 커넥션을 통하여 접속한다면 UGA는 SGA 내에 존재하지만, Dedicated Server 커넥션을 사용하면
Session 상태에 대한 보편적인 접근에 대한 요구가 없어지므로 UGA는 PGA와 같은 것을 의미하게 된다.
PGA는 프로세스 메모리를 담고 있으며, UGA도 함께 포함할 수 있다. PGA 메모리의 다른 영역은 일반적으로
in-memory 정렬, Bitmap Merging 그리고 Hashing과 같은 작업에도 사용된다.
Bitmap Merging는 Bitmap Index를 타고 내려가 데이터를 병합해서 정보를 가지고 있다가 실행계획에 의해서 실행되는 것을
말하며, Hashing은 Hashing은 하나의 문자열을 원래의 것을 상징하는 더 짧은 길이의 값이나 키로 변환하는 것이다.
그 이유는 원래의 값을 이용해 찾는 것보다 더 빠르기 때문에 Hashing은 Database 내의 항목들을 색인하고 검색하는데 사용된다
오라클에서는 두 가지 메모리 관리방법이 있다.
1. 수동 PGA 메모리 관리
- 수동 PGA 메모리 관리에서 크기에 가장 큰 영향을 주는 Parameter들은 다음과 같다.
- Sort_Area_size : 디스크에 쓰기 이전 정보를 정렬하는데 사용될 메모리 총량
- Sort_Area_Retained_size : 정렬작업이 완료된 후에 정렬한 데이터를 유지하기 위해 사용될 메모리의 양
즉 Sort_Area_size가 512KB이고 Sort_Area_Retained_size가 256KB라고 하면
서버 프로세스가 초기 Query 처리 단계에서 데이터를 정렬하기 위해 512KB까지
메모리를 사용하고 작업을 완료할 때 영역은 256KB로 줄어들고 256KB안에 포함
안되는 정렬 데이터는 Temporary Tablespace에 기록된다.
- Hash_Area_Size : 서버 프로세스가 Hash Table을 저장하는 데 사용하는 메모리의 양.
이 Parameter에서 정의하는 메모리 영역은 커다란 집합과 또 다른 집합을 조인할 때
사용하는 Hash Join에서 많이 활용된다. 두 집합 중 더 작은 쪽이 메모리에 Hash되며
메모리의 Hash영역을 초고하는 부분은 Join Key에 의해 Temporary Tablespace에
저장된다.
2. 자동 메모리 관리
- 자동 관리 방식에서 먼저 할 일은 단순히 SGA를 쓸 수 있게 그 크기만 정하는 것이다.
SGA는 고정 크기의 메모리 조각이기 때문에 정확하게 크기를 알 수 있고 그것이 바로 SGA의 총량이다.
- Workarea_Size_Policy : 할당 대상 메모리량을 제어하기 위해 정렬영역과 Hash영역 Parameter들을
Manual이나 Auto로 설정할 수 있는데, Auto는 현재 Database의 작업부하에 근거해
할당되는 메모리량을 자동으로 조정할 수 있고 기본값 및 권장값은 Auto이다.
- Pga_Aggregate_Target : 데이터를 정렬하거나 Hash작업을 수행하기 위해 사용하는 모든 작업영역에 대해
통틀어 얼마나 많은 메모리를 Instance에 할당할 것인가를 제어한다.
Workarea_Size_Policy가 Auto로 설정되고 Pga_Aggregate_Target의 정의값이
0 이 아니라면 Instance가 자동 PGA 메모리 관리를 하는 것이다.
- 자동 PGA 메모리 등장 배경
- 자동 PGA 메모리 관리의 최종 목표는 메모리 활용을 극대화 하는 것이다. 만약 수동 메모리 관리 환경을 보면
Sort_Area_Size를 10MB로 설정되어 있고, 한 명의 사용자가 정렬 작업시 최대 10MB까지 사용할 수 있지만
100명의 사용자가 동일한 작업을 한다면 1,000MB까지의 메모리를 사용할 것이다. 가용한 메모리가 500MB
이면 한 명의 사용자가 정렬 작업을 수행하는 데 충분하지만 100명의 사용자가 작업을 한다면 한 명이 작업을
할 때보다 훨씬 적은 메모리를 각각 사용할 수밖에 없을 것이다. 이 개념이 자동 PGA 메모리 관리기법을
설계하게 된 배경이다.
▒ Redo Buffer
Redo Buffer는 Online Redo Log를 작성하기 위해 필요한 데이터를 임시로 저장하는 공간으로 Redo의 내용을 디스크에 쓰기
전에 보관하는 곳이다. 메모리에서 메모리로 데이터를 전송하는 것이 메모리에서 디스크로 데이터를 전송하는 것보다 빠르기
때문에, Redo Log Buffer를 사용하면 Database 동작의 속도 향상에 도움이 된다.
Redo Log 데이터를 오랫동안 Redo Buffer에 담을 이유는 없기 때문에 LGWR 백그라운드 프로세스가 일정 조건을 갖추면
Redo Buffer를 비우고 로그에 데이터를 저장한다.
- 매 3초마다
- commit 할 때마다
- LGWR에 로그 파일 Switch 요청이 있을 때
- Log Buffer가 1/3 찼거나 Log Buffer에 Redo Log 데이터의 크기가 1MB가 됐을 때
위와 같은 이유로 Redo Buffer의 크기가 매우 크게 설정되어도 좋은 성능을 기대하긴 어렵다.
▒ Block Buffer Cache
Block Buffer Cache는 디스크에 쓰기 전, 그리고 디스크로부터 읽은 후의 Database 블록을 저장하는 공간으로서 아주 중요한
SGA 영역이다. 만약 Block Buffer Cache가 너무 작으면, Query 실행이 끝나지 않을 것이다.
초기 오라클은 한 개의 Block Buffer Cache를 가지고 모든 Segment의 블록들은 모두 이 Block Buffer Cache 영역으로 들어갔다
오라클 8.0이 시작되면서 SGA에서 개별 Segment들을 따로 저장할 수 있는 세 개의 저장 공간을 갖게 되었다.
- Default Pool : 모든 Segment Block들이 일반적으로 캐시되는 공간, 과거 단일 Buffer Cache를 지원 했던 시기의
버퍼 풀이다.
- Keep Pool : Default Pool의 대안으로 주기적으로 아주 자주 Access되는 Segmenet를 여기에 할당 할 수 있는데,
다른 Segment가 공간을 요구하면 오래된 블록은 Default Pool로 밀려난다.
- Recycle Pool : Default Pool의 대안으로 주기적으로 큰 Segment를 아주 랜덤하게 Access해서 다른 많은
Segment의 많은 블록들을 버퍼에서 밀려나도록 만드는 경우에 그 Segment를 여기에 할당한다.
▒ Shared Pool
Shared Pool은 SGA 메모리에서 성능과 가용성 측면에서 핵심 부분 중 하나인데 Shared Pool이 너무 작으면 시스템에 장애가
발생한 것처럼 성능이 저하될 수 있다. 또한 Shared Pool이 너무 커도 동이한 영향이 미칠 수 있다.
Shared Pool의 정확한 역활은 많은 '프로그램' 데이터 조각을 Cache 하는 곳이다. Query를 Parsing할 때 파싱된 표현식은
Shared Pool에 저장된다. 전체 Query 문장을 Parsing하는 작업을 수행하기 이전에 오라클은 Shared Pool에 캐싱되고,
다음에 그것을 실행할 때는 오라클은 디스크에서 다시 읽지 않는다.
PL/SQL 코드는 Shared Pool에 캐싱될 뿐만 아니라 이를 공유한다. 만일 같은 SQL 코드를 실행하는 1,000개의 세션이 있다면
SQL 코드에 대한 하나의 복사본만이 로드되어 모든 세션이 이를 공유한다. 오라클은 시스템 파라미터도 Shared Pool에 저장
하는데, Database Object들에 대한 정보를 담고 있는 데이터 딕셔너리 캐시 또한 Shared Pool에 저장된다.
Shared Pool은 수 많은 Chunk로 구성되어 있는 것이 특징인데, 명심할 것은 4KB가 제약사항은 아니라는 것이다. 그러나
일반적인 메모리의 작은 Chunk를 이용해서 각기 다른 크기로 할당될 때 발생되는 단편화 문제를 방지하는 것이다.
Shared Pool은 LRU 알고리즘을 기반으로 관리된다. DBMS_SHARED_POOL이라는 내장 패키지를 이용해서 Shared Pool의
동작방식을 변경 할 수 있다. 이 패키지를 이용하면 Database가 시작할 시점에서 자주 사용하는 프로시저나 패키지를 메모리에
로드하고 메모리에서 밀려나지 않게 만든다.
▒ Large Pool
Large Pool은 이름과 같이 큰 구조는 아니다. Shared Pool에서 다를 수 없을 만큼 큰 '메모리 조각'을 할당하는데 사용한다.
오라클 8i에서 Large Pool이 소개되기 전, 모든 메모리 할당은 Shared Pool에서 이루어졌다.
따라서 Shared Server에서의 UGA 메모리 할당과 같은 매우 큰 크기의 메모리를 할당할 때는 굉장히 불리했다.
Shared Pool은 LRU 기반으로 메모리를 관리하는데, 이는 데이터를 캐싱하고 재사용하기에는 완벽하다. 그러나 큰 크기의
메모리 할당은 큰 메모리 덩어리를 할당하고, 사용하고, 다 사용한 후에 그것을 버려야 한다. 즉 , 이런 메모리는 캐시에 둘
필요가 없다.
오라클이 필요한 것은 Block Buffer Cache를 위해 구현된 recycle buffer pool과 keep buffer pool과 유사한 무엇인데, 정확히
Large Pool과 Shared Pool이 그것이다.
Large Pool = recycle buffer pool
Shared Pool = keep buffer pool
Large Pool에서 메모리 할당은 Heap 방식이고, malloc(), free() 함수를 사용하는 C 메모리 관리 방식을 많이 사용한다.
메모리 Chunk를 할당해제하자마자 다른 프로세스는 Large Pool을 사용할 수 있고 Shared Pool에서 메모리를 할당해제한다는
개념은 없다. 메모리를 할당하고, 이용하고, 멈추기만 하는데 잠시 뒤에 다시 사용할 필요가 있다면 메모리 Chunk를 밀어낸다.
Large Pool은 특별한 경우에만 사용되는데
- Shared Server 커넥션 환경에서 SGA 영역에 UGA를 할당
- 병렬 실행문장에서 병렬 쿼리 서버의 조정자가 사용하는 interprocess message buffer를 할당하는데 사용
- RMAN disk I/O 버퍼 백업
▒ Java Pool
Java Pool은 오라클 8.1.5에서 Database에서 자바 프로그램 실행을 돕기 위해 추가됐다. 자바로 된 저장 프로시저 코딩을 한다면
오라클은 프로그램 코드를 메모리 Chunk를 이용할 것이다. 이 Parameter는 JAVA_POOL_SIZE를 이용해서 지정한 메모리는
지정된 모든 세션에 자바 코드와 데이터를 위해 Java Pool에 할당된다.
오라클 9i 이전 버전에서는 Java Pool의 전체 크기는 고정되어 있어서 Application 개발자는 Application에 필요한 전체 요구 수와
동시 세션 수를 곱하여 필요한 메모리의 크기를 구하는 상황이였지만 오라클 10g 이상에서는 이 Parameter가 수정될 수 있고
Java Pool은 Database 재구동 없이 커지거나 줄어들 수 있다.
▒ Stream Pool
Stream Pool은 오라클 10g에서 시작된 새로운 SGA 구조이다. Stream 자체는 오라클 9i Release 2 이상에서 소개된 신규 기능
으로서 데이터 공유 / 복제 툴로 디자인 되었으며, 데이터 복제를 위한 오라클이 추구하는 미래의 모습이기도 하다.
Stream Pool은 (Stream Pool이 지정되어 있지 않다면 Shared Pool의 10%까지 할당한다.) 하나의 Database에서 다른
Database로 데이터를 Moving / Copying하는 Stream Process에 필요한 Buffer Queue Message에 사용된다.
디스크를 기반으로 둔 Queue 기능을 사용함으로써 오버헤드가 발생하는 과거 데이터 이관 방식에 비해 Stream은 in-momory
큐를 사용한다. 물론 Queue가 꽉 찼다면 결국 디스크를 사용할 수밖에 없을 것이다.
오라클 Instance가 특정한 사유 (Instance 장애, 소프트웨어 충돌, 전원 문제 등)로 메모리 큐 사용에 실패한다면, 어쨋든
Redo log에서 in-momory Queue를 재구성할 것이다.
따라서 Stream Pool은 스트림 데이터베이스 기능을 이용하는데 있어서 매우 중요하다. Shared Pool의 영역의 10% "무임승차"
를 방지하기 위해서 이 영역을 설정해야 한다.
|
첫댓글 아~~~ 메모리의 구조..... ^^