: DBMS마다 데이터베이스에 대한 정의가 조금씩 다르다. Oracle에서는 디스크에 저장된 데이터 집합을 데이터베이스라고 부른다. 그리고 SGA공유메모리영역과 이를 액세스하는 프로세스 집합을 합쳐서 인스턴스라고 부른다.
기본적으로 하나의 인스턴스가 하나의 데이터베이스만 액세스하지만 RAC환경에서는 여러 인스턴스가 하나의 데이터베이스를 액세스할 수 있다. 하나의 인스턴스가 여러 데이터베이스를 액세스할 수는 없다.
SQL Server는 쓰레드 기반 아키텍처이므로 프로세스 대신 쓰레드라는 표현을 써야 한다. Oracle도 윈도우 버전에선 쓰레드를 사용하지만, 프로세스와 일일이 구분하면서 설명하려면 복잡해지므로 프로세스로 통칭하기로 한다.
프로세스는 서버프로세스와 백그라운드 프로세스 집합으로 나뉜다. 서버프로세스는 전면에서 사용자로부터 전달받은 각종 명령을 처리하고, 백그라운드 프로세스는 뒤에서 묵묵히 할당받은 역할을 수행한다.
: 서버프로세스는 사용자 프로세스와 통신하면서 사용자의 각종 명령을 처리한다. 좀 더 구체적으로 말하여 SQL을 파싱하고 필요하면 최적화를 수행한다.
클라이언트가 서버프로세스와 연결하는 방식은 DBMS마다 다르지만 Oracle을 예로 들면 전용서버방식과 공유서버방식 두가지가 있다.
위의 사진을 보면 전용서버방식으로 접속할 때 내부적으로 어떤 과정을 거쳐 세션을 수립하고 사용자 명령을 처리하는지 잘 보여준다.
처음 연결요청을 받는 리스너가 서버프로세스를 생성해주고 이 서버 프로세스가 단 하나의 사용자 프로세스를 위해 전용 서비스를 제공한다는 점이 특징이다.
만약 SQL을 수행할 때마다 연결요청을 반복하면 서버 프로세스의 생성과 해제도 반복하게 되므로 DBMS에 매우 큰 부담을 주고 성능을 크게 떨어뜨린다. 따라서 전용서버 방식을 사용하는 OLTP성 어플리케이션에선 Connection Pooling 기법을 필수적으로 사용해야 한다.
공유서버방식은 말 그대로 하나의 서버 프로세스를 여러 사용자 세션이 공유하는 방식이다. 앞에서 설명한 Connection Pooling기법을 DBMS내부에 구현해놓은 것으로 생각하면 쉽다. 즉 미리 여러개의 서버프로세스를 띄어 놓고 이를 공유해 반복 재사용한다.
Oracle과 SQL Server 모두 물리적으로는 데이터 파일에 데이터를 저장하고 관리한다. 공간을 할당하고 관리하기 위한 논리적인 구조도 크게 다르지 않지만 약간의 차이는 있다.
대부분 DBMS에서 I/O는 블록단위로 이뤄진다. 데이터를 읽고 쓸 때의 논리적인 단위가 블록이다. Oracle은 2,4,8,16,32KB의 다양한 블록크기를 사용할 수 있다.
블록단위로 I/O한다는 것은, 하나의 레코드에서 하나의 컬럼만을 읽으려 할 때도 레코드가 속한 블록 전체를 읽게 됨을 뜻한다. SQL성능을 좌우하는 가장 중요한 성능지표는 액세스하는 블록개수이며 옵티마이저의 판단에 가장 큰 영향을 미치는 것도 액세스해야 할 블록개수이다.
테이블스페이스로부터 공간을 할당하는 단위를 익스텐트라고 한다.
테이블, 인덱스, Undo처럼 저장공간을 필요로 하는 데이터베이스 오브젝트다. 저장공간을 필요로 한다는 것은 한개 이상의 익스텐트를 사용함을 뜻한다.
한 세그먼트는 자신이 속한 테이블스페이스 내 여러 데이터 파일에 걸쳐 저장될 수 있다. 즉 세그먼트에 할당된 익스텐트가 여러 데이터 파일에 흩어져 저장되는 것이며 그래야 디스크 경합을 줄이고 I/O 분산 효과를 얻을 수 있다.
세그먼트를 담는 컨테이너로서, 여러 데이터 파일로 구성된다.
사용자는 세그먼트를 위한 테이블스페이스를 지정할 뿐, 실제 값을 저장할 데이터 파일을 선택하고 익스텐트를 할당하는 것은 DBMS의 몫이다.
각 세그먼트는 정확히 한 테이블스페이스에만 속하지만 한 테이블스페이스에는 여러 세그먼트가 존재할 수 있다. 특정 세그먼트에 할당된 모든 익스텐트는 해당 세그먼트와 관련된 테이블스페이스내에서만 찾아진다. 한 세그먼트가 여러 테이블 스페이스에 걸쳐 저장될 수는 없다.
하지만 앞서 말했듯이 한 세그먼트가 여러 데이터 파일에 걸쳐 저장될 수는 있다. 한 테이블스페이스가 여러 데이터파일로 구성되기 때문이다.
사진으로 요약하면 아래와 같다.
임시데이터 파일은 특별한 용도로 사용된다. 대량의 정렬이나 해시작업을 수행하다가 메모리공간이 부족해지면 중간 결과 집합을 저장하는 용도다.
임시데이터파일에 저장되는 오브젝트는 말 그대로 임시로 저장했다가 자동으로 삭제된다. Redo 정보를 생성하지 않기 때문에 나중에 파일에 문제가 생겼을 때 복구되지 않는다. 따라서 백업할 필요도 없다.
Oracle에선 임시테이블스페이스를 여러개 생성해두고 사용자마다 별도의 임시 테이블스페이스를 지정해 줄 수도 있다.
DB버퍼캐시에 가해지는 모든 변경사항을 기록하는 파일을 Oracle에서는 Redo로그 라고 부른다.
대부분 DBMS는 버퍼블록에 대한 변경사항을 건건이 데이터파일에 기록하기보다 우선 로그파일에 Append방식으로 빠르게 기록하는 방식을 사용한다. 그러고 나서 버퍼블록과 데이터파일간 동기화는 적절한 수단을 이용해 나중에 배치방식으로 일괄처리한다.
◽️ ONnline Redo 로그
◽️ 트랜잭션 로그
◽️ Archived(=Offline) Redo 로그
메모리 구조는 시스템 공유 메모리 영역과 프로세스 전용 메모리 영역으로 구분된다.
◽️ 시스템 공유 메모리 영역
말 그대로 여러 프로세스가 동시에 액세스할 수 있는 메모리 영역으로서, Oracle에선 SGA라고 부른다.
◽️ 프로세스 전용 메모리 영역
: 데이터 파일로부터 읽어들인 데이터블록을 담는 캐시영역이다.
인스턴스에 접속한 모든 사용자 프로세스는 서버 프로세스를 통해 DB 버퍼 캐시의 버퍼블록을 동시에 액세스할 수 있다.
1) 버퍼블록의 상태
모든 버퍼블록은 아래 세가지 중 하나의 상태에 놓인다.
Free 버퍼
: 인스턴스 기동 후 아직 데이터가 읽히지 않아 비어 있는 상태이거나 데이터가 담겼지만 데이터 파일과 서로 동기화돼 있는 상태여서 언제든지 덮어 써도 무방한 버퍼블록을 말한다.
Dirty 버퍼
: 버퍼에 캐시된 이후 변경이 발생했지만 아직 디스크에 기록되지 않아 데이터 파일블록과 동기화가 필요한 버퍼블록을 말한다.
Pinned 버퍼
: 읽기 또는 쓰기 작업이 현재 진행중인 버퍼블록을 말한다.
2) LRU 알고리즘
: 모든 DBMS는 사용빈도가 높은 데이터 블록 위주로 버퍼 캐시가 구성되도록 LRU알고리즘을 사용한다.
: 공유 풀은 딕셔너리 캐시와 라이브러리 캐시로 구성되며 버퍼 캐시처럼 LRU알고리즘을 사용한다.
딕셔너리 캐시
: 테이블, 인덱스같은 오브젝트는 물론 테이블스페이스, 데이터파일, 세그먼트, 익스텐트, 사용자, 제약에 관한 메타정보를 저장하는 곳이다.
딕셔너리 정보를 캐싱하는 메모리 영역이다.
라이브러리 캐시
: 사용자가 수행한 SQL문과 실행계획, 저장프로시저를 저장해 두는 캐시영역이다.
같은 SQL에 대한 반복적인 하드파싱을 최소회하기 위한 캐시공간을 따로 두게 됐고 그것이 라이브러리캐시영역이다.
캐싱된 SQL과 그 실행계획의 재사용성을 높이는 것은 SQL 수행성능을 높이고 DBMS 부하를 최소화하는 핵심원리 중 한가지다.
로그 엔트리도 파일에 곧바로 기록하는 것이 아니라 먼저 로그버퍼에 기록한다.
서버프로세스가 데이터 블록버퍼에 변경을 가하기 전에 Redo 로그 버퍼에 먼저 기록해 두면 주기적으로 LGWR프로세스가 Redo로그파일에 기록한다.
로그파일에 기록했음이 보장돼야 안심하고 커밋을 완료할 수 있다.
각 Oracle서버프로세스는 자신만의 PGA메모리영역을 할당받고 이를 프로세스에 종속적인 고유 데이터를 저장하는 용도로 사용한다.
PGA는 다른프로세스와 공유되지 않는 독립적은 메모리 공간으로서, 래치메커니즘이 필요 없어 똑같은 개수의 블록을 읽더라도 SGA 버퍼 캐시에서 읽는 것보다 빠르다.
User Global Area (UGA)
: 전용서버방식으로 연결할 때는 프로세스와 세션이 1:1 관계를 갖지만 공유서버방식으로 연결할때는 1:M관계를 갖는다.
각 세션을 위한 독립적인 메모리 공간이 필요한데 이를 UGA라고 한다.
UGA는 전용서버방식으로 연결할때는 PGA에 할당되고 공유서버방식으로 연결할때는 SGA에 할당된다.
Call Global Area (CGA)
: CGA는 Parse Call, Execute Call, Fetch Call마다 매번 할당받는다. CGA에 할당된 공간은 하나의 Call이 끝나자마자 해제돼 PGA로 반환된다.
Sort Area
: 데이터 정렬을 위해 사용되는 Sort Area는 소트오퍼레이션이 진행되는 동안 공간이 부족해질 때마다 청크단위로 조금씩 할당된다.
참고자료 : SQL전문가가이드