- 다양한 시나리오로 어떻게 리두와 언두가 함께 작동하는지 살펴본다.
- 언두 테이블스페이스 또는 언두 세그먼트에 저장된 언두 정보는 리두에 의해서도 보호된다.
- 언두에 대한 변경은 리두를 생성하며 로깅된다.
- 언두 데이터는 언두 세그먼트에 추가되고 버퍼 캐시에 캐시된다.
INSERT-UPDATE-DELETE 시나리오 예제
- 다음 문장을 실행할 때 무슨 일이 일어날지 조사한다.
insert into t (x, y) values (1, 1) ;
update t set x = x + 1 where x = 1 ;
delete from t where x = 2 ;
- 문장 처리 중 시스템이 실패한다면 ?
- 중간에 ROLLBACK 하면 ?
- 성공 후 COMMIT 하면 무슨 일이 일어날 것인가 ?
INSERT
- 리두, 언두 모두 생성.
- 언두 : INSERT 결과를 원래대로 되돌리는데 필요한 정보를 포함
- 변경된 언두/인덱스/테이블 블록이 조금씩 캐시되어있다.
- 각 블록은 리두로그 버퍼에 있는 엔트리에 의해 보호된다.
- 가설 1 : 시스템이 지금 중단된다.
- 아무 문제 없음. 재시작 될 때 이 트랜잭션은 원래 없었던 것 처럼 처리된다.
- 가설 2 : 버퍼 캐시가 현재 가득 찼다.
- DBWR 이 버퍼캐시 공간 확보를 위해 디스크 플러시 해야하는 상황
- DBWR 이 LGWR 에 데이터베이스 블록 보호를 위해 리두 엔트리 플러시를 요청
- LGWR 이 관련 리두 정보를 플러시 한다.
- 만일 언두 블록과 관련된 리두 엔트리를 플러시하지 않고 테이블 T 의 변경된 블록만 플러시 한 채로 시스템이 실패하면 ?
- 리두로그 버퍼는 3초마다 플러시 / 버퍼가 ⅓ 이상 차거나 / 버퍼에 저장된 데이터 크기가 1MB 정도 될 경우/커밋 발생시 마다 디스크로 플러시 된다. 어느 시점에라도 리두 버퍼가 플러시될 수 있다.
- 커밋 하지 않은 채 버퍼캐시에 존재하는 변경 블록이 존재하고, 변경내용을 디스크에 리두한다.
UPDATE
- INSERT 와 거의 같은 작업을 일으키지만, UPDATE 로 인한 before 이미지 저장 공간이 필요하여 INSERT 보다는 언두 양이 클 것이다.
- 블록 버퍼 캐시에 좀 더 많은 새로운 언두 세그먼트 블록을 갖고있다.
- 필요시 UPDATE를 언두하기 위해 테이블/인덱스 블록을 캐시에서 변경함.
- 좀 더 많은 리두 로그 버퍼 엔트리를 생성했다.
- INSERT로 인해 생성된 리두로그 일부는 디스크에 있고 일부는 캐시에 있다고 가정한다.
- 가설 1 : 시스템이 지금 중단된다.
- 시작 시 오라클은 리두 로그를 읽고 트랜잭션에 대한 리두 로그 엔트리를 찾는다.
- INSERT 에 대한 리두엔트리는 리두 로그 파일에, UPDATE에 대한 리두는 리두 로그 버퍼에 있는 상태에서 INSERT 를 롤포워드 한다.
- (Roll forward : 인스턴스 복구 시 리두로그 파일에 기록된 변경내용을 데이터파일에 다시 적용하는 과정)
- 트랜잭션이 커밋되지 않음을 확인하고, 트랜잭션을 롤백한다.
- 버퍼 캐시에 방금 롤 포워드 된 언두를 가져와 데이터와 인덱스 블록에 적용하여 INSERT 실행 이전 모습으로 되돌린다.
- 가설 2 : 애플리케이션이 트랜잭션을 롤백한다.
- 해당 트랜잭션에 대한 언두 정보를 캐시된 언두 세그먼트 블록에서 찾거나, 플러시된 디스크에서 찾을 것이다.
- 롤백이 진행될 경우 리두 로그를 사용할 일은 없다.
- 오라클에서 작업이 정상적으로 진행될 때에는 리두 로그를 읽는 일이 없다.
- 다른 데이터베이스에서 로그파일을 '트랜잭션 로그' 로만 간주하여 언두와 리두를 분리하지 않는데, 오라클은 분리되어 설계되었다.
DELETE
- delete 결과로 언두가 생성. 블록은 변경되고 리두는 리두 로그 버퍼로 보내진다.
COMMIT
- 변경된 블록은 버퍼 캐시에 있다. (일부는 디스크에 플러시 되었다.)
- 트랜잭션을 재현하는데 필요한 모든 리두는 디스크에 있으므로 영속적이다.
- 이 순간 데이터파일로 부터 직접 데이터를 읽으면, DBWR 이 변경된 블록들을 디스크로 쓰지 않았을 것으로, 트랜잭션이 일어나기 전 모습의 블록을 보게된다.
- 장애가 발생해도, 리두 로그 파일을 이용해 블록을 최신상태로 만들 수 있기 때문에 상관없다.