728x90

캐시(Cache)

- 오라클 시스템 구조에서의 캐시를 살펴보기 이전에 컴퓨터 공학에서 사용되는 캐시라는 용어에 대한 일반적인 개념부터 살펴보는 게 좋다

컴퓨터 구조에서의 캐시 개념

https://www.geeksforgeeks.org/cache-memory-in-computer-organization/

Cache Memory is a special very high-speed memory. The cache is a smaller and faster memory that stores copies of the data from frequently used main memory locations. There are various different independent caches in a CPU, which store instructions and data. The most important use of cache memory is that it is used to reduce the average time to access data from the main memory. 

- 캐시는 캐시 메모리라고 불리며 빠른 속도의 메모리이다. 캐시 메모리는 메인 메모리에서 자주 사용되는 데이터를 더 빠르게 접근하기 위해 따로 저장해두는 메모리를 뜻한다.

CPU와 메모리 사이에 위치한 캐시 메모리

- 위는 컴퓨터 구조에서의 캐시 개념을 설명한 것이다. 일반적으로 캐시는 '자주 쓰이는 데이터를 더 빠르게 접근하도록 임시보관하는 메모리 공간'이라고 생각하면 된다. 

- 오라클 시스템에서의 캐시를 살펴보기 이전에 일반적인 캐시 개념을 이용해 유추해보자면 시간이 상당히 걸리는 디스크 접근 횟수를 줄이기 위해 자주 쓰이는 데이터를 캐시라는 메모리 공간에 두고 사용하지 않을까라는 추측을 할 수 있다.

 

오라클의 캐시(데이터 캐시 혹은 버퍼 캐시)

- 오라클의 캐시는 data cache 혹은 buffer cache라고 불린다. 서버 프로세스(클라이언트의 요청을 처리하는 오라클 프로세스)가 원하는 데이터가 캐시에 존재하면 그 데이터에 접근하여 DISK I/O를 줄인다. 즉, SQL의 처리 속도를 높인다.

 

오라클 캐시의 데이터 관리 단위 : 블록

- 오라클은 'block'이라는 단위로 데이터를 관리한다. 디스크 I/O 및 버퍼 캐시 모두 블록 단위로 관리한다.(OS에도 블록이라는 개념이 있지만 이것과는 다르다)

- 데이터를 한 개만 꺼내오려고 해도 필요한 데이터를 포함한 블록 자체가 캐시에 보관된다. 2KB, 4KB, 8KB, 16KB, 32KB 등 블록 사이즈를 고를 수 있다. 

Multi Level Index 구조

- 그림과 같이 인덱스가 단계적으로 되어 있을 때 인덱스를 이용해 데이터를 구하기 위해서는 Outer인덱스의 블록에서 데이터를 가져와(DISK IO 1회) Inner 인덱스 블록을 찾으러 다시 디스크에 접근한다(DISK IO 2회). 그리고 나서 데이터의 주소를 가져와 데이터 블록에 다녀온다.(DISK IO 3회). 위와 같은 구조에서는 디스크에 총 3번을 접근해야 원하는 데이터에 접근할 수 있다.

- 이 때, 원하는 데이터가 데이터 캐시(버퍼 캐시)에 존재한다면, DISK에 접근을 한 번도 하지 않고 디스크 접근이라는 물리적인 움직임 없이 전기적인 신호만으로 클라이언트의 요청에 대한 응답이 가능하다. 이것이 캐시를 이용하는 이유이다.

 

 공유 메모리(SGA;System Global Area)

- 프로세스는 캐시를 공유한다. 기본적으로 다른 프로세스의 메모리를 보는 것을 불가능하다. 데이터에 손상을 입히지 않도록 OS가 제한을 두기 때문이다. DBMS는 이런 불편한 점을 해결하고 다른 프로세스와 데이터를 공유하기 위해 OS의 기능 중 특수한 메모리 기능인 '공유 메모리'를 사용한다. 즉 자신의 캐시를 다른 프로세스도 볼 수 있게 되고 자신 또한 다른 프로세스의 캐시를 볼 수 있게 된다. 이런 공유 메모리 영역을 오라클에서 SGA(System Global Area)라고 불린다. 공유되지 않는 메모리는 PGA(Program Global Area, 이 명칭은 Process가 Program이 실행된 형태를 의미하는 것을 안다면 쉽게 와닿는다)

