9. 버퍼 관리자#
Altibase 디스크 테이블스페이스의 데이터 객체가 접근 또는 갱신되기 위해서는 디스크로부터 메모리에 적재되어야 한다. 이렇게 임시로 사용되는 메모리를 버퍼라고 하며, Altibase에서는 이 메모리를 일괄적으로 버퍼 풀이라고 한다.
디스크의 모든 데이터를 버퍼 풀에 쌓아두면 어떤 데이터에 대한 접근이라도 디스크 I/O 없이 빠르게 수행된다. 하지만 한정된 메모리로 인해 디스크 데이터의 일부만 버퍼 풀에 적재할 수 있다. 버퍼 풀에 적재된 데이터는 다른 데이터에 의해 제거될 수 있는데, 이를 데이터 교체라고 한다. 이 때 어떤 데이터를 버퍼에 오래 둘 것인가는 시스템 성능에 중요한 영향을 주기 때문에 효율적인 알고리즘이 사용되어야 한다.
Altibase에서는 버퍼 풀을 관리하는 주체를 버퍼 관리자 (Buffer Manager)라고 한다. 버퍼 관리자의 주된 역할은 자주 접근되는 데이터를 보다 버퍼에 오래 두어 효율적으로 버퍼를 관리하는 데 있다.
이 장에서는 버퍼 관리자의 구조와 기능, 버퍼 풀 관리 방법 및 관련 프로퍼티 등에 대해 설명한다.
버퍼 관리자의 구조#
버퍼 관리자 구성요소#
버퍼 관리자의 구성요소에는 버퍼 영역, 버퍼 풀, 버퍼 프레임, 및 BCB (Buffer Control Block)가 있다. 버퍼 풀의 버퍼들은 효율적인 관리를 위해 LRU 리스트, 프리페어(prepare) 리스트, 플러시(flush) 리스트, 체크포인트(checkpoint) 리스트, 해시(hash) 테이블로 구성된다.
이 절에서는 버퍼 관리자의 구성요소에 대해 설명한다.
버퍼 영역 (Buffer Area)#
버퍼 영역은 준비된 메모리 공간으로 이는 버퍼 풀에 할당된다. 버퍼 관리자에 의해 관리되는 버퍼 크기는 버퍼 영역의 크기에 따른다.
버퍼 풀 (Buffer Pool)#
버퍼 풀은 버퍼 관리자의 핵심 요소로, 버퍼를 교체하는 정책을 구현한다. 요청된 데이터 페이지를 버퍼에 적재하고 적재된 페이지 영역의 메모리 주소를 반환한다. 버퍼 풀은 내부적으로 해시 테이블과 LRU 리스트, 프리페어 리스트, 및 플러시 리스트들로 BCB들을 관리한다.
버퍼 프레임 (Buffer Frame)#
버퍼 프레임은 메모리에 하나의 페이지를 적재할 수 있도록 확보된 공간으로, 하나의 버퍼 프레임은 하나의 페이지와 크기가 같다. 버퍼 프레임이 모여서 버퍼 풀을 구성한다.
BCB (Buffer Control Block)#
BCB는 버퍼 프레임에 대한 정보를 가지며, 하나의 BCB는 하나의 버퍼 프레임에 대응된다. 버퍼 관리자는 버퍼에 적재된 모든 페이지에 대한 정보를 BCB로 관리하며, 버퍼 프레임은 단지 페이지가 메모리에 적재되는 공간이다. 각 BCB는 대응하는 버퍼 프레임에 대한 주소를 유지한다.
다음의 그림과 표는 BCB의 구조와 정보를 설명한다.

