태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

INITRANS와 MAXTRANS

오라클 2009.09.15 16:18
세그먼트의 속성 중 동시 트랜잭션 수를 제어하는 INITRANS와 MAXTRANS 파라미터는 역사적인 이유로 정확한 동작 방식이 혼란스러운 면이 있습니다. 가장 최근 버전에서의 동작 방식은 다음과 같습니다.
  • INITRANS의 기본값은 2이며 최소값도 2입니다. 단, 딕셔너리(all_tables 등)에는 "1"의 값으로 관찰됩니다. 그래도 실제 값은 2입니다.
  • MAXTRANS의 기본값은 255이며 최소값도 255입니다. 즉 고정값입니다.
여기서 두 가지 재미있는 질문을 할 수 있습니다.
  1. INITRANS의 실제 기본값이 "1"이 아니라 "2"라는 것을 어떻게 증명할 것인가?
  2. MAXTRANS의 값을 255가 아니라 더 낮출 수 있는 방법은 없는가? (255보다 큰 값으로 하는 것은 불가능합니다. 1 바이트로 표현할 수 있는 최대값이기 때문입니다)
간단한 데모를 통해서 답을 보겠습니다.

우선 다음과 같이 테이블을 하나 만듭니다. INITRANS 값과 MAXTRANS 값을 각각 1, 5로 지정했습니다. 하지만 딕셔너리에는 1, 255로 지정되어 있는 것을 알 수 있습니다.

UKJA@ukja1021> create table t1(c1 int)
  2  initrans 1      -- 1!
  3  maxtrans 5    -- 5!
  4  ;

Table created.

Elapsed: 00:00:00.03
UKJA@ukja1021> 
UKJA@ukja1021> select table_name, ini_trans, max_trans
  2  from user_tables where table_name = 'T1';

TABLE_NAME            INI_TRANS  MAX_TRANS
-------------------- ---------- ----------
T1                            1        255

Elapsed: 00:00:00.01
UKJA@ukja1021> 
UKJA@ukja1021> insert into t1 select level from dual connect by level <= 10;

10 rows created.

Elapsed: 00:00:00.01
UKJA@ukja1021> commit;

Commit complete.

Elapsed: 00:00:00.00
하나의 트랜잭션을 발생시키고 블록 덤프를 수행해봅니다.
UKJA@ukja1021> col f# new_value fno
UKJA@ukja1021> col b# new_value bno
UKJA@ukja1021> 
UKJA@ukja1021> select dbms_rowid.rowid_relative_fno(rowid) f#,
  2  			dbms_rowid.rowid_block_number(rowid) b#
  3  from t1
  4  where rownum <= 1;

        F#         B#
---------- ----------
         8       9011

Elapsed: 00:00:00.01
UKJA@ukja1021> 
UKJA@ukja1021> update t1 set c1 = 1 where c1 = 1;

1 row updated.

Elapsed: 00:00:00.00
다음과 같이 2개의 ITL이 등록되어 있는 것을 볼 수 있습니다. 지금까지 최대 하나의 트랜잭션만을 발생시켰기 때문에 INITRANS의 실제값이 2라는 것을 알 수 있습니다.
UKJA@ukja1021> alter system dump datafile &fno block &bno;
old   1: alter system dump datafile &fno block &bno
new   1: alter system dump datafile          8 block       9011

System altered.

Elapsed: 00:00:00.01

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0005.017.000004d6  0x0080095b.01ca.19  C---    0  scn 0x0000.0015f76c
0x02   0x0004.008.00000370  0x008001b8.0181.26  ----    1  fsc 0x0000.00000000
이제 다음과 같이 5개의 트랜잭션을 추가로 발생시킵니다.
UKJA@ukja1021> ho type temp.sql
update t1 set c1 = &1 where c1 = &1;

UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 2

UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 3

UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 4

UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 5

UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 6
MAXTRANS의 값을 5로 지정했으므로 이 설정이 동작했다면 6번째 트랜잭션은 대기상태에 빠져야 합니다. 하지만 다음과 같이 총 6개의 ITL 엔트리가 성공적으로 등록되었고 모든 트랜잭션이 대기없이 성공적으로 수행됩니다. MAXTRANS는 255라는 고정값을 사용하기 때문입니다.
UKJA@ukja1021> alter system dump datafile &fno block &bno;
old   1: alter system dump datafile &fno block &bno
new   1: alter system dump datafile          8 block       9011

System altered.

