본문 바로가기

I T./Oracle

ORacle REDO/UNDO

Point
1. Buffer Cache 가 Disk Wirte 전에
    항상 관련 Redo / UNdo 가 먼저 Disk 로 Wirte 된다.
2. Redo 는 복구 및 Archive 를 위한것이고,
   Undo 는 읽기 일관성 용도
   그렇다면 Instance Recovery 시 필요한것은 ? 맞다 Redo 를 가지고 복구
P198
REDO 와 UNDO 의 동작 방법과 결과에 대한 개념적 이해는 데이터베이스를 보다 잘
이해하는 데 도움을 줄 것이다.

예로서 다음과 같은 트랜잭션에서 발생할지 모르는 상황들을 조사해보자
- INSERT INTO T (X,Y) VALUES ( 1,1 ) ;
- UPDATE T SET X = X+1 WHERE X = 1 ;
- DELETE FROM T WHERE X = 1 ;

여러 다른 방향으로 이 트랜잭션을 따라가 보기로 하자.
- 갱신 후에 시스템이 고장나면 어떻게 되는가 ?
- 갱신을 성공하고 커밋을 하면 무슨 일이 발생하는가 ?
- 롤백을 하면 무슨 일이 발생한는가 ?

초기 INSERT INTO T 는 REDO와 UNDO 정보를 모두 생성 한다.
생성된 UNDO 정보는 INSERT 가 없던 일로 만들 수 있을 만큼의 충분한 정보를 가진다.
생성된 REDO 정보는 INSERT 를 다시 발생시킬 수 있을 만큼의 충분한 정보를 가진다.
UNDO 는 많은 조각의 정보로 구성되어 있다.
예를 들면, ROW X와Y에 대한 인덱스가 포함된다.
갱신으로 인한 변화는 반드시 ROLLBACK(UNDO)에 따라 실행 취소가 되어야 한다.
실행 취소 정보는 ROLLBACK(UNDO) 세그먼트에 저장되어 있다.
ROLLBACK(UNDO) 세그먼트는 하나의 테이블 영역에 저장되어 있고,
다른 세그먼트들처럼 REDO LOG 에 의해서 보호된다.
다시 말해, ROLLBACK(UNDO) DATA 또는 인덱스 데이터처럼 다루어 진다.
ROLLBACK(UNDO) SEGMENT 들의 변화는 로그로 기록되는 REDO 정보를 생성한다.
UNDO DATA는 ROLLBACK(UNDO) SEGMENT에 추가되고 다른 데이터와 마찬가지로 버퍼 캐시에
저장된다. REDO 정보 역시 UNDO 정보처럼 많은 정보의 조각들로 구성된다.

이 시점에서 삽입이 발생한 후에 다음과 같은 데이터를 가지게 된다.
캐시되고 변경된 ROLLBACK BLOCK, INDEX BLOCK, TABLE DATA BLOCK 등이 존재 한다.
이들 각각의 변경된 블록은 REDO 로그 버퍼에 있는 엔트리에 의해서 보호된다.
이 모든 정보들은 즉시 캐시된다.

[ 가상 시나리오 1 ]
시스템이 지금 막 고장났다.[  INSERT INTO T (X,Y) VALUES ( 1,1 ) ; 후
디비가 전원이 나갔다가 DATABASE 가 재기동 되었다. ]
모든 것이 괜찮다. SGA 가 지워졌으나, SGA 에 있었던 어떠한 내용도 요구되지 않는다.
재시작을 할 때는 트랜잭션이 전혀 일어나지 않는 것처럼 될것이다. [ INSERT 가 없었던 것처럼 ]
변경된 블록은 디스크에 기록되지 않았고, REDO 정보도 디스크에 기록되지 않았다.

