I/O에서의 대기이벤트들
db file scattered read
풀 테이블 스캔, 인덱스 풀 스캔시 -> 멀티 블록 IO 발생 -> 멀티 블록 IO 발생시마다 - 물리적인 IO가 끝나기를 기다림 -> db file scattered read 대기 이벤트
DB_FILE_MULTIBLOCK_READ_COUNT : 멀티 블록 IO시 몇 블록씩 한번에 읽을 것인가 - 이 값에는 OS마다 최대치가있다 (말도 안되게 높은 값으로 파라미터를 변경해보면 최대값 만큼으로 설정될 것이다)
주의점
- 풀테이블스캔시에도 싱글 블록 IO를 수행하는 경우가 있다 -> 이경우에는 db file sequential read 대기가 발생하게 됨
풀테이블스캔시 - 싱글 블록 IO로 읽게되거나 DB_FILE_MULTIBLOCK_READ_COUNT 값보다 적은 수의 블록을 읽는 경우
1. 익스텐트 경계에 도달한 경우: 익스텐트가 9블록인데 멀티블록으로8블록 읽었다면, 남은 1블록은 싱글블록IO
2. 스캔 도중에 캐시된 블록이 있을 경우: 8개의 블록을 읽는데, 세번째 블록이 캐시되어있다면 앞2개를 멀티블록IO, 세번째 블록은 Logical IO, 남은 5블록은 멀티블록IO
3. Chained Row가 있는 경우: 풀테이블스캔중 chained row를 만나면 - 로우의 나머지 부분을 읽어들이기 위해 이때는 싱글블록IO로 읽어온다.
(풀테이블스캔도중 Migrated Row를 만났다면 - HWM이하에만 들어있다면 풀테이블스캔중 다시 읽게되어있으므로, 싱글 블록 IO없이 그대로 쭉 읽는다)
db file scattered read 이벤트는 db file sequential read 이벤트와 함께 오라클에서 가장 보편적으로 발생하는 대기 이벤트이다.
db file scattered read 이벤트는 - 물리 IO와 관련있음 + 풀테이블스캔시 발생

어플리케이션 레이어
db file scattered read대기 이벤트가 주로 발생하는 SQL문 추출 -> 불필요하게 풀테이블스캔 이용하고있다면 -> SQL문을 수정해 주거나, 인덱스를 생성해준다.

오라클 메모리 레이어
버퍼캐시 크기가 작을 경우 -> 물리적 I/O가 반복해서 필요 -> db file scattered read 대기도 늘어난다 => 다중 버퍼 풀을 사용하도록 해본다.
다중버퍼풀의 효능
1. 자주 액세스되는 객체를 메모리에 상주시켜 -> 물리I/O최소화
2. 휘발성 데이터는 빨리빨리 제거 -> 메모리 낭비 최소화
3. 버퍼마다 별도의 cache buffer lru chain 래치 사용 -> 경합 감소

오라클 세그먼트 레이어
파티셔닝을 수행하여 풀테이블스캔의 범위를 줄일수 있도록 해본다

OS/디바이스 레이어
위의 방법들을 다 시도해 봤는데도 문제가 해결되지 않는다면 I/O 시스템의 성능이 않좋은 것은 아닌지 살펴보도록 한다.


db file sequential read
db file scattered read와는 달리 싱글 블록 IO와 함께 발생하는 대기이벤트이다.
일반적으로, 비효율적인 인덱스스캔, chained row, migrated row에 의해 추가적인 I/O 가 발생하는 경우

어플리케이션 레이어
비효율적 SQL문장이나, 비효율적인 인덱스 스캔이 주 원인 -> SQL문장 최적화 + 인덱스 구성 최적화
인덱스 제대로 타려면 -> 통계정보를 항상 최신으로 유지해주는 것도 중요 -> DBMS_STAT패키지 이용
SQLPlus에서는 제대로 되는데 실제로는 제대로 안되더라 -> 바인드피킹인가?
-> _OPTIM_PEEK_USER_BINDS 히든파라미터 -> TRUE면 바인드 피킹 기능 사용하는것 -> 바인드피킹: 바인드 변수를 사용하더라도, 최초에 수행되는 단계에 변수가 받아온 값으로 실행계획을 세움

