I. Cache Buffer

1) Data Buffer Cache 구조도

  • Hash bucket - 해쉬 함수를 통해 그룹핑된 버퍼 헤더의 목록을 관리
  • Buffer header list(list chain) - 동일한 해쉬 값을 가지는 BH(buffer header) 들의 모임
  • LRU list - 프리 버퍼나 DBWR에 의해서 기록된 재사용 가능한 버퍼들을 연결한 리스트
  • LRUW list - 더티 버퍼들의 모임으로 DBWR에 의해서 기록될 버퍼들이나 기록중인 버퍼들의 리스트
  • Buffer header - 버퍼의 메타정보를 가지고 있으며 실제 버퍼 캐시와 연결됨

참고
해쉬 버켓과 버퍼 헤더는 SGA의 shared pool 내부에 저장된다.

2) Buffer Pools

  • Buffer Cache는 여러 Buffer Pool로 이루어져 있음
    • DEFAULT
    • KEEP, RECYCLE Oracle 8.0 이상
    • 2K, 4K, 8K, 16K, 32K Oracle 9.0 이상
  • Default - 기본적인 버퍼 캐시
  • Keep - 접근 빈도가 높거나 메모리에 상주시켜 놓아야 할 필요가 있는 해당 오브젝트의 모든 블록이 항상 메모리에 상주하도록 설정
  • Recycle - 재사용 빈도수가 비교적 낮은 특정 오브젝트의 블록들을 접근 후 바로 메모리에서 제거하도록 관리
  • 데이터 블록의 크기에 따라 2KB, 4KB, 8KB, 16KB, 32KB로 설정
    • 9i부터 필요에 따라 테이블스페이스 블록의 크기를 서로 다른 크기로 설정할 수 있음.
    • 표준블록 크기는 DB_BLOCK_SIZE 에 의해서 설정되며 캐시 크기는 DB_CACHE_SIZE로 설정된다

참고
Keep 과 Recycle 버퍼 풀의 블록 크기와 시스템 테이블스페이스는 표준 블록 크기를 사용해야 한다.

3) Hash Bucket

  • DBA(Data Block Address) 와 Class Number (Data, Sort, Undo, etc)의 Hash 값에 의해 Grouping 된 Data Buffer Header들의 목록을 관리

오라클은 버퍼 캐시에 적재된 블록을 검색하기 위해 DBA(Data Block Address)와 클래스 넘버에 대해 간단한 해시 함수를 적용한 결과 값을 이용해 해쉬 버켓을 검색한다.

  • DBA(data block address)
    • -> 데이터 블럭이 저장되어 있는 데이터파일의 파일 번호와 파일 내에서의 블록 번호로 구성됨
  • Class Number
    • -> 1:data block, 2:sort block, 3:save undo block 4:...등 블록의 클래스에 대한 정보

하나의 cache buffers chains 래치가 다수의 해쉬 버켓을 관리한다. (1:N)
하나의 캐시 버퍼는 다수의 해쉬 버켓에 의해서 관리된다.(1:M)

4) Hash Chain

  • 하나의 Hash Bucket 에 연결된 Buffer Header 집합

  • 동일한 해쉬 값을 가지게 되는 블록의 헤더들은 하나의 해쉬 버켓에 의해 관리된다.
  • 해쉬 버켓의 버퍼 헤더들은 양방향 링크드 리스트(double linked list) 형태로 연결되어 하나의 해쉬 체인으로 관리된다.
  • 동일한 해쉬 버켓에 위치한 버퍼 헤더들은 실제 버퍼 캐시의 메타정보를 가지고 매칭 된다.
  • 해쉬 체인을 탐색하거나 변경하기 위해서는 cache buffers chains 래치를 획득해야 한다.

5) Buffer Header

  • Data Buffer, Cache Buffers Chains Latch, Hash Chain, LRU Chain 의 정보를 관리
  • User List, Waiters List 관리
  • X$BH에서 Buffer Header정보를 제공

버퍼 헤더는 버퍼의 메타 정보 및 버퍼 메모리 영역의 실제 버퍼에 대한 포인터 값을 가지고 있다.
버퍼 헤더는 cache buffers chain list, replacement list, users list, waiter list등의 정보를 가지고 있으며 각 버퍼 헤더들은 양방향 링크드 리스트(double linked list)형태로 관리된다.

