빠른 데이터 입출력을 위해 SGA 공유 메모리를 이용한다.

정확히는 캐시 영역은 SGA 구성요소 중 하나인 DB 버퍼 캐시이다.

 

블록 단위 I/O

오라클에서 I/O은 블록 단위로 이루어져있다.

메모리 버퍼 캐시에서 버퍼 블록을 액세스할 때뿐만 아니라 데이터파일에 저장된 데이터 블록을 DB 버퍼 캐시로 적재하거나 캐시에서 변경된 블록을 다시 데이터파일에 저장할 때도 블록 단위로 처리한다.

데이터파일에서 버퍼 캐시로 블록을 적재할 때

인덱스를 경유한 테이블 엑세스 -> 한번에 한 블록씩 (Single block read)

Full Scan 시                           -> 성능 향상을 위해 한번에 여러블록 (Multiblock read)

DBWR 프로세스는 버퍼 캐시로부터 변경된 블록 (Dirty 버퍼 블록)을 주기적으로 데이터파일에 기록하는 작업을 수행 이때도 여러 블록 처리

* SQL 성능 최적화하는데 가장 중요한 것은 액세스하는 블록 개수, 옵티마이저의 판단에 가장 큰 영향도 액세스 블록 개수, (레코드 수 x)

 

버퍼 캐시 구조

SGA에서 가장 많이 사용하는 것이 해시 테이블, DB 버퍼 캐시도 해시 테이블 구조로 관리됨

DB 버퍼캐시내에서 데이터 블록을 해싱하기 위해 사용되는 키 값 -> 데이터 블록 주소 (DBA), 즉 해시함수에 데이터 블록 주소를 입력해 리턴받은 해시 값이 같은 블록들을 같은 해시 버킷에 연결리스트 구조로 연결 (각각의 연결 리스트를 해시 체인이라고 한다)

정확히는 버퍼 헤더만 해시 체인에 연결, 실제의 데이터 값이 필요해지면 버퍼 헤더에 있는 포인터를 이용해 버퍼 블록을 찾아간다.

 

캐시 버퍼 체인

각 해시 체인은 래치(Latch)에 의해 보호된다. 래치를 획득한 프로세스만이 래치에 의해 보호되는 자료구조로 진입 허용

* DB 버퍼 캐시는 공유 메모리 영역인 SGA 내에 있어서 여러 프로세스에 의해 동시 액세스가 일어날 수 있음. 그래서 같은 리소스에 대한 액세스를 반드시 직렬화(Serialization)해야함 이 Lock 알고리즘이 래치다.

두개 이상의 프로세스가 같은 해시 체인으로 진입해 새로운 블록을 연결하고 해제하는 작업을 동시에 진행하면 문제가 있다

-> 이를 방지하는 것이 cache buffers chains 래치

select count(*) from v$latchname; 하면 래치 개수를 알수있다.

하나의 체인에 하나의 버퍼만 달리는 것을 목표로 해야한다.

오라클 9i부터 읽기전용 작업일때는 캐시 버퍼 체인 래치를 Share 모드로 획득할 수 있다.

* 읽기 전용 작업이란 select문이 아니라 해시체인을 스캔하면서 필요한 블록을 찾는 작업

selct를 동시에 수행하면 cache buffers chains 래치 경합이 발견된다.

래치는 데이터 자체를 보호하는게 아니라 SGA에 공유돼 있는 자료구조를 보호하는 것이며 cache buffers chains 래치는 버퍼 캐시에 연결된 체인구조를 보호한다. 해시체인을 스캔하거나 블록을 추가 제거할때 래치가 요구된다.

버퍼 헤더에 Pin을 설정하기도 한다. (나중에 설명 중요)

 

캐시 버퍼 LRU 체인

버퍼헤더는 해시 체인뿐만아니라 LRU 체인에 의해서도 연결돼있다.

DB 버퍼 캐시는 읽은 데이터 블록을 캐싱해두는 메모리 공간이지만 모든 데이터를 캐싱할 순 없다.

-> 버퍼 캐시가 사용빈도가 높은 데이터 블록들 위주로 구성될 수 있도록 LRU 알고리즘으로 관리

--> 사용빈도 순으로 위치를 옮기다가 Free 버퍼가 필요해질때마다 빈도가 낮은 데이터를 밀어냄

- Dirty 리스트 : 캐시 내에서 변경됐지만 아직 디스크에 기록되지 않은 Dirty 버퍼블록들을 관리한다 , LRUW 리스트

- LRU 리스트 : 아직 Dirty 리스트로 옮겨지지 않은 나머지 버퍼 블록들 관리

--> 모든 버퍼 블록은 이 둘 중 하나에 반드시 속하지만 읽기 또는 쓰기 작업을 위해 액세스 되는 동안에는 리스트에서 잠시 풀려나왔다가 다시 원래의 리스트로 연결되거나, 최초 변경이 발생하였을 때 Dirty 리스트로 옮겨간다. 

LRU 리스트를 보호하기 위해 사용하는 래치는 cache buffeds lru chain 래치

 

Free 버퍼 : 인스턴스 가동후 아직 데이터가 읽히지 않아 비어있는 상태거나 데이터가 담겼지만 데이퍼파일과 서로 동기화되어있어 언제든지 엎어 써도 무방한 버퍼. 데이터 파일로부터 새로운 데이터 블록을 로딩하려면 먼저 Free 버퍼를 확보해야하고 Free 버퍼에서 변경이 발생하면 더티 버퍼로 바뀐다.
Dirty 버퍼 : 변경이 발생했지만 아직 디스크에 기록되지 않아 데이터 파일 블록과 동기화가 필요한 버퍼블록, 재사용됟려면 먼저 디스크에 기록되야한다. 기록되면 Free 버퍼로 바뀜
Pinned 버퍼 : 읽기 쓰기 작업을 위해 현재 액세스되고있는 버퍼 블록

 

 

+ Recent posts