오라클 메모리 레이어
버퍼 캐시 부족으로 -> 반복적 물리 I/O 발생 -> db file sequential read 대기 증가할 수 있음 -> 버퍼 부족이라면 free buffer waits도 함께 발생할 가능성 높다.
둘이 같이 나타나도 있다면 메모리 부족한 것이라 생각하고 조치하도록 한다.
다중버퍼풀을 사용하도록 한다.
높은 클러스터링 팩터 -> 테이블 블록을 읽는 회수가 증가 (인덱스 타고 랜덤 액세스) -> 물리 I/O증가 -> db file sequential read대기 이벤트 증가
클러스터링 팩터가 높다해서 늘 성능이 낮은 것은 아니다 -> 정확한 원인이 무엇인지 파악 하는 것이 더 중요.
analyze 명령문이느 dbms_stat 패키지를 이용해 인덱스의 CF를 구할 수 있다.
Row chaining / Row migration
인덱스 이용 -> 테이블 스캔 -> 마침 해당 로우가 rwo chaining, row migration등이 발생했던 로우라면 -> 추가적인 블록을 읽음 -> I/O 증가 -> db file sequential red 대기 이벤트 증가
alalyze명령으로 통계정보를 생성하면 dba_tables 뷰의 chain_cnt 컬럼에 chaining 이나 migration이 발생한 로우 수가 기록된다.
row migration 제거법
- export후 import한다
- alter table xxx move ... 를 수행한다
- analyze table xxx list chained rows into yyyy를 수행해서 migraton이 발생한 로우들을 추출하고 로우들에 대해 delete/insert를 수행한다.
- pctfree 조정, 어플리케이션 보완

OS/디바이스 레이어
이렇게 해도 해결이 안된다면 I/O시스템 자체의 성능 문제일 수 있음.


direct path read
direct path read 대기 이벤트 -> parallel query 수행시 슬레이브 세션이 수행하는 direct path I/O에 의해 발생
슬레이브 세션이 direct path read 하는 동안, 코디네이터 세션은 슬레이브 세션으로부터 응답을 대기함 -> PX Deq: Excute Reply 대기 이벤트
parallel query수행시 direct path read대기 이벤트는 필연적으로 발생한다고는 하지만 -> 지나치게 높다면 문제가 있는 것일 수 있다 -> 해결법 =
- Parallel Query 자체의 성능을 높인다 - direct path read 대기 이벤트에 대해서의 튜닝은 불가하다 - SQL튜닝을 통해 Parallel Query 성능을 개선하여 빨리 수행되도록 하는 것이 옳다.
- I/O시스템 자체의 성능을 높인다.
Parallel Query를 사용하지 않는데 db file scattered read / db sequential read 등과 함께 direct path read가 발생한 경우라면 -> I/O 부하로 인해 오라클이 알아서 direct path read를 사용한 것으로 보면된다
direct path I/O를 사용하면 버퍼 캐시를 경유하지 않기 때문에 - 버퍼 캐시 경합 발생 피할 수 있다.
여러 세션에서 동시에 같은 테이블을 풀테이블스캔 -> latch: cache buffers chain 대기이벤트 + read bu other session 대기 이벤트 -> 이를 해결하기 위한 방법으로 Parallel Query를 사용해본다 -> direct path I/O가 실행되면서 버퍼 캐쉬를 거치지 않게된다 -> 버퍼캐시에 해당하는 경합을 피해갈 수 있다. || 단, CPU로드, 메모리 사용량, 체크포인트 발생등이 증가하는 부차적인 문제가 생길 것에 대해 고려해야한다.
_DB_FILE_DIRECT_IO_COUNT - direct I/O에서 최대 I/O버퍼 크기 결정짓는 히든 파라미터 - 9i부터 1M가 기본값인데, 일반적으로 1M면 충분하다
direct path read에 대해 알아야 할 점
1. direct path read가 데이터파일에서 직접 데이터를 읽어온다고는 하지만, 언두쪽 메커니즘은 그대로이다 - 읽기 일관성 보장하는 방법 동일 -> snapshot too old가 발생하기도 함
2. Parallel Query 수행시 - 슬레이브 세션에서의 direct path read - 임시 영역 아닌 데이터파일에 대한 direct path read 임