[표 9‑1] BCB 정보
속성 | 설명 |
---|---|
BCB 상태 (BCB Status) | BCB의 현재 상태를 나타낸다. 가능한 값은 FREE, CLEAN, DIRTY이다. - FREE: 버퍼에 페이지가 적재되지 않은 상태 - CLEAN: 버퍼에 페이지가 적재되었지만 갱신되지 않은 상태 - DIRTY: 버퍼의 페이지가 갱신되었으나 디스크에는 반영되지 않은 상태 |
버퍼 프레임 주소 (Buffer Frame Address) | 이 BCB에 해당하는 버퍼 프레임의 주소 |
테이블스페이스 식별자 (Space ID) | 페이지가 속한 테이블스페이스의 식별자 |
페이지 식별자 (Page ID) | 테이블스페이스내의 페이지들이 갖는 고유 번호 |
페이지 소유자의 락 (Page Owner Lock) | 페이지에 접근하기 위해서는 우선 락을 획득해야 한다. Read, Write, 또는 Fix 모드로 얻을 수 있다. 페이지에 대응하는 BCB에 대해 락을 특정 모드로 획득한 후에, 버퍼에 올라온 페이지에 해당 모드로 접근할 수 있다. |
수정 LSN (Modified LSN) | 버퍼내의 페이지가 수정된 시점의 LSN(Log Sequence Number)이다. 이 값은 플러셔가 버퍼에 올라온 페이지를 플러시할 때 어느 시점의 로그에 해당하는 변경까지 플러시할 것인지 나타낸다. |
Fix 개수 (Fix Count) | 페이지에 동시에 접근하고 있는 트랜잭션의 개수이다. 이 값이 1 이상이면 그 페이지는 교체될 수 없으며, 0이면 교체가 가능하다. |
접근 회수 (Touch Count) | 페이지가 버퍼에 적재된 후 트랜잭션들이 접근한 회수이다. 이 값은 버퍼의 hot, cold 여부를 판단하는데 사용된다. |
해시 테이블#
Altibase 서버는 페이지에 대한 요청이 들어오면 해당 페이지가 버퍼에 적재되었는지 확인하기 위해 해시 테이블내에서 그 페이지의 BCB를 찾는다. 해시 테이블에는 버퍼에 적재된 모든 페이지에 대한 BCB가 등록되어 있다.
LRU (Least Recently Used) List#
이는 접근한지 오래된 버퍼를 우선 교체 대상으로 선정하기 위해 사용된다.
Altibase는 LRU 리스트를 hot-cold 영역으로 나누어 관리하고 있어 "hot-cold LRU List"라고도 한다. 접근 빈도가 높은 버퍼들은 hot 영역에 넣고, 그렇지 않은 버퍼들을 cold 영역에 넣어 교체 대상 검색시 cold 영역만 확인하기 때문에 hot 버퍼들은 교체 대상에서 제외된다.
버퍼에 페이지가 처음 적재될 때, 이는 mid-point(LRU cold first)에 삽입된다. 새로운 데이터 페이지에 버퍼를 할당할 때, Prepare리스트에 빈 버퍼가 없으면 이 리스트의 마지막(LRU cold last)부터 검색하여 cold 버퍼가 교체된다. 교체되는 버퍼를 "victim"이라고 한다.

