Redo와 Undo

밥벌이/Database 2015. 9. 23. 23:06

 - 둘다 복구에 사용된다. Redo의 경우 '다시실행한다' 라는 의미로 제대로 반영되지 못한
   변경사항을 다시 재현하는 역할을 한다. 이를 'roll forward단계'라 한다.
   이때 버퍼 캐시에 최종커밋되지 않은 변경사항까지 모두 복구되기 때문에 이러한 사항들을
   롤백 해야 하는데 이를 Undo라고 하며 '되돌린다' 라는 의미로 'rollback 단계'라고 한다.

 

1. Redo

1) online redo 로그 : 실제 로그버퍼에 버퍼링된 로그 엔트리를 기록, 최소 2개 이상의 파일로

                                구성되며 라운드로빈 방식사용.

2) archived redo 로그 : 라운드로빈 방식에 의해 online redo 로그파일이 재사용 되기 전에 다른 위치로

                                    백업해둔 파일.

▶ Redo로그의 사용 목적
  - Database Recovery : 물리적으로 디스크가 깨지는 등의 문제 발생시 Archived Redo로그가

                                      사용된다.
  - Cache Recovery : 모든 DBMS는 I/O 성능 향상을 위해 버퍼 캐시가 사용되는데 이는 휘발성으로

                                  디스크 상의 데이터 블록에 기록되지 않은 상태에서 인스턴스가 비정상

                                  종료되면 작업내용을 모두 잃게됨.
                                  이에 재기동시 Online Redo 로그에 저장된 기록사항을 읽어 버퍼캐시에만 있고 

                                  데이터 블록에 반영되지 못한 변경사항을 재현함(roll forward단계)
  - Fast Commit : 변경된 메모리 버퍼블록을 딧크 상의 테이터 블록에 기록하는 작업은 Random 엑세스
                          방식으로 이루지기 때문에 느리지만, 로고는 Append 방식으로 기록하므로 상대적으로

                          매우 빠르다. 

  이에 트랜잭션 발생시마다 우선 변경사항을 Append 방식으로 빠르게 로그에 기록하고 
  메모리 블록과 데이터 블록의 동기화는 적절한 수단(DBWR, Checkpoint를 이용해

  나중에 배치처리) 으로 일괄 수행한다.
  이러한 내용들이 Redo로그에 기록되며 오라클은 Redo로그를 믿고 언제든 Recovery

  가 가능한 상태가 되므로 빠르게 Commit을 완료할 수 있다.
  이러한 Fast Commit은 빠르게 트랜잭션을 처리해야 하는 모든 DBMS의 공통적인 메커

  니즘이다.

 

   ▶ Write Ahead Logging : 버퍼 캐시에 있는 블록 버퍼를 갱신하기 전에 먼저 Redo 엔트리를
                                          로그 버퍼에 기록해야 하며, DBWR이 버퍼 캐시로부터 Dirty 블록들을

                                          디스크에 기록하기 전에 먼저 LGWR이 해당 Redo 엔트리를 모두 Redo로그

                                          파일에 기록했음이 보장되어야 한다.
 
