Database/ORACLE

1일차 - 1장. 오라클 데이터베이스 구조 탐색

99iberty 2013. 12. 2. 15:21

 

엑사데이터를 쓰지 않는다면 ASM 은 죽어가는 분위기...

<< ASM 미룸

 

6장에서는 C-S 환경만 포커스, 미들웨어는 빼고

 

서비스명 : DB서버에 연결하기 위한 정보

 

오라클은 크게 두 개 키워드로 나뉨.

1. 인스턴스

-> 1) 메모리 : 용도에 따라 데이터를 분류해서 데이터를 빠르게 처리하겠다.

ㄱ. System Global Area (a.k.a Shared Global Area)

DB를 사용하는 전체 유저가 공유하는 정보를 올림.

ㄴ. Program Global Area (a.k.a Private GA)

개별적인 사용자가 사용하는 데이터를 올림.

-> 2) 프로세스 : 메모리와 데이터베이스를 연결해 주는 걸 프로세스라 한다. Background Process, 리스너 등등이 프로세스 이다.

서버프로세스가 사용하는 메모리 공간은 PGA.

 

2. 데이터베이스

-> 데이터의 안정성을 가지는 스토리지를 가리킴.

 

1) Data file

   : .dbf 확장자.

ㄱ. User data : 유저의 데이터.

ㄴ. Data dictionary : DB에는 어떤 유저가 있는지 테이블이 있는지 뷰가 있는지 어떤 권한이 있는지 등등의 오라클의 데이터.

 

2) Control file

  : .ctl 확장자. 물리적인 구조 정보를 가지고 있음.

    ~위치 ~이름으로 데이터 파일이 있고 이 데이터파일은 어떤 상태이다.

    메모리에 있던 데이터가 언제 싱크가 됐는지, 아카이브로그 어느 시점에서부터 운영했는지 등등..

 

3) Redo log file

   : .rdo, .log 확장자. 유저들이 메모리에서 작업했던 작업 내역 정보를 가지고 있음.

    메모리 혹은 DB쪽에 문제가 생기면 이것 가지고 복구.

 

 

 

유저가 리스너를 통해서 서버 프로세스를 할당받아 연결을 맺는 방식.

2가지 연결 방식 존재.

 

1. Dedicated Server (1:1)

디폴트 방식.

이 방식으로 연결하면 하나의 커넥션당 서버 프로세스 올라가고 해당 메모리 공간도 할당된다.

 

2. Shared Server (n:1)

USER N명이서 하나의 서버 프로세스를 공유.

그 DB를 사용하는 사용자에 대한 예측을 하고, 서버 프로세스 갯수를 지정. 미리 서버 프로세스를 띄워 놓음.

디스패처를 띄워놔서 사용자와 서버 프로세스 연결해줌.

단점 ; 순차적으로 리퀘스트 받은 것 넘어갔다가 작업 진행 됨. 내 작업만 쭉 진행되지 않음.

         우선순위를 둘 수 없음.

 

 

* SQL 문장 해석 방식.

1.인터프리터드 방식 ; 문장 베이스로 인식. 디폴트 방식.

1) Parse : 3'S 체크를 함. (Syntax , Semantic , Security)

(1) SQL을 오라클 서버에 날림.

구문에 오타가 있는지, 의미 분석( 테이블이 있는지 해당 행이 있는지) , ORA1이라는 유저가 select할 수 있는 권한이 있는지

구문 분석 단계를 거치면서 오라클 서버(프로세스)가 사용됨.

semantic , Security 는 데이터 파일에 있음. - 데이터 딕셔너리.

서버 프로세스가 그 정보를 copy 해서 메모리에 올림.

그 정보가 올라가는 메모리 공간이 SGA. 그 SGA는 3분야로 나뉘어짐.

SGA 중 데이터 딕셔너리 캐시에 올려짐.