검색하는 도중에 접근 빈도가 높은 버퍼는 hot 영역인 LRU hot first로 옮겨진다. 또한 페이지가 갱신되었지만 디스크에 플러시되지 않은 dirty 버퍼는 Flush 리스트로 옮겨진다. 그리고 버퍼에 페이지가 올라왔지만 갱신되지 않은 clean 버퍼가 hot 영역에 있지 않으면 교체 대상 버퍼로 선정된다.
hot 영역의 비중은 HOT_LIST_PCT프로퍼티로 조정이 가능하다. 기본값은 50이며, 이는 LRU 리스트의 절반을 hot 영역으로 사용한다는 의미이다.
Flush List#
LRU 리스트에서 교체 대상을 검색할 때 dirty 버퍼가 나타나면 플러시 리스트로 옮겨진다. 플러시 리스트는 페이지가 갱신되었지만 디스크에는 아직 반영되지 않은 버퍼들이 모여있는 리스트이다. 그러나 모든 dirty 버퍼가 플러시 리스트에 있는 것은 아니다. 갱신된 시점에 플러시 리스트로 옮겨지는 것이 아니라 LRU 리스트에서 교체 대상을 검색하는 과정에서 플러시 리스트로 옮겨지기 때문이다.
교체 플러시(replacement flush)가 발생하면 이 리스트의 갱신된 페이지는 디스크에 반영되고, clean 버퍼가 확보된다.
Prepare List#
플러시 리스트에서 디스크로 반영이 된 버퍼들은 모두 Prepare 리스트로 옮겨진다. 즉 Prepare 리스트는 플러시 작업을 마친 clean 버퍼들로 구성된 리스트이다.
버퍼 관리자는 교체 대상 버퍼를 찾을 때 우선 Prepare 리스트를 검색한다. 만약 Prepare 리스트에서 적합한 버퍼를 찾을 수 없다면 LRU 리스트를 찾아본다. 그러나 버퍼가 Prepare 리스트에 있어도 갱신이 가능하기 때문에 항상 clean 상태인 것은 아니다.
Checkpoint List#
LRU 리스트, Flush 리스트, Prepare 리스트는 상호 배타적인 리스트이기 때문에 한 개의 버퍼는 이 중의 두 개 이상의 리스트에 존재할 수 없다. 그러나 체크포인트 리스트는 세가지 리스트와 달리 독립적으로 관리가 가능하기 때문에 다른 세가지 리스트에 존재하는 버퍼가 체크포인트 리스트에 속할수 있다.
dirty 버퍼 즉 갱신된 버퍼들은 체크포인트 리스트에 존재하게 되며, 체크포인트 리스트의 모든 버퍼는 dirty 상태이다. 이 리스트의 버퍼들에는 처음에 갱신된 시점에 해당하는 LSN이 부여되며, 이를 기준으로 정렬 관리된다. 체크포인트 리스트가 플러시될 때 체크포인트 리스트의 LSN이 작은 버퍼부터 플러시 된다.
다음의 그림은 LRU 리스트, Flush 리스트, Prepare 리스트의 모든 버퍼들이 해시 테이블을 통해 접근이 가능한 것을 나타낸다.