2. Undo
 - Undo 세그먼트는 구조적으로 볼 때 데이터를 저장하는 일반 세그먼트와 별반 다르지 않다.
   익스텐트 단위로 확장되고, 빠른 읽기/쓰기를 위해 Undo블록들을 버퍼 캐시에 캐싱하며,
   데이터 유실 방지를 위해 Redo로그에 로깅하는 점도 같다.
   다른 점이라면 저장되는 내용으로, 각 트랜잭션 별로 Undo세그먼트를 할당해주고
   (두 개의 이상의 트랜잭션이 하나의 Undo블록 세그먼트를 할당받아 같이 사용할 수 있음)
   그 트랜잭션이 발생시킨 테이블과 인덱스에 대한 변경사항들을 Undo 레코드 단위로
   Undo세그먼트 블록에 차곡차곡 기록된다.


 ▶ Undo 세그먼트의 사용 목적
  - Transaction Rollback : 트랜잭션에 의한 변경사항을 최종 커밋하지 않고 롤백하고자 할때
                                         Undo 데이터가 사용됨.
  - Transaction Recovery(rollback 단계) : Instance Crash 발생 후 Redo를 이용해서

                                                                'Roll forward단계'가 완료되면 최종커밋되지 않은 변경사항

                                                                까지 모두 복구되는데 이러한 트랜잭션들을 롤백하는데

                                                                사용된다.
  - Read Consistency : DB2, MS-SQL, Sybase 등은 Lock을 통해 읽기 일관성을 구현하지만 오라클은

                                    Undo데이터를 이용해서 이를 구현한다.


 ※ 상세 과정

 트랜잭션을 시작하려면 먼저 Undo 세그먼트 헤더에 있는 트랜잭션 테이블로 부터 슬롯을 할당받아야 하며, 할당받은 슬롯의 헤더에 자신이 현재 Active 상태임을 표시하고서 갱신을 시작한다.
 Active 상태의 트랜잭션이 사용하는 Undo블록과 트랜잭션 테이블 슬롯은 상태정보가 commited로 변경되기 전까지는 절대 다른 트랜잭션에 의해 재사용되지 않는다.
 이때부터 트랜잭션이 발생시키는 데이터 또는 인덱스 블록에 대한 변경사항은 Undo블록에 레코드로서 하나씩 차례대로  기록된다. Undo 세그먼트 헤더는 가장 마지막 Undo 레코드와 Last UBA(Undo Block Address)라는 일종의 포인터로 연결되어 있으며 각 Undo 레코드 간에는 체인형태로 연결되어 있다.
 v$transaction 뷰에 있는 used_ublk와 used_urec 칼럼을 통해 각각 현재 사용중인 Undo블록 개수와 Undo레코드 양을 확인할 수 있다. 인덱스가 전혀 없는 테이블이라면 한건을 갱신할때마다 used_urec 값이 하나씩 증가하지만 인덱스가 있다면 인덱스의 갱신내용까지 레코드로 추가된다.

 

 ▶ 블록 헤더 ITL 슬롯
  - Undo 세그먼트 헤더에 트랜잭션 테이블 슬롯이 있다면 각 데이터 블록과 인덱스 블록헤더에는

     ITL슬롯이 있다.
  - 특정 블록에 속한 레코드를 갱신하려면 먼저 블록 헤더로부터 ITL슬롯을 확보해야 한다.
    거기에 트랜잭션 ID를 기록하고 현재 해당 트랜잭션이 Active 상태임을 표시한 후에 블록 갱신이

    가능하다.
  - 오라클에서는 ITL슬롯 부족으로 인해 트랜잭션이 블로킹 되는 현상을 최소화할 수 있도록 3가지

     옵션을 제공한다.
    테이블을 생성할 때 initrans, maxtrans, pctfree 파라미터를 지정한다.
    각각 ITL슬롯 초기할당 개수, ITL슬롯 최대할당 개수, ITL슬롯 할당에 사용될 수 있는 예약된 데이터

    공간이다.

 

 ▶ Lock Byte
  - 블록헤더에서 블록으로 내려오면 Lock Byte에 대해 알아볼 필요가 있다.
    오라클은 레코드가 저장되는 로우마다 그 헤더에 Lock Byte를 할당해서 해당 로우를 갱신 중인

    트랜잭션의 ITL슬롯번호를 기록해둔다. 이것이 로우단위 Lock이다.
  - 레코드를 생신하려고 할 때 대상 레코드의 Lock Byte가 활성화 되어 있으면 ITL 슬롯을 찾아가고,
    ITL슬롯이 가리키는 트랜잭션 테이블 슬롯을 찾아가서 아직 Active 상태라면 트랜잭션이 완료될때까지

    대기한다.
  - ITL 슬롯에 기록되는 내용중 UBA(Undo Block Address)가 트랜잭션에 의해 발생한 변경 이전

    데이터가 저장된 Undo 블록주소를 가리키는 포인터 정보로 '문장수준 읽기 일관성' 구현을 위해

    CR Copy를 생성해서 과거버전으로 되돌리려고 할때 사용된다.   
 

'밥벌이 > Database' 카테고리의 다른 글

[Oracle] null 값 순위변경  (0) 2015.09.18
[Oracle] 제약조건 활성화/비활성화  (0) 2015.09.18
[Oracle] 외래키 옵션  (0) 2015.09.18
[Oracle] MERGE 구문  (0) 2015.09.18
[Oracle] 계층쿼리  (0) 2015.09.18
Posted by mypiece
,