본문 바로가기
인프라 7기/Oracle

Oracle 구조 및 주요 구성 요소

by 킹버거 2023. 2. 27.

Oracle의 Instance 구조 

Shared Pool 

- Data Dictionary Cache(데이터 딕셔너리 캐시) : 문법 오류 혹은 해당 테이블 존재 여부를 알기 위해 사용하는 메모리 영역으로 자주 사용하는 데이터 딕셔너리를 캐싱해 두어 성능을 높인다. 

 

- PMON : 좀비 프로세스가 있는지 확인하고 죽인다. 

* 좀비 프로세스 : 

프로세스가 종료되고 리소스는 모두 회수되었지만, 시스템 프로세스 테이블에 남아있는 defunct 상태의 프로세스

실행이 종료되었지만 아직 삭제되지 않은 프로세스라고 볼 수 있다.

 

SQL을 실행하여 Database가 Connection되었을 때  Server Process가 실행된다.

만약 User Process가 N개, Server Process가 N개 실행 중이라고 가정하자.

이 때, User가 실행 중인 창을 닫아버리면 Server는 User가 작업을 마친 것인지 아무런 작업을 수행하지 않는 것인지 알 수 없다. 이런 프로세스를 좀비 프로세스라고 하고 PMON은 이런 좀비 프로세스를 찾아 종료시킨다. 

 

- SMON : DB를 startup할 때 Redo Log Files 내용을 Datafiles에 동기화한다.

- DBWR : 

- LGWR : 

- CKPT(체크포인트) : Datafiles과 Redo Log Files의 시점이 맞지 않을 때 동기화 작업을 수행한다. 

* Check Point Event (주기적 발생) : DBWR, LGWR에게 동기화 관련 작업 명령을 내림.

 

Oracle의 Database 구조

1) Control files : Datafiles의 위치, 이름, 상태 정보가 들어있는 파일. 

모든 작업은 Controlfiles를 참고하여 수행된다. 만약 Controlfiles이 날아간다면 Database를 날리는 것과 같다. 

완벽한 복구(Recovery)가 불가능하기 때문에 반드시 별도 백업이 필요하다. 

2) Data files:

유일하게 복구가 가능한 파일.

3) Redo Log files :

삭제된 데이터를 살릴 수 있는 파일. 

 

* DELETE문이나 DROP문은 절대 사용하지 않아야 한다.

기술적으로 복구가 가능하기는 하지만 현실적으로 쉽지 않다.

복구 시간이 얼마나 걸릴 지도 모르는데 복구를 위해 회사 전체 DB를 SHUTDOWN하는 것은 사실상 불가능하기 때문이다. 

 

SELECT 문장의 실행 원리 

#1  파스 (Parse)

0) 실행 계획(Execution Plan)

Shared Pool 영역의 Library Cache에 해당 SQL 문장을 실행했던 기록이 있는지 즉, 실행 계획이 있는지 검사한다. (Library Cache는 파싱된 SQL 문과 실행 계획을 매핑하여 저장한다.)

만약 이미 실행된 적 있는 문장이라면 구문 분석(Parsing)을 할 필요가 없기 때문이다. 

  1. 해당 SQL 문이 존재한다면, 곧바로 실행한다. 이를 소프트 파싱(Soft Parsing)이라고 한다. 
  2. 해당 SQL 문이 존재하지 않는다면, 옵티마이저(Optimizer)가 최적화 과정을 거쳐 실행계획을 생성한다. 이를 하드 파싱(Hard Parsing)이라고 한다. 

