Code Forest
[I. 오라클 아키텍처] DB 버퍼캐시 본문
02. DB 버퍼캐시
빠른 입출력을 위해 사용되는 부분은 SGA캐시영역 내에 있는 DB버퍼캐시이며,
데이터를 쓰거나 읽을 때 반드시 경유되는 영역이다.
DB버퍼캐시에는 다음과 같은 4가지 특징이 있다.
(01) 블럭단위 I/O
일부 컬럼기반 DBMS를 제외한 대부분의 DBMS는 블럭단위로 데이터를 처리한다.
블럭단위로 데이터를 처리한다는 것은 블럭내의 한 레코드만 갱신하거나 읽더라도,
해당 레코드가 속한 블럭 전체를 읽어야 함을 뜻한다.
가령 수많은 레코드를 읽더라도, 이 레코드 집합이 한 블럭내에 존재한다면
한 레코드를 읽었을 때와 비교해도 읽기비용만큼은 같다는 것을 의미한다.
이것은 SQL의 SELECT구문 성능이 읽어야하는 레코드 수가 아닌 읽어야하는 블럭 수로 좌우됨을 의미하고,
데이터베이스 I/O 튜닝을 이해하는 데 가장 중요한 원리이다.
(02) 버퍼캐시 구조
버퍼캐시는 다음 그림과 같이 DBA(Data Block Address)를 키로 하는 해쉬테이블과
실제 데이터가 저장된 버퍼 블록으로 다시 나뉘어진다.
특정 블럭을 읽을 때, 먼저 목표 블록의 주소(DBA)를 키 값으로 해쉬 테이블을 탐색 한 후,
있다면 해당 블럭이 버퍼 블럭에 캐시되어 있다는 뜻 이므로,
찾은 버퍼헤더가 가르키는 포인터로 이동하면 해당 블럭의 내용을 캐시에서 얻을 수 있다.
없다면 디스크에서 해당 블럭을 읽어 버퍼블럭에 저장하고,
해시 테이블(정확히는 해시 버켓)에 연결한 뒤 읽는다.
이것을 캐싱이라 한다.
기반 자료구조가 해시 테이블이므로 성능의 장단점도 해시 자료구조와 같다.
따라서 각 해시 버킷당 하나의 버퍼 헤더만이 연결되는 것을 목표로 해야 한다.
(03) 캐시버퍼 체인
두 개 이상의 프로세스가 같은 해시체인으로 진입하여
- 목표 블럭을 찾기 위해 해시 체인을 스캔하거나. (9i 이상부터 적용)
- 해시 체인에 버퍼헤더를 연결하거나.
- 해시 체인에 버퍼헤더를 제거하거나.
- 버퍼 헤더에 Lock을 설정할 때.
문제가 발생할 가능성이 있으므로,
래치(Lacth)라는 락 매커니즘을 사용하여 특정 해시체인의 접근을 직렬화 해야한다.
각 해시 체인은 래치에 의해 보호되며,
래치를 획득한 프로세스만이 그 래치에 의해 보호되는 해시 체인에 진입이 허용되는 식이다.
이것을 cache buffers chanis 래치라고 한다.
하나의 cache buffers chanis 래치는 여러개의 해시체인을 담당한다.
(04) 캐시버퍼 LRU 체인
버퍼캐시는 유한한 자원이므로 되도록 사용빈도가 높은 블럭만 캐시될 수 있도록
LRU(Least Recently Used) 알고리즘을 사용하여 내부적으로 다음과 같이 관리한다.
- Dirty (=LRU Write) 리스트
- Non-Dirty (=LRU) 리스트
캐시버퍼 LRU 체인을 보호하기 위핸 래치를 cache buffers lru chain 래치라고 하며,
Dirty 블럭들은 클린아웃(디스크에 쓰여지는 작업) 이전에는
버퍼에서 밀리지 않는다는 점도 착안할만 하다.