메모리에 올리는 이유는 다른 유저가 똑같은 체크 할 때 다시 3'S 체크 하지 말고 메모리에 올려져 있으면 속도 빠르게.

위 과정에서 문제가 없었으면 (2) P-Code 가 생성됨.

이때서야 오라클 서버가 해당 SQL을 이해함.

P-Code가 생성되면 Optimizer가 구동됨.

옵티마이저는 유저가 작성한 P-Code를 보고 어느 인덱스를 처리했을 때 데이터가 빨리 올라올 수 있을지. 등등의 경우의 수를 계산하면서

어떤 방식으로 유저의 데이터를 처리해 줄 건지 실행계획이라는 (3)Excution Plan (E-Plan)을 작성한다.

실행계획 작성하면 오라클 서버에서는  (4) Hash-value (y')를 메모리에 다시 보관함. (E-Plan의 아스키 코드값이라고 생각하면 되겠다.)

위 네개는 다 라이브러리 캐쉬에 있다.

 

이 실행계획이 다른 유저가 요청할 때 동일한 실행계획인지 확인은 어떻게 하느냐,

오라클은 문자를 아스키코드로 확인함.

오라클 서버프로세스는 우선 메모리를 뒤져봄. 거기에 동일한 y' (해쉬벨류) 값이 있으면 그냥 메모리에서 보내줌.

또 동일한 해쉬밸류는 아니더라도 동일한 딕셔너리 캐쉬가 있으면 스토리지단까지 안 내려가고 바로 다음 단계(P-code 생성) 수행함.

 

변화되는 값을 변수로 바꿔서 하든가.. (예를 들어 WHERE 절 값을...  WHERE 사번 = 'a' )

또 하나, 회사의 코딩 규칙을 만듦.

SQL 패턴을 동일하게 만들면(SELECT 이런 건 대문자, 테이블은 소문자 등등), 메모리에 있던 실행계획이 공유될 확률이 높아짐.

 

2) Bind ; 변수값 확인.

- Cache hit ; 메모리에 해당 정보가 있을 때. 메모리 정보로 3'S 체크 했을 때. (=soft parse)

- Cache miss ; 메모리에 정보가 없어서 디스크에서 정보를 올려서 처리. (=hard parse)

 

3) Excute ; 실행 단계.

유저가 요청한 데이터는 데이터베이스의 user 데이터 공간에 있을 거다.

그 데이터를 메모리에 copy해서 올린다.

오라클은 블럭 단위로써의 I/O를 일으켜서 블럭 단위로 데이터를 올림.

그 데이터가 올라오는 곳을 SGA의 Database Buffer Cache 라고 함.

유저의 데이터를 포함한 블럭 하나를 올려서, 그 많은 데이터 중에서 요청데이터인 사번이 100번인 데이터를 보여줌.

 

4) Fetch ; 클라이언트로 올려서 유저가 볼 수 있게 하는 단계

order by 라든지.. 이런 내용은 나만 필요한 부분. 데이터 자체는 데이터 버퍼 캐쉬에 있고.

해당 정렬 부분은 PGA에서 수행됨.

변수, 권한 같은 부분.. 이런 부분은 PGA에서 수행됨.

 

ex) 사번 7788, 직원 이름 A , 샐러리 1000 -> Update hr.employess

Set salary = salary * 1.30

