05 UNDO

목차

Undo의 개념
Undo의 목적
AUM의 개념
AUM의 목적
Undo Segment 할당되는 원리
참고 1. 버전별 Undo의 특징 정리
참고 2. Undo Retention(10g)
참고 3. Undo 정보 조회
참고 4. Redo, Undo가 발생하지 않는 경우
Undo Segment Transaction Table Slot
블록 헤더 ITL 슬롯

Undo의 개념


1. Undo Data - DML이 발생할 경우 변경되기 전의 데이터 값
2. Undo Segment - Undo Data를 저장하는 Segment
3. Undo Tablespace - Undo Segment를 저장하는 Tablespace

Undo의 목적

1. Transaction Rollback

Transaction Rollback


특정 작업을 수행한 후 커밋을 수행하지 않은 작업에
롤백을 수행하게 되면 작업 수행 전의 데이터로 복구되는 기능

2. Read Consistency

Read Consistency


수행시간이 많이 걸리는 조회 수행 중 조회 대상에 대한 다른 트랜잭션의 변경 작업이
일어날 경우 오라클에서는 조회 트랜잭션과 변경 트랜잭션의 SCN을 비교하여
CR 작업을 통해 원래의 데이터를 보여줌

3. Instance Recovery

Instance Recovery


transaction이 수행되고 있을 때 instance가 실패하여 crash가 발생되면 redo를 이용해 
roll forward 단계가 완료 된 후 최종 commit 되지 않은 변경 사항까지 모두 복구. 
따라서 system이 shutdown 된 시점에 commit 되지 않았던 transaction들을 
모두 rollback 해야 하는데, 이때 undo segment에 저장된 undo data를 사용.

AUM(Automatic Undo Management)의 개념

  • Undo Data는 Undo Tablespace를 사용하여 관리됨
  • Oracle Server가 자동으로 Undo Data를 Undo Tablespace에서 관리
  • Undo Segment는 _SYSSMUn$ 형태의 이름으로 생성됨

AUM(Automatic Undo Management)의 목적


1. 이전 version에서 자주 발생되었던 rollback segment관련 오류를 방지 할 수 있음
- ORA-01555 snapshot to old
- rollback segment 할당 오류

2. Oracle Flashback Query 기능을 사용할 수 있음
- 사용자 실수 인하여 발생한 data recovery시 사용하는 기능

3. DBA의 업무로드를 줄일 수 있음
- rollback segments의 경합 및 개수, size에 대한 DBA의 업무가 줄어듦
- 트랜잭션 후 undo space에 관하여 DBA가 관리를 해야 하지만 AUM에서는 Oracle 자체적으로 online과 offline을 수행함

Undo Segment 할당되는 원리


1. 현재 online segment 중에 free block이 있는 segment 중 하나를 랜덤하게 선택하여 우선적으로 사용한다.
2. 다른 transaction이 사용중이라면 1번의 과정을 3번까지 재시도 한다.
3. 2번의 과정이 실패하면 offline undo segment를 online 해서 사용한다.
4. 3번의 과정이 실패하면 undo tablespace에 free space가 있거나 autoextend 상태일 때 새로운 undo segment를 생성한다.
5. 4번의 과정에서도 실패하면 Oracle 8i 에서 사용했던 Rollback Segment 알고리즘을 사용한다. 즉, 이미 다른 transaction에 의해 사용중인 undo segment 중에서 가장 사용량이 적은 것을 사용한다.

※ 위의 과정에서 undo_retention에 명시한 시간이 지나지 않은 extent (unexpired extent)도 재사용 한다. 단. undo guarantee가 적용되지 않았을 때만 해당한다.

※ 8i에서는 undo segment를 더 이상 확장할 수 없을 때 곧바로 ORA-01562 에러를 만났지만 AUM에서는 다른 undo segment로부터 free undo space를 가져올 수 있으며 undo tablespace의 모든 free undo space를 소진했을 때 비로소 에러를 발생시킨다.

#참고 1. 버전별 Undo의 특징 정리

버전특징
8i롤백(rollback)이라는 용어로 사용.롤백 세그먼트를 생성하고 ONLINE/OFFLINE의 상태변경 등의 작업을 DB관리자가 수동으로 관리했고, rollback_segments 파라미터에 의해 개수 고정.
9i공식 문서에 Undo라는 용어를 사용.AUM(Automatic Undo Management)기능 도입. Undo 세그먼트마다 하나의 트랜잭션이 할당되는 것을 목표로 세그먼트 개수를 오라클이 자동 관리.트랜잭션에 독립적으로 할당해 줄 Undo 세그먼트가 없을 때는(Online으로 전환할 수 있는 Offline 세그먼트가 없고 새로운 Undo 세그먼트를 생성할공간도 부족할 때)8i에서처럼 가장 적게 사용되는 Undo 세그먼트 중 하나를 할당. Undo 세그먼트를 더 이상 확장할 수 없을 때 다른 Undo 세그먼트로부터 Free Undo Space를 가져 올 수 있으며(Dynamic Extent Transfer), Undo 테이블스페이스 내에 있는 모든 Undo Space를 소진했을때 비로소 에러 발생
10gundo retention이라는 기능이 추가 되었다.Oracle 9i 에서는 ORA-1555 error가 가끔 발생하여 DBA가 이에 대한 조정을 해줄 필요가 있었다. 그러나, Oracle 10g 부터는 UNDO_RETENTION 에 대한 자동 튜닝 기능을 제공하게 되었다. 따라서, ORA-1555 에러가 발생하지 않도록 자동으로 UNDO RETENTION을 튜닝한다.

