기본적으로 하나의 인스턴스가 하나의 데이터베이스만 액세스한다.
RAC(Real Application Cluster) 환경에서는 여러 인스턴스가 하나의 데이터베이스를 액세스할 수 있다.
(하나의 인스턴스가 여러 데이터베이스를 액세스할 수는 없다.)
1) 전용 서버 방식
처음 연결요청을 받는 리스너가 서버 프로세스를 생성해주고 이 서버 프로세스가 단 하나의 사용자 프로세스를 위해 전용 서비스를 제공한다.
전용 서버 방식을 사용하는 OLTP성 애플리케이션에서는 Connection Pooling 기법을 필수적으로 사용해야 한다.
2) 공유 서버 방식
하나의 서버 프로세스를 여러 사용자 세션이 공유하는 방식이며 Connection Pooling 기법을 DBMS 내부에 구현해놓은 것이다.
사용자 프로세스는 서버 프로세스와 직접 통신하지 않고 Dispatcher를 거친다.
데이터 파일 : 디스크 상의 물리적인 OS 파일
테이블 스페이스 : 세그먼트를 담는 콘테이너
세그먼트 : 테이블, 인덱스, 파티션, LOB 등 데이터 저장 공간이 필요한 오브젝트(View, Sequence, Synonym 등은 세그먼트 아님)
익스텐트 : 공간을 확장하는 단위로 세그먼트의 공간이 부족해지면 테이블스페이스로부터 추가로 할당받는다. 연속된 블록의 집합. (익스텐트끼리는 연속된 공간의 집합이 아니다.)
블록 : 데이터를 읽고 쓰는 단위. 한 블록에 저장된 레코드는 모두 같은 테이블 레코드다.
대량의 정렬이나 해시 작업을 수행하다가 메모리 공간이 부족해지면 중간 결과집합을 저장하는 용도다.
(정렬이나 해시 작업은 우선 메모리 영역인 PGA 영역에서 진행하다가 공간 부족 시 디스크 영역인 임시 데이터 스페이스를 이용하게 된다. 참고로 정렬은 메모리 영역 내에서 해결하는 것이 좋다.)
Redo 정보를 생성하지 않기 때문에 나중에 파일에 문제가 생겼을 때 복구되지 않는다.
DB 버퍼 캐시에 가해지는 모든 변경사항을 기록하는 파일. 대부분 DBMS는 버퍼 블록에 대한 변경사항을 건건이 Random table access 방식으로 데이터 파일에 기록하기보다 우선 로그 파일에 Append 방식으로 빠르게 기록하는 방식을 사용한다. 그리고 나서 버퍼 블록과 데이터 파일 간 동기화는 DBWR, Checkpoint를 이용해 나중에 배치 방식으로 일괄 처리한다.
여러 프로세스가 동시에 액세스할 수 있는 메모리 영역으로 서버 프로세스와 백그라운드 프로세스가 공통으로 액세스하는 데이터와 제어 구조를 캐싱하는 메모리 공간이며 DB 버퍼 캐시, 공유 풀, 로그 버퍼가 있다. SGA는 여러 프로세스에 공유되기 때문에 내부적으로 래치, 버퍼 Lock, 라이브러리 캐시 Lock/Pin 같은 액세스 직렬화 메커니즘이 사용된다.
DB 버퍼 캐시
: 데이터 파일로부터 읽어들인 데이터 블록을 담는 캐시 영역. 읽고자 하는 블록을 먼저 버퍼 캐시에서 찾아보고 없을 때 디스크에서 읽는다. 디스크에서 읽을 때도 먼저 버퍼 캐시에 적재한 후 읽는다.
(Free 버퍼, Dirty 버퍼, Pinned 버퍼 중 하나의 상태로 놓인다.)
사용빈도가 높은 데이터 블록 위주로 버퍼 캐시가 구성되도록 LRU 알고리즘을 사용한다.
공유 버퍼
1) 딕셔너리 캐시
테이블, 인덱스같은 오브젝트는 물론 테이블 스페이스, 데이터 파일, 세그먼트, 익스텐트, 사용자, 제약에 관한 메타 정보를 저장하는 곳이다. 구문 분석 시 SQL문에 지정된 오브젝트의 이름을 찾아내고 접근 권한을 검증하기 위해 정보를 찾을 때 사용된다.
2) 라이브러리 캐시
사용자가 수행한 SQL문과 실행계획, 저장 프로시저를 저장해두는 캐시영역. SQL을 캐시에서 찾아 곧바로 실행단계로 넘어가는 것을 소프트 파싱이라고 하고, 찾는 데 실패해 최적화 및 로우 소스 생성 단계까지 모두 거치는 것을 하드 파싱이라고 한다. 특히, 최적화 과정은 하드 파싱을 무겁게 하는 주요 요인인데 이러한 작업을 반복적으로 수행하는 것을 방지하기 위해 라이브러리 캐시를 두어 SQL 수행 성능을 높이고 DBMS 부하를 최소화한다.
로그 버퍼
DB 버퍼 캐시에 가해지는 모든 변경사항을 로그 파일에 기록하기 전에 먼저 로그 버퍼에 기록한다. 서버 프로세스가 데이터 블록 버퍼에 변경을 가하기 전에 Redo 로그 버퍼에 먼저 기록해두면 주기적으로 LGWR 프로세스가 Redo 로그 파일에 기록한다.
버퍼 캐시 블록을 갱신하기 전에 변경사항을 먼저 로그 버퍼에 기록해야 하며, Dirty 버퍼를 디스크에 기록하기 전에 해당 로그 엔트리를 먼저 로그 파일에 기록해야 하는데, 이를 'Write Ahead Logging'이라고 한다.
늦어도 커밋 시점에는 로그 파일에 기록해야 한다!
서버 프로세스가 갖는 자신만의 전용 메모리 영역으로 데이터를 정렬하고 세션과 커서에 관한 상태 정보를 저장하는 용도로 사용한다.
(참고로 Oracle은 프로세스 기반 아키텍처이므로 PGA를 사용하는 것이고 SQL Server같은 경우는 쓰레드 기반 아키텍처이므로 사용하지 않는다고 한다.)
똑같은 개수의 블록을 읽더라도 SGA 버퍼 캐시에서 읽는 것보다 훨씬 빠르다.
Response Time
= Service Time + Wait Time
= CPU Time + Queue Time
서비스 시간(Service Time, CPU Time)
: 프로세스가 정상적으로 동작하며 일을 수행하는 시간
대기 시간(Wait Time, Queue Time)
: 프로세스가 잠시 수행을 멈추고 대기한 시간
라이브러리 캐시 부하
: 라이브러리 캐시에서 SQL 커서를 찾고 최적화하는 과정에 경합이 발생했음을 나타나는 대기 이벤트다.
데이터베이스 Call과 네트워크 부하
디스크 I/O 부하
: db file sequential read - single block I/O 수행 시 나타남
db file scattered read - multi block I/O 수행 시 나타남
버퍼 캐시 경합
Lock 관련 대기 이벤트
: latch free - 특정 자원에 대한 래치를 여러 차례 요청했지만 해당 자원이 계속 사용 중이어서 잠시 대기 상태로 빠질 때마다 발생하는 대기 이벤트다.