where 사번 = (7788);

                    : B

     조작한 나(ORA1)에게는 SELECT 했을 때는 1300으로 보인다. (COMMIT 전에)

     이 때 ORA2가 SELECT 했을 때는 1000으로 보인다.

 

     DML 작업일 때(SELECT 이외)는 두 개의 데이터 블럭이 데이터 버퍼 캐쉬에 올라온다. (하나는 실제 데이터 1000, 또 하나는 언두블럭.)

     조작 전에 언두블럭에 1000이라는 값이 있고 실제 메모리에 올라와 있는 다른 원본데이터를 수정.

 

     그럼 어떤 사용자에게는 1300, 어떤 사용자에겐 1000 보여주는 걸 어떻게 결정하느냐?

     블럭의 헤더에 transaction slot이라는 부분이 있음. 해당 블럭의 특정한 row에 조작이 일어나게 되면 어떤 row의 어떤 내용이 바뀌었다라고

     블럭의 헤더에 락을 걸고 데이터를 변경함.

     위에서부터 데이터를 읽어들이는데 transaction slot 부분에 부합하는 사용자라면 해당 데이터 블럭에서 데이터를 가져오고

     그 이외의 사람은 언두데이터 블럭의 값을 보여줌.

 

 

COMMIT이라는 처리가 오라클 서버에 전달되게 되면?

-> 그때그때마다 물리적 디스크 데이터 파일에 쓰지 않는다!

 리두로그 버퍼라는 메모리를 사용한다 !!

유저의 작업 내용 정보는 시간순으로 갖고 있다.

Redo entry 에 기록.

나 말고 다른 사람의 조작이 있을 수 있기 때문에 시간 순으로 기록된다.

COMMIT 을 내리게 되면 리두로그 버퍼의 내용을 물리 디스크 리두로그 파일(작업 내역 정보)에 내린다.

해당 작업을 해주는게 로그 라이터 라는 백그라운드 프로세스가 해 준다. (LGWR)

COMMIT 했을 때 내 작업 내역만 저장하는 게 아니라 다른 사용자들 거 모두 다 내려써짐.

리두로그 디스크에 써지면 COMMIT 되었다 라고 시그널이 보내진다. (데이터파일까지 쓰지 않는다.)

사용하다가 비정상적으로 종료되었을 때, 거기에 대해 복구하고 올라오는 걸 Instance Recovery 라고 한다.

System Monitor (SMON) 이 가장 중요한 일은 Instance Recovery를 함.

 

 

2.컴파일러 방식 ; 컴파일 시켜서 sql 인식.

 

 

 

 

 

*백그라운드 프로세스

DBWR : 데이터 버퍼캐쉬를 전담하면서 메모리의 공간확보를 해주고,

           1300으로 변경된 데이터를 물리디스크(데이터파일)에 써 주는 역할.

 

PMON : 유저가 DML작업을 하다가 네트워크가 꺼졌다.

유저가 쓰던 공간을 해제해 줘야 함. 정리 작업을 PMON 이 해 줌.

 

CKPT : 체크 포인트의 약자.

메모리에 있던 변경된 내용을 물리적 디스크에 내려쓰는 작업을 체크포인트 라고 한다.

체크포인트라는 상황을 일으키는 프로세스다. 다른 프로세스보다 상위 프로세스.

그 상황이 되면 CKPT프로세스가 DBWR에게 시그널을 보낸다.

그러면 DBWR는 쓰기 전에 LGWR에게 시그널을 보낸다. 그럼 LGWR가 먼저 내려쓴다 리두로그파일에.

다 내려쓰면 LGWR은 DBWR에 완료시그널을 보낸다.

그 때 DBWR가 메모리에서 변경된 내역을 내려쓴다.

다 쓰면 CKPT에 완료 시그널이 간다.

그 때 CKPT는 데이터 파일의 헤더와 컨트롤 파일의 헤더에 동기화 정보를 기록한다.

어느어느 시점에 무슨 데이터가 바뀌었다, 리두로그 파일의 어디까지 적용되었다 라고 포인터를 지정해 준다.

 

 

지금까지 말한 SGA의 구성요소는 필수적이고,

옵셔널한 부분이 있다. 아래 셋은 필요하면 구성하고 필요 없으면 구성 X.

 

1. Large pool ; parellal 처리 , RMAN 사용시 데이터를 이곳에 올려서 속도 빠르게 할 경우 필요.

