Oralce에서 Buffer Cache와 관련된 Wait Event를 알아본다 

 

Oracle 주요 구성 요소별 I/O 관련 Wait Event

주요 I/O 대상 구분 Wait Event Wait Class
Datafile I/O db file sequential read User I/O
db file scattered read User I/O
direct path reads and writes User I/O
Temporary
Datafile I/O
direct path reads temp User I/O
direct path write temp User I/O
Buffer Cache
(Latch 포함)
latch: cache buffer chains Concurrency
latch: cache buffer LRU chains Concurrency
buffer busy wait Concurrency
db file parallel write System I/O
free buffer wait Configuration I/O
read by other session User I/O

 

 

Buffer Cache에 접근하는 방법  

Session이 Data를 조회한다면 과정은 아래와 같다 

1) server process가 생성 되고-> 2) Dictionary 에서 해당 data를 갖고 있는 block의 DBA값을 알아낸다 -> 3) 'DBA값+Class정보' 를 Hash 함수로 돌린다 ->  4) hash 값으로 몇번 hash bucket(table)을 보면 되는지 알 수 있다  -> 5) 해당 hash bucket에서 찾으려는 데이터의 block을 찾는다 -> 6) 메모리상 block의 위치를 알 수 있다. (만약 hash bucket LRU list에 없다면 storage에서 찾아서 LRU list에 올려둔 다음 buffer/cache에 올린다) 

 

 

좀 더 디테일하게 설명해보겠다 

1. DBA란? Data Block Address로 storage 상에 있는 데이터들의 위치 정보를 갖고있다

- DBA 값으로 file number와 block number 정보를 알 수 있다

(ex) DBA 예시 :"10003 , 03 , 20" 10003번 DBA값으론  03번 파일의 20번째 block을 알 수 있다)

2.  hash bucket이란? Data block 들이 buffer cache상에 어디에 위치해있는지 알기 위한 주머니이다 

- 각 data block의 정보는 여러 hash bucket에 LRU list로 들어가있다 

- hash bucket에 있는 block들은 buffer cache상의 본인의 위치를 알려준다 

- DBA값과 Class 값을 hash 함수로 돌리면 어떤 hash bucket을 봐야 찾으려는 block 의 메모리상 위치정보를 얻는지 알 수 있다.   

3. class 정보란 ? Object정보로 Data 인지 Undo인지 Redo 인지 등등 

   

 

 

Buffer Cache에서의 latch 에 대해 자세히 살핀다 

buffer cache에 접근하는데 비용이 든다

 

latch : cache buffer chains 

buffer cache 에 접근 하려면 - buffer cach 내의 block의 위치를 알아야 하고 -> block의 위치를 알려면 해당 hash bucket내의 block들을 찾아봐야한다 "이때 bucket에 Latch를 잡는다"

 

latch : cache buffer LRU chains 

hash bucket에 latch를 잡았다면, 해당 hash bucket이 가르키는 LRU List에도 latch를 잡아야한다 

 

 

buffer busy wait

 LRU List에도 latch를 잡고  해당 block의 buffer cache 내의 주소를 알았다면, 그 주소로 가서 latch를 잡는다 

 

- 문제점 

 - 특정 hash bucket에 있는 block들만 접근을 많이 할 경우 (hot block), latch가 몰리면서 wait 시간이 길어지게 된다 

 - 잘 일어나진 않지만, 대량의 범위의 IO를 수행하는 쿼리가 많을 경우 발생할 수 있다   

 - IO줄일려고 Buffer Cache 썼더니 이번엔 Latch 경합으로 오히려 느려질 수 있다

 

- 해결 방안

 - 1. hot block 을 이르키는 SQL tunning을 해야한다 

 - 2. SQL tunning이 이미 됐을 경우, Block 내부의 데이터를 재정렬 한다 

    - 2-1. PCT free등을 재조정해서 block에 데이터를 조금만 들어가게 한다- block안에 데이터를 적게 넣게 된다면 block 이 많이 생기고 hash bucket 분산이 될 수 있다 

    - 2-2. hash partition - 파티션으로 하나의 table를 hash값으로 여러 segment로 쪼갠다

      - 파티션으로 나누면서 , hash key에 따라 block을 재생성하게 된다. hot block 을 피할 수 있다 

      - hash partition 쓰면, Global Index 생성 등 관리 필요성이 증대 된고 & Clustering factor 저하 등이 발생할 수 있다

      - 단점, 재정렬 되었기에 실행 계획들 한번씩 다 확인을 해야한다  

 

 

buffer busy wait 세부 

하나의 block안에는 여러 row 들이 있다 . 

하나의 서버프로세스가 특정 block에 latch 를 잡고 row를 읽게 된다 

여러 서버 프로세스가 동시에 동일한 block 내의 있는 각기 다른 row를 update,select 한다하면 ? "Hot Block" 

 

Oracle 은 row level lock 인데 왜 block을 lock을 잡는건가요? 

질문에서 말하는 lock은 transaction 개념에서 설명하는 좀더 위의 단에 있는 lock 이다 

 

Hot block은 언제 발생 하나?

- 넓은 범위의 데이터를 빈번하게 접근할 경우 (lock을 잡는 block들이 많아지면서 )

- index scan 할때도 발생한다 

  - 특정 leaf block 만 접근하는 경우가 있다. 만약 index key가 sequencial 하게 증가된다면(001,002,003...501) 아래그림처럼 오른쪽 leaf block 에만 데이터가 몰릴 수 있다 

 

reverse index

reverse index 로 오른쪽으로 치우치는 현상은 막을 수 있지만.

index key 컬럼의 데이터를 reverse 하여 인덱스를 생성한다 

range 조건을 줄 경우 이상한 데이터가 나올 수 있기때문에 잘쓰지 않는다 (where절에 equal 조건이 있을때만 사용 ) 

아래 데이터에서 "where id between 20080000 and 20100000" 이런 조건이라면 reverse index일 경우 index full scan을 해야된다 . reverse가 아니었다면 3개의 block 만 보면 되는거였