- 이 문서는 구루비에서 작성하였습니다.
- 이 문서를 다른 블로그나 홈페이지에 게재하실 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 출처 : http://wiki.gurubee.net/pages/viewpage.action?pageId=6260280&
- 구루비 지식창고의 모든 문서는 크리에이티브 커먼즈의 저작자표시-비영리-동일조건변경허락(BY-NC-SA) 라이선스에 따라 자유롭게 사용할 수 있습니다.
I/O 개요
- 오라클에서의 I/O 작업 레이어
- 어플리케이션 레이어 : select/insert/update/delete/truncate...
- 오라클 메모리 레이어 : Buffer cache | PGA
- 오라클 세그먼트 레이어 : Datafile, tempfile, Tablespace, Segment
- OS/디바이스 레이어 : Asynch I/O, Direct I/O, Raw Device, RAID, ...
- I/O 성능문제의 원인을 파악하는 것과 해결책을 찾는 과정은 항상 1->2->3->4의 순서를 따라야 한다.
어플리케이션 레이어(Application Layer)
- 어플리케이션을 효과적으로 구현하여, 불필요한 I/O를 최소화 해야 한다.
- I/O를 효율적으로 처리하는 다양한 기법들을 제공하며, Parallel Query, Parallel DML, Nologging, Direct Load,
Direct Read, Analytical Function등을 잘 이용하여 효과적으로 작업을 처리 해야 한다. - 데이터의 성격에 따라 클러스터(Cluster), IOT, 파티셔닝(Partitioning), 비트맵 인덱스(Bitmap Index)등의 기능을
적절히 사용해서 I/O를 효과적으로 사용하는 것 또한 어플리케이션의 몫이다.
오라클 메모리 레이어(Oracle Memory Layer)
- 버퍼 캐시는 오라클 I/O 관리의 핵심이다. 자주 사용하는 블록들을 메모리에 캐시 함으로써 물리적인 I/O를 줄일 수 있다.
- 오라클이 제공하는 Buffer Cache 기능은 다음과 같은 것들이 있다.
- Touch Count 기반의 효율적인 LRU 알고리즘을 제공한다.
- Buffer Pinning 기법을 통해 불필요한 래치 경합을 줄이고, 현재의 읽기 작업에 사용될 확률이 높은 블록들을 메모리에서 밀려나지 않게끔 한다.
- 다중 버퍼 풀(Multiple Buffer Pool) 기능을 이용하면 휘발성 블륵과 메모리 상주 블록을 구분해서 효과적으로 관리 할 수 있다.
시스템에서 보편적으로 자주 사용되는 객체들은 Default 버퍼를 사용한다. 비교적 주기적으로 사용되는 작은 크기의 객체들은
Keep 버퍼에 상주시키는 것이 좋다. 반대로 아주 적은 빈도로 사용되는 큰 크기의 객체들은 Recycle 버퍼를 사용함으로써 중요한 메모리 영역을
낭비하는 일을 방지할 수 있다. - 오라클 9i 부터는 블록 크기를 2K ~ 32K까지 사용 가능하다. 객체의 속성을 고려하여 큰 사이즈의 블록을 사용하는 것이 유리한 경우
(가령 로우의 크기가 크고 풀 테이블 스캔으로 데이터를 읽는 경우가 많은 경우)에는 큰 크기의 블록을 사용함으로써 성능 개선 효과를 얻을 수 있다. - 메모리에 올릴 필요가 없는 대용량의 데이터를 처리할 때는 버퍼 캐시를 우회하는 방법을 사용할 수 있다. (Direct Path I/O)
Direct Path I/O를 사용하면 SGA 영역을 거치지 않기 때문에 메모리 공유를 위한 동기화 매커니즘이 불필요하고 그만큼 성능이 개선된다.
![]() | 다중 버펄 풀 Keep, Default, Recycle 버퍼의 기본적인 내용을 정리하면 다음과 같다.
|
오라클 세그먼트 레이어(Oracle Segment Layer)
- Temporary Tablespace를 사용할 경우, 기본적으로 데이터 파일이 아닌 임시파일(Temp File)에 데이터를 저장한다.
- 오라클 7.3 이전 버전에서는 정렬 작업을 위해 Permanent Tablespace를 사용해야 했는데 이 경우 과도한 익스텐트의
할당과 해제로 인해 많은 성능문제가 야기되며, 특히 ST락 경합으로 인한 성능 저하 현상이 생기는 경우가 많았다. - 오라클 8i부터 사용가능한 Temporary Tablespace와 Tempfile 기능을 사용하면 ST락 경합은 더이상 문제가 되지 않는다.
- 오라클 8i부터 제공되는 LMT(Locally Managed Tablespace)와 오라클 9i부터 제공되는 ASSM(Automatic Segment Space
Management)을 사용하면 익스텐트 및 세그먼트 공간의 부적절한 관리에서 오는 성능문제를 대부분 해결 할 수 있다. - 대용량의 테이블은 파티션(Partition)을 이용하면 관리적인 측변에서 뿐만 아니라, 대량의 데이터를 처리하는 경우
원하는 범위만을 스캔하는 것이 가능하므로 필요한 I/O 범위를 줄이는 효과가 있다.
OS/디바이스 레이어(Device Layer)
- 오라클은 가능하면 비동기 I/O(Asynchronous IO)를 사용할 것을 권장한다. 비동기 I/O는 읽기 작업 뿐만 아니라 특히
DBWR이나 LGWR등 쓰기 작업을 수행하는 프로세스가 비동기적으로 작업을 처리할 수 있도록 해줌으로써 I/O 작업의 속도를
전반적으로 개선시켜준다. - 많은 OS들에서 진저한 비동기 I/O는 Raw Device에서만 사용한 것으로 알려져 있다. 비동기 I/O를 사용하는 것이 불가능하다면 OS
차원에서 Direct I/O를 사용하는 것이 바람직하다. - Direct I/O를 사용하는 경우 OS의 버퍼 캐시를 우회함으로써 불필요한 I/O작업을 최소화 한다. DBWR 프로세스를 복수개로 사용하는 것 또한
방법이 될 수 있다.
- Control File의 개수나 리두로그 파일의 개수가 불필요하게 많다면 복구가 가능한 최소한만큼만 유지하는 것도 도움이 된다.
- Direct I/O를 사용할 경우 OS의 버퍼캐시를 경유하지 않으므로 그 작동 방식이 로디바이스와 거의 동일하기 때문에 Direct I/O
를 사용하는 경우에는 로디바이스를 사용할 필요가 없다는 견해가 많지만, 로디바이스가 I/O성능개선의 중요한 방법중에 하나이다.
Direct path I/O
- 오라클 I/O는 기본적으로 SGA를 경유한다. 하지만 특수한 상황에서는 SGA를 우회해서 PGA에 데이터를 올린다.
데이터를 공유할 필요가 없을 때는 버퍼캐시에 데이터를 적재하는 과정에서 발생하는 오버헤드를 피함으로써 성능을
개선하는 것이 가능하다. - 버퍼 캐시내의 변경된 블록을 데이터파일에 기록하는 것은 DBWR 고유의 작업이다. 반면 버퍼 캐시를 우회하는 쓰기
작업은 개별 프로세스가 직접 수행하게 된다. 이처럼 버퍼 캐시를 우회하는 I/O 작업을 direct path I/O라고 부른다. - Direct Path I/O를 사용하는 경우
- 정렬작업을 위해 정렬 세그먼트(Sort Segment)를 읽고 쓰는 경우. direct path read temp, direct path write temp 이벤트를 대기
- Parallel Query를 위해 데이터파일을 읽는 경우. direct path read 이벤트를 대기한다.
- PDML이나 CTAS를 위해 데이터 파일을 쓰는 경우. direct path write 이벤트를 대기한다.
- NOCACHE 속성으로 생성된 LOB 세그먼트를 읽고 쓰는 경우. direct path read(lob), direct path write(lob)이벤트를 대기한다.
- I/O 시스템이 데이터를 읽어서 오라클에 반환하는 속도보다 훨씬 빠른 속도로 버퍼를 요구할 때.
이 경우 오라클 성능개선을 위해 readahead I/O(이후에 읽을 것으로 판단되는 데이터를 미리 한꺼번에 읽는 I/O 작업을 말함)
를 이용한다. 이 경우 direct path read 이벤트를 대기한다.
- Direct Path I/O와 관련된 통게 값에 대한 정리
- physical reads : 디스크에서 읽은 블록 수. Direct path I/O 여부와 무관하게 물리적인 읽기 작업이 발생할 경우에는 항상 증가한다.
- Physicla reads direct : Direct path I/O를 통해 읽은 블록 수. LOB 데이터에 대한 direct path I/O는 포함하지 않는다.
- physical reads direct(lob) : LOB 데이터를 direct path I/O를 통해 읽는 블록 수
- physical writes : 디스크에 기록한 블록 수. Direct path I/O 여부와 무관하게 물리적인 쓰기 작업이 발생할 경우에는 항상 증가한다.
- physical writes direct : Direct path I/O를 통해 기록한 블록 수. LOB 데이터에 대한 direct path I/O는 포함하지 않는다.
- physical writes direct(lob) : LOB 데이터를 direct path I/O를 통해 기록한 블록 수
- sort(disk) : 디크를 이용한 정렬 작업 회수. 디스크를 이용한 정렬 작업이 발생할 경우에는 정렬 세그먼트에 대해 direct path I/O를 사용한다.
- sort(memory) : 메모리수를 이용한 정렬 작업 회수.
![]() | Conventional Path I/O의 공식 Conventional Physical reads = physical reads(physical reads direct + physical direct(lob)) |
문서정보
- 이 문서는 구루비에서 작성하였습니다.
- 이 문서를 다른 블로그나 홈페이지에 게재하실 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 출처 : http://wiki.gurubee.net/pages/viewpage.action?pageId=6260280&
- 구루비 지식창고의 모든 문서는 크리에이티브 커먼즈의 저작자표시-비영리-동일조건변경허락(BY-NC-SA) 라이선스에 따라 자유롭게 사용할 수 있습니다.