Post

<오라클 성능 고도화 원리와 해법1> Ch01-08 블록 클린아웃

오라클 성능 고도화 원리와 해법1 - Ch01 오라클 아키텍처 - 08 블록 클린아웃

블록 클린아웃(Block Cleanout)은 트랜잭션에 의해 설정된 로우 Lock을 해제하고 블록 헤더에 커밋 정보를 기록하는 오퍼레이션이다. 오라클에서 로우 단위 Lock은 레코드의 속성(Lock Byte)으로 관리되며, 이는 로우 헤더로부터 블록 헤더에 있는 ITL(Interested Transaction List) 엔트리를 가리키는 포인터다.

사용자가 트랜잭션을 커밋하면 블록 클린아웃까지 완료해야 완전한 커밋이라고 할 수 있는데, 대량의 갱신 작업이 있고 나서 커밋을 위해 해당 블록들을 일일이 찾아다니며 클린아웃을 수행하려면 시간이 오래 걸릴 수밖에 없다. 오라클은 그래서 대량의 갱신 작업이 있고 나서는 커밋 정보를 트랜잭션 테이블에만 기록하고 빠르게 커밋을 끝내버린다.

그렇다면 블록을 클린아웃하는 시점은 언제일까? 나중에 해당 블록이 처음 액세스되는 시점이다. 항상 이 방식으로 작동하는 것은 아니며, 오라클은 (1)Delayed 블록 클린아웃과 (2)커밋 클린아웃(=Fast 블록 클린아웃) 두 가지 메커니즘을 사용한다.

(1) Delayed 블록 클린아웃

트랜잭션이 갱신한 블록 개수가 총 버퍼 캐시 블록 개수의 1/10을 초과할 때 사용하는 방식이다. 커밋 이후 해당 블록을 액세스하는 첫 번째 쿼리에 의해 클린아웃이 이루어지며, 이때 아래와 같은 작업을 수행한다.

  1. ITL 슬롯에 커밋 정보 저장
  2. 레코드에 기록된 Lock Byte 해제
  3. Online Redo에 Logging

블록을 읽는 과정에서 Active 상태의 블록, 즉 다른 트랜잭션이 발생시킨 변경사항에 대한 커밋 정보가 아직 ITL에 기록되지 않았다면 읽기 전에 먼저 블록 클린아웃을 시도한다.

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

만약 모든 클린아웃을 Delayed 블록 클린아웃 방식으로 처리한다면 select 시에 블록을 클린아웃하는 일이 빈번히 발생한다. 블록 클린아웃도 쓰기 작업이므로 Current 블록에 작업을 수행해야 하며, RAC 또는 OPS 환경에서는 이를 위해 Exclusive 모드의 Current 블록을 요청하게 된다. RAC에서는 Dirty 상태의 버퍼 블록을 디스크 쓰기 작업 없이 인스턴스끼리 주고받는 것이 가능하지만, 과거 OPS 환경에서는 일단 Dirty 블록을 디스크에 기록한 후 그것을 디스크에서 읽어가는 방식을 사용했다. 이처럼 인스턴스 간에 블록을 주고받는 과정을 ‘핑(ping)’이라고 한다. (RAC 캐시 퓨전 메커니즘에 대해서는 6장에서 자세히 설명한다.)

과거 OPS 환경에서 이렇게 과도한 핑이 발생하는 문제를 해결하기 위해 버전 7.3에서 커밋 클린아웃 방식이 도입되었다. 즉, 트랜잭션이 갱신한 블록 개수가 버퍼 캐시 블록 개수의 1/10을 초과하지 않을 때는 커밋 시점에 곧바로 블록 클린아웃을 수행한다. (버퍼 캐시에서 밀려나면서 데이터 파일에 기록되었거나 다른 트랜잭션에 의해 사용 중인 블록은 놔두면서 Delayed 블록 클린아웃 방식을 따르도록 함), 다만, 이 경우에도 커밋 시점에는 ‘불완전한 형태의 클린아웃’을 수행하며 해당 블록을 ‘갱신하는’ 다음 트랜잭션에 의해 완전한 클린아웃이 이루어진다.

ITL 슬롯에 커밋 정보를 저장하면서 Lock Byte를 해제하지 않고 그대로 두는 이유는 로깅을 수행하지 않기 위해서다. 즉, 커밋 클린아웃 시에는 Online Redo에 로그를 남기지 않는다. 로깅 시점을 뒤로 미루는 것이다. 그러고 나서 해당 블록을 갱신하려고 Current 모드로 읽는 시점에 (ITL 슬롯이 필요해지므로) 비로소 Lock Byte를 해제하고 완전한 클린아웃을 수행한다. 그리고 그 내역을 Online Redo에 로깅(logging)한다. 블록 클린아웃 정보를 나중에 로깅한다는 의미에서 이를 ‘Delayed 로깅 블록 클린아웃(Delayed Logging Block Cleanout)’이라고 부른다.(Delayed 블록 클린아웃과 혼동하지 말기 바란다.)

(3) ITL과 블록 클린아웃

앞에서 ITL에 실제 어떤 정보들이 담기는지를 설명하기 위해 블록 Dump 내용을 추출해 본 것을 기억할 것이다 (5절 Undo).

참고로, 3번 슬롯(0x03)도 Lock Byte가 완전히 해제된, 완전히 클린아웃된 상태이고 ITL도 언제든 재사용 가능하지만, 여기에 찍힌 커밋 SCN은 ‘추정된 커밋 SCN(upper bound commit number)’ 정보이다. 이는 커밋 Flag가 ‘C-U-‘인 것을 통해 알 수 있다. ‘추정된 커밋 SCN’에 대해서는 다음 절 ‘Snapshot too old’에서 설명한다.

This post is licensed under CC BY 4.0 by the author.