Buffer Cache - HashTable

2024. 7. 12. 11:50DBMS/ORACLE Admin

반응형

 사용자가 임의의 쿼리를 실행하거나 DML(특히 Update 문장)을 실행하게 되면, 오라클은 그 쿼리 결과값을 가지는 오라클 블록을 데이터 파일로부터 물리적으로 읽어들여서 복사본을 데이터베이스 버퍼 캐시에 저장한다. 이후에 같은 데이터 블록을 요구하는 SQL 문장이 실행되면, 오라클은 데이터베이스 버퍼 캐시에 해당 블록이 존재하는지 확인한다. 만약 해당 블록이 데이터베이스 버퍼 캐시에 존재하면 메모리로부터 바로 읽어서 처리하지만, 존재하지 않으면 디스크에 저장된 데이터 파일로부터 디스크 I/O를 발생시키며 다시 읽게 된다.

 

 

 

Hash Table

데이터베이스 버퍼 캐시 내부 관리는 해시 테이블(Hash table) 구조로 관리된다. 해시 테이블은 인스턴스가 시작될 때 내부적으로 자동 생성되고 해시 테이블은 데이터 블록의 위치를 빠르게 찾을 수 있도록 도와주며 메모리 내에서 필요한 데이터를 신속하게 접근할 수 있다.

 

 

 

 

 

 데이터베이스 버퍼 캐시 내부 구조이며 이 구조는 해시 테이블(Hash table)을 기반으로 관리된다. 

- Hash Latch: 해시 테이블의 버킷 접근을 동기화하는 데 사용된다.
- Hash Bucket:  해시 테이블의 각 버킷은 여러 버퍼 헤더를 가질 수 있다.
- Buffer Header: 버퍼 헤더를 나타낸다. 각 버퍼 헤더는 실제 데이터 블록을 가리킨다.
- Hash Chain:  해시 체인은 같은 해시 버킷에 속하는 버퍼 헤더들을 연결한다.
- Buffers Memory: 실제 데이터 블록들이 저장되는 메모리 영역이다.

 LRU (Least Recently Used)와 LRUW (Least Recently Used Write) 는 버퍼 캐시에서 데이터를 효율적으로 관리하기 위한 알고리즘이다. LRU 목록은 최근에 사용된 데이터 블록을 추적하여 가장 오래된 블록을 교체하고, LRUW 목록은 쓰기 작업이 필요한 블록을 추적하여 적절한 시점에 디스크에 기록한다.

 

 

 

데이터베이스 버퍼 캐시에서 특정 버퍼를 찾는 과정

 

 1: 해시 체인 스캔을 위한 래치 획득
- 데이터베이스는 해시 체인을 스캔하기 위해 먼저 해시 래치를 획득해야 한다. 이는 동시에 하나의 프로세스만 해시 체인을 스캔하도록 제약을 두기 위해서이다. 따라서, 래치를 획득하는 것이 첫 번째 단계이다.

 2: 해시 값 계산 및 해시 버킷 검색
- 래치를 획득한 후, 오라클 블록의 주소 값(Data Block Address)과 오라클 블록의 클래스 정보를 해시 함수에 입력한다. 이로부터 해시 값이 출력된다.
- 이 해시 값을 사용하여 해시 버킷들을 스캔하고, 동일한 해시 값을 가진 해시 버킷을 찾는다.

 3: 버퍼 헤더 스캔 및 버퍼 액세스
- 특정 해시 버킷에 도달하면, 해당 해시 버킷 내부에 체인 방식으로 연결된 버퍼 헤더들을 처음부터 스캔한다. 찾고자 하는 버퍼를 발견하면, 래치를 반환하고 해당 버퍼를 액세스한다.
- 이때, 만약 해당 버퍼가 다른 프로세스에 의해 사용 중이면, 버퍼 헤더에 저장된 버퍼 락 대기자 명단(Buffer Lock Wait List)에 자신을 등록하고, 버퍼 락이 해제될 때까지 기다린다. 이 상황에서 발생하는 대기 이벤트를 "buffer busy waits"라고 한다.
- 버퍼 락을 점유한 프로세스의 작업이 끝나 버퍼 락이 해제되면, 대기자 명단에 있던 프로세스가 버퍼 락을 획득한 후 작업을 진행할 수 있다.

4: 작업 완료 후 버퍼 락 해제
- 작업 완료 후 버퍼 락을 해제해야 한다. 이때 다른 프로세스와의 충돌을 피하기 위해 해당 버퍼가 속한 캐시 버퍼 체인 래치(Cache Buffer Chains Latch)를 다시 획득해야 한다.

 

데이터 블록(버퍼) 상태
- Pinned: 해시 버퍼로부터 버퍼 락을 획득하고 현재 작업 중인 버퍼이다. 버퍼 락을 반환할 때까지 Pinned 상태를 유지한다.
- Free: 아직 사용되지 않고 있는 버퍼로서 언제든지 사용할 수 있는 버퍼이다.
- Clean: 이미 사용된 적이 있지만 지금은 Read consistent 버전의 이미지를 가지고 있는 버퍼이다. 다시 말해, 디스크에 있는 블록 이미지와 동일한 블록 이미지를 의미한다.
- Dirty: 데이터베이스 버퍼 캐시에서 변경되어 디스크로 내려적히기를 기다리는 버퍼이다. 이후 체크포인트 대상 버퍼가 된다.

 

 

 

버퍼 요청 시점에 따른 버퍼의 상태(모드)
 1. Consistent Mode Get
- 상황: 커밋되지 않은 트랜잭션이 두 개의 로우를 변경하는 동안 다른 프로세스가 읽기 요청(SELECT)을 하는 경우.
- 이 경우, 변경된 버퍼 이미지를 반환하면 안 된다. 이유는 해당 트랜잭션이 아직 커밋되지 않았기 때문이다. 따라서, 읽기 요청이 들어온 시점에서의 데이터를 반환해야 한다.
- 처리 방법: 오라클은 읽기 일관성을 유지하기 위해 언두 세그먼트로부터 언두 데이터를 생성하여 새로운 버퍼를 생성한다. 이 새로운 버퍼는 읽기 일관성을 유지하는 버퍼(Consistent mode)로, 사용자에게 반환된다.

 

 2. Current Mode Get
- 상황: 커밋되지 않은 트랜잭션이 두 개의 로우를 변경하는 동안 다른 프로세스가 쓰기 요청(UPDATE, DELETE)을 하는 경우.
- 설명: 이 경우, 해당 프로세스는 트랜잭션이 커밋되지 않은 상태의 버퍼(Current mode)를 반환받아야 한다. 이는 최종적으로 변경된 블록 이미지를 의미한다.
- 처리 방법: 오라클은 현재 변경된 데이터를 포함한 버퍼(Current mode)를 사용자에게 반환한다. 이 버퍼는 다른 쓰기 작업이 진행될 수 있도록 현재 상태를 반영하고 있다.

반응형

'DBMS > ORACLE Admin' 카테고리의 다른 글

DB buffer cache 영역 구성  (0) 2024.07.13
LRU 알고리즘  (0) 2024.07.13
Reserved Pool & Chunk  (0) 2024.07.11
Flashback Database  (0) 2024.07.11
Result Cache  (0) 2024.07.11