'메모리관리'에 해당되는 글 1건

  1. 2008.09.25 | Oracle의 메모리 구조 - SGA(DataBase Buffer Cache)

오라클 10g에서는 ASMM(자동공유메모리관리)를 사용하여 메모리 관리작업을 간소화하고 있다.

ASMM이 활성화되어 있는 경우 처음부터 메모리를 관리할 특정구성요소에 대해 초기화파라미터를 설정하지 말것을 권장하고 있으며 ASMM 할당의 영향을 확인한 후에 특정구성요소할당을 조정할지를 결정한 다음 해당 구성요소에 대해 값을 지정할 수 있다.

이러한 값은 각 구성요소의 최소메모리 크기로 간주되어 자동조정에 사용할 수 있는 메모리양이 제한 되지만 작업환경에서 ASMM으로 제공되지 않은 특별한 크기조정이 필요한 경우 사용된다.

대상 초기화파라미터는 SHARED_POOL_SIZE, LARGE_POOL_SIZE, JAVA_POOL_SIZE, DB_CACHE_SIZE, STREAMS_POOL_SIZE 가 있다. 

 

Database Buffer Cache는 초기파일에서 정한 DB_Cache_SIZE 만큼의 메모리 영역으로 , 데이터 파일에서 읽어 들여 가장 최근에 사용된 데이터 블록을 저장하는 데이터베이스 버퍼들로 구성되어 있으며. 즉 사용자들에 의해 사용된 데이터의 캐시 정보라고 보면 된다.

예를 들어 소트나 병렬 읽기와 같은 Operation에서는 Database Buffer Cache를 사용하지 않으며 그 외의 대부분의 경우엔 Database Buffer Cache를 사용 합니다. Database Buffer Cache는 요구된 데이터를 메모리 블록에서 처리 함으로서 물리적인 디스크 I/O를 줄여 주게 된다.

오라클 서버의 사용자들이 어떤 데이터를 요구할 때 오라클 서버 프로세스는 Database Buffer Cache를 체크하여 여기에 있으면 즉시 반환하고 없으면 해당 데이터 파일에서 데이터를 읽어 들여 Database Buffer Cache에 로딩 후 요청한 데이터를 반환 한다.

데이터베이스버퍼 캐시는 크게 두 부분으로 구성되어 있는데 Data Block(after image), Undo Block(before image)로 구분이 가능하다… 찾고자 하는 데이터가 데이터베이스버퍼 캐시에 있지 않으면 데이터파일에서 읽어 오는데 읽은 블록을 USER가 수정하면 데이터베이스버퍼 캐시의 블록이 변경 되는 것이다. 이때 이 블록은 새로운 데이터를 가지고 있는 상태이기 때문에 AFTER 이미지라고 하며 오라클은 Undo Block에 데이터의 원본을 저장하는데 이를 before image라고 한다. 변경된 사항을 DB에 Commit하기 전에 변경을 취소하면 Undo Block의 정보를 이용하여 원래 상태로 되돌릴 수 있다.

Database Buffer Cache는 메모리에서 수정 되었지만 아직 디스크에 기록하지 않은 Dirty Buffer로 구성된 Write List와 LRU 리스트가 있으며 LRU List는 사용이 가능한 Free Buffer와 현재 사용중인 Pinned Buffer, 저장이 필요한 수정된 Dirty Buffer로 구성 된다.

사용자의 질의(SELECT, INSERT, UPDATE, DELETE)로 인해 Database Buffer Cache에 로딩된 데이터와 변경된 데이터들은 Database Buffer Cache에 보관 되며 시간이 지나면 Dirty Buffer가 되어 Writr List로 옮겨 지고 한정된 Database Buffer Cache내에서 서버 프로세스가 더 이상 Free Buffer를 찾을 수 없을 때 DBW0(database Writer) 프로세스는 Write List의 Dirty Buffer를 데이터 파일에 저장하게 된다.