X$BH에서 버퍼 헤더의 정보를 제공

  • Cache buffers chain list
    Prev. buffer header(PRV_HASH) - 해쉬 체인에서 이전 버퍼 헤더의 주소를 가리킨다
    Next. buffer header(NXT_HASH) - 해쉬 체인에서 다음 버퍼 헤더의 주소를 가리킨다
  • Replacement list
    Prev. LRU(PRV_REPL) - LRU 리스트의 이전 버퍼 헤더의 주소를 가리킨다
    Next. LRU(NXT_REPL) - LRU 리스트의 다음 버퍼 헤더의 주소를 가리킨다
  • Users list - 이 블록을 사용하고 있는 유저 정보
  • Waiter list - 이 블록을 사용하기 위해 대기하고 있는 유저 정보

6) Working Set

LRU 리스트와 LRUW 리스트를 묶어 하나의 working set이라고 한다.
버퍼 캐시의 모든 버퍼들은 반드시 LRU 리스트, LRUW 리스트 둘 중 하나에 속해야 한다.
Working set에서 LRU 리스트 및 LRUW 리스트를 탐색하거나 변경하기 위해서는 cache buffers lru chain 래치를 획득해야 한다.

  • 각 Buffer Pool은 하나 이상의 Working Set을 가짐
  • Working Set은 LRU, LRU-W, LRU-XO, LRU-XR List 1 Set
    • LRU : Normal Block을 관리 하며 Replacement List라고도 함
    • LRU-W : Write List라고도 하며 Dirty Block을 관리
    • LRU-XO : Object List라고도 하며 DROP, TRUNCATE 에 관련된 Buffer들을 관리
    • LRU-XR : Range List라고도 하며 Tablespace 작업에 관련된 Buffer들을 관리
  • Working Set은 Instance가 기동될 때 Buffer Pool에 할당 (최소 8개)
  • Working Set의 개수 = cache buffers lru chain latch의 개수

LRU 리스트 및 LRUW 리스트는 메인 리스트와 보조 리스트를 가지고 있다.

  • LRU list : Replacement list 라고도 하며 일반적인 버퍼를 관리한다.
    • 메인 리스트 : 사용된 버퍼들의 리스트. 핫 영역과 콜드 영역으로 구분 된다.
    • 보조 리스트 : 프리 버퍼들의 리스트. 미 사용된 버퍼 또는 DBWR에 의해 이미 기록된 버퍼
  • LRUW list : Dirty list 또는 write list 라고도 하며 아직 디스크에 기록되지 않은 더티한 버퍼를 관리한다.
    • 메인 리스트 : 변경된 버퍼들의 리스트
    • 보조 리스트 : 현재 DBWR에 의해 기록중인 버퍼들의 리스트
  • LRU-XO list : Object list라고도 하며 drop, truncate작업을 하는데 사용되는 버퍼들을 관리 한다.
  • LRU-XR : Range list 라고도 하며 아래와 같은 작업들을 할 때 사용한디.
    • ALTER TABLESPACE BEGIN BACKUP
    • ALTER TABLESPACE END BACKUP
    • ALTER TABLESPACE OFFLINE
    • ALTER TABLESPACE READ ONLY

참고
Startup 또는 FLUSH_CACHE시 모든 버퍼가 프리 리스트(LRU의 보조 리스트)에 할당된다.
Working set의 개수는 cache buffers lru chain 래치의 개수를 결정하는 _DB_BLOCK_LRU_LATCHES 히든 파라미터에 의해 결정된다.

7) cache buffers chains latch

  • Hash Chain을 보호하는 목적의 Latch
  • Shared / Exclusive Mode 로 획득 가능
    • 대부분의 다른 Latch들은 Exclusive Mode만 사용
  • 하나의 Cache Buffers Chains Latch가 여러 개의 Hash Chain을 보호
  • 부모/자식 Latch
    • V$LATCH_CHILDREN : 자식 Latch 통계 정보

버퍼를 탐색하거나 변경하기 위해 해쉬 체인을 탐색하거나 변경하려는 프로세스는 반드시 해당 체인을 관리하는 cache buffers chains 래치를 획득해야 한다. 이때 cache buffers chains 래치를 획득하는데 경합이 이루어지면 latch: cache buffers chains 이벤트가 발생하게 된다.

참고
9i이후부터는 읽기 전용의 목적으로 체인을 탐색할 경우 cache buffers chains 래치를 shared 모드로 획득할 수 있어 경합을 줄일 수 있게 되었다. 하지만 shared 모드로 획득한다고 해도 경합이 발생하지 않는 것은 아니다. 왜냐하면 버퍼에 대해 shared 모드로 바꿀 경우에도 버퍼 헤더의 정보를 변경해야 하는데 이 때 변경을 하기 위해 버퍼 락(buffer lock)을 획득하고 래치를 exclusive모드로 변경해야 한다. 버퍼 락을 해제 할 때도 동일한 과정을 거치게 된다.

문서에 대하여