#참고 2. Undo Retention (10g)

Mandatory setting
1) UNDO_RETENTION=0 (10g: 이 파라미터 값을 0으로 해야 자동 활성화됨)
2) 반드시 SMU(System Managed Undo)를 사용해야 함.

자동 튜닝의 방식
UNDO_RETENTION을 0으로 셋팅하면 UNDO_RETENTION의 최소값은 900초. 즉 15분임.
MMON process가 매 30초마다 query duration을 계산.
MAXQUERYLEN 이라는 값을 계산하는데 이 값에 따라서 MMON은 TUNED_UNDORETENTION 이라는 수치를 결정.
이것은 새로운 UNDO RETENTION 값이 TUNED_UNDORETENTION 로 셋팅이 됨을 의미.
TUNED_UNDORETENTION = MAXQUERYLEN + 300 Sec.

Automatic Undo Retention의 튜닝은 ORA-1555 ERROR 발생을 예방.
그러나 undo tablespace가 autoextend off 이면 DML 수행 시 UNDO SPACE 부족과 같은 상황에 처할 수 있음.
UNDO tablespace의 사이즈가 부족하면 UNDO RETENTION 값이 줄어들 수 있음.
어떤 UNDO RETENTION을 가능하게 하기 위해서는 그 만큼의 UNDO 공간이 필요.
Oracle 9i에서는 DBA가 직접 해주어야 했던 이런 고려를 Oracle Database 10g에서는 Oracle 서버가 대신 해줌.

#참고 3. Undo 정보 조회

  • DBA_ROLLBACK_SEGS - 현재 데이터베이스에 존재하는 모든 Undo Segment에 대한 내용 조회 가능.
  • V$ROLLSTAT - 현재 데이터베이스에 존재하는 언두 세그먼트 중 온라인 상태인 언두 세그먼트에 대한 내용 조회 가능.
  • V$ROLLNAME - 모든 언두 세그먼트의 이름 확인 가능.
  • V$UNDOSTAT - 언두 테이블스페이스에 대한 모니터링 및 튜닝을 위한 정보 조회 가능.

#참고 4. Redo, Undo가 발생하지 않는 경우


1. read-only transactions
2. direct path loader
3. temp 및 sort operation 
4. DCL ( grant ) 등의 operation 

Undo Segment Transaction Table Slot

Undo Segment Transaction Table Slot

트랜잭션 ID : USN#(Undo Segment Number) + Slot# + Wrap#
트랜잭션 상태정보 : committed, Active
커밋 SCN : 트랜잭션이 commit 된 경우
LAST UBA (Undo Block Address)
기타

할당 대기 : undo segment tx slot



Insert : 추가된 레코드의 rowid
update : 변경되는 컬럼에 대한 before image
delete : 지워지는 로우의 모든 커럼에 대한 before image




SQL> 

  1  select xidusn, xidslot, xidsqn
  2   from v$transaction
  3*  where addr=(select taddr from v$session where sid = 191)

SQL> /

    XIDUSN    XIDSLOT	  XIDSQN
---------- ---------- ----------
	 8	    5	  135143

Elapsed: 00:00:00.00

SQL> alter system dump undo header '_SYSSMU8_3131027383$';

System altered.

SQL> alter system dump undo block '_SYSSMU8_3131027383$' xid 8 5 135143;

System altered.

Elapsed: 00:00:00.72

********************************************************************************
Undo Segment:  _SYSSMU8_3131027383$ (8)
********************************************************************************
  Extent Control Header
  -----------------------------------------------------------------
  Extent Header:: spare1: 0      spare2: 0      #extents: 47     #blocks: 14207
                  last map  0x00000000  #maps: 0      offset: 4080
      Highwater::  0x00c1833f  ext#: 7      blk#: 319    ext size: 1024
  #blocks in seg. hdr's freelists: 0
  #blocks below: 0     
  mapblk  0x00000000  offset: 7
                   Unlocked
     Map Header:: next  0x00000000  #extents: 47   obj#: 0      flag: 0x40000000


  TRN CTL:: seq: 0x05e1 chd: 0x0015 ctl: 0x0000 inc: 0x00000000 nfb: 0x0001
            mgc: 0xb000 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe)
            uba: 0x00c18326.05e1.25 scn: 0x0281.d17c806a