옵티마이저(Optimizer)는 두 가지 방식이 있다.

  • 규칙기반 옵티마이저(RBO) : 규칙(우선순위)을 기반으로 실행 계획을 생성한다. 다음 정보를 참조하여 최적화를 수행한다. 1) PK나 UK 유무, 2) 인덱스 유무와 구성, 3) 연산자, 4) 객체 타입
  • 비용기반 옵티마이저(CBO) : 자원 사용량이나 소요시간에 근거하여 최소한의 비용으로 실행 계획을 생성한다. 딕셔너리의 다양한 통계 정보를 기반으로 최적화를 수행하는데 딕셔너리의 통계 정보가 최신이 아닐 때 비효율적인 실행 계획이 수립될 수 있다. 동일 RDBMS라도 상황에 따라 동일한 SQL문에 다른 실행 계획이 나올 수 있다. 

 

1) Syntax 검사

: 문장에 오타가 있는지 검색한다.

 

2) Semantics 검사

: 만약 문장에 오타가 없다면 어떤 테이블이 있고 테이블 안에 어떤 컬럼이 있는지 등 구문을 분석한다.

예를 들면, SELECT * FROM EMP; 의 구문을 분석할 때 EMP 테이블이 존재하는지 

Data Dictionary Cache에서 확인한다.

 

* 테이블 및 컬럼 확인 

sys의 경우에는 DBA_TABLES, DBA_TAB_COLUMNS 

user의 경우에는 USER_TABLES (User가 소유하고 있는 TABLE 정보만 나옴), USER_TAB_COLUMNS

 

#2 실행 (Execute) 

- 실행 계획에 따라 쿼리를 실행한다.

- 테이블이나 인덱스를 다양한 방법으로 스캔하여 원하는 데이터를 검색한다.

 

Database Buffer Cache에서 서버 프로세스가 원하는 블록이 있는지 검색한다 .

원하는 블록이 없다면 Datafiles에서 서버 프로세스가 원하는 블록을 Database Buffer Cache로 복사한다.

 

만약 insert 문을 실행하면 Database Buffer Cache에 데이터가 입력되면서 문장이 실행된다.

여기서 주의해야 할 점은 Database Buffer Cache의 해당 테이블과 Datafiles의 해당 테이블의 내용이 달라진다. insert문이 실행됨에 따라 달라진 내용은 Datafiles에 저장해줘야 한다. ( = 동기화) 

 

* Database Buffer Cache에 저장된 데이터 중에 Datafiles에 동기화되지 않은 데이터가 블록 단위로 모여있다.

이 블록을 더티블록(Dirty Block)이라고 한다. 

 

이 작업(동기화)은 DBWR(DataBaseWriteR)가 사용자의 작업과는 별개로 적절한 시기에 수행한다. 

 

* 적절한 시기

1) Database Buffer Cache의 가용한 메모리 공간이 부족해지기 전

- 사실 DBWR가 메모리 공간이 부족해지기 전 시기를 알 수는 없을 것.

DBWR가 기동하는 케이스가 있을 것이다. 

2) Datafiles에 Redo Log Files의 내용을 복구하려고 할 때 지정된 시간을 초과할 것 같을 때 

3) Database가 종료될 때 (Oracle을 shutdown할 때) 

4) 테이블 스페이스(TableSpace)가 off 될 때 

5) Redo Log Files을 순환시킬 때

 

Database가 변경되는 작업 한해서 '누가 언제 어떤 작업을 어떻게 실행했다.'라는 Log 정보가 남는다. 

이 Log 정보를 Redo 정보라고 한다. 이 Redo 정보는 Redo Log Buffer에 저장한다. DML문을 실행한 후에 COMMIT을 하면 Redo Log Buffer에 있는 내용을 LGWR가 Redo Log Files에 적어준다. 

 

 

#3 추출 (Fetch)

Server Process가 User Process에게 요청받은 데이터를 던져주는 과정이다.

하지만 Server가 던져주는 데이터는 바이너리 코드이기 때문에 이것을 User가 읽기 위해서는 PHP의 Fetch 함수를 써야 한다.

 

단, SELECT 문을 실행하는 경우에만 패치 과정이 실행되고 DML 문 실행시엔 패치 과정이 실행되지 않는다.