2. Java pool ; 자바 버추얼 코드 사용해서 속도 빠르게 할 경우 필요. (자바 안 쓰면 필요 없음)

3. Streams pool ; ...이 기능은 뭔 기능인지 몰겠당.

 

 

 

 

< Memory 관리 방식 >

 

1. LRU (Least Recently Used)

데이터 버퍼캐쉬에 4개의 데이터 올라올 수 있다고 치고.

데이터 올라오는 공간을 Most 라고 함.

SELECT 문장시.

----------------------------------------

->100

     A

----------------------------------------

MOST

 

----------------------------------------

200     |   100

B       |    A

----------------------------------------

MOST

...

...

...

----------------------------------------

500     |   400   |    300    |  200                            -> 100 데이터는 밀려나감.   

E       |    D      |    C      |    B                                   A

----------------------------------------

MOST                                END

 

한번 불려져서 더 이상 사용되지 않으면서 메모리에서 사라지게 하는 걸 Aging Out 이라고 한다.

이미 메모리에 있는 상태면 또 불리면 MOST 로 다시 감.

계속 안 불리면 END까지 갔다가 밀려 나감.

 

실제로 오라클은 위와 같이 작동하지 않고 가운데로 들어가서 ....어쩌구져쩌구...ㅋㅋ

 

 

DML 작업은 다른 방식으로 관리가 되야 한다.......

여튼 LRU가 안 좋다..ㅋ.ㅋ

 

 

오라클 9i 부더 데이터 버퍼 캐쉬를 Multi - Buffer pool 로 관리 가능함.

2. Multi - Buffer Pool

- Default (LRU)

- Keep

테이블 정의시 스토리지 정의? 를 해서 내가 원하는 디폴트 부분 .. 올라오고 ..오잉

keep 해 놓으면 DB를 내리기 전까지 절대 안 내려감. 즉 코드성 데이터, LRU의 영향을 안 받음.

메모리에서 KEEP을 잡아 놓음.

- Recycle

한 번 메모리에 올라왔다가 작업이 끝나면 사라짐.

일회성 데이터라면 LRU 말고 여기다가 하고, 애매하면 걍 오라클이 관리하게 디폴트(LRU)로 올리고..

 

개념은 좋지만... 이 세 개를 잘 적절히 쓰는 곳이 많지 않다.

 

 

 

*데이터베이스 버퍼 캐쉬 상태.

1. Free / unused / Clean

FREE : DB가 올라와서 지금 아무도 안 쓴 상태.

Clean : Dirty한 부분을 DBWR가 물리디스크에 쓰고 난 후.

Unused : 사용하지 않던 부분이 데이터베이스 버퍼 캐쉬로 변경됐을 때 잠깐 이 상태. 나중에 쓸 수 있는 상태가 되면 FREE로 바뀜.

2. Pinned

Cache miss 가 나서 불러올 때 누구도 못 쓰게 잠시 내껄로 찜해 둘 때. 고정됐다. LRU로 밀려나도 안 됨. 누가 건드려도 안 됨.

SELECT해서 내가 조작할 데이터 보고 UPDATE함. 락도 걸고 트랜잭션 슬롯에 데이터도 걸고.. 이런 작업 할 때 누가 건드리면 안되니까 찜해둠.

즉 데이터를 조작 중인 상태.

3. Dirty

조작이 끝났어. 그래서 스토리지의 데이터와 내용이 달라졌어. 그러면 메모리에서 밀리면 안 된다. 그 상태를 Dirty라고 한다.

Dirty한 상태로 되어 있는 곳을 물리 스토리지에 내려씀. (FREE, PINNED 는 내릴 수 없다.)

 

 

 

 

오라클 버전 9i 이후로 변함.

Automatic.으로...

먼저..

1. 성능과 관련된 메모리 부분을 자동화 함.

-> 9i부터는 PGA 를 자동화함.