[ 가상 시나리오 2 ]
버퍼 캐시가 지금 막 채워졌다. [ 즉 버퍼 캐시 내용이 디스크에 WRITE 되었다. ]
DBWR 는 공간을 만들어야 하고 수정된 블록만 디스크에 써야 한다.
이러한 경우 DBWR는 LGWR 에게 데이터베이스 블록을 보호하는 REDO 블록을 디스크에
쓰라고 요청함으로써 시작될 것이다. [ DBWR가 디스크에 쓸려고 하는 버퍼 캐시와
연관된 REDO 블록을 디스크에 쓰라고 요청 ]
DBWR가 변경된 임의의 블록을 디스크에 쓸 수 있기 전에 LGWR는 이 블록과 관련된
REDO 정보를 디스크에 쓰지 않은 상태에서 시스템이 고장났다면, 연관된 REDO 정보가
없는 변경된 테이블 T 블록을 가지게 된다. REDO 로그 버퍼는 SGA를 방금 전의
상태로 실행 취소하기 위해서 필요한 모든 변경을 다시 할 수 있도록 변경된 블록들을
쓰기 전에 디스크에 쓰여져야 한다. 그래야만 ROLLBACK이 일어날 수 있다.
'테이블 T의 블록들은 디스크에 썼고, UNDO 블록에 대한 REDO 정보는 디스크에 쓰지
않은 상태에서 시스템이 고장났다면' 이라고 조건은 더 복잡해질 것이다.
이 시점에서 우리는 위에서 서술된 상황에 처해 있다. 일부 변경된 테이블과 인덱스
블록들을 생성 하였다. 이들은 새로운 ROLLBACK SEGMENT 블록들을 생성하였다.
이들 세 가지 블록들은 모두 자신들을 보호하는 REDO 정보를 생성 하였다.
REDO 로그 버퍼에 대한 이전의 논의를 회상해 보면,
REDO 로그 버퍼는 3초마다, 롤백 세그먼트가 가득 찼을 때, 그리고 커밋이 발생할 때
디스크에 쓰여진다. 처리 도중에 REDO 로그 버퍼는 디스크에 쓰여질 것이고,
일부 변경된 내용도 디스케 쓰여질 것이다.
블록들은 결국 디스크에 쓰여지겠지만 이 경우에는 아니다. 계속 갱신을 하게 되면
실행 취소 양은 더 커질 것이다.( 현재, 갱신의 결과로서 저장하는 '이전의 이미지
(BEFORE IMAGE)'를 가지고 있다.)
블록 버퍼 캐시에 새로운 롤백 세그먼트 블록들을 가진다. 갱신을 취소하기 위하여,
필요하다면 캐시에 있는 데이터베이스 테이블과 인덱스 블록을 변경하였다.
또한 더 많은 REDO 로그 버퍼 엔트리를 생성하였다. 생성된 REDO 로그의 일부는
디스크에 있고, 일부는 캐시에 있다.
가상 시나리오 1:
시스템이 지금 막 고장났다. 재시작을 하면서, 오라클은 REDO 로그를 읽어서 트랜잭션과
관련된 REDO 로그 엔트리를 찾는다. REDO 로그 파일에 INSERT INTO T을 위한
재실행 엔트리가 있고, 갱신을 위한 REDO 정보가 버퍼에 여전히 존재한다면,
오라클은 INSERT 을 진행 할 것이다. 이로써, 우리는 INSERT을 되돌리기 위한 ROLLBACK
SEGMENT 실행 취소 블록, INSERT 이후에 변경된 테이블 블록, 삽입 이후에 변경된
인덱스 블록 등을 가지는 첫번째 그림과 매우 유사한 상황이 된다.
시스템이 고장 복구중이고 세션이 더 이상 접속되어 있지 않으므로, 오라클은
트랜잭션이 커밋하지 않았다는 것을 발견하고 ROLLBACK 을 할 것이다.
오라클은 버퍼 캐시에서 방금 진행된 UNDO 정보를 택하여 테이블 데이터와 인덱스
블록에 적용하여 삽입이 발생하기 이전의 상태로 만든다. 이제 모든 것이
이전의 상태로 돌아갔다. 디스크에 있는 블록은 시스템 고장 이전에 블록이 디스크에
블록이 디스크에 기록되었는지에 따라서 INSERT를 반영했을 수도 있고 그렇지 않을
수도 있다. 만일 INSERT 이 디스크에 반영되었다면 INSERT 은 효과적으로 되돌려졌고,
블록이 버퍼 캐시로 부터 디스크에 쓰여졌을 때 데이터 파일은 그것을 반영할 것이다.
만약 INSERT이 반영되지 않았다면, 그것들은 어떠한 방식으로든지 나중에 덮어쓰여질
것이다.
가상 시나리오 2:
애플리케이션이 트랜잭션을 ROLLBACK 한다. 이 시점에서, 오라클은 캐시된 ROLLBACK
SEGMENT 블록 또는 블록이 디스크에 기록되었다면 이 디스크에서 트랜잭션에 대한
UNDO 정보를 찾을 것이다. 버퍼 캐시에 있는 데이터와 인덱스 블록들에 UNDO 정보를
적용할 것이다. 또는 데이터와 인덱스 블록들이 더 이상 캐시 요청에 존재하지 않는다면
디스크로부터 캐시로 읽어들여 UNDO 를 적용 한다. 이들 데이터와 인덱스 블록들은
나중에 원래의 형태로 디스크의 데이터 파일에 쓰여질 것이다.
첫번째 시나리오는 시스템 고장 복구에 대한 기본적인 세부 사항을 설명하였다.
시스템은 시스템 고장 복구를 2단계로 수행한다.
먼저 시스템을 고장난 시점까지 가져다 놓는다. 그리고 나서 아직 커밋되지 않는
모든 것들을 ROLLBACK 한다. 이 행동은 데이터 파일을 다시 동기화할 것이다.
진행중이던 작업을 다시 수행하고 아직 커밋되지 않을 것을 되돌린다.
두번째 시나리오는 보다 자주 발생할 수 있는 상황이다. ROLLBACK 과정에서 REDO 로그는
포함되지 않음을 설명하기에 유용하다. REDO 로그는 단지 복구와 아키이브로 기록하는
동안에만 읽혀진다. 이는 REDO 로그들이 기록되는 중요한 튜닝 개념이다.
오라클은 평상시에 처리 과정에는 REDO 로그를 읽지 않는다. ARCH가 파일을 일고 있을 때
LGWR 가 다른 장치에 쓰기를 하도록 충분한 장치를 가지고 있는한, REDO 로그에 대한
접근 경합은 없다. 많은 다른 데이터베이스는 로그 파일을 '트랜잭션 로그'로 취급한다.
트랜잭션 로그는 REDO와 UNDO를 분리하여 가지고 있지 않고 같은 파일 안에 함께
유지한다. 이러한 시스템들에서의 ROLLBACK 행위는 큰 부담이 될 수 있다.
( ROLLBACK 과정은 로그 WRITER가 쓰기를 시도한 로그 들을 읽어야 한다. )
그러므로 이러한 시스템에서는 공유 자원에 대한 경합이 발생할 수밖에 없다.
오라클의 목적은 로그가 연속적으로 쓰여질 수 있도록 하는 것이다.
그리고 로그는 쓰여지는 동안에는 아무로 그 로그를 읽지 않는다.
이제, DELETE 명령에 대해서 살펴보자. 다시, UNDO가 생성되고,
블록은 변경되고, REDO 정보는 REDO 로그 버퍼에 보내진다. 이는 이전 상황과
크게 다르지 않다. 사실을 곧 COMMIT 될 UPDATE 와 매우 유사하다. 다양한 고장
시나리오와 여러 경로를 살펴보았고 이제 마지막으로 COMMIT 에 도착했다.
여기서, 오라클은 REDO 로그 버퍼를 디스크에 쓸 것이고 그림은 다음과
같이 될 것이다.
변경된 블록은 버퍼 캐시에 있다. 아마도 변경된 블록의 일부분은 디스크에 쓰여졌을
것이다. 이 트랜잭션을 다시 수행하기 위해 필수적인 REDO 정보는 모두 안전하게
디스크에 있고 변경된 내용은 영구적으로 유지된다. 데이터 파일로부터 직접 데이터를
읽으려 하면, 아마도 DBWR가 아직 데이터를 쓰지 않았기에 트랜잭션이 발생하기 이전에
존재하던 블록을 보게 될 것이다. 그래도 상관없다. REDO 로그 파일은 고장이 발생할
때 이들 블록을 복구하는 데 사용될 수 있다. UNDO 정보는 ROLLBACK 세그먼트가
이 블록들을 감싸고 재사용하기 전까지 기다릴 것이다. 오라클은 UNDO 정보를 필요로
하는 임의의 세션에 대해 영향을 받는 객체들의 일관설 읽기를 제공하기 위하여
이 UNDO 정보를 사용할 것이다.

'I T. > Oracle' 카테고리의 다른 글

자동으로 UNDO 세그먼트 구성  (0) 2009.12.11
Oracle Tablespace  (0) 2009.12.11
ORacle Index 선정방법  (0) 2009.12.11
Oracle Recovery 복구  (0) 2009.12.11
Oracle Backup  (0) 2009.12.10
Oracle 권한  (0) 2009.12.10