List 다중화#
LRU 리스트, Flush 리스트, Prepare 리스트, 체크포인트 리스트는 각각 다중화가 가능하다. 리스트 다중화를 통해 다수의 데이터베이스 클라이언트가 동시에 서비스 요청시 리스트 락(LOCK) 경합이 발생하는 것을 방지한다.
각 종류별 리스트의 개수는 BUFFER_LRU_LIST_CNT, BUFFER_PREPARE_LIST_CNT, BUFFER_FLUSH_LIST_CNT, 및 BUFFER_CHECKPOINT_LIST_CNT프로퍼티에 설정할 수 있고, 설정된 값은 V$BUFFPOOL_STAT성능 뷰의 LRU_LIST_COUNT, PREPARE_LIST_COUNT, FLUSH_LIST_COUNT, 및 CHECKPOINT_LIST_ COUNT 칼럼을 조회해서 확인할 수 있다. 그러나 서버가 운영중일 경우에는 이들 값의 변경이 불가하다.
BCB 상태 전이#
각 BCB의 상태는 항상 FREE, CREAN, DIRTY 3가지 중의 하나이다.
FREE#
버퍼에 어떤 페이지도 적재되지 않은 상태이다. 시스템이 처음 구동되면 대부분의 버퍼들이 free 상태가 된다. 또한 테이블스페이스가 삭제(drop)되거나 오프라인(offline)으로 되면 해당 테이블스페이스에 속한 페이지에 해당하는 모든 버퍼들은 free상태로 된다.
CLEAN#
버퍼에 페이지가 적재되어 있지만 아직 갱신되지 않은 상태이다. 즉, 버퍼의 페이지 내용이 디스크의 페이지 내용과 동일한 상태이다. 이 버퍼는 해시 테이블로 접근될 수 있다. 이 버퍼는 LRU 리스트, 플러시 리스트, Prepare 리스트 중 하나에 있을 수 있으나, 체크포인트 리스트에는 있을 수 없다.
DIRTY#
버퍼에 있는 페이지가 갱신은 되었으나, 디스크에는 반영되지 않은 상태이다. DIRTY 버퍼는 체크포인트 리스트에 포함되며, LRU 리스트, 플러시 리스트, Prepare 리스트 중 하나에도 속한다. 더티 버퍼는 플러시 된 후 CLEAN 상태로 변경된다.
플러셔 (Flusher)#
플러셔(Flusher)는 교체될 모든 버퍼를 디스크에 반영하는 플러시(flush)를 수행한다. Altibase에서는 두 종류의 플러시가 행해지는데, 교체 플러시(Replacement Flush)와 체크포인트 플러시(Checkpoint Flush)가 있다.
-
교체 플러시(Replacement Flush)#
버퍼 교체를 위해 접근된지 오래된 갱신된 버퍼를 플러시
-
체크포인트 플러시(Checkpoint Flush)#
체크포인트 시간을 줄이기 위해 처음 갱신한 시점이 오래된 버퍼를 플러시
교체 플러시는 주기적으로 발생하거나 교체 대상 버퍼를 찾지 못했을 때 강제적으로 수행된다. 체크포인트 플러시 역시 주기적으로 발생할 수 있으나 사용자가 ALTER SYSTEM CHECKPOINT 명령으로 수행할 수 있다.
플러셔는 교체 플러시를 먼저 수행한 후 해당 작업이 없을 때에만 주기적으로 체크포인트 플러시를 수행한다. 즉 플러셔는 일정 시간을 대기한 후 교체 플러시를 할 버퍼가 있으면 디스크에 반영한다. 플러셔는 DEFAULT_FLUSHER_WAIT_SEC이상 MAX_FLUSHER_WAIT_SEC 미만의 시간을 대기한다. 교체 플러시 이후 다시 일정 시간을 대기하여 교체 플러시할 대상이 없으면 체크포인트 플러시의 작업 여부를 판단하여 플러시를 하거나 다시 대기한다.
체크포인트 플러시가 발생하기 위한 조건은 다음과 같다.
- 마지막으로 플러셔가 플러시한 후 CHECKPOINT_FLUSH_MAX_WAIT_SEC이 지났을 때
- 시스템 재구동시 복구해야 하는 페이지들에 대한 로그 수가 일정 개수를 넘어설 때. 즉 갱신되었으나 디스크에 플러시되지 않은 페이지들이 갖는 LSN 중에서 가장 작은 LSN이 CHECKPOINT_FLUSH_MAX_GAP 만큼 벌어졌을 때
그러나 플러셔가 오랜 시간을 대기하도록 설정되었다고 하더라도, 트랜잭션이 자주 발생하여 교체할 버퍼가 많이 발생하면 강제적인 플러셔도 가능하다.
체크포인트 플러시를 위해 플러셔가 한 번의 주기에서 플러시 할 수 있는 버퍼 페이지(프레임)의 개수는 CHECKPOINT_FLUSH_COUNT 프로퍼티를 사용해서 명시할 수 있다.
또한 BUFFER_FLUSHER_CNT프로퍼티의 값을 조정하여 다수의 플러셔를 둘 수 있다. 그러나 이 프로퍼티는 서버 운영중에는 변경될 수 없다. 각각의 플러셔는 ALTER SYSTEM START/STOP FLUSHER 구문으로 구동 또는 정지시킬 수 있다.
SQL에 대한 자세한 내용은 SQL Reference를 참조하기 바란다.
버퍼 관리#
접근 모드#
페이지에 접근하기 위해서는 우선 락(Lock)이 획득되어야 한다. 접근 모드는 페이지에 대한 접근을 어떤 권한으로 허가해 줄 것인가에 따라 다음과 같이 Read, Write, Fix로 구분된다.
[표 9‑2] 버퍼 접근 모드
접근 모드 | 설명 |
---|---|
Read(읽기) | 버퍼에 올라온 페이지를 읽기 위한 접근 모드이다. 여러 개의 트랜잭션이 동시에 페이지에 접근할 수 있다. |
Write(쓰기) | 버퍼에 올라온 페이지에 쓰기 위한 접근 모드이다. 쓰기 모드로는 한 시점에 하나의 트랜잭션만 같은 페이지 접근이 가능하다. |
Fix | 이 접근 모드로 버퍼에 페이지를 올리면, 이 페이지는 버퍼 관리자에 의해 교체되지 않는다. Fix 모드로 트랜잭션이 페이지에 접근하여 데이터를 읽으면 그 데이터가 정확한 데이터임이 보장되지 않는다. 정확한 데이터를 읽기 위해서는 페이지에 읽기(Read) 모드로 접근해야 한다. |
접근 모드간 허가 관계를 살펴보면 다음과 같다.
[표 9‑3] 접근 모드간 허가 관계
타 트랜잭션 획득 모드
요청한 접근 모드
|
Read | Write | Fix |
---|---|---|---|
Read | O | X | O |
Write | X | X | O |
Fix | O | O | O |
위의 표를 보면 트랜잭션이 write 모드를 요청한 경우, 이미 다른 트랜잭션이 read나 write를 획득중이라면, 페이지에 대한 해당 접근 모드의 요청은 대기하거나 실패한다는 것을 나타낸다. 또는 read를 요구한 경우에 이미 다른 트랜잭션이 그 페이지에 read 접근 모드로 락을 획득하고 있다면 접근이 성공하지만, write 접근 모드로 락을 획득하고 있다면 이 요청은 실패한다.
대기 모드#
대기 모드는 이미 다른 트랜잭션이 페이지를 사용하고 있어 요구한 접근 모드를 허가해 줄 수 없는 경우, 대기할 것인가 혹은 대기하지 않고 바로 에러를 리턴할 것인가를 결정한다.
[표 9‑4] 대기 모드
대기 모드 | 설명 |
---|---|
대기(Wait) | 다른 트랜잭션이 작업을 마치고 락(Lock)을 해제할 때까지 해당 트랜잭션이 대기한다. |
대기 안 함(No-Wait) | 다른 트랜잭션이 작업을 마치는 것을 대기하지 않고 해당 트랜잭션은 바로 에러를 리턴한다. |
페이지 요청 처리 절차#
1. 해시 테이블 검색#
버퍼 관리자는 페이지 식별자, 접근 모드, 및 대기 모드가 포함되어 있는 페이지 요청을 받는다.
버퍼 관리자가 요청을 받으면, 먼저 해시 테이블에 해당 BCB가 있는지 검사한다. 요청된 페이지가 이미 버퍼에 적재되어 있다면, 해당 페이지를 기술하는 BCB는 해시 테이블에서 검색될 것이다. 만약 해시 테이블에서 그 BCB를 찾을 수 없다면 페이지는 버퍼에 올라오지 않은 것이므로, 버퍼 관리자는 디스크로부터 페이지를 읽어 버퍼에 적재해야 한다.

