ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 그림으로 공부하는 오라클 구조 : I/O와 디스크의 관계
    STUDY/DB 2022. 4. 24. 22:30

    - 오라클을 이해하기 위한 키워드

     1. 병렬 처리를 가능케 하고 높은 처리량을 실현한다.
     2. 응답 시간(response time)을 중시한다.
     3. 커밋(commit)한 데이터는 지킨다.

    DBMS의 내부 구조는 복잡한데, 그 이유는 위 세 가지 특성을 충족시켜야하는데 세 가지 특성이 상반된 성향을 가지고 있어서 동시에 모두 만족시키기 어렵기 때문이다.

    ex1) '커맛(commit)한 데이터는 지킨다.' 를 만족하기 위해 커밋하는 순간 데이터를 디스크에 기록하고 싶지만, 그렇게 하면 응답 시간이 나빠지게 된다.
    ex2) '벙렬 처리를 가능케 하고 높은 처리량을 실현한다' 도 병렬 처리할 때는 모순되는 처리가 발생하지 않도록 Lock이 필요하며, 그로 인해 성능이 저하되는 경우가 발생할 수 있다.

    - 오라클과 디스크(하드디스크)

    오라클은 DBMS이며, 오라클의 관점에서 데이터베이스는 오라클이 디스크에 저장하고 관리하는 데이터를 의미한다. 오라클은 디스크에서 데이터를 읽어오고, 필요한 처리를 한 후 다시 디스크에 기록한다.

    - 디스크

     1. 거의 항상 회전하고 있으며, 그 위로 헤드가 움직여서 데이터를 읽거나 기록한다.
     2. 원반이 여러 개 겹쳐 있고, 액추에이터가 양면을 사용한다.
     3. 음악의 트랙의 첫머리를 찾는 작업을 1초에 100번 할 수 있을 정도로 헤드가 빠르게 움직인다.
     4. 1분에 1만 번 정도의 엄청난 속도로 회전한다.

    - 디스크 동작

     1. 탐색(seek, 시크) : 데이터를 읽기(또는 기록하기) 위해서 원하는 데이터가 저장되기 시작한 첫머리를 찾아야 한다. 이렇게 원하는 위치를 찾는 작업을 디스트 용어로 탐색이라고 한다.
     2. 회전 대기 시간(rotational latency time) : 원하는 정보를 읽을 수 있는 위치가 회전해서 다가올 때까지 기다리다가 해당 위치가 오면 데이터를 읽고 쓴다. 이렇게 원하는 위치가 다가올 때까지 기다리는 시간을 회전 대기 시간이라고 한다.

    메모리에 접근할 때는 나노초(ns) 단위로 수행할 수 있으나, 디스크에 접근할 때는 밀리초(ms) 단위의 시간이 필요한다. 그 이유는 메모리는 전기 신호로 작업을 처리하지만, 디스크는 기계 동작이 필요하기 때문이다. DBMS의 입장에서 디스크 I/O는 반드시 필요한 것이면서 처리 시간을 단축하기 위해서는 가능한 한 줄여야하는 부분이다. 그렇다면 어떻게 I/O의 대기 시간을 줄일 수 있을까?

    - 인덱스

    시퀀셜 액세스 : 시퀀셜(sequential)은 '순서를 따라서'라는 의미의 '순차'를 뜻하며, 시작점에서부터 마지막까지 중간 부분을 바트리지 않고 전부 액세스(읽기/쓰기)하는 것을 의미한다. 메모리에 테이블의 데이터가 없으면 풀 스캔(Full Scan, 테이블의 모든 데이터를 읽어오는 것)할 때 시퀀셜 액세스가 발생한다.

    모든 데이터를 시퀀셜 액세스로 가져오면, 데이터를 가져오는 시간이 오래 걸리게 되고, 수행하는 대부분의 SQL 성능이 만족스럽지 못하게 된다. 그래서 나온 것이 인덱스(index, 색인)이다.

    책을 예로 들면, 책의 색인에는 키워드가 순서대로 나열되어 있으며, 해당 페이지 번호도 함께 기재되어 있다. 그 페이지 번호를 이용하면 원하는 페이지를 빠르게 찾은 후 필요한 정보를 얻을 수 있고, 이는 책을 처음부터 끝까지 읽어나가지 않아도 되게 한다.

    데이터베이스의 인덱스도 마찬가지로 검색할 때 사용하는 키 값(SQL문의 WHERE절에 적는 조건의 값)과 그 키가 존재하고 있는 위치가 기록되어 있다.

    사용 예시)

     SELECT "소속 회사" FROM "개인 데이터" WHERE "이름" = '래리';

    오라클의 인덱스는 '인덱스에 인덱스를 추가하는 것'처럼 여러 계층으로 구성되어 있다. 이렇게 여러 계층으로 구성된 구조를 트리(tree) 구조라 부른다. 트리 구조의 장점은 인덱스의 필요 없는 부분은 읽지 않고 검색(작업)을 끝낼 수 있다는 것이다.

    - 랜덤 인덱스

    인덱스를 사용할 때는 필요한 부분만 읽어오면 충분하지만, 필요한 부분이 디스크 위에 연속적으로 존재하는 경우가 거의 없다. 따라서 헤드를 움직여가며 띄엄띄엄 접근하게 되는데, 이런 방식을 '랜덤 액세스(random access)'라고 하고 시퀀셜 액세스와 반대의 의미를 가진다.

    디스크의 관점에서 랜덤 액세스는 탐색하는 작업과 회전 대기로 인해 데이터에 접근할 때마다 어쩔 수 없이 시간이 소모되는 비효율적인 부분이 존재한다. 즉, 디스크에서의 랜덤 액세스는 데이터를 읽어오는 효율성이 시퀀셜 액세스보다 떨어진다는 특성을 가진다.

    ex) 오라클 블록 크기를 8KB, 1초에 탐색할 수 있는 횟수를 100회라고 가정한다면, 1초 동안 겨우 800KB밖에 읽어올 수 없다. 디스크의 전송 속도(헤드를 움직이지 않고 읽고 쓸 수 있을 때나 가능한 처리량)를 20MB/초라고 가정했을 때, 데이터를 탐색하지 않고 한 번에 가져올 수 있는 20MB라는 크기에 비하면 25분의 1에 불과하다.

    실제로 데이터 전송의 효율 측면에서 바라보면 DBMS의 I/O도 마찬가지이다. 탐색을 반복하기 때문에 DBMS에서 사용하는 디스크는 IOPS(I/O Per Sec, 초당 수행 가능한 I/O의 횟수) 지표가 중요하다. 대부분의 디스크는 IOPS가 100회나 200회 정도이기 때문에, 한 개나 두 개의 디스크만을 사용해서 데이터베이스를 구성하면 부하가 집중적으로 발생했을 때 요청이 오는 것을 탐색이 따라잡을 수 없어 디스크에 병목 현상이 발생하게 된다.

    '인덱스를 사용하는 것이 유리한 경우는, 필요한 데이터가 전체 데이터의 15% 미만'?

    테이블의 데이터가 대량이고 그 중 한 개의 로우(행)를 꺼내야 한다면 당연히 인덱스를 통한 액세스가 빠르다. 하지만 모든 데이터를 보려고 할 때 매번 인덱스를 찾은 후 데이터를 찾아가면 오히려 속도가 느려진다.

    만약 데이터가 50%라면, 2만 건의 데이터(한 로우는 8KB) 중 1만 건을 읽어온다고 했을 때, 랜덤 액세스(800KB/초)는 약 100초가 걸린다. 그것과 비교해서 전부를 읽어오는 시퀀셜 액세스(20MB/초)는 모든 데이터를 디스크에서 읽어온다 해도 8초면 끝난다. 즉, 특성상 모든 데이터가 아니더라도 일정 크기 이상의 데이터를 읽는다면 시퀀셜 액세스를 사용하여 테이블을 풀 스캔하는 편이 빠르다.

    - 데이터를 보증하기 위한 디스크

    데이터는 오라클의 프로세스가 비정상적으로 종료되어도 무사해야 한다. 데이터는 CPU나 메모리가 고장이 나거나 정전이 발생했다 하더라도 손실되어서는 안된다. 오라클은 데이터를 변경한 후에 COMMIT이라고 입력하면 데이터를 디스크에 기록한다. 속도가 느려질거라 생각할 수 있지만 속도를 빠르게 하기 위한 장치가 마련되어 있다.


    시퀀셜 액세스는 'db file scattered read'라고 표시되고, 랜덤 액세스는 'db file sequential read'라고 표시된다. 시퀀셜 액세스는 여러 블록을 한꺼번에 빠짐없이 읽어와서, 읽어온 여러 블록을 메모리상에 연속되지 않은(분산된, scattered) 형태로 놓는다. 반면에 랜덤 액세스에서 읽어오는 데이터 블록은 한 번에 한 개이며, 메모리 공강에 반드시 역속적으로(sequential) 놓인다. 이렇게 한 번 읽어온 블록을 메모리에 어떻게 배치하는지에 따라 표현 방식이 다르다.

    다음장 : 오라클의 여러 프로세스

    출처 : 스키타 아츠시 외 4명, 『그림으로 공부하는 오라클 구조』, 이민재, 제이펍(2022), p2-p15

Designed by Tistory.