개요

  • 언두 레코드들에 대한 링크드 리스트를 생성하기 위한 매커니즘을 설명한다.
  • 언두 세그먼트 헤더 블록내에 관리하는 트랜잭션테이블, 데이터 블록에서 관리되는 ITL(interrested transaction list)를 살펴본다.
  • LOB(large object)의 언두, 리두, 읽기 일관성, 트랜잭션을 처리하는 방식이 다른 데이터와 다름을 설명한다.

트랜잭션과 언두

  • 데이터베이스에는 최소 1개의 언두테이블 스페이스가 있어야 한다.(RAC의 경우에는 노드당 1개씩)
  • 트랜잭션의 관리는 언두 세그먼트를 중심으로 관리된다.
  • 트랜잭션 테이블의 덤프내용

  index  state cflags  wrap#    uel         scn            dba            parent-xid    nub     stmt_num    cmt
  ------------------------------------------------------------------------------------------------
   0x00    9    0x00  0x0700  0x0001  0x0000.00261e9a  0x00c00556  0x0000.000.00000000  0x00000001   0x00000000  1445942394
   0x01    9    0x00  0x0701  0x000d  0x0000.00261e9e  0x00c00556  0x0000.000.00000000  0x00000001   0x00000000  1445942397
   0x02    9    0x00  0x0701  0x000a  0x0000.00261958  0x00c0054d  0x0000.000.00000000  0x00000002   0x00000000  1445942348
...
   0x0f    9    0x00  0x06ff  0x0016  0x0000.00261f38  0x00c00557  0x0000.000.00000000  0x00000001   0x00000000  1445942516
   0x10   10    0x80  0x0700  0x0002  0x0000.00261fd2  0x00c0055c  0x0000.000.00000000  0x00000006   0x00000000  0               <<<<< 현재 active된 세션
