거의 한달여 만에 글을 작성하네요-_-
지난 시간에 잠시 언급했던 버퍼 Pinning에 대해 잠깐 언급하고 Redo에 대해 알아보겠습니다
버퍼 Pinning은 버퍼를 읽고 나서 버퍼 Pin을 즉각 해제하지 않고 데이터베이스 Call이 진행되는 동안 유지하는 기능입니다
버퍼 Pinning은 하나의 데이터베이스 Call(Parse Call, Execute Call, Fetch Call) 내에서만 유효하고
Call이 끝나고 사용자에게 결과를 반환하고 나면 Pin은 해제되어야 하므로
첫 번째 Fetch Call에서 Pin된 블록은 두 번째 Fetch Call에서 다시 래치 획득 과정을 거쳐 Pin됩니다
Index Range Scan하면서 인덱스와 테이블 블록을 교차 방문할 때 블록 I/O를 체크해보면
테이블 블록에 대한 I/O만 계속 증가하는데
이는 버퍼 Pinning이 적용되는 지점이 인덱스를 스캔하면서 테이블을 엑세스할 때의 인덱스 리프 블록이기 때문입니다
참고로 인덱스를 경유해 테이블을 엑세스할 때
인덱스 클러스터링 팩터가 좋다면,
즉 인덱스 레코드가 가리키는 테이블 rowid 정렬 순서가 인덱스 키 값 정렬 순서와 거의 일치한다면
같은 테이블 블록을 반복 엑세스할 가능성이 그만큼 커지므로
오라클 8i부터 인덱스로부터 액세스되는 하나의 테이블 블록을 Pinning하기 시작했고
9i부터는 기준 테이블을 읽으면서 두 번째 테이블을 건건이 액세스하는 방식인 NL 조인 시
두 번째 테이블인 Inner 테이블을 룩업(Lookup)하기 위해 사용되는 인덱스 루트 블록을 Pinning하기 시작했습니다
버퍼 Pinning은 여기까지 보고 Redo에 대해 알아보겠습니다
오라클은 데이터 파일과 컨트롤 파일의 모든 변경사항을 하나의 Redo 로그 엔트리로서 Redo 로그에 기록하고
Redo 로그는 Online Redo 로그와 Archived(=Offline) Redo 로그로 구성됩니다
Online Redo 로그는 최소 2개 이상의 파일로 구성되고
Redo 로그 버퍼에 버퍼링된 로그 엔트리를 기록하는 파일입니다
만약 현재 사용 중인 Redo 로그 파일이 꽉 차면
다음 Redo 로그 파일로 로그 스위칭(Log switching)이 발생하고
모든 로그 파일이 꽉 차면 다시 첫 번째 로그 파일부터 재사용하는 라운드 로빈(Round-robin)방식을 사용합니다
Archived Redo 로그는 Online Redo 로그가 재사용되기 전에 다른 위치로 백업해 둔 파일입니다
그렇다면 Redo 로그는 왜 쓰는 것일까요??
먼저 물리적으로 디스크가 깨지는 등의 Media Fail 발생 시
데이터베이스를 복구(Database Recovery)하기 위해 사용하며 Archived Redo 로그를 이용하게 됩니다
Media Fail 발생 시므로 Media Recovery라고도 합니다
다음으로는 Cache Recovery를 위해 사용되며 Instance Recovery라고도 합니다
캐시가 휘발성이기 때문에 한 트랜잭션이 정상 종료되기 전에 정전 등에 의해
인스턴스가 비정상적으로 종료되면 데이터가 유실됩니다
이를 대비하기 위해 Redo 로그를 이용합니다
Instance Crash 발생 후 시스템을 재기동하면 우선 Online Redo 로그에 저장된 기록 사항들을 읽어들여
마지막 Checkpoint 이후부터 사고 발생 직전까지 수행되었던 트랜잭션들을 재현합니다(roll forward 단계)
이는 트랜잭션의 커밋여부를 불문하고 일단 버퍼 캐시를 시스템이 셧다운 되기 이전 상태로 되돌리는 것입니다
Cache Recovery가 완료되면
Undo 데이터를 이용해 커밋되지 않았던 트랜잭션들을 모두 롤백합니다(Transaction Recovery, rollback 단계)
마지막으로 Redo 로그는 Fast Commit을 위해 사용합니다
변경된 메모리 버퍼 블록을 디스크 상의 데이터 블록에 기록하는 작업(Random 액세스 방식)이 로그를 기록하는 작업(Append) 방식보다 상대적으로 느리기 때문에 트랜잭션 발생 시 건건이 데이터 파일에 기록하기보다 우선 변경사항을 Append방식으로 빠르게 기록하고 메모리 데이터 블록과 데이터 파일 간 동기화는 DBWR이나 Checkpoint 등을 이용해 나중에 Batch 방식으로 일괄 수행합니다
Redo 레코드를 기록할 때도 당연히 곧바로 파일에 기록하지 않고 먼저 Redo 로그 버퍼에 기록합니다
다시 말해서 데이터 블록 버퍼를 변경하기 전에 항상 Redo 로그 버퍼를 먼저 기록하고
일정 시점하다 LGWR 프로세스에 의해 Redo 로그 버퍼에 있는 내용을 Redo 로그 파일에 기록합니다
버퍼 캐시에 있는 블록 버퍼를 갱신하기 전에 먼저 Redo 앤트리를 로그 버퍼에 기록해야 하며
DBWR가 버퍼 캐시로부터 Dirty 블록들을 디스크에 기록하기 전에
먼저 LGWR가 해당 Redo 앤트리를 모두 Redo 로그 파일에 기록했음이 보장되어야합니다
이를 Write Ahead Logging이라고 합니다
이것으로 Redo에 대한 학습을 마치고 다음에 Undo에 대해 알아보겠습니다
그럼 이만-_-
'DBMS' 카테고리의 다른 글
[DBMS] Oracle(오라클)_3 (0) | 2020.02.02 |
---|---|
[DBMS] Oracle(오라클)_1 (0) | 2019.12.15 |