direct path write
SGA를 경유하지 않고 데이터 파일에 직접 쓰기 작업 수행하는 방식 -> DBWR이 아닌 서버프로세스가 직접 쓴다.
CTAS , insert /* + append */, SQLLoader - direct모드
direct path write 특징
- SGA를 거치지 않고, 데이터 파일에 직접 쓰기 수행
- HWM 이후 부분에 블록을 추가 -> 프리리스트나 비트맵블록에서 관리하는 프리 블록 사용하는 것이 아님
- 추가된 데이터에 대해 언두 생성 안함 (CTAS시, 딕셔너리 변경 정보에 대한 언두는 생성된다고 한다)
- 테이블에 nologging -> 리두가 생성 안됨
- 작업중, 테이블에 TM락 exclusive하게 획득한다. - 다른 세션은 DML 못하게됨
direct path write + Paraller모드 혼합사용하면 훨씬 효율 좋다 - Parallel CTAS, insert /*+parallel (alias degree)*/, direct parallel모드로 SQLLoader 사용
이경우 오라클 동작 방식
- 각 슬레이브 세션들은, 테이블이 속한 테이블스페이스에 임시 세그먼트를 만든다 -> DBA_SEGMENTS.SEGMENT_TYPE 컬림이 "TEMPORARY"로 나올것이다
- 각 슬레이브 세션들이 만든 임시 세그먼트는, 작업 끝나면 하나의 임시 세그먼트로 합쳐짐
- 커밋시 - 임시 세그먼트가 테이블 세그머느로 합쳐지면서 HWM이 이동된다.
- 록백시 - 임시 세그먼트가 드롭된다.


direct path read temp / direct path write temp -> 정렬 작업시 사용되는 임시 영역에 대해서는 I/O는 direct path read temp / direct path write temp 대기 이벤트 발생
- PGA 공간이 부족해서 메모리 상에서 정렬 작업을 완료할 수 없을 시 발생한다.

어플리케이션 레이어
SQL 문장이 최적화 되이있는지 검토 - 불필요한 정렬

오라클 메모리 레이어
PGA공간 관리가 제대로 되고 있는지 검토 - 9i 이후로는 PGA_AGGREGATE_TARGET 파라미터를 통해, 오라클이 PGA영역을 통합해서 자동으로 관리하게끔 할 수 있다.
_SMM_MAX_SIZE -> 개별 프로세스에 할당 가능한 최대 메모리영역
_SMM_PX_MAX_SIZE -> Parallel Query사용시, 전체 슬레이브 세션이 사용 가능한 최대 메모리 크기
V$SESSTAT뷰 session pga memory max값 -> 세션이 실제로 사용한 최대 메모리 영역 조회
PGA_AGGREGATE_TARGET 값을 적절하게 설정해 주는 경우, direct path I/O가 사라지고 -> 이로 인해 direct path read temp, direct path write temp 대기 이벤트가 완전히 사라짐 - 성능도 개선된다.