- 메모리의 데이터를 공유하기 떄문에 데이터에 손상을 가하지 않도록 락을 걸어 배타 제어(exclusive control)을 DBMS가 내부적으로 수행한다. 예를 들어, 동시에 같은 데이터를 변경하려고 하는 등의 시도를 발생하지 않도록 방지하는 것이다.

오라클 시스템 구조
책 참고 이미지

버퍼 캐시를 정리하는 LRU 알고리즘

- 정보처리기사에서 페이징 처리 알고리즘에서 배웠던 LRU 알고리즘이 버퍼 캐시를 정리하기 위해 쓰인다. 간단하게 최근에 사용하지 않은 데이터부터 캐시 아웃(버리기)하는 것이다.

데이터 변경도 캐시에서 이루어진다

- 데이터를 변경(update)하는 것과 같은 요청 또한 캐시에서 선제적으로 이루어진다. 설명하자면 클라이언트의 데이터 변경(UPDATE)요청 시 서버 프로세스는 디스크에 직접 변경된 데이터를 전달하여 기록하지 않고 버퍼 캐시에 읽어온 데이터를 변경하여 놔둔다. 이러면 디스크 IO없이 UPDATE SQL요청을 빠르게 처리하고 클라이언트에게 작업완료 응답을 보낼 수 있다. 

- 서버 프로세스가 캐시에 변경된 데이터를 두면 백그라운드 프로세스인 DBWR가 캐시에서 변경된 데이터가 버려지기 전에 디스크에 기록한다. 디스크에 부하를 주지 않기위해 정기적으로 수행한다.

 

모든 것을 버퍼 캐시에 두지는 않는다

- 오라클은 큰 테이블이라고 판단하면 풀 스캔한 것을 버퍼 캐시에 오랜 시간 보관하지 않도록 하고 있다. 일반적으로 풀 스캔 시의 데이터는 버퍼 캐시에 적재되지 않는다고 생각하면 된다.

- 큰 테이블, 작은 테이블 등의 기준은 '_small_table_threshold' 과 같은 설정값을 바꾸어 조정할 수 있다. 

 

스토리지 캐시와 OS의 가상메모리

스토리지라는 저장장치의 캐시를 이용하면 IO 시간을 줄일 수 있다

스토리지 캐시 사용 시 구조

- 스토리지의 캐시에만 데이터 CRUD를 하면 OS입장에서는 스토리지가 캐시 데이터를 알아서 디스크에 기록할 테니 작업이 끝난 것으로 간주할 수 있다. 즉, DBMS입장에서도 디스크 IO가 실제로 이루어지지 않고 스토리지의 캐시에만 기록을 적재한 것이지만 디스크 IO가 끝난 것으로 간주하여 응답을 빠르게 할 수 있다.

- 이렇듯 서버 프로세스가 버퍼 캐시를 사용하는 것만이 데이터 처리의 효율성을 증가시키는 것이 아니라 스토리지 레벨에서도 효율성을 증가시키는 방법이 있다는 것을 알 수 있다.

 

 

가상 메모리 때문에 버퍼 캐시가 항상 속도를 증가시키는 것이라고 단언할 수 없다.

- 가상 메모리란 메모리에서 사용 빈도가 낮은 데이터를 물리적인 디스크에 보관하고 메모리에 있는 것처럼 간주하는 기술이다. 이는 OS 레벨에서의 기능이기 때문에 DBMS는 이를 고려하지 않을 것이다.

 

- 그렇다면 버퍼 캐시가 사용 가능한 물리 메모리의 용량보다 크게 설정되어 있다면 어떻게 될까?

- 그렇게 되면 OS는 가상메모리 기술을 사용해 버퍼 캐시가 사용할 초과분의 용량을 디스크에 마련해 이를 메모리처럼 사용하게 할 것이다.

- 그리고 이 가상 메모리 공간에는 버퍼 캐시에서 잘 사용되지 않는 데이터를 보관하게 하는 것이 가장 효율적일 것이다. 그러다 서버 프로세스가 가상 메모리에 있는 데이터를 요청하면 어떻게 될까?

- 가상 메모리는 디스크에 있기 때문에 디스크 IO가 일어날 것이다. 그러면 서버 프로세스 입장에서는 캐시에만 접근해서 데이터를 가져왔는데도 불구하고 디스크 IO가 일어난 것과 같은 속도로 처리되어 캐시를 사용하는 의미가 없어지게 된다. 즉 아무런 효과도 없는 현상이 발생한다. 가상 메모리 개념과 버퍼 캐시의 개념이 서로 상충하기 때문이다.

