01 | 오라클 아키텍처
02 ) DB 버퍼 캐시
빠른 데이터 입출력을 위하 SGA 공유 메모리를 이용한다.
사용자가 입력한 데이터를 데이터파일에 저장하고 이를 다시 읽는 과정에서 거쳐 가는 캐시 영역이 SGA 구성 요소 중 하나인 DB 버퍼 캐시이다.
(1) 블록 단위 I/O
오라클에서 I/O는 블록(block)단위로 이루어진다.
1. DB buffer Cache → Datafile
2. Datafile → DB buffer Cache
두 과정 모두 블록 단위로 I/O 가 이루어진다.
인덱스를 경유한 테이블 액세스 시에는 한 번에 한 블록씩(single block read) 읽어들이지만, Full Scan 시에는 성능 향상을 위해 한 번에 여러 개 블록(multi block)을 읽어들인다.
DBWR 프로세스는 버퍼 캐시로부터 Dirty block을 주기적으로 데이터파일에 기록하는 작업을 수행하느데, 이때도 성능 향상을 위해서 한 번에 여러 블록을 처리한다.
▶ DBWR은 주기적으로 DB Buffer Cache에서 변경된 블록을 데이터파일에 기록 (동기화 과정)
블록 단위로 읽는다는 것은 하나의 레코드에서 하나의 컬럼만 읽고자 하는 경우에도, 레코드가 속한 블록 전체를 읽는다는 것이다.
SQL의 성능을 좌우하는 가장 중요한 성능지표는 블록 개수이며, 옵티마이저의 판단에 가장 영향을 미치는 것도 액세스해야 할 블록 개수이다. 옵티마이저가 인덱스를 이용해 테이블을 액세스할지 아니면 Full Table Scan 할지를 결졍하는 데 있어 가장 중요한 판단 기준은, 읽어야 할 레코드 수가 아니라 블록 개수이다.
(2) 버퍼 캐시 구조
DB Buffer Cache 의 가장 직관적인 그림은 바둑판 모양이다.
SGA 내에서 가장 많이 사용되는 자료구조는 해시 테이블(Hash Table)이다.
DB Buffer Cache 도 Hash Table 구조로 관리된다.
Hash Key : 데이터 블록 주소(DBA; Data Block Address)
Hash Function : DBA 입력한 해쉬 값 리턴
Hash Bucket : 해시 함수에 의해 리턴 받은 해시 값을 저장
Hash Chain : 동일한 해시 값에 의한 Buffer Header 를 Linked List 로 연력한 구조 (실제 데이터 값은 버퍼 헤더에 있는 포인터에 의해 버퍼 블록을 찾아감)

즉, 사용자가 찾고자하는 데이터 블록 주소를 해시값으로 변환해서 해당 해시 버킷에서 체인을 따라 스캔하여 데이터를 찾고, 찾고자한 데이터블록이 있는 경우 그대로 읽고, 없는 경우 디스크에서 읽어 해시 체인에 연결한 후 읽는다.
이렇게 체인에 연결된 데이터는 다른 사용자들도 나중에 읽을 수 있도록 캐싱하는 것이다.
▶ Buffer Header만 Hash Chain에 연결되며, 실제 데이터 값이 필요해지면 버퍼 헤더에 있는 포인터를 이용해 버퍼 블록을 찾아가는 구조이다.
(3) 캐시 버퍼 체인
각 해시 체인은 래치(Latch)에 의해서 보호된다. DB 버퍼 캐시는 공유 메모리 영역인 SGA에 존재하므로 여러 프로세스에 의한 동시 액세스 요청이 일어날 가능성이 높다.
같은 리소스에 대한 액세스를 반드시 직렬화해야 하고, 이를 위해 구현된 일종의 Lock 매커니즘이 Latch이다.
래치를 흭득한 프로세스만이 그 래치에 의해 보호되는 자료구조로의 진입이 허용된다.
두 개 이상의 프로세스가 같은 해시 체인으로 진입해 새로운 버퍼 블록을 연결하고 해제하는 작업을 동시에 진행한다면 문제가 발생할 수 있다. 이를 방지하기 위해서 사용하는 것이 cach buffers chains 래치이다.
cache buffers cahins : 여러개의 해시 체인을 동시에 관리
Oracle 9i 부터 Shared Mode와 Exclusive Mode로 관리
Shared Mode : 해시 체인을 스캔하여 필요한 블록 검색
Exclusive Mode : 체인 구조 변경(체인 추가, 삭제) 혹은 Buffer Pin 설정
해시 버킷 : 해시 체인 = 1 : 1 을 목표 ▶ 해시 체인을 찾고난 후 추가적인 스캔에 의한 비용 최소화
✔︎ Latch 는 데이터 자체를 보호하는 것이 아닌, SGA에 공유되어 있는 자료구조를 보호하는 것이며, 그 중 cache buffers chains 래치는 버퍼 캐시에 연결된 체인구조를 보호하는 것이다.
(4) 캐시 버퍼 LRU 체인
버퍼 헤더는 해시 체인뿐만 아니라 LRU체인에 의해서도 연결되어 있다.
버퍼 캐시는 한번 읽은 데이터 블록을 캐싱해두지만, 유한한 자원이 아니기 때문에 읽은 모든 데이터를 캐싱할 수 없다.
버퍼 캐시가 사용도가 높은 데이터 블록들 위주로 구성될 수 있도록 LRU(Least Recently Used) 알고리즘을 사용해 관리한다.
모든 버퍼 블록 헤더를 LRU체인에 연결해 사용빈도 순으로 위치를 옮겨가다가, Free 버퍼가 필요해질 때마다 액세스 빈도가 낮은 데이터 블록들을 우선하여 알아냄으로써 자주 액세스 되는 블록들이 캐시에 더 오래 남아 있도록 관리한다.
📌 LRU알고리즘
- 가장 최근에 사용한 버퍼 캐시를 MRU(Most Recently Used) End에 위치
- Free Buffer가 필요할 때 LRU(Least Recently Used) End에 위치한 버퍼 캐시부터 밀어냄
📌 LRU List
- Dirty List : 캐시 내에서 변경되었지만, 아직 디스크에 기록되지 않은 Dirty Buffer Block 관리, LRUW(LRU Write) 리스트라고도 한다.
- LRU List : 아직 Dirty 리스트로 옮겨지지 않은 나머지 버퍼 블록들을 관리 ( Pinned Buffer, Free Buffer, Dirty List에 옮겨 가지 않은 Dirty Buffer)
- 모든 버퍼 블록은 둘 중 하나에 반듯 속해 있다.
- LRU List 를 보호하기 위한 래치 : cache buffers lru chain
⭐️ Buffer 상태
1. Free Buffer : Instance 기동 후 한번도 사용 하지 않은 버퍼 / 데이터를 사용하였으나 변경되지 않은 버퍼 / 변경 후 데이터 파일과 동기화된 버퍼
2. Dirty Buffer : 캐시된 후 데이터의 변경이 발생 되었으나 데이터파일에 아직 기록되지 않은 버퍼
3. Pinned Buffer : 읽기 혹은 변경을 위해 현재 액세스 되고 있는 버퍼
'Database > Oracle' 카테고리의 다른 글
| [Oracle] 오라클 성능 고도화 (3) (0) | 2026.03.18 |
|---|---|
| [Oracle] 오라클 성능 고도화 (1) (0) | 2026.03.18 |
