Undo란?

  • 8i까지는 롤백(rollback)이라는 용어를 사용.
    롤백 세그먼트를 생성하고 ONLINE/OFFLINE의 상태변경 등의 작업을 DB관리자가 수동으로 관리했고, rollback_segments 파라미터에 의해 개수 고정.
    롤백 세그먼트를 더 이상 확장할 수 없을 때 곧바로 ORA-01562 에러 발생.
  • 9i부터 오라클사는 공식 문서에 Undo라는 용어를 사용.
    AUM(Automatic Undo Management)기능 도입.
    Undo 세그먼트마다 하나의 트랜잭션이 할당되는 것을 목표로 세그먼트 개수를 오라클이 자동 관리.
    트랜잭션에 독립적으로 할당해 줄 Undo 세그먼트가 없을 때는(Online으로 전환할 수 있는 Offline 세그먼트가 없고 새로운 Undo 세그먼트를 생성할
    공간도 부족할 때)8i에서처럼 가장 적게 사용되는 Undo 세그먼트 중 하나를 할당.
    Undo 세그먼트를 더 이상 확장할 수 없을 때 다른 Undo 세그먼트로부터 Free Undo Space를 가져 올 수 있으며(Dynamic Extent Transfer),
    Undo 테이블스페이스 내에 있는 모든 Undo Space를 소진했을때 비로소 에러 발생.
  • Undo 세그먼트의 구조는 일반 테이블 세그먼트와 같다.(익스텐트 단위로 확장, 버퍼 캐시에 캐싱, 변경사항을 Redo로그에 로깅)
  • 다른 점이라면 Undo 세그먼트에 저장하는 내용이다.
    각 트랜잭션 별로 Undo 세그먼트를 할당(두 개이상의 트랜잭션이 하나의 Undo 세그먼트를 할당받아 같이 사용할 수 있음)해 주고
    그 트랜잭션이 발생시킨 테이블과 인덱스의 변경사항들을 Undo 레코드 단위로 Undo 세그먼트 블록에 기록한다.

Undo 의 목적

목적설명
Transaction Rollback최종 커밋하지 않고 롤백하고자 할 때 Undo 데이터 이용
Transaction Recovery(instance Recovery시 rollback 단계)Instance Crash 발생 후 Redo를 이용해 Roll forward 단계가 완료되면 최종 커밋되지 않은 변경사항까지 모두 복구.
Read Consistency읽기 일관성을 위해 사용.(다른DB는 Lock을 통해 읽기 일관성을 구현)

(1). Undo 세그먼트 트랜잭션 테이블 슬롯

Transaction Table Slot
컬럼내용비고
Transaction IDUSN# + Slot# + Wrap#USN : Undo Segment Number
Transaction Status상태정보COMMITTED, ACTIVE
Commit SCN트랜잭션이 커밋된 경우
Last UBAUndo 레코드 체인을 유지하는 일종의 포인터UBA: Undo Block Address
기타
트랜잭션의 시작/종료
상태Transaction Table 슬롯비고
시작슬롯을 할당 받고, Status 를 ACTIVE 로 변경슬롯을 얻지 못한경우 undo segment tx slot (대기이벤트) 발생
종료Status 를 COMMITTED 로 변경, Commit SCN 저장

!undo header.jpg!

  • Undo 세그먼트 중 첫 번째 익스텐트, 그중에서도 첫 번째 블록에는 Undo 세그먼트 헤더정보가 담긴다.
  • Undo 세그먼트 헤더에는 트랜잭션 테이블 슬롯(Transaction Table Slot)이 위치하며 각 슬롯에 기록되는 사항은 위 표와 같다.
  • 트랜잭션을 시작하려면 먼저 Undo 세그먼트에 있는 트랜잭션 테이블로 부터 슬롯을 할당 받아야 하며, 할당받은 슬롯에 자신이 현재 Active 상태임을 표시.
    (트랜잭션 슬롯을 얻지 못해 이용 가능한 슬롯이 생기기를 기다릴 때 발생하는 대기 이벤트가 'undo segment tx slot')
  • 트랜잭션이 발생시키는 데이터 또는 인덱스 블록에 대한 변경사항은 Undo 블록에 Undo 레코드로서 하나씩 차례대로 기록된다.
구분내용
Insert추가된 레코드의 rowidUpdate변경되는 컬럼에 대한 before image
Delete지워지는 로우의 모든 컬럼에 대한 before image
v$transaction.used_ublk현재 사용 중인 Undo 블록 개수
v$transaction.used_urec현재까지 기록한 Undo 레코드 양

  • 사용자가 커밋해 트랜잭션이 완료되면 트랜잭션 상태정보를 'commited'로 변경하고 그 시점의 커밋 SCN을 트랜잭션 슬롯에 저장. 이 트랜잭션 슬롯과 Undo 블록들은
    다른 트랜잭션에 의해 재상용될 수 있다.(in a circular fashion - 가장 먼저 커밋된 트랜잭션 슬롯부터 순차적으로 재사용)

(2). 블록헤더 ITL 슬롯

컬럼내용비고
ITL 슬롯 번호
Transaction ID
UBAUndo Block AddressCR 블록을 생성할때 사용
커밋Flag
Locking 정보
커밋 SCN트랜젹션이 커밋 된 경우
  • 특정 블록에 속한 레코드를 갱신하려면 먼저 블록 헤더로부터 ITL 슬롯을 확보하여 트랜잭션 ID를 기록하고 Active 상태임을 표시한 후에야 블록 갱신 가능.
    initrans : 블록을 처음 사용하려고 포맷할 때 블록 헤더에 ITL슬롯을 몇 개 할당할지를 결정하는 파라미터.
    maxtrans : initrans 파라메터에서 지정한 갯수만큼 다 썼을 때, 지정된 갯수(maxtrans파라메터) 만큼 ITL 슬롯을 추가 할당.
    pctfree에 의해 예약된 공간이 update(인텍스는 insert)에 의해 모두 사용되고 없다면 ITL을 할당받지 못해 Lock 경합이 발생.
    (ITL 슬롯이 부족할 때 발생하는 대기 이벤트가 'enq:TX - allocate ITL entry')

!block header.jpg!

Lock Byte

  • 레코드가 저장되는 ROW마다, 헤더에 Lock Byte를 할당해, 트랜잭션의 ITL 슬롯 번호를 기록해 둔다. (Row-level Lock)
레코드 갱신 시도시
순서대상동작비고
#1레코드의 헤더Lock ByteTRUE 인 경우 다음 단계 진행FALSE 인 경우 레코드 갱신
#2ITL 슬롯Transaction ID값을 얻어 다음 단계 진행
#3Transaction Table 슬롯StatusCOMMITTED 인 경우 레코드 갱신ACTIVE 인 경우 대기
DBMS 별 레코드 정보 관리
DBMS레코드 정보 관리 방법Lock 에스컬레이션비고
오라클레코드 속성없음별도 리소스 사용 없음
다른 DBMSLock 매니저있음

참조문서

블로그(오라클 성능 문제에 대한 통찰) : http://ukja.tistory.com/252
위키(오라클클럽) : http://wiki.gurubee.net/pages/viewpage.action?pageId=3900637