2. Lock 획득#
Altibase는 항상 정확한 데이터를 읽도록 보장하기 위해 디스크로부터 read가 진행중인 페이지는 read가 끝날 때까지 접근하지 않는다.
이를 위해 Altibase는 디스크로부터 read를 수행할 때 write 권한을 획득한다. 임의의 트랜잭션이 한 페이지에 대해 read 혹은 write 권한을 획득할 수 있다면, 그 시점에는 디스크로부터 read가 진행 중이 아님을 의미한다.
Lock의 허가는 아래의 표와 같이 접근 모드, 디스크로부터 페이지 읽기, 및 대기 모드에 따라 달라진다.
[표 9‑5] Lock 획득 허가
접근 모드 | 디스크로부터 읽기 | 대기 모드 | Lock 획득 결과 |
---|---|---|---|
Fix | O | 상관없다 | 읽기가 끝날 때까지 대기 후 허가 |
Fix | X | 상관없다 | 허가 |
Read | O | 대기 | 접근 모드가 허가되면 허가, 실패 시 대기 |
Read | O | 대기안함 | 접근 모드가 허가되면 허가, 실패 시 대기 |
Read | X | 대기 | 접근 모드가 허가되면 허가, 실패 시 대기 |
Read | X | 대기안함 | 접근 모드가 허가되면 허가, 실패 시 바로 에러 리턴 |
Write | O | 대기 | 접근 모드가 허가되면 허가, 실패 시 대기 |
Write | O | 대기안함 | 접근 모드가 허가되면 허가, 실패 시 대기 |
Write | X | 대기 | 접근 모드가 허가되면 허가, 실패 시 대기 |
Write | X | 대기안함 | 접근 모드가 허가되면 허가, 실패 시 바로 에러 리턴 |
표에서 나타나는 것처럼, Fix모드로 접근을 요청한 경우 현재 페이지가 어떤 권한으로 락(Lock)이 잡혀 있더라도 바로 허가가 될 것이다. 그러나 디스크로부터 페이지를 읽어오는 중이라면 read가 끝날 때까지 그 요청은 대기한다.
Read 또는 Write 권한과 대기를 하지 않는 모드로 접근이 요청되는 경우, 만약 디스크로부터 페이지를 읽어오는 중이라면 Read가 끝날 때까지 그 요청은 대기한다.
디스크로부터 페이지 읽기#
버퍼 관리자가 페이지를 요청하였을 때, 버퍼에 존재하지 않는다면 디스크로부터 페이지를 읽는 과정을 수행한다.
1. 사용 가능한 BCB 획득#
Altibase 서버가 버퍼에 존재하지 않는 페이지를 버퍼로 적재하기 위해서는 우선 BCB를 확보해야 한다. 페이지가 적재될 버퍼를 찾기 위해 먼저 Prepare 리스트를 검색한다. Prepare 리스트에서 free 버퍼를 찾으면 페이지 적재를 가장 쉽게 수행할 수 있다.
그러나 이 방법으로 free 버퍼를 확보하지 못하면, 다음 단계로 교체할 버퍼를 찾는다. 시스템 구동 초기에는 많은 free 버퍼가 존재하지만, 테이블스페이스가 삭제(drop) 또는 오프라인으로 되지 않는 이상 버퍼 풀에 free 버퍼가 존재할 가능성은 낮다. 특히 플러시한 후에도 버퍼에는 페이지 내용이 유지되기 때문에 free 버퍼가 새로 생기지는 않는다.
2. 버퍼 교체#
교체할 버퍼를 검색할 때 먼저 prepare 리스트가 검사된다. prepare 리스트는 플러시 되어 플러시 리스트로부터 옮겨진 clean 버퍼를 보유하고 있기 때문이다.
prepare 리스트에서 적합한 교체 대상 버퍼를 찾지 못했다면 LRU 리스트가 검색된다. 그러나 LRU 리스트를 검색했는데도 clean 버퍼를 찾지 못했다면, 또 다른 prepare 리스트를 검사한다. 이 과정을 clean 버퍼를 찾을 때까지 prepare 리스트 개수만큼 반복한다.
그러나 모든 prepare 리스트를 검색하여도 clean 버퍼를 찾지 못한다면, 플러셔들을 작동시키고, prepare 리스트에 버퍼가 삽입될 때까지 대기한다. 이 대기 시간은 BUFFER_VICTIM_SEARCH_INTERVAL프로퍼티로 설정된다. 그러나 대기시간 동안에도 clean 버퍼를 찾지 못 할 경우, 다음 prepare 리스트에서 검색을 진행한다. 이를 victim search warp이라고 한다.
V$BUFFPOOL_STAT성능 뷰에서 VICTIM_SEARCH_WARP 값이 증가하고 있다면 버퍼 교체를 위해 많은 대기를 하고 있다는 의미이다. 이러한 문제가 지속된다면 버퍼의 크기를 늘리거나 플러셔의 개수를 증가시켜 시스템을 재구동시켜야 할 것이다.
LRU list에서 버퍼 교체 대상이 되기 위해서는 다음의 조건을 만족해야 한다.
- 아무도 fix하지 않은 것 (fix count가 0인 버퍼)
- 버퍼에 적재되었으나 아직 갱신되지 않은 페이지 (clean 버퍼 상태)
- 버퍼가 Hot하지 않는 것 (touch count가 HOT_TOUCH_CNT 미만인 버퍼)
교체 대상 버퍼를 찾으면 해시 테이블에서 제거를 한 후 다음 과정을 진행한다.
3. 읽기 후 페이지 검증#
BCB가 확보되면 디스크로부터 페이지를 버퍼에 적재한다. 그러나 디스크에 저장된 페이지는 하드 디스크 이상이나 정전 등의 예상하지 못한 이유로 일부 페이지의 내용이 유실될 수 있다. 이러한 상황을 인식하지 못하면 사용자는 잘못된 데이터를 볼 수 있기 때문에, Altibase 서버는 이를 인식할 수 있어야 한다. 이를 위해 Altibase 서버는 디스크로부터 페이지를 버퍼에 적재한 후 바로 해당 페이지가 무결한지 검사한다.