이러한 Database Buffer Cache의 크기는 DB_BLOCK_SIZE(데이터베이스 버퍼캐시내의 고정된 블록의 크기)와 DB_CACHE_SIZE(Standard BLOCK의 CACHE 크기)로 결정되며 단위는 바이트 이다. 물론 9i이전 버전에서는 DB_BLOCK_BUFFERS (데이터베이스 버퍼 캐시 내의 블록의 수)로 그 크기(DB_BLOCK_SIZE * DB_BLOCK_BUFFERS)를 변경 했는데 9i에서부터 DB_BLOCK_BUFFERS는 DB_CACHE_SIZE로 대체되었고, 이는 4개까지의 DB_nK_CACHE_SIZE로 구성될 수 있다.

데이터베이스 버퍼 캐시에 올려지는 데이터의 성격에 따라 데이터베이스 버퍼 캐시의 영역을 다음과 같이 구분하고 있다.

KEEP : Access 빈도가 높아 버퍼 캐시안에서 지속적으로 보관해야 하는 데이터
RECYCLE : 재사용 가능성이 낮아서 데이터나 대용량의 데이터를 Access 한 직후에 메모리에서 삭제
DEFAULT : 일반적인 LRU 알고리즘을 적용하는 데이터베이스 버퍼 캐시

[예]
Create index emp_ename …. storage  (buffer_pool keep);

Alter table emp …. Storage (buffer_pool recycle);

오라클 8i에서 Database Buffer Cache는 오라클 데이터베이스 서버와 다르게 데이터베이스를 생성 할 때 DB_BLOCK_SIZE 만큼 고정된 블록의 크기로 Database Buffer Cache를 만들었지만 9i부터는 DB_nk_CACHE_SIZE로서 파라미터가 사용되어 데이터베이스 관리자가 직접 2KB~32KB까지 가변적인 데이터 베이스 버퍼 블록의 크기를 정하여 사용하는 것이 가능하다. 또한 Buffer Cache Advisory 가능을 제공하여 버퍼 캐시를 조절 했을 경우 성능을 예측하는 통계정보 등도 보여주며 V$DB_CACHE_ADVICE를 모니터링 하고 시스템의 전체적인 메모리 사용과 데이터베이스 고유의 메모리 영역을 고려하여 9i에서는 동적으로 SGA를 조절함으로서 인스턴스의 다운 없이 튜닝한 Database Buffer Cache를 적용하는 것이 가능해 졌다.

[예]
예) initSID.ora 파일에서
SGA_MAX_SIZE = 128M
DB_CACHE_SIZE = 96M
SHARED_POOL_SIZE = 32M 일때…

Note : DB_CACHE_SIZE는 Oracle 9i에 새롭게 도입된 파라미터

위와 같은 상태일 때 동적으로 SHARED_POOL_SIZE를 64M로 늘리면 에러가 발생 한다.

SQL> ALTER SYSTEM SET SHARED_POOL_SIZE=64M;
(insufficient memory error message)

이 에러는 SHARED_POOL_SIZE를 늘림으로써 전체 SGA의 크기가 SGA_MAX_SIZE
보다 커지기 때문에 발생한다. (96M + 64M > 128M)

이를 해결하기 위해서는 DB_CACHE_SIZE를 줄인 후, SHARED_POOL_SIZE를 늘린다.

SQL> ALTER SYSTEM SET DB_CACHE_SIZE=64M;
SQL> ALTER SYSTEM SET SHARED_POOL_SIZE=64M;
Note : DB_CACHE_SIZE가 shrink되는 동안에
ALTER SYSTEM SET SHARED_POOL_SIZE=64M;
를 하면 insufficient error가 발생할 수도 있다.

이 경우는 DB_CACHE_SIZE가 shrink된 후 다시 수행하면 정상적으로 수행이 된다.

Note : 위 예제의 경우 estimated SGA 크기가 128M 이상이므로, granule의 단위는 16M이다. 따라서 SGA 파라미터의 크기를 16M의 정수배로 했다. 16M의 정수배가 아닌 경우는 지정한 값보다 큰 값에 대해 16M의 정수배 중 가장 가까운 값을 택하게 된다.

