본문 바로가기
스터디/오라클 성능고도화 원리와 해법1

06.I/O 효율화 원리 - 05. Direct Path I/O

by 취미툰 2020. 2. 13.
반응형

일반적인 블록 I/O는 DB버퍼 캐시를 경유합니다. 읽고자 하는 블록을 먼저 버퍼 캐시에서 찾아보고, 찾지 못할 때만 디스크에서 읽습니다. 데이터의 변경도 버퍼 캐시에 적재된 블록에서 이루어지며, DBWR 프로세스가 주기적으로 변경된 블록들(dirty 버퍼 블록)을 데이터파일에 기록합니다.
재사용 가능성이 없는 임시 세그먼트 블록들을 읽고 쓸 때도 버퍼 캐시를 경유할 경우 오히려 성능이 더 나빠질 수 있습니다.
오라클은 이럴 때 버퍼 캐시를 경유하지 않고 곧바로 데이터블록을 읽고 쓸 수 있는 Direct Path I/O 기능을 제공합니다.
아래는 이 기능이 작동하는 경우입니다.
- Temp 세그먼트 블록들을 읽고 쓸 때
- 병렬 쿼리로 Full Scan을 수행할 때
- nocache 옵션을 지정한 LOB 칼럼을 읽을 때
- direct 옵션을 지정하고 export를 수행할 때
- parallel DML을 수행할 때
- Direct Path Insert를 수행할 때

(1) Direct Path Read/Write Temp
데이터를 정렬할 때는 PGA메모리에 할당되는 Sort Area를 사용합니다. 정렬할 데이터가 많아 Sort Area가 부족해지면 Temp 테이블스페이스를 이용하는데, Sort Area에 정렬된 데이터를 Temp 테이블스페이스를 이용하는데, Sort Area에 정렬된 데이터를 Temp 테이블스페이스에 쓰고 이를 다시 읽을 때 Direct Path I/O 방식을 사용합니다. 이 과정에서 I/O Call이 완료될 때 까지 대기가 발생하는데 direct path write temp와 direct path read temp 이벤트입니다.

(2) Direct Path Read
병렬 쿼리로 Full Scan을 수행할 때도 Direct Path Read 방식을 사용합니다. 병렬도를 2를 주고 병렬쿼리를 수행하면 쿼리 수행 속도가 2배만 빨라지는 게 아니라 그 이상의 빠른 수행속도를 보이는 이유가 여기에 있습니다. 따라서 대용량 데이터를 읽을 때 Full Scan과 병렬 옵션을 적절히 사용함으로써 시스템 리소스를 적게 사용하도록 하는 것이 좋습니다. Direct Path Read 과정에서 읽기 Call이 완료될 때까지 대기가 발생하는 이벤트가 direct path read이벤트입니다. 버퍼캐시에만 기록된 변경사항이 아직 데이터파일에 기록되지 않은 상태에서 데이터파일을 직접 읽으면 정합성에 문제가 생깁니다. 따라서 병렬로 Direct Path Read를 수행하려면 메모리와 디스크간 동기화를 먼저 수행함으로써 Dirty버퍼를 해소해야 합니다. 예전에는 병렬 쿼리 수행 시 체크포인트를 통해 버퍼 캐시 전체를 데이터파일에 기록했지만 10gR2부터는 병렬 쿼리와 관련된 세그먼트만 동기화를 수행합니다.

(3) Direct Path Write
병렬로 DML을 수행하거나 Direct Path Insert방식으로 데이터를 insert할 때 사용됩니다. 이 과정에서 I/O Call이 발생할 때마다 direct path write이벤트가 나타납니다.
아래는 Direct Path Insert방식으로 데이터를 입력하는 방법입니다.
- insert ... select 문장에 /*+append*/힌트 사용
- 병렬 모드로 insert
- direct 옵션을 지정하고 SQL*Loader로 데이터를 로드
- CTAS문장을 수행
일반적인 insert시에는 freelist를 통해 데이터를 삽입할 블록을 할당받습니다. freelist를 조회하면서 random 액세스 방식으로 버퍼 캐시에서 해당 블록을 찾고, 없으면 데이터파일에서 읽어 캐시에 적재한 후 데이터를 삽입하므로 대량의 데이터를 insert할 때 매우 느립니다.
Direct Path Insert시에는 freelist를 참조하지 않고 테이블 세그먼트 또는 각 파티션 세그먼트의 HWM 바깥영역에 데이터를 순차적으로 입력합니다. freelist로부터 블록을 할당받는 작업이 생략될 뿐 아니라 insert할 블록을 버퍼 캐시에 적재하지 않고 데이터파일에 직접 insert하므로 일반적인 insert와는 비교할 수 없을 정도로 빠릅니다. HWM 바깥 영역에 데이터를 입력하므로 Undo 방생량도 최소화됩니다. 게다가 Direct Path Insert시에는 redo 로그까지 최소화하도록 옵션을 줄 수 있어서 빠른 insert가 가능합니다. 이 기능을 활성화하려면 nologging으로 테이블 속성을 바꿔주면 됩니다.
주의할 것은, DIrect Path Insert방식으로 데이터를 입력하면 Exclusive 모드 테이블 락이 걸린다는 사실입니다. 성능은 빠르지만 exclusive 모드 테이블 락을 사용하면 해당 테이블에 다른 트랜잭션이 DML을 수행하지 못하도록 막습니다.

반응형

댓글