direct path read(lob) / direct path write(lob)
lob컬럼을 생성할때 nocache 옵션 사용하면 - lob세그먼트를 읽고 쓸때 direct path I/O를 사용 - 이 발생하는 대기 이벤트가 direct path read(lob) / direct path write(lob)
cache옵션이라면 일반적인 방식으로 사용된다.
- 즉 direct path 쳐서 세그먼트에 TM을 거시는냐~ 일반 방식 사용하며 메모리쪽에서 래치 경합 먹느냐 하는식의 차이가 될듯 - 어떤 옵션이 더 유리한지는 사용 방식따라 다르다고한다
LOB 생성시 주의사항
1. enable storage in row 옵션 사용시 : 4000bytes보다 작은 LOB데이터는 로우와 같은 블록에 저장됨 -> 이로인해 row chaining이 발생할 것 같다면 애초에 disable 옵션으로 걸어라.
2. disable storage in row 옵션 사용시 : LOB데이터는 별도의 LOB세그먼트에 저장됨 - 로우에는 20bytes의 LOB Locator만 저장됨 - 언두는 LOB Locator에 대해서만 생성됨 - LOB데이터에 대한 언두정보는 LOB세그먼트 내에 저장된다 - LOB 세그먼트내에 몇 %를 언두 공간으로 쓸 것인지는 PCTVERSION옵션에 의해 정해짐 -> PCTVERSION이 적으면 snapshot too old 발생가능성 -> 너무 높으면 공간낭비
3. CACHE/NOCACHE, LOGGING,NOLOGGING : NOCACHE 옵션 사용시 리두 남길지 말지 옵션 사용 가능해짐 -> 데이터 크기나 얼마나 자주 접근하는지 등의 여부에 따라 캐쉬를 거칠지 말지 정해주고 -> 캐시를 거치지 않겠다면, 복구 필요한지 아닌지에 따라 리두 사용여부를 정해준다.
NOCACHE옵션이면 캐시 경우 안하므로 direct path read(lob), direct path write(lob) 대기 이벤트 발생할 수 있다. // CACHE옵션이라면 db file sequential read, latch: cache buffers chains 대기 이벤트 발생할 수 있다.
4. 청크의 크기 : LOB 세그먼트에 저장되는 LOB는, 청크단위로 기록됨 - 청크 그기가 크다면 공간 낭비// 작다면 오버헤드 발생 가능성 -> 적절한 값 잘 지정하도록 한다


db file parallel write
DBWR이 더티 블록을 기록하기 위한 I/O 요청을 보낸 후 요청이 끝나기를 기다리는 동안 db file parallel write 대기 이벤트
db file parallel write 대기 이벤트가 광범위 하게 나타난다는 것은 - DBWR이 빨리빨리 못 내려 쓴다는 것 -> I/O 성능이 낮을 것이다.
해결책
I/O 시스템의 성능이 느리다면 -> 로디바이스, AIO사용 || OS차원에서 Direct I/O사용 || DBWR 개수 증가시키기
I/O 작업이 너무 많다면 -> 체크포인트 발생 간격을 늘려줄 수 있도록 조치
버퍼 캐시를 비효율적으로 사용하는 경우 -> 다중버퍼풀을 적절히 사용하도록 한다

control file parallel write
컨트롤 파일 갱신 요청 프로세스는 -> 갱신이 완료될 때까지 control file parallel write 대기 이벤트
일반적으로는 컨트롤 파일을 자주 변경할 일이 없다
문제가 되는 상황
- 로그 스위치가 자주 발생 -> 로그 파일 스위치가 일어날 때 마다 컨트롤 파일을 갱신한다 -> LGWR프로세스가 control file parallel write 이벤트 대기
- 체크 포인트가 자주 발생 -> CKPT 프로세스가 control file parallel write 대기 이벤트
- Nologging 작업이 자주 발생 -> unrecoverable SCN(RMAN 백업시 사용된다고 한다)을 변경 -> 컨트롤파일 갱신 -> 서버프로세스가 control file paraller write 이벤트 대기
- I/O 성능이 낮을 경우 -> 컨트롤 파일을 디스크 분산, 로디바이스 , Direct I/O등 사용하여 관리. 컨트롤 파일 개수가 많다면 줄이는 것도 방법이다.
control file parallel write 대기 이벤트는 주로 - control file sequential read 대기 이벤트, enq: CF - contention 대기 이벤트와 함께 발생한다.
enq: CF - contention 대기 이벤트는 여러 세션이 동시에 컨트롤 파일을 갱신위해 CF락 획득하려 시도하며 발생함

레이블 (0)

  • 레이블 없음

0 댓글

로그인 상태가 아닙니다. 변경하는 경우 익명으로 표기됩니다. 이미 계정이 있다면 로그인을 원하실 수 있습니다.

첨부 파일  (0)

첨부 파일 추가하기
공유된 파일이 아직 없습니다.