...
   0x21    9    0x00  0x06fe  0x0019  0x0000.00261b31  0x00c00553  0x0000.000.00000000  0x00000003   0x00000000  1445942352

    • 위 덤프는 자동언두 관리를 사용한 11g에서 추출된 데이터임, 24개의 엔트리 보관된다.
    • 트랜잭션 테이블의 엔트리 보관 갯수는 제한되며, 엔트리들은 지속적으로 재사용된다.(재사용시 wrap#이 증가함)

트랜잭션의 시작과 끝

  • 트랜잭션이 시작 -> 언두 세그먼트 획득 -> 트랜잭션 테이블내 엔트리 획득 -> warp# 증가 -> state 값을 active로 변경(value: 10 ) -> 엔트리내 다른 컬럼 값 변경 -> 리두 체인지 벡터 생성 -> 리두 로그 파일 기록
  • 트랜잭션 종료(commit 발생) -> state 값을 free로 변경(value : 9) -> 엔트리 내 다른 컬럼 변경(current scn 기록) -> 리두 체인지 벡터 생성 -> 리두로그 파일 기록
  • 트랜잭션ID : 언두 세그먼트 번호 + 트랜잭션 테이블 내 엔트리의 인덱스 번호 + 엔트리의 가장 최근 wrap#으로 구성
  • 트랜잭션 조회 쿼리

SELECT XIDUSN, XIDSLOT, XIDSQN FROM V$TRANSACTION;

    XIDUSN    XIDSLOT     XIDSQN
---------- ---------- ----------
         7         27       1697


1 row selected.

SELECT TRUNC(ID1 / 65536) USN, MOD(ID1, 65536) SLOT, ID2 WRAP, LMODE FROM V$LOCK WHERE TYPE = 'TX'; 

       USN       SLOT       WRAP      LMODE
---------- ---------- ---------- ----------
         7         27       1697          6


1 row selected.

트랜잭션 테이블

컬럼명설명
index트랜잭션 테이블 내의 로우의 순번(transaction table slot 번호)
state엔트리의 상태 inactive=9 active=10
cflags트랜잭션의 상태 flag, 0x0 : no transaction, 0x10 : dead transaction, 0x80 : active transaction
wrap#슬롯이 재사용된 횟수
uel이 슬롯이 active상태로 변경된 후에, 다음 번으로 사용될 트랜잭션 테이블 슬롯에 대한 포인터
scn커밋 된 트랜잭션에 대한 commit SCN(트랜잭션이 active일 때는 start SCN으로도 사용)
dba트랜잭션이 마지막으로 사용한 언두 블록의 주소(Data Block Address), 롤백 작업의 시작 위치를 알 수 있음
nub해당 트랜잭션에 의해 지금까지 사용된 언두 블록의 수(롤백을 수행하면 감소됨
cmtCommit 시점과 가장 가까운 초. 1970년 1월 1일 0시(UTC)부터의 시간을 초로 환산
  • 트랜잭션 테이블 정보조회 쿼리

SELECT INDX
     , KTUXESTA
     , KTUXECFL
     , KTUXESQN WRAP#
     , KTUXESCNW SCNW
     , KTUXESCNB SCNB
     , KTUXERDBF DBA_FILE
     , KTUXERDBB DBA_BLOCK
     , KTUXESIZ NUB
  FROM X$KTUXE
 WHERE KTUXEUSN = 7 AND KTUXESLT <= 28;

INDX	KTUXESTA	KTUXECFL	WRAP#	SCNW	SCNB	DBA_FILE	DBA_BLOCK	NUB
0	INACTIVE	NONE	1700	0	2606387	3	32900	1
1	INACTIVE	NONE	1699	0	2606480	3	32901	1
2	INACTIVE	NONE	1697	0	2606448	3	32901	1
3	INACTIVE	NONE	1698	0	2605864	3	32898	1
4	INACTIVE	NONE	1700	0	2606585	3	32901	1
5	INACTIVE	NONE	1693	0	2606406	3	32901	1
6	INACTIVE	NONE	1698	0	2606456	3	32901	1
7	INACTIVE	NONE	1698	0	2606430	3	32901	1
8	INACTIVE	NONE	1698	0	2606031	3	32898	1
9	INACTIVE	NONE	1697	0	2605995	3	32898	1
10	INACTIVE	NONE	1699	0	2606244	3	32898	1
11	INACTIVE	NONE	1699	0	2606458	3	32901	1
12	INACTIVE	NONE	1697	0	2606595	3	32901	1
13	INACTIVE	NONE	1698	0	2607103	3	32902	1
14	INACTIVE	NONE	1697	0	2605899	3	32898	1
15	INACTIVE	NONE	1696	0	2606341	3	32900	1
16	INACTIVE	NONE	1697	0	2606716	3	32901	1
17	INACTIVE	NONE	1698	0	2606485	3	32901	1
18	INACTIVE	NONE	1699	0	2606898	3	32902	1
19	INACTIVE	NONE	1696	0	2606097	3	32898	1
20	INACTIVE	NONE	1698	0	2606743	3	32901	1
21	INACTIVE	NONE	1699	0	2606272	3	32900	1
22	INACTIVE	NONE	1696	0	2606190	3	32898	1
23	INACTIVE	NONE	1698	0	2606422	3	32901	1
24	INACTIVE	NONE	1697	0	2606269	3	32900	2
25	INACTIVE	NONE	1699	0	2606665	3	32901	1
26	INACTIVE	NONE	1699	0	2606857	3	32902	1
27	ACTIVE	NONE	1697	0	2607103	3	32902	1
28	INACTIVE	NONE	1698	0	2605924	3	32898	1


    • 1개의 언두 세그먼트에는 34개의 슬롯(인덱스)가 있다.(11g 경우)
    • 트랜잭션이 롤백을 하거나, 인스턴스에 장애가 발생한다면, active transaction 을 찾아서 마지막 언두 블럭(dba) 을 거슬러 올라가는 식으로 언두레코드를 적용할 수 있다.

언두 블록 다시보기


********************************************************************************
UNDO BLK:  Extent: 65   Block: 30   dba (file#, block#): 3,0x0000119e
xid: 0x0003.01a.0000072f  seq: 0x1bb cnt: 0x32  irb: 0x32  icl: 0x0   flg: 0x0000                      <<<<<< xid: 0x0003.01a.0000072f : 언두세그먼트 + 슬롯번호 + wrap#(재사용횟수)
 
 Rec Offset      Rec Offset      Rec Offset      Rec Offset      Rec Offset
---------------------------------------------------------------------------
0x01 0x1f3c     0x02 0x1e90     0x03 0x1e18     0x04 0x1db0     0x05 0x1d48     
0x06 0x1c9c     0x07 0x1c24     0x08 0x1bbc     0x09 0x1b54     0x0a 0x1aa8     
0x0b 0x19fc     0x0c 0x1994     0x0d 0x18e8     0x0e 0x1880     0x0f 0x1830     
0x10 0x17d0     0x11 0x1728     0x12 0x167c     0x13 0x1614     0x14 0x159c     
0x15 0x1534     0x16 0x1488     0x17 0x1410     0x18 0x1364     0x19 0x12fc     
0x1a 0x1294     0x1b 0x122c     0x1c 0x1180     0x1d 0x1118     0x1e 0x10a0     
0x1f 0x1038     0x20 0x0fd0     0x21 0x0f68     0x22 0x0ebc     0x23 0x0e54     
0x24 0x0dec     0x25 0x0d74     0x26 0x0cc8     0x27 0x0c1c     0x28 0x0b90     
0x29 0x0b40     0x2a 0x0a94     0x2b 0x09bc     0x2c 0x096c     0x2d 0x08e8     
0x2e 0x0890     0x2f 0x07f0     0x30 0x0758     0x31 0x06ec     0x32 0x0680     
 
*-----------------------------
* Rec #0x32  slt: 0x1a  objn: 76065(0x00012921)  objd: 76065  tblspc: 4(0x00000004)                 <<<<<<  slt: 0x1a
*       Layer:  11 (Row)   opc: 1   rci 0x31   
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  
compat bit: 4 (post-11) padding: 0
op: C  uba: 0x00c0119e.01bb.31
KDO Op code: IRP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x0100028c  hdba: 0x0100028a
itli: 2  ispac: 0  maxfr: 4858
tabn: 0 slot: 2(0x2) size/delt: 9
fb: --H-FL-- lb: 0x0  cc: 2
null: --
col  0: [ 2]  c1 04
col  1: [ 2]  c1 04
 
*-----------------------------
* Rec #0x31  slt: 0x1b  objn: 76065(0x00012921)  objd: 76065  tblspc: 4(0x00000004)             <<<<<< slt: 0x1b 
*       Layer:  11 (Row)   opc: 1   rci 0x30   
Undo type:  Regular undo   Last buffer split:  No 
Temp Object:  No 
Tablespace Undo:  No 
rdba: 0x00000000

*-----------------------------
* Rec #0x30  slt: 0x1a  objn: 76065(0x00012921)  objd: 76065  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: 0x00000000Ext idx: 0
flg2: 0


  • 하나의 언두 블록은 다스의 트랜잭션에 의해 언두 레코드가 저장될 수 있다. 단, 한번에 한 트랜잭션만 언두 레코드를 기록할 수 있다.

데이터 블록 방문 및 언두

  • 테스트 설정하기

create table t1(id number, n1 number);

insert into t1 values(1,1);
insert into t1 values(2,2);
insert into t1 values(3,3);

commit;


Block header dump:  0x0040fad2
 Object id on Block? Y
 seg/obj: 0x4aa15  csc: 0x76c.7f167cb3  itc: 2  flg: O  typ: 1 - DATA
     fsl: 0  fnx: 0x0 ver: 0x01
---------------------------------------------------------------------------------------
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0001.001.00001de4  0x01802ec8.0543.05  --U-    3  fsc 0x0000.01731c46             <<<<< 트랜잭션 0x000d.002.000306a3 (14번째 세그먼트, 2번째 슬롯, 시퀀스번호 000306a3 )가 최근 블록을 변경했다는 사실 확인, SCN 01731c46 시점에 커밋, 해당 블록은 클린아웃 되지 않음(Flag = U), Lock 카운트는 3개(Lck), 이 트랜잭션의 롤백 레코드는 0x01802ec8.0543.05 에 저장되어 있음
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000             <<<<< 2번째 인덱스의 커럼값이 모두 0으로 이번에 처음 사용되는 블록임을 알 수 있음

data_block_dump,data header at 0x1881085c
===============
tsiz: 0x1fa0
hsiz: 0x18
pbl: 0x1881085c
bdba: 0x0040fad2
     76543210
flag=--------
ntab=1
nrow=3
frre=-1
fsbo=0x18
fseo=0x1f85
avsp=0x1f6d
tosp=0x1f6d
0xe:pti[0]      nrow=3  offs=0
0x12:pri[0]     offs=0x1f97
0x14:pri[1]     offs=0x1f8e
0x16:pri[2]     offs=0x1f85
block_row_dump:
tab 0, row 0, @0x1f97
tl: 9 fb: --H-FL-- lb: 0x1  cc: 2                            <<< lb:0x1  : Lock이 설정됨
col  0: [ 2]  c1 02
col  1: [ 2]  c1 02
tab 0, row 1, @0x1f8e
tl: 9 fb: --H-FL-- lb: 0x1  cc: 2                            <<< lb:0x1  : Lock이 설정됨
col  0: [ 2]  c1 03
col  1: [ 2]  c1 03
tab 0, row 2, @0x1f85
tl: 9 fb: --H-FL-- lb: 0x1  cc: 2                            <<< lb:0x1  : Lock이 설정됨
col  0: [ 2]  c1 04
col  1: [ 2]  c1 04
end_of_block_dump

언두헤더 덤프하는 법

SELECT UBAFIL, UBABLK, UBAREC FROM V$TRANSACTION;

UBAFIL UBABLK UBAREC



--

--

--
3 32902 7

SELECT SEGMENT_NAME FROM DBA_EXTENTS WHERE FILE_ID = 3 AND 32902 BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS - 1;

SEGMENT_NAME






















_SYSSMU7_137577888$

ALTER SYSTEM DUMP undo block '_SYSSMU7_137577888$' xid 7 27 1697;

ITL(Interested Transaction List)

컬럼명설명
Itl리스트에 대한 인덱스
Xid이 블록을 변경한 최근 트랜잭션ID. "언두세그먼트"."언두슬롯"."언두시퀀스번호"
Uba이 블록의 트랜잭션에 의해 생성된 가장 최근 언두 레코드의 주소. "절대블록주소"."블록시퀀스번호"."블록 내의 레코드 번호"
Flag트랜잭션의 상태 bit 플래그

: active
--U -: Upper bound commit
C---: Commited 및 cleaned out(관련된 모든 lock type들은 0으로 초기화)
Lck해당 트랜잭션에 의해 이 블록 내에 락이 설정된 로우의 수
Scn/FscCommit SCN 또는 사용 가능한 free영역의 크기

동시수행


Session 1:              update t1 set n1 = 101 where id = 1;
Session 2:              update t1 set n1 = 102 where id = 2;
                        commit;
My session:             set transaction read only;  -- isolation level을 read only로 설정
                                                    -- 다른 사용자의 uncommit 된 데이터 및 이후 시점에 commit 된 변경사항을 볼 수 없다고 함
Session 3:              update t1 set n1 = 99 where id = 3;
                        commit;
My session:             select id, n1 from t1;      -- 교재에서는 (1,1), (2,102), (3,3) 출력된다고 함


>> 실제 출력데이터는 
        ID         N1
---------- ----------
         1          1
         2        102
         3         99


3 rows selected.
         
Block header dump:  0x0040fad2
 Object id on Block? Y
 seg/obj: 0x4aa15  csc: 0x76c.7f167cd7  itc: 2  flg: O  typ: 1 - DATA
     fsl: 0  fnx: 0x0 ver: 0x01

---------------------------------------------------------------------------------------
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x000a.00e.00001b93  0x01800518.04f5.34  -U--    1  fsc 0x0000.01731c83              <<<< 3개의 세션에서 작업이 실행됐지만 엔트리는 총 2개 존재(ITL은 제한된 자원이므로), Lock count는 1
0x02   0x0004.00c.00001964  0x018036ad.05ff.3a  ----    1  fsc 0x0000.00000000              <<<< uncommit된 트랜잭션, Lock count는 1


0x12:pri[0]     offs=0x1f7b
0x14:pri[1]     offs=0x1f71
0x16:pri[2]     offs=0x1f85

block_row_dump:
tab 0, row 0, @0x1f7b
tl: 10 fb: --H-FL-- lb: 0x2  cc: 2                                                          <<<<< ITL 2번 트랜잭션에 의해 lock 설정됨
col  0: [ 2]  c1 02
col  1: [ 3]  c2 02 02

tab 0, row 1, @0x1f71
tl: 10 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 2]  c1 03
col  1: [ 3]  c2 02 03

tab 0, row 2, @0x1f85
tl: 9 fb: --H-FL-- lb: 0x1  cc: 2                                                           <<<<< ITL 1번 트랙잰션에 의해 lock 설정됨
col  0: [ 2]  c1 04
col  1: [ 2]  c1 64
end_of_block_dump

  • ITL엔트리와 언두 세그먼트 간의 링크

일관성 생성

1. 버퍼 내에 블록을 복사한 후, 다음 4단계를 수행
2. 필요한 경우, commit된 트랜잭션에 대한 클린아웃 수행
3. Uncommit된 트랜잭션으로부터 변경된 내용을 원복
4. 만일 target SCN(트랜잭션 또는 쿼리시작시점의 SCN)보다 큰 commit SCN을 가진 트랜잭션의 변경사항이 존재한다면, 가장 큰 commit SCN을 가진 트랜잭션의 변경사항부터 원복
5. 필요한 경우, 4번 단계를 반복.


 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x000a.00e.00001b93  0x01800518.04f5.34  -U--    1  fsc 0x0000.01731c83
0x02   0x0004.00c.00001964  0x018036ad.05ff.3a  ----    1  fsc 0x0000.00000000

  • 읽기 일관성을 위한 단계
    • 1. 해당 트랜잭션 상태가 active인지 확인(0x000a.00e.00001b93 : 4번째 언두세그먼트, 12번째 슬롯 상태확인)
    • 2. 변경 전 데이터를 확인(0x018036ad.05ff.3a : 언두 블록 0x018036ad, 시퀀스 번호 05ff 점검, 레코드 0x3a를 읽음)
    • 3. 2번에서 원복데이터 정보를 가져옴(테이블0의 로우 0의 컬럼 1은 c1 02(십진수 1)로 변경, 2번 ITL엔트리는 전혀사용하지 않은 상태임)
    • 4. 3번 작업은 로우의 길이가 달라지므로 블록의 free영역에 로우를 복사하고, 데이터를 원복함
    • 5. 3번 작업에서 확인한 ITL엔트리 상태를 반영
  • 복제본 ITL 엔트리 상태

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x000a.00e.00001b93  0x01800518.04f5.34  -U--    1  fsc 0x0000.01731c83   
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

    • 6. 위 엔트리 상태에서 Uncommit 상태가 없는지 확인
    • 7. 없으면 target SCN과 ITL내의 모든 SCN을 비교
    • 8. scn이 현재 scn보다 크다고 판단되면 가장 큰 commit scn부터 변경사항을 원복, 여기서는 0x01731c83이 너무 크다고 판단
    • 9. 언두 레코드 0x01800518.04f5.34를 읽고, 트랜잭션 0x000a.00e.00001b93에 의해 변경된 내용을 원복
    • 10. 9번 작업의 언두 레코드 내용을 적용(테이블0의 로우 2의 컬럼 1은 c1 04(십진수 3)로 변경)
    • 11. 해당 언두 레코드에는 ITL 0x01 이전 버전을 보유
    • 12. target SCN 보타 큰 SCN이 ITL내에 없다는 것을 확인
    • 13. 해당 작업의 ITL내용도 적용

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0009.00d.00002100  0x018030ca.074c.11  C---    0  scn 0x0000.01731c7a   
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

일관성은 이력을 의미하지 않는다.

  • 읽기 일관성을 위해 생성한 블록의 버전은 실제로는 존재하지 않았던 버전이다.

일량을 측정할 수 있는 통계정보

  • CR blocks created : 읽기 일관성 복제본을 생성할 때마다 증가
  • data blocks consistent reads - undo records applied : 언두 블록의 언두 레코드를 읽을때마다 증가
  • consistent gets - examination : 언두블록 헤더 블록을 읽은 횟수
  • no work - consistent read get : 읽기 일관성을 위해 어떠한 작업도 할 필요가 없는 블록을 읽은 횟수

Commit SCN

  • 트랜잭션 commit 시에는 commit SCN을 트랜잭션 테이블 슬롯에 기록, 해당 변경의 리두 체인지 벡터를 commit record라고 한다.
  • Fast commit : 트랜잭션 커밋 시 언두 헤더 블록만 변경하여 일을 끝냄, 변경사항은 lgwr이 백그라운드에서 로그버퍼에서 디스크로 기록한다.( 변경한 데이터의 양과 상관없이 oommit는 빠름)
  • Deleayed block cleanout : commit 발생 시 데이터 블록을 정리하는 작업(lock byte해제, commit scn, flag 설정 등)을 다른 세션에게 맡기는 방법
  • Commit cleanout : RAC환경에서 "pinging"인한 성능문제로 추가된 로직, 세션이 데이터 블록을 변경할 때 해당 블록의 리스트를 세션 메모리에 생성 -> 리스트의 블록을 재방문하여 ITL 플래그, commit SCN 설정

트랜잭션 테이블 롤백

  • 트랜잭션 컨트롤(TRN CTL::)

TRN CTL: : seq: OxO85f chd: Ox0000 ctl: Ox0017 inc : Oxoooooooo nfb: Ox0001
           mgc: OxOb02 xts: Ox0069 flg: Ox0001 opt : 2147483646 (0x7ffffffe)
	   uba: 0x0190120f.08f5.21 scn: 0x018bc704

    • chd(chain head) : 링크드 리스트의 시작, 다음번 트랜잭션이 사용할 트랜잭션 테이블 슬룻
    • ctl(chain tail) : 링크드 리스트의 끝, 해당 언두 세그먼트에서 마지막으로 사용한 트랜잭션 테이블 슬롯
    • uba : 트랜잭션 컨트롤을 마지막으로 변경한 트랜잭션의 첫 번째 언두 레코드 주소
    • scn : 가장 오래전에 기록된 트랜잭션의 scn

트랜잭션 테이블 읽기 일관성

  • 1. 메모리 내에 언두 세그먼트 헤더블록을 복제한다.
  • 2. 트랜잭션 컨트롤을 마지막으로 변경한 트랜잭션의 첫 번째 언두 레코드를 찾기 위해서 트랜잭션 컨트롤 내의 uba를 사용한다.
  • 3. 해당 언두 레코드는 언두를 적용해야 할 트랜잭션 테이블 슬롯과 해당 슬롯에 대한 commit SCN을 알려주므로, 해당 언두를 복제본에 적용한다.(과거 시점으로 롤백된 상태)
  • 4. 현재 트랜잭션과 언두의 scn를 비교하여 충분히 작은 SCN을 발견하지 못했다면 현재보다 이전 버전의 트랜잭션 컨트롤울 다시 생성(찾을 때까지 2~4번 작업 반복)
  • 5. 언두레코드를 모두 사용한 후에도 적절한 값을 찾지 못했다면 ora-01555 snapshot too old 에러가 발생한다.

LOB에서의 언두와 리두 처리 방법

  • LOB값이 로우 내에 저장된다면, 다른 데이터 처리방식과 동일하게 undo, redo 관리
  • LOB값이 "로우의 외부"에 저장될 경우 기존의 LOB값은 UNDO로 활용하고, 새로운 LOB 값을 생성함(LOBINDEX의 새로운 값의 위치와 이전값의 위치 두 군데를 수정해줌)
  • 이전 LOB 로우가 재사용되면 마찬가지로 ora-01555 snapshot too old 에러가 발생