목차
Undo의 개념
Undo의 목적
AUM의 개념
AUM의 목적
Undo Segment 할당되는 원리
참고 1. 버전별 Undo의 특징 정리
참고 2. Undo Retention(10g)
참고 3. Undo 정보 조회
참고 4. Redo, Undo가 발생하지 않는 경우
Undo Segment Transaction Table Slot
블록 헤더 ITL 슬롯
1. Undo Data - DML이 발생할 경우 변경되기 전의 데이터 값
2. Undo Segment - Undo Data를 저장하는 Segment
3. Undo Tablespace - Undo Segment를 저장하는 Tablespace
Transaction Rollback
특정 작업을 수행한 후 커밋을 수행하지 않은 작업에
롤백을 수행하게 되면 작업 수행 전의 데이터로 복구되는 기능
Read Consistency
수행시간이 많이 걸리는 조회 수행 중 조회 대상에 대한 다른 트랜잭션의 변경 작업이
일어날 경우 오라클에서는 조회 트랜잭션과 변경 트랜잭션의 SCN을 비교하여
CR 작업을 통해 원래의 데이터를 보여줌
Instance Recovery
transaction이 수행되고 있을 때 instance가 실패하여 crash가 발생되면 redo를 이용해
roll forward 단계가 완료 된 후 최종 commit 되지 않은 변경 사항까지 모두 복구.
따라서 system이 shutdown 된 시점에 commit 되지 않았던 transaction들을
모두 rollback 해야 하는데, 이때 undo segment에 저장된 undo data를 사용.
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을 수행함
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를 소진했을 때 비로소 에러를 발생시킨다.
버전 | 특징 |
---|---|
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를 소진했을때 비로소 에러 발생 |
10g | undo retention이라는 기능이 추가 되었다.Oracle 9i 에서는 ORA-1555 error가 가끔 발생하여 DBA가 이에 대한 조정을 해줄 필요가 있었다. 그러나, Oracle 10g 부터는 UNDO_RETENTION 에 대한 자동 튜닝 기능을 제공하게 되었다. 따라서, ORA-1555 에러가 발생하지 않도록 자동으로 UNDO RETENTION을 튜닝한다. |
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 서버가 대신 해줌.
1. read-only transactions
2. direct path loader
3. temp 및 sort operation
4. DCL ( grant ) 등의 operation
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 슬롯 번호 (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 을 할당해 해당 로우를 갱신중인 ITL 슬롯번호 기록함 (Row-level Lock)
레코드 갱신
LockByte 활성화(turn on) -> ITL slot -> transcation Solt -> acitve 대기
Committed 레코드 갱신