플러시(Flush)#
1. 플러시할 버퍼 선정#
버퍼에 적재된 이후 수정된 페이지는 희생자로 선택되거나 체크포인트를 할 때 디스크에 플러시된다. 버퍼에 적재된 페이지가 플러시되기 위해서는 다음의 조건을 만족해야 한다.
- 적어도 한 번 수정되어야 함
- fix 개수가 0이어야 함
플러시 중에 다른 트랜잭션에 의한 읽기는 동시에 가능하다. 즉 플러시 수행을 위해서는 read 모드 권한이 획득된다.
2. I/O 버퍼에 페이지 복사#
플러시 대상 페이지가 정해지면 이 페이지는 디스크에 기록되기 전에 먼저 I/O 버퍼라는 메모리 공간에 복사된다. 디스크 I/O 작업은 메모리 연산에 비해 긴 시간을 소요하기 때문에 I/O 버퍼라는 메모리 공간에 먼저 복사가 된 후, 디스크에 기록된다.
버퍼 페이지가 I/O 버퍼에 복사되면 그 버퍼는 다른 트랜잭션에 의해 읽혀질 수도 있고, 재갱신될 수도 있다. 그러나 /O 버퍼가 사용되지 않는다면 페이지가 디스크에 기록되는 동안 (즉, 디스크 I/O 작업이 일어나는 동안) 그 페이지는 갱신되거나 읽혀질 수 없을 것이다.
3. 로그 플러시#
수정된 페이지가 디스크에 반영되기 전에 수정된 내용에 대한 로그가 먼저 디스크에 반영되어야 한다. 이를 WAL(Write-Ahead Logging) 프로토콜이라고 한다.
그리고 디스크로부터 버퍼에 페이지가 적재될 때 이 페이지의 데이터가 깨졌는지 확인하기 위해서 체크 섬이 계산된다. 페이지를 디스크로부터 읽을 때마다 이 체크 섬을 계산하여 페이지의 체크 섬과 비교함으로써 페이지가 무결한지 여부를 가리게 된다.
4. I/O 버퍼의 페이지들을 디스크에 기록#
I/O 버퍼의 페이지들이 디스크에 기록될 때 이 버퍼의 내용은 더블 라이트 파일(Double-write file)에 모두 한 번에 기록된 후, 각각의 페이지가 데이터 파일에 기록된다.
이처럼 디스크에 두 번 기록하는 이유는 페이지를 디스크에 기록하는 중에 시스템 장애가 발생하면 디스크에는 부분 쓰기(partial write)된 페이지가 남게 되는데 이는 복구가 불가능하기 때문이다. 일관성이 깨진 페이지에 대해서는 리두 로그(redo log)로도 복구가 불가능하다.
Altibase에서는 DOUBLE_WRITE_DIRECTORY 프로퍼티를 사용해서 더블 라이트 파일이 저장될 디렉터리가 지정된다. 이 파일은 시스템 구동시 데이터 파일의 정합성을 검증 또는 복구하기 위해 사용되며, 이 파일이 없으면 이 과정은 생략된다.

