정미나닷컴

[Oracle] 오라클 블록 클린아웃, Block Cleanout 본문

IT

[Oracle] 오라클 블록 클린아웃, Block Cleanout

정미나 2018. 4. 13. 22:00

오늘은 어디선가 들어본 적 있는 블록 클린아웃에 대해 알아보자.

우선 cleanout은 '청소'라는 뜻이므로 『블록 청소』 뭔가 dirty 상태의 블록을 free 상태로 바꿔주는 행위같다는 느낌적인 느낌이 든다.


블록 클린아웃 (Block Cleanout)

- 트랜잭션에 의해 설정된 로우 Lock을 해제하고 블록 헤더에 커밋 정보를 기록하는 오퍼레이션

- 보통은 트랜잭션 커밋 후 블록 클린아웃까지 완료해야 완전한 커밋이라고 할 수 있지만 대량 갱신 작업 후에는 시간 관계상 커밋 정보를 트랜잭션 테이블에만 기록하고 빠르게 커밋을 완료, 나중에 해당 블록이 처음 액세스되는 시점에 블록 클린아웃을 함

흠.. 커밋을 때리면 Redo Log Buffer의 정보를 Redo Log File에 기록한다 라고 알고 있는데 위 내용과 어떻게 연관성이 있는건지 차근차근 정리해보도록 하자.

※ Redo Buffer의 내용을 Redo Log File에 기록하는 시점 

① 매 3초마다

② Redo Log Buffer의 1/3이 찼을 때

③ 사용자가 Commit or Rollback을 날렸을 때 

→ 해당 Transaction과 관계된 모든 Redo 정보를 Log File에 저장하고 나서 Commit을 완료: Log Force at Commit

④ DBWR에 의해 신호를 받았을 때

→ Data Buffer Block을 Disk로 기록하기 전에 Redo Buffer Log를 먼저 기록: Write Ahead Log



TRANSACTION

① 사용자가 쿼리(DML)를 날린다.

② 해당 트랜잭션에 대해 Undo Segment를 할당한다. 

※ Undo Segment

구조적으로 데이터를 저장하는 일반 테이블 세그먼트와 동일, 각 트랜잭션 별로 Undo 세그먼트 할당, 트랜잭션이 발생시킨 테이블과 인덱스에 대한 변경 사항을 Undo 레코드 단위로 Undo 세그먼트 블록에 기록

③ 할당받은 Undo Segment Header에 트랜잭션 테이블 슬롯을 생성한다.

④ 트랜잭션 테이블 생성 후 TXID(트랜잭션 ID)를 생성하고 해당 트랜잭션에 할당한다.

※ TXID

트랜잭션에 할당된 Undo Segment의 Header에 존재하는 트랜잭션 테이블의 정확한 위치를 가리킴 

(흠.. 뭔가 RowID랑 비슷한 거 같다!)

⑤ 트랜잭션의 대상이 되는 블록들을 버퍼 캐시로 적재하고 블록 헤더의 ITL에 트랜잭션 엔트리를 기록한다.

⑥ 이전 정보를 Undo 블록에 기록하고 데이터 블록을 변경한다. 변경된 데이터 블록은 Dirty 상태가 되고 해당 블록에 대한 CR블록이 버퍼 캐시에 생성된다.

⑦ 사용자가 커밋을 때린다. 

⑧ 트랜잭션에 SCN(System Commit Number:global)을 할당한다. 커밋 정보는 Redo Log Buffer에 저장된다.

⑨ Undo Segment Header의 트랜잭션 테이블에 커밋이 됐음을 저장한다.

⑩ Redo Log Buffer의 내용을 Redo Log File에 기록한다.

⑪ 블록 헤더의 ITL 슬롯에 커밋 정보를 저장한 후 Lock을 해제한다. 

⑪이 수행되는 시점에 의해 Delayed 블록 클린아웃과 커밋 클린아웃으로 나뉜다.


Delayed 블록 클린아웃

- 트랜잭션이 갱신한 블록 개수가 총 버퍼 캐시 블록 개수의 1/10을 초과할 때 사용

- 커밋 이후 해당 블록을 액세스하는 첫 번째 쿼리에 의해 클린아웃


* 블록을 읽는 과정에서 Active 상태의 블록을 만났을 때

(다른 트랜잭션이 발생시킨 변경사항에 대한 커밋 정보가 ITL에 기록되기 전 일때) 

① 블록 클린아웃을 시도 

② ITL 슬롯에 기록된 트랜잭션 ID 확인 

③ 확인한 ID를 이용해 Undo 세그먼트 헤더에 있는 트랜잭션 테이블 슬롯 탐색

④ 트랜잭션의 현재 상태가 커밋이라면 ITL 슬롯에 반영

⑤ 로우 Lock 정보 해제


커밋 클린아웃 (=Fast 블록 클린아웃)

- 트랜잭션이 갱신한 블록 개수가 버퍼 캐시 블록 개수의 1/10을 초과하지 않을 때 사용

① 커밋 시점에 ITL 슬롯에 커밋 정보 저장 → Lock Byte는 해제하지 않음 (로깅을 수행하지 않기 위해)

② 해당 블록을 갱신하기 위해 Current 모드로 읽는 시점에 Lock Byte 해제

Online Redo에 로깅 (Delayed Logging Block Cleanout) → Delayed Block Cleanout과 혼동하지 말자!


이해하기 쉽게 비유를 하자면 블록 클린 아웃은 설거지와 비슷하다.

밥 먹고 나서 바로 설거지를 하면 Fast 블록 클린 아웃, 

놔뒀다가 다음 끼니 먹기 직전에 설거지를 하면 Delayed 블록 클린 아웃

ITL과 블록 클린아웃

Itl     Xid                    Uba                    Flag    Lck    Scn/Fsc

0x0l    0x0004.00c.000035c3    0x008005a2.042f.lc     --U-      1    fsc 0x0003.03536d7f

0x02    0xffff.000.00000000    0x00000000.0000.00     C---      0    scn 0x0000.035368ge

0x03    0x0005.00d.000003c4    0x00801a0b.0ldl.ld     C-U-      0    scn 0x0000.006770c0

1번 슬롯

- Fast 클린아웃한 상태 (Lck:1 / fsc / Flag:U)

쓰기 작업을 위해 블록 액세스 시 Lock Byte 해제 → 2번 슬롯과 같은 상태로 바뀜

3번 슬롯

- 완전히 클린아웃된 상태이이고 언제든 재사용도 가능하지만 추정된 커밋 상태 (Flag:C-U-)

추정된 커밋 상태가 뭔진 모르겠지만 일단 오늘은 여기까지..!