오라클은 물리적인 I/O를 최소화 하기 위해 최근에 사용된 블럭에 대한 정보를 메모리의 일정 부분에 보관하려 한다 ⇒ 이 영역을 Buffer Cache 라고함.
Buffer Cache 구조
Hash Chain 구조의 시작점은 Hash Table인데, Hash Table은 Hash Bucket으로 구성되어져 있다
오라클 블럭(DBA: Data Block Address File# , Block# )과 블럭 클래스 에 대한 Hash 함수 결과 값으로 해당 Hash Bucket을 찾아가서 해당 데이터 블럭이 메모리에 존재 하는지를 확인 할 수 있는 것 이다
Hash Bucket에 딸린 Buffer Header는 Buffer에 대한 메타 정보만 가지고 있고 Buffer 메모리 영역의 실제 버퍼에 대한 포인터 값을 가지고 있다.
Hash Chain 구조는 Shared Pool 영역에 존재 하며 실제 버퍼에 대한 정보들은 버퍼 캐쉬 영역에 존재 한다
특정 블럭에 대한 Scan을 할려고 하면 Cache buffer chains latch를 획득 해야만 한다. ※ 9i부터 읽기 작업에 한하여 buffer cache chains latch를 shared 모드로 획득 한다
다음과 같은 쿼리를 이용하여 cache buffer chains latch의 갯수를 확인가능 하다
SQL>SELECTCOUNT(*)FROM v$latch_children WHERE name ='cache buffers chains'COUNT(*)----------65536
cache buffer chains latch ⇒ hash 함수로 얻은 값으로 해당 데이터가 어떠한 bucket에 있는가를 확인할때 발생되는 latch
Working Set
오라클은 Buffer Cache에 대하여 효율적으로 사용하기 위해 두 종류의 LRU리스트를 사용한다.
LRU List : 가장 최근에 사용되거나 미사용된 버퍼들의 List
Free(미사용) , 사용중이거나 사용된 버퍼 아직 LRUW로 옮겨지지 않은 Dirty 버퍼
메인 리스트 : 사용된 버퍼들의 리스트 , 핫 영역과 콜드 영역으로 구분 관리 됨
보조 리스트 : 프리 버퍼들의 리스트 , 미사용 된 버퍼나 DBWn에 의해 기록 된 버퍼 관리
LRUW List : 아직 디스크에 기록 되지 않은 Dirty한 버퍼들의 List
메인 리스트 : 변경된 버퍼들의 리스트
보조 리스트 : 현재 DBWR에 의해 기록중인 버퍼 리스트
다음 그림과 같이 LRU , LRUW를 합쳐서 하나의 Working Set 이라고 부른다.
Working Set 개수는 Cache buffer lru latch 개수에 의해 결정( 하나의 working set을 하나의 lru latch가 관리함 )되며 X$KCBWDS( Kerner Cache Buffer Working sets Descriptors )를 조회 하면 확인 가능 하다
LRU , LRUW List를 탐색 하고자 하는 프로세스는 반드시 cache buffer lru chain latch를 획득 해야 함.
오라클은 개별 버퍼 마다 Touch Count를 관리 하며 , 프로세스에 의해서 스캔이 이루어 질때 마다 Touch Count를 1씩 증가시킴
Cold 영역의 꼬리에 있으면서 Touch Count가 1이하인 것이 Free Buffer로 사용된다.
Cold 영역의 꼬리에 있으면서 Touch Count가 2 이상인 블럭을 만나면 Hot영역의 head 부분으로 옮기고 Touch count를 0 으로 초기화 한다.
핫 영역으로 옮기는 기준은 _DB_AGING_HOT_CRITERIA 파라메터 이며 기본이 2 이다.
만약 Single블럭 I/O에 의해 읽혀진 블럭은 Mid-Point에 삽입되며 Touch Count는 1 이다.
Full table scan 이나 인덱스 Full Scan으로 읽혀진 데이터 들은 Mid-Point에 삽입되었다 바로 Cold 영역의 꼬리로 옮겨져서 버퍼 캐쉬에 머무를 확률이 작아 진다.
Buffer lock
buffer 자체 보호 . 즉 , 버퍼의 내용을 변경하거나 읽으려고 하는 프로세스는 변경 작업이나 읽기 작업을 완료할때 까지 해당 버퍼 (정확하게 말하면 Buffer header)에 대해서 buffer lock을 exclusive 또는 shared 하게획득 해야 한다.
Buffer Cache 블록을 올리거나 버퍼캐시에 올라와있는 블록을 사용하고자 할때
sql문에 의해서 조건에 만족하는 데이터가 버퍼캐시에 존재 여부 확인하기 위해 DBA(data block address) + class(data, sort, undo)를 조합하고 > hash function을 돌려 해당 데이터가 어떠한 bucket에 있는가 확인(= DBA + class를 hash 함수로 돌린뒤 그값을통해 hash bucket를 찾음)