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 만 보면 되는거였