Version: 0x01
  FREE BLOCK POOL::
    uba: 0x00c18326.05e1.2a ext: 0x7  spc: 0x13ea
    uba: 0x00000000.05e1.02 ext: 0x7  spc: 0x1f06
    uba: 0x00000000.05e1.03 ext: 0x7  spc: 0x18a0
    uba: 0x00000000.052c.01 ext: 0x1c spc: 0x1f7c
    uba: 0x00000000.0419.01 ext: 0x29 spc: 0x1ed0
  TRN TBL::
 
  index  state cflags  wrap#    uel         scn            dba            parent-xid    nub     stmt_num    cmt
  ------------------------------------------------------------------------------------------------
   0x00    9    0x00  0x20ff2  0xffff  0x0281.d17c8718  0x00c18326  0x0000.000.00000000  0x00000001   0x00000000  1330944981
   0x01    9    0x00  0x20fd4  0x001b  0x0281.d17c8530  0x00c18321  0x0000.000.00000000  0x00000001   0x00000000  1330944603
   0x02    9    0x00  0x20fd7  0x000e  0x0281.d17c837c  0x00c18320  0x0000.000.00000000  0x00000001   0x00000000  1330943868
   0x03    9    0x00  0x20fe3  0x0010  0x0281.d17c8220  0x00c1831f  0x0000.000.00000000  0x00000001   0x00000000  1330943387



블록 헤더 ITL 슬롯

ITL 슬롯 번호 (Interested Transaction List)
트랜잭션 ID
UBA (Undo Block Address)
커밋 Flag
Locking 정보
커밋 SCN (- 트랜잭션이 커밋된 경우)


 레코드를 갱신하기 위해서는 해당 블록에 ITL 슬롯을 확보해야 한다.
 - 부족할 경우 :  enq: TX - allocate ITL entry 
 - initrans(default 2), maxtrans(max 255), pctfree 
 - UPDATE 으로 인한 PCTFREE 여유 공간이 없는 경우 추가 슬롯 생성이 불가능.


SQL> alter session set tracefile_identifier='beforecommitblock';
SQL> alter system dump datafile 1 block 60290;

*** 2010-12-23 18:13:20.757
Start dump data blocks tsn: 0 file#: 1 minblk 60290 maxblk 60290
buffer tsn: 0 rdba: 0x0040eb82 (1/60290)
scn: 0x0000.000954da seq: 0x01 flg: 0x02 tail: 0x54da0601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x0CC29E00 to 0x0CC2BE00
Block header dump:  0x0040eb82
Object id on Block? Y
seg/obj: 0xcd17  csc: 0x00.95283  itc: 2  flg: O  typ: 1 - DATA
fsl: 0  fnx: 0x0 ver: 0x01
 
 Itl           Xid                                Uba                    Flag  Lck        Scn/Fsc
0x01   0x0007.021.000000db  0x0080131f.00c5.1c  C---    0  scn 0x0000.00094c80
0x02   0x0002.029.00000101  0x00801038.0128.0d  --U-    2  fsc 0x0036.000954da
 
SQL> alter session set tracefile_identifier='beforecommitblock';
SQL> alter system dump datafile 1 block 60290;

*** 2010-12-23 18:13:20.757
Start dump data blocks tsn: 0 file#: 1 minblk 60290 maxblk 60290
buffer tsn: 0 rdba: 0x0040eb82 (1/60290)
scn: 0x0000.000954da seq: 0x01 flg: 0x02 tail: 0x54da0601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x0CC29E00 to 0x0CC2BE00
Block header dump:  0x0040eb82
Object id on Block? Y
seg/obj: 0xcd17  csc: 0x00.95283  itc: 2  flg: O  typ: 1 - DATA
fsl: 0  fnx: 0x0 ver: 0x01
 
 Itl           Xid                                Uba                    Flag  Lck        Scn/Fsc
0x01   0x0007.021.000000db  0x0080131f.00c5.1c  C---    0  scn 0x0000.00094c80
0x02   0x0002.029.00000101  0x00801038.0128.0d  --U-    2  fsc 0x0036.000954da
 

Xid: 3개의 필드(Usn#, Slot#, Wrap#)로 구성
Uba: 3개의 필드(UDBA, SEQ, SLOT)로 구성


Lock Byte

 레코드가 저장되는 로우마다 그 헤더에 Lock Byte 을 할당해 해당 로우를 갱신중인 ITL 슬롯번호 기록함 (Row-level Lock)

 레코드 갱신 
 LockByte 활성화(turn on) -> ITL slot -> transcation Solt -> acitve    대기
                                                             Committed 레코드 갱신