Elapsed: 00:00:00.06

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x000a.003.00000365  0x00800430.0212.0c  ----    1  fsc 0x0000.00000000
0x02   0x0004.008.00000370  0x008001b8.0181.26  ----    1  fsc 0x0000.00000000
0x03   0x0003.02a.000001ef  0x00800276.0167.09  ----    1  fsc 0x0000.00000000
0x04   0x0008.023.00000434  0x00800348.01d4.34  ----    1  fsc 0x0000.00000000
0x05   0x0001.027.00000372  0x00800763.01bb.30  ----    1  fsc 0x0000.00000000
0x06   0x0002.00e.00000419  0x008003d3.016d.13  ----    1  fsc 0x0000.00000000
이 255의 고정값을 바꿀 수는 없을까요? 다음과 같이 TAB$ 테이블을 직접 수정함으로써 더 낮은 값으로 바꿀 수 있습니다. 즉 다음과 같은 작업을 수행하면 MAXTRANS의 값이 255가 아니라 5로 낮아집니다.
SYS@ukja1021> connect sys/oracle as sysdba
Connected.

SYS@ukja1021> col object_id new_value v_obj_id
SYS@ukja1021> col data_object_id new_value v_data_obj_id
SYS@ukja1021> 
SYS@ukja1021> select object_id, data_object_id from all_objects
  2  where object_name = 'T1';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
     54298          54298

Elapsed: 00:00:00.07
SYS@ukja1021> 
SYS@ukja1021> alter system flush shared_pool;

System altered.

Elapsed: 00:00:00.07
SYS@ukja1021> alter system flush shared_pool;

System altered.

Elapsed: 00:00:00.00
SYS@ukja1021> 
SYS@ukja1021> update tab$
  2  set maxtrans = 5
  3  where obj#	= &v_obj_id and	dataobj# = &v_data_obj_id
  4  ;
old   3: where obj#	= &v_obj_id and	dataobj# = &v_data_obj_id
new   3: where obj#	=      54298 and	dataobj# =      54298

1 row updated.

Elapsed: 00:00:00.03
SYS@ukja1021> 
SYS@ukja1021> commit;

Commit complete.

Elapsed: 00:00:00.00
SYS@ukja1021> 
SYS@ukja1021> alter system flush shared_pool;

System altered.

Elapsed: 00:00:00.00
SYS@ukja1021> alter system flush shared_pool;

System altered.

Elapsed: 00:00:00.00
5로 바뀐 MAXTRANS의 설정값이 제대로 동작하는지 테스트해보겠습니다. 다음과 같이 동시에 7개의 트랜잭션을 만듭니다. 지금까지 6개의 ITL을 이미 만들었기 때문에 만일 5의 값이 동작한다면 7번째 트랜잭션은 ITL 엔트리 대기(enq: TX - allocate ITL entry)상태가 될 겁니다.
UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 1

UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 2

UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 3

UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 4

UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 5

UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 6

UKJA@ukja1021> ho start sqlplus ukja/ukja@ukja1021 @temp 7

UKJA@ukja1021> @wait
UKJA@ukja1021> set echo off

       SID EVENT                     P1              P2              P3
---------- ------------------------- --------------- --------------- ----------
SECONDS_IN_WAIT
---------------
       136 enq: TX - allocate ITL en 1415053316(5458 524332(0008002C 1075(00000
           try                       0004)           )               433)
              0

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0008.02c.00000433  0x00800349.01d4.01  ----    1  fsc 0x0000.00000000
0x02   0x0002.01d.00000419  0x008003c0.016d.17  ----    1  fsc 0x0000.00000000
0x03   0x0007.00f.0000036f  0x00800609.0217.0c  ----    1  fsc 0x0000.00000000
0x04   0x0004.010.00000370  0x008001b8.0181.27  ----    1  fsc 0x0000.00000000
0x05   0x0005.027.000004d6  0x0080095b.01ca.1e  ----    1  fsc 0x0000.00000000
0x06   0x0001.00b.00000372  0x00800764.01bb.01  ----    1  fsc 0x0000.00000000
ITL이 6개에서 더 이상 커지지 않고 7번째 트랜잭션은 ITL 엔트리 대기 상태가 된 것을 알 수 있습니다.

MAXTRANS를 낮출 필요가 과연 있을까?라는 의문을 가지시는 분이라면 아래 블로그 포스트를 읽어보세요.

저작자 표시
신고
Trackback 0 : Comment 1
  1. 혈기린 2009.09.16 09:42 신고 Modify/Delete Reply

    동욱님책 재미나게 정독하고 있는 독자입니다.
    재미난 테스트이네요
    동욱님글을 눈팅하지만 볼때마다 놀랍습니다.
    동욱님같은 선지자때문에 지식이 쌓여가는거 같네요

Write a comment

티스토리 툴바