h1.3.3 Undo Header Block & Undo Block Structures

가. Undo Header Block

  • Extent Control - 언두 세그먼트의 익스텐트 관리
  • Extent Map - 언두 세그먼트의 익스텐트의 주소 관리
  • Retention Table - 언두 리텐션을 적용하기 위한 영역
  • Transaction Control
  • Free Block Pool
  • Transaction Table

나. Undo Block

  • Undo block Header
  • User Undo Record
  • Undo Record

SQL> sqlprompt SYS_Session>
SYS_Session>

SQL> set sqlprompt Session_A>
Session_A>

Session_A>create table undo_layer_t1 ( c1 number, c2 varchar2(10), c3 char(20));
Table created.
Session_A>insert into undo_layer_t1 values ( 1, 'A','a');
1 row created.
Session_A>update undo_layer_t1 set c3='aa' where c1= 1 ;
1 row updated.
Session_A>delete from undo_layer_t1 where c1= 1 ;
1 row deleted.
Session_A>select sid from v$mystat where rownum = 1 ;
SID
----------
148

SYS_Session>select xidusn, xidslot, xidsqn
2 from v$transaction
3 where addr=(select taddr from v$session where sid = 148 ) ;
XIDUSN XIDSLOT XIDSQN
---------- ---------- ----------
10 1 946

SYS_Session>alter system dump undo header'_SYSSMU10$';
System altered.
SYS_Session>alter system dump undo block '_SYSSMU10$' xid 10 1 946;
System altered.

Extent Control Header & Extent Map ( Undo Header Block )


Extent Control Header & Extent Map ( Undo Header Block ) 
********************************************************************************
Undo Segment: _SYSSMU10$ (10)
********************************************************************************
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 3 #blocks: 143
last map 0x00000000 #maps: 0 offset: 4080
Highwater:: 0x008006ea ext#: 2 blk#: 97 ext size: 128
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 2
Unlocked
Map Header:: next 0x00000000 #extents: 3 obj#: 0 flag: 0x40000000