- 최근에는 메모리 값이 저렴해지고 용량이 커졌기 때문에 가상 메모리를 사용하지 않는 것을 권고한다. 이렇게 OS레벨에서의 기술과 DBMS레벨에서의 기술이 서로 상충되면 문제를 해결하기 어렵기 때문이 아닐까 싶다

 

 

*OS의 버퍼 캐시도 고려해야 한다. 

- OS에도 파일 캐시나 페이지 캐시라고 불리는 버퍼 캐시가 있다. 오라클의 버퍼 캐시와 같은 역할을 수행한다. 그렇기 때문에 오라클을 재기동하고 오라클의 버퍼 캐시를 비워도 OS가 재기동되지 않았다면 OS 버퍼 캐시에 데이터가 계속 남아 성능 측정에 오류가 생길 수 있다.(OS의 버퍼 캐시에서 데이터를 가져왔는데 디스크IO한 것이라고 판단할 수가 있다.)

 

 

728x90
728x90

오라클 프로세스 구조

프로세스란?

- 실행 상태에 있는 프로그램. 실행 상태라서 메모리나 자원을 가지고 있다.

스레드 

- 프로세스 내에 존재하는 실행 단위. 하나의 프로세스 안에서 처리를 병렬로 하고 싶을 때 사용

 

일반적인 프로세스와 데이터베이스 프로세스의 차이

- 데이터베이스를 사용하지 않는 프로그래밍에서는 일반적으로 개개의 프로세스가 자신이 가진 변수(데이터)를 처리하는 것이 일반적이지만 데이터베이스의 프로세스는 여러 프로세스나 사용자가 하나의 데이터베이스(데이터 집합)에 접근한 다는 점이 큰 차이점이다. 즉, 여러 사용자나 프로그램이 데이터베이스의 데이터를 공유한다.

 

 

오라클이 여러 개의 프로세스로 구성된 이유

 위의 그림을 보면 RECO, PMON, SMON, DBW0, LGWR, ARC0 등 오라클 데이터베이스는 여러 개의 프로세스를 지니고 있다. 이와 같이 여러 종류의 프로세스가 있기도 하고, DBW0, DBW1 ... 와 같이 동일한 종류의 프로세스가 여러 개 있기도 하다. 

 동일 종류의 프로세스가 여러 개인 이유는? - 디스크 I/O 대기시간에 CPU를 쉬게 하는 낭비를 최소화하도록 다른 프로세스가 CPU를 사용하여 다른 일을 해서 CPU를 쉬게 하지 않도록 하기 위함일 것이다. DBWx, ARCx 모두 디스크에 데이터를 I/O하는 작업을 하는 프로세스이다.

 

서버 프로세스와 백그라운드 프로세스의 역할

 오라클은 서버 프로세스와 백그라운드 프로세스로 구성되어 있다.

- 서버 프로세스 : SQL문을 처리하는 프로세스

- 백그라운드 프로세스 : 서버 프로세스를 도와주는 프로세스, 위 그림에서 RECO, PMON, SMON, DBW0, LGWR, ARC0 들이 해당된다.

오라클 시스템 구조

 클라이언트(유저 프로세스)는 서버 프로세스와 통신한다. 이 때 클라이언트는 자바, C, SQL*Plus등 데이터베이스 입장에서의 사용자를 의미한다.

 

각 프로세스가 수행하는 처리

  1. SQL문의 수신 - 서버
  2. SQL문의 파싱 - 서버
  3. 데이터 읽기 - 서버
  4. 데이터 기록 - 백그라운드(DBWR)
  5. SQL문의 결과 회신 - 서버
  6. 로그 기록 - 백그라운드(LGWR)
  7. 각종 정리 - 백그라운드(PMON)
  8. 로그 보관 -백그라운드(ARC0)

서버 프로세스 : 1, 2, 3, 5 역할 수행(수신-파싱-읽기-회신)

백그라운드 프로세스 : 4, 6, 7, 8 역할 수행 

- 예를 들어 '4. 데이터 기록'은 서버 프로세스가 하지 않고 DBWR이 한다. 즉 서버 프로세스는 디스크에서 데이터를 읽어오지만 데이터를 기록은 하지 않는다.

- 서버 프로세스가 모든 일을 다 하게 되면 회신이 늦어지는 단점이 생겨 이를 백그라운드 프로세스에게 넘기고 클라이언트 응대에 집중한다.

 

 