ex) 1건 sorting 하는데 1MB 든다고 치면.. 10건 sort하는 A , 20건 B, 30건 C 하는 애가 있다고 하면..

고정값을 줄 수가 없지. 자동화 해서 그 때 그 때 필요한 값 할당.(필요한 값 계산 할 때에도 delay 발생)

총 SIZE PGA만 정의해 놓고 그 안에서 분배해 주는 것. 작업 다 끝나면 반환. (회수에 대해 delay 발생)

전체 SIZE 풀만 적절히 하면..  전제 size 보다 더 쓰는 건 어쩔 수 없고.

저런 delay들이 발생하는 거 싫으면 안 쓰면 됨.

 

-> 10g 부터는 SGA도 자동화함.

총 SGA 안에서 데이터버퍼캐시 크기도 조정하고...

 

-> 11g 부터는 메모리 자동화. (PGA+SGA)

     그 전까지는 PGA SGA 영역 지정하면 둘 사이는 넘나들 수 없다. 처음에 잡아둔 용도로만 써야 한다.

     총 사용할 메모리 양을 잡아줌. 이 안에서 오라클이 분배해 주겠다.

 

 

 

RAC는 인스턴스에 대한 가용성만 보장

DB 자체에 대한 가용성을 보장 받으려면 DATA GUARD 필요.

 

 

LGWR는....

useR가 작업하면서 COMMIT을 아무도 안 했음.

그래도 리두 로그 버퍼가 1/3이 찼을 때 로그라이터가 리두로그를 쓴다.

안 차도 3초마다 내려씀.

1MB 되면 또 내려씀.

DBWn 프로세스가 수정된 버퍼를 디스크에 기록하기 전에 라는 게 체크포인트가 시그널을 보낼 때라는 말인가..,?

 

 

RECO는 분산DB에서만 의미 있음 싱글 DB에서는 의미없음.

 

 

 

 

그리드 인프라스트럭처 - 11g r2부터 생김.

 

10g부터 생겼는데, raw device를 대체하기 위해 들고 온게 ASM 이다.

스토리지 유형이 여러 개가 있는데, 일반 파일시스템을 쓰면 OS단에서 컨트롤 가능.

FS 를 쓰면 OS의 버퍼를 통한 I/O를 일으키기 때문에 속도가 느림. 대량의 데이터를 쓰기엔 안 좋음.

그래서 Raw Device 유형을 선택. 볼륨매니저라는 다른 툴을 통해서 핸들링해야 함. 관리적인 측면에서는 불편.

 

ASM을 통해서 RAID0, RAID1 구현 가능. RAW DEVICE 대체하기 위해...

사용자들이 안 쓰니깐 11g R2부터는 GUI 로 설치 할 때 RAW DEVICE 지원 안 하고 ASM , FS 밖에 선택 못 함.

오라클 운영할 때 각각의 운영요소에 비정상적으로 문제가 생기면 자동적으로 올려주겠다.

ASM, DB INSTANCE, LSTNR 자동 관리 해 주겠다.

띄워주고 로그 남겨주고... 싱글 DB에 마치 RAC같이 지원해 주겠다.

OS에 데몬같이 떠 있어서...

 

 

 

 

Q1. 체크포인트는 언제 발생하는가?

-> COMMIT 할때는 발생 안 함.

-> 발생 안해도 LGWR은 3초마다 내려씀. 다른 LGWR 구동조건 때도 마찬가지. 여튼 체크포인트 발생하든 안 하든 자기 갈 길 감.

-> 사용자가 COMMIT 날릴 때는 DBWR도 안 움직임.

 

Q2. 사용자가 commit 날릴 때면 리두로그에만 써지고 데이터파일에는 안 써짐.

-> DBWR 작동하면 원본데이터 블록과 언두데이터 블록 둘 다 사라짐.

 

Q3. DBWR 는 CKPT가 명령할 때만 작동하지 않음. 다른 조건이 또 있음.