즉, 아래 두 문장의 결과는 똑같다.
SQL> ALTER SYSTEM SET SHARED_POOL_SIZE=64M;
SQL> ALTER SYSTEM SET SHARED_POOL_SIZE=49M;

Note : LARGE_POOL_SIZE 와 JAVA_POOL_SIZE 파라미터는 동적으로 변경하는 것이 불가능하다.


또한 Oracle 9i부터 테이블스페이스를 서로 다른 block size로 만들 수 있는 기능 및, 각 block size별 cache의 크기를 지정 할 수 있게 되었으며.  SYSTEM 테이블스페이스는, 데이터베이스의 표준 BLOCK SIZE를 사용하며 다른 테이블스페이스는, 4종류의 서로 다른 BLOCK SIZE를 사용할 수 있게 되었다. 표준 BLOCK SIZE는 DB_BLOCK_SIZE 파라미터에 의해 지정되고 그 블럭에 대한 CACHE의 크기는 DB_CACHE_SIZE 파라미터에 의해 지정된다.

표준 이외의 BLOCK SIZE는 CREATE TABLESPACE 문장의 BLOCKSIZE 절에 의해 지정할 수 있다. 표준이외의 BLOCK SIZE별 CACHE 크기는, DB_nK_CACHE_SIZE 파라미터에 의해 지정되며 여기서 n은 2, 4, 8, 16, 또는 32 Kbytes 가 될 수 있다.

표준 BLOCK SIZE 또는 기본 BLOCK SIZE는 일반적으로 OS의 시스템 BLOCK SIZE와 동일한 크기 또는 그 배수로 지정한다.

DB_CACHE_SIZE 파라미터(DEFAULT CACHE SIZE) 는 표준 BLOCK SIZE에 대한 CACHE의 크기를 지정한다.(기본은 48MB로 지정)

SYSTEM 테이블스페이스는 표준 BLOCK SIZE로 생성이 되며 DEFAULT CACHE SIZE를 사용하게 된다. 표준 BLOCK SIZE 또는 비 표준 BLOCK SIZE 이거나 각 BLOCK SIZE별 cache는 동일한 크기의 BLOCK SIZE를 사용하는 어떤 테이블스페이스에 의해서도 사용될 수 있으며 만약, 데이터베이스를 디자인 할 때 다중 BLOCK SIZE를 고려한다면   DB_CACHE_SIZE 이외에도, 사용하고자 하는 BLOCK SIZE에 대한   DB_nK_CACHE_SIZE 값을 지정하여야 한다.
이는 사용하고자 하는 모든 BLOCK SIZE에 대해, 각각의 CACHE의 크기를 지정해 주어야 한다는 말로. 이와 같이 BLOCK SIZE 별 CACHE 크기 지정을 하는 방법은 4개 까지의 표준 이외의 BLOCK SIZE를 사용하는 테이블스페이스를 데이터베이스에서 액세스 할 수 있게 함으로써 BLOCK SIZE별 목적에 맞는 CACHE의 크기를 상세하게 지정할 수 있게 해 주는 것이다.

DB_BLOCK_SIZE 값은 데이터베이스를 생성할 때만 지정 가능하며 한번 생성된 데이터베이스에 대해서는 그 값을 바꿀 수 없으므로 값을 정할 때 신중하게 결정하여야 합니다.  SGA 크기를 산정하기 위해서는 다음과 같은 공식을 사용 합니다.

DB_CACHE_SIZE + DB_KEEP_CACHE_SIZE + DB_RECYCLE_CACHE_SIZE + DB_nk_CACHE_SIZE+ SHARED_POOL_SIZE + LARGE_POOL_SIZE + JAVA_POOL_SIZE + LOG_BUFFERS + 1MB

 

 

 
블로그 이미지

시반

시반(詩伴)이란 함께 시를 짓는 벗이란 뜻을 가지고 있습니다. 함께 나눌수 있는 그런 공간이길 바라며...

카테고리

분류 전체보기 (233)
개발 이야기 (73)
WEB2.0 (57)
DB2 (24)
MySQL (6)
오라클 (26)
기타 (44)
취미 (0)
잡담 (2)