버퍼 관련 프로퍼티#
버퍼 관리자를 사용하기 위해서는 Altibase 프로퍼티 파일의 프로퍼티들을 사용 목적에 맞게 설정해야 한다. 버퍼와 관련된 프로퍼티는 다음과 같다. 각 프로퍼티에 대한 상세한 설명은 General Reference > 2장. Altibase 프로퍼티를 참조한다.
- BUFFER_AREA_CHUNK_SIZE
- BUFFER_AREA_SIZE
- BUFFER_CHECKPOINT_LIST_CNT
- BUFFER_FLUSH_LIST_CNT
- BUFFER_FLUSHER_CNT
- BUFFER_HASH_BUCKET_DENSITY
- BUFFER_HASH_CHAIN_LATCH_DENSITY
- BUFFER_LRU_LIST_CNT
- BUFFER_PINNING_COUNT
- BUFFER_PINNING_HISTORY_COUNT
- BUFFER_PREPARE_LIST_CNT
- BUFFER_VICTIM_SEARCH_INTERVAL
- BUFFER_VICTIM_SEARCH_PCT
- BULKIO_PAGE_COUNT_FOR_DIRECT_PATH_INSERT
- CHECKPOINT_FLUSH_COUNT
- CHECKPOINT_FLUSH_MAX_GAP
- CHECKPOINT_FLUSH_MAX_WAIT_SEC
- CM_BUFFER_MAX_PENDING_LIST
- DEFAULT_FLUSHER_WAIT_SEC
- DIRECT_PATH_BUFFER_PAGE_COUNT
- FAST_UNLOCK_LOG_ALLOC_MUTEX
- HIGH_FLUSH_PCT
- HOT_LIST_PCT
- HOT_TOUCH_CNT
- LOG_BUFFER_TYPE
- LOG_FILE_SIZE
- LOW_FLUSH_PCT
- LOW_PREPARE_PCT
- MAX_FLUSHER_WAIT_SEC
- REPLICATION_LOG_BUFFER_SIZE
- SECONDARY_BUFFER_ENABLE
- SECONDARY_BUFFER_FILE_DIRECTORY
- SECONDARY_BUFFER_FLUSHER_CNT
- SECONDARY_BUFFER_SIZE
- SECONDARY_BUFFER_TYPE
- SMALL_TABLE_THRESHOLD
- TABLE_BACKUP_FILE_BUFFER_SIZE
- TOUCH_TIME_INTERVAL
버퍼 관리자 통계 정보#
버퍼 관리자 통계 정보는 Altibase가 제공하는 성능 뷰를 통해 확인할 수 있다. 성능 뷰에 대해서는 General Reference > 3장. Altibase Data Dictionary를 참조한다.
버퍼 풀과 관련된 정보는 V$BUFFPOOL_STAT을 통해 확인할 수 있고, 플러셔와 관련된 정보는 V$FLUSHINFO와 V$FLUSHER을 통해 확인할 수 있다. 버퍼 매니저의 버퍼 프레임 통계 정보는 V$BUFFPAGEINFO을 통해 확인할 수 있고, 언두 테이블스페이스의 버퍼 풀 관련 통계 정보는 V$UNDO_BUFF_STAT를 통해 확인할 수 있다.
통계 정보는 서버가 시작한 이래로 계속 누적된 값이므로 특정 기간 동안의 값을 알기 위해서는 모든 칼럼에 대해 다음의 방법으로 계산해야 한다: (현재의 값 - 측정 시작 시점의 값).
Hit Ratio 계산#
V$BUFFPOOL_STAT성능 뷰의 HIT_RATIO 칼럼을 통해 버퍼 풀의 누적된 히트율을 확인할 수 있다.
Exmple
SELECT HIT_RATIO FROM V$BUFFPOOL_STAT;
히트율은 다음의 수식에 의해 구해진다.
Hit Ratio = (GET_PAGES + FIX_PAGES - READ_PAGES) / (GET_PAGES + FIX_PAGES)