"오라클 블럭 덤프"의 두 판 사이의 차이
DB CAFE
(차이 없음)
|
2024년 4월 23일 (화) 08:30 기준 최신판
thumb_up 추천메뉴 바로가기
- DBA { Oracle DBA 명령어 > DBA 초급 과정 > DBA 고급 과정 }
- 튜닝 { 오라클 튜닝 목록 }
- 모델링 { 데이터 모델링 가이드 }
1 Block Dump[편집]
- 트랜잭션 발생시 어떤 단계에서 어떤 데이터들이 어떤 형태로 변경되는지 이해 필요
- 데이터 블록과 언두 영역에서의 데이터 변경에 대한 이해가 반드시 필요
- 덤프(Dump) 기능을 이용하면, 트랜잭션에 의해 변경되는 데이터 정보를 물리적으로 관찰 할수 있음
1.1 덤프 방법[편집]
- 프로세스 A 가 test 라는 이름의 테이블의 특정 로우를 다음과 같이 변경
SQL> update test set id = 1 where rownum = 1;
- Update가 이루어진 로우의 위치를 DBMS_ROWID 패키지를 이용해서 얻는다.
SQL>select rowid
, dbms_rowid.rowid_relative_fno(rowid) as fno
, dbms_rowid.rowid_block_number(rowid) as blkno
from test where rownum = 1;
ROWID FNO BLKNO
------------------ ---------- ----------
AAAMZqAABAAANoKAAA 1 55818
- 변경된 로우가 위치한 블록 주소는 파일번호가 1번, 블록번호가 55818번에 해당한다. - 이 값을 이용해 해당 데이터 블록을 다음과 같이 덤프할 수 있다.
SQL> alter system dump datafile 1 block 55818
Start dump data blocks tsn: 0 file#: 1 minblk 55818 maxblk 55818
buffer tsn: 0 rdba: 0x0040da0a (1/55818)
scn: 0x0000.02ec5e30 seq: 0x02 flg: 0x02 tail: 0x5e300602
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Block header dump: 0x0040da0a
Object id on Block Y
seg/obj: 0xc66a csc: 0x00.2ec5e34 itc: 2 flg: - typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0016.026.00003222 0x01c0003f.0410.26 ---- 1 fsc …
0x02 0x0016.025.00003222 0x01c0003f.0410.25 C--- 0 scn …
ITL 정보
data_block_dump,data header at 0x862025c
===============
tsiz: 0x1fa0
hsiz: 0x20
pbl: 0x0862025c
bdba: 0x0040da0a
76543210
flag=--------
ntab=1
nrow=7
...
block_row_dump: Row 데이터 정보
tab 0, row 0, @0x13cd
tl: 1009 fb: --H-FL-- lb: 0x1 cc: 2 로우에 Lock Byte 정보가 있음
col 0: [ 2] c1 02
col 1: [1000]
31 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
...
tab 0, row 1, @0xfdc
tl: 1009 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [1000]
31 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
...
- 블록 덤프 파일의 내용을 통해 다음과 같은 사실을 확인할 수 있다.
- ITL (Interested Transaction List)에 로우를 변경한 트랜잭션이 itl=0x01로 등록되어있다.
- 현재 상태는 아직 커밋되지 않은 액티브(Active) 상태이며, 따라서 TX 락을 획득하고 있다.
- Xid = 0x0016.026.00003222 인데 이 값을 십진수로 변환하면 USN=22, SLOT=38, SQN=12384가 된다.
- V$TRANSACTION 뷰에서 현재 세션에 해당하는 정보를 확인해보면 정확히 일치하는 것을 확인할 수 있다.
SQL> select xidusn,xidslot,xidsqn from v$transaction
where addr = (select taddr from v$session where sid = 162);
XIDUSN XIDSLOT XIDSQN
---------- ---------- ----------
22 38 12834 XID = USN + SLOT + SQN
2) ITL 정보에서 Lock = 1 인데, 이것은 Transaction에 의해 변경된 로우수를 의미
- 또한 아직 커밋이 수행되지 않았으므로 Flag에는 아무런 값도 세팅되어 있지 않다. 같은 이유로 SCN도 아직 할당되지 않았다.
- Flag 값이 “C”이거나 “U”인 경우에는 커밋이 이루어졌다는 것을 의미
3) ITL 정보의 UBA(Undo Block Address)정보를 이용해 현재 트랜잭션이 가장 최근에 사용한 언두 블록과 언두레코드의 위치를 파악할 수 있다.
- UBA는 [언두 블록 DBA + Seq# + Record#]으로 이루어진다.
- 롤백을 수행할 경우 이 정보들을 이용한다.
4) block_row_dump 영역에서 첫번째 로우의 lb값은 0x1로 세팅되어 있다.
- lb는 Lock Byte의 약자로, 현재 로우에 대해 락을 건 ITL 번호를 말한다.
- 1번 ITL이 현재 로우를 변경했음을 의미한다.
- Lock byte의 값은 실제로 커밋이 발생해도 정리(Cleanout)되지 않으며, 나중에 Delayed block cleanout 이 발생하거나 다른 프로세스에 의해 블록이 변경되는 경우에 정리된다.
- 한가지 주의할 것은 첫번째 로우를 변경한 1번 트랜잭션(ITL에 등록된)에서 커밋이 이루어졌는지 아닌지의 여부는 실제로는 언두 세그먼트 헤더의 트랜잭션 테이블을 조회해보아야 알 수 있다는 것이다.
- 오라클은 커밋이 이루어졌을 때, 트랜잭션에 의해 변경된 모든 데이터 블록의 ITL 에 대해 일일이 커밋 처리를 하지 않는다.
- 변경된 블록 중 현재 버퍼 캐시에 올라와 있는 것들 중 일부만을 커밋 처리하며, 나머지 블록들에 대해서는 트랜잭션에 할당된 언두 세그먼트 헤더의 트랜잭션 테이블 슬롯에만 커밋 처리를 한다.
- 이 데이터 블록들은 나중에 다른 세션에 의해 스캔될 때, 실제 Cleanout 처리된다.
- 이러한 메커니즘을 delayed block cleanout 이라고 부른다.
- 따라서 현재 특정 로우가 다른 트랜잭션에 의해 변경 중인지의 여부를 완벽하게 파악하려면 ITL 정보뿐만 아니라 때로는 언두 정보까지 같이 조회해야 한다.
- 한때, 오라클의 최대 장점 중 하나로 로우 레벨 락(Row level lock)을 꼽았던 적이 있다.
- 오라클의 로우 레벨 락은 명시적으로 존재하는 락이 아니라 위의 정보들이 조합되어 구현되는 논리적인 락이다.
- 오라클은 개개의 로우를 누가 변경중인지에 대한 목록이나 메타정보를 별도로 관리하지 않는다.
- 로우가 변경되었는가의 정보는 해당 로우를 직접 방문해보아야만 알 수 있다.
- 로우 레벨 락이 물리적으로 존재하지 않는다는 것을 이해해야 한다.
- 로우 레벨 락은 해당 [로우의 변경여부 + 로우를 변경한 트랜잭션정보(ITL) + 언두영역의 트랜잭션 테이블 슬롯 + TX 락]의 정보들이 조합된 일종의 논리적인 락이다.
- 로우 레벨 락은 상당히 명확하면서도 혼란스러운 개념인데, 이는 대부분의 문서에서 TX 락을 로우 레벨 락이라고 표현하고 있기 때문이다.
- 심지어 오라클 매뉴얼에서도 애매모호한 표현으로 설명되어 있다.
- 로우 레벨 락은 TX 락을 이용해 구현되지만 TX 락 자체가 로우 레벨 락은 아니며, 다양한 정보들이 조합되어 로우 레벨 락이 구현된다.