언두 세그먼트를 구성하는 익스텐트의 개수(#extents), 언두 헤더 블록을 제외한
블록 개수(#blocks), HWM(High Water Mark) 위치(Highwater::)를 나타낸다.

Extent Map (Undo Header Block)


Extent Map (Undo Header Block) 
Extent Map
-----------------------------------------------------------------
0x0080009a length: 7
0x00800061 length: 8
0x00800689 length: 128


언두 세그먼트를 구성하는 각 인스텐트의 시작 DBA 및 익스텐트를 구성하는 블록 개수를 나타낸다.

DBA(Data Block Address)의 이해


SYS_Session>set serveroutput on
SYS_Session> DECLARE
2 l_dba NUMBER := TO_NUMBER ('0080009a','XXXXXXXX');
3 l_file NUMBER := DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE (l_dba);
4 l_block NUMBER := DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK (l_dba);
5 BEGIN
6 DBMS_OUTPUT.PUT_LINE ('File : '||l_file);
7 DBMS_OUTPUT.PUT_LINE ('Block : '||l_block);
8 END;
9 /
File : 2
Block : 154
PL/SQL procedure successfully completed
SYS_Session>select tablespace_name, file_id, file_name from dba_data_files where file_id = 2 ;
TABLESPACE_NAME FILE_ID FILE_NAME
------------------------------ ---------- --------------------------------------------------
UNDOTBS1 2 /u01/app/oracle/db/TLO/undotbs01.dbf


Retention Table ( Undo Header Block )


Retention Table ( Undo Header Block ) 
Retention Table
-----------------------------------------------------------
Extent Number:0 Commit Time: 1305766196
Extent Number:1 Commit Time: 1305871253
Extent Number:2 Commit Time: 1305871253



언두 세그먼트를 구성하는 각 인스텐트의 Commit Time 을 나타낸다.
해당 시간과 언두 리텐션 설정 수치를 이용하여 각 인스텐트의 상태를 관리 하게 된다.

Transaction Table ( Undo Header Block )

트랜잭션 테이블을 구성하는 각 슬롯들은 트랜잭션 관리를 위해 중요한 정보를 저장하고 있다.
이중에서 관심있게 봐야할 부분은 state, wrap#, dba 칼럼이다.
●state : 현재 활성화된 트랜잭션 상태는 10으로 표시되며, 비활성화된 경우에는 9로 표시된다.
●wrap# : 슬롯이 몇 번 재사용되었는지를 나타낸다. 이 부분은 3.5 절에서 자세히 다룬다.
●dba : 해당 트랜잭션의 언두 정보를 저장하고 있는 마지막 언두 블록 주소를 나타낸다.

Undo Header (Undo Block)


********************************************************************************
Undo Segment:  _SYSSMU10$ (10)
xid: 0x000a.001.000003b2
Low Blk   :   (0, 0)
High Blk  :   (2, 127)
Object Id :   ALL
Layer     :   ALL
Opcode    :   ALL
Level     :   2

********************************************************************************
UNDO BLK:  Extent: 2   Block: 96   dba (file#, block#): 2,0x000006e9
xid: 0x000a.001.000003b2  seq: 0x6d1 cnt: 0x2e (46)   irb: 0x2e  icl: 0x0   flg: 0x0000

 Rec Offset      Rec Offset      Rec Offset      Rec Offset      Rec Offset
---------------------------------------------------------------------------
0x01 0x1f70     0x02 0x1ef8     0x03 0x1e50     0x04 0x1de4     0x05 0x1d38
0x06 0x1c90     0x07 0x1bc8     0x08 0x1b1c     0x09 0x1ab0     0x0a 0x1a04
0x0b 0x1988     0x0c 0x191c     0x0d 0x18b0     0x0e 0x1804     0x0f 0x1758
0x10 0x16dc     0x11 0x1670     0x12 0x1604     0x13 0x1558     0x14 0x1488
0x15 0x141c     0x16 0x13b0     0x17 0x1304     0x18 0x1288     0x19 0x11dc
0x1a 0x1160     0x1b 0x10b4     0x1c 0x1048     0x1d 0x0fdc     0x1e 0x0f30
0x1f 0x0eb4     0x20 0x0e48     0x21 0x0d9c     0x22 0x0cf0     0x23 0x0c44
0x24 0x0b98     0x25 0x0b2c     0x26 0x0ac0     0x27 0x0a14     0x28 0x09a8
0x29 0x0924     0x2a 0x08c4     0x2b 0x0864     0x2c 0x07f8     0x2d 0x0770
0x2e 0x06e8

언두 블록내의 언두 헤더 영역에는 언두 블록의 주소와 언두 레코드들에 대한 메타 정보를 저장하고 있다.
이중에서 관심 있게 봐야할 부분은 xid, cnt, irb 칼럼이다.
xid : Transaction Identifier 로 불리면 undo#, slot#, wrap# 로 구성된다.
cnt : 해당 언두블록 내에 저장된 언두 레코드의 수를 나타낸다.
irb : 트랜잭션이 rollback 할 경우 첫 번째로 적용해야하는 언두 레코드의 번호를 나타낸다.

User Undo Record & Undo Record ( Undo Block )


*-----------------------------
* Rec #0x2e  slt: 0x01  objn: 53533(0x0000d11d)  objd: 53533  tblspc: 4(0x00000004)
*       Layer:  11 (Row)   opc: 1   rci 0x2d
Undo type:  Regular undo   Last buffer split:  No
Temp Object:  No
Tablespace Undo:  No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02  ver: 0x01
op: C  uba: 0x008006e9.06d1.2d
KDO Op code: IRP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x01012c00  hdba: 0x01012bfb
itli: 1  ispac: 0  maxfr: 4858
tabn: 0 slot: 0(0x0) size/delt: 29
fb: --H-FL-- lb: 0x1  cc: 3
null: ---
col  0: [ 2]  c1 02
col  1: [ 1]  41
col  2: [20]  61 61 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20

*-----------------------------
* Rec #0x2d  slt: 0x01  objn: 53533(0x0000d11d)  objd: 53533  tblspc: 4(0x00000004)
*       Layer:  11 (Row)   opc: 1   rci 0x2c
Undo type:  Regular undo   Last buffer split:  No
Temp Object:  No
Tablespace Undo:  No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02  ver: 0x01
op: C  uba: 0x008006e9.06d1.2c
Array Update of 1 rows:
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 1 ckix: 10
ncol: 3 nnew: 1 size: 0
KDO Op code:  21 row dependencies Disabled
  xtype: XAxtype KDO_KDOM2 flags: 0x00000080  bdba: 0x01012c00  hdba: 0x01012bfb
itli: 1  ispac: 0  maxfr: 4858
vect = 5
col  2: [20]  61 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20

*-----------------------------
* Rec #0x2c  slt: 0x01  objn: 53533(0x0000d11d)  objd: 53533  tblspc: 4(0x00000004)
*       Layer:  11 (Row)   opc: 1   rci 0x00
Undo type:  Regular undo    Begin trans    Last buffer split:  No
Temp Object:  No
Tablespace Undo:  No
rdba: 0x00000000
*-----------------------------
uba: 0x008006ea.06d1.01 ctl max scn: 0x0000.001e43c3 prv tx scn: 0x0000.001e43c4
txn start scn: scn: 0x0000.001e4aa4 logon user: 54
 prev brb: 8390370 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03  ver: 0x01
op: Z
KDO Op code: DRP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x01012c00  hdba: 0x01012bfb
itli: 1  ispac: 0  maxfr: 4858
tabn: 0 slot: 0(0x0)

실질적으로 ROLLBACK 을 수행하기 위해 필요한 정보들을 저장하고 있다.
본 테스트에서는 INSERT/UPDATE/DELETE 를 각각 1회씩 수행하였으므로, 3개의 언두 레코드가 생성되었으며,
INSERT 에 대한 ROLLBACK 을 위한 정보는 Rec #0xa, ( #0x2c )
UPDATE 에 대한 ROLLBACK 을 위한 정보는 Rec #0xb, ( #0x2d )
DELETE 에수행에 대한 ROLLBACK 을 위한 정보는 Rec #0xc에 각각 저장된다. ( #0x2e )
ROLLBACK 시에는 마지막에 적용된 것부터 시작하여 역순으로 적용하므로,
Rec #0xc -> Rec #0xb -> Rec #0xa 순으로 ROLLBACK 을 수행하게 된다.
관심있게 봐야할 부분은 rci 와 rdba 칼럼이다.

● rci - ROLLBACK 시에 다음번으로 적용해야할 언두 레코드를 나타낸다.
● rdba - ROLLBACK 시에 다음번으로 적용해야할 언두 블록의 주소를 나타낸다.