*참고로 서버 프로세스는 shadow process, foreground process 라고도 불린다. 서버 프로세스라는 용어는 오라클에서만 클라이언트의 요청에 대응하여 SQL을 처리하는 프로세스를 가리키기 위해 쓰이는 용어에 가깝다.

 

 

공식 문서

https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/process-architecture.html#GUID-A4FA88C6-8447-4636-911C-5864E0DC8572

 

 

728x90
728x90

http://aladin.kr/p/pNCjM

 

그림으로 공부하는 오라클 구조

일본의 데이터베이스 잡지인 DB Magazine의 인기 연재물 ‘그림으로 공부하는 오라클 입문’을 재구성한 책이다. 오라클 아키텍처의 세계를 그림으로 체험함으로써 그 어떤 오라클 책보다도 쉽고

www.aladin.co.kr

 

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

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

오라클의 동작 원리를 공부할 때 위의 3가지 관점을 가지고 공부하면 이해하기에 좋다.

디스크의 동작

 디스크에 데이터를 넣고 꺼내는 I/O작업이 메모리에 비해 현저히 느리기 때문에 디스크 I/O 작업은 최소화 되어야 한다. 이를 이해하기 위해서는 디스크와 메모리의 차이를 알아야 한다.

 메모리(RAM)은 데이터에 대한 빠른 접근을 위해 데이터를 임시로 저장하고 있는 저장소이다. 컴퓨터가 꺼지면 들고 있던 데이터가 사라지는 단점이 있지만 데이터에 대한 빠른 접근을 가능하게 한다.

 반면에 디스크는 HDD, SDD와 같이 데이터를 영구적으로 저장하는 저장 장치이다. 메모리의 데이터에 접근하는 것은 전기적 신호로 이루어지지만 디스크의 데이터에 접근하는 것은 암(Arm)을 움직이게 하는 기계적인 동작이 필요하기 때문에 메모리와 비교해서 상당히 느리다.

 따라서, 디스크에 접근하는 I/O의 시간과 횟수를 줄여야 시스템의 성능이 좋아진다. 

 

어떻게 디스크 I/O 대기시간을 줄일까?

  1.  인덱스 사용하기 : 데이터베이스의 인덱스를 통해 처음부터 모든 데이터를 훑지 않고 원하는 데이터가 어디 있는지 인덱스를 통해 확인한 후 원하는 랜덤 엑세스 방식으로 데이터를 찾아간다. 이렇게 하면 데이터를 full scan하는 시퀀셜 엑세스 방식보다 빠르게 데이터를 찾을 수 있다.
  2. 랜덤 엑세스 : 인덱스로 확인한 ROWID를 통해 데이터를 찾아갈 때 한 번에 하나의 블록만 엑세스하는 것을 랜덤 엑세스라고 한다. 이 때, 찾으려는 데이터가 항상 물리적으로 연속적인 공간에 저장되어 있지는 않으므로 디스크를 회전시켜가며 찾아야 한다. 그래서 적은 양의 데이터에 접근할 때에는 한 번에 하나의 블록만 특정하여 접근하는 랜덤 엑세스 방식이 좋으나 데이터의 양이 전체 데이터의 15% 이상(절대치 아님)되면 디스크 계속 회전시켜  왔다갔다 하는 랜덤 엑세스 방식보다는 시퀀셜 엑세스(데이터를 그냥 처음부터 훑어 가며 여러 블록 씩 접근하는 것)방식이 효율적일 수 있다. 즉 인덱스를 사용한 엑세스가 무조건 효율적인 것은 아니다!

 

 

※오라클은 랜덤 엑세스를 'db file sequential read'라고 표시하며, 시퀀셜 엑세스는 'db file scattered read'라고 표시한다.

- 표현이 정반대로 되어 있는 것 같은데 이는 메모리에 데이터가 적재되는 방식이 다르기 때문이다.

- 오라클은 데이터를 블록 단위로 메모리에 배치한다.

- 랜덤 엑세스는 1개의 블록만을 읽어 오므로 읽어온 데이터(블록)은 메모리에서 연속이다(sequential)

- 시퀀셜 엑세는 여러 개의 블록을 읽어 와 메모리에 분산적으로(scattered) 배치된다.

- 따라서 위와 같이 용어의 혼동이 발생하는 것이다.

- 정리하자면 랜덤 엑세스와 시퀀셜 엑세스는 '디스크'에서 데이터에 접근하는 방식의 구분이며, db file sequential read와 db file scattered read은 가져온 데이터(블록)을 메모리에 적재하는 방식을 구분한 것이다.

 

 

 

728x90

+ Recent posts