Database/Oracle2012. 3. 18. 10:38

래치와 락의 차이점을 집중적으로 들어가기에 앞서 가볍게 래치와 락의 차이를 알아보자.

 분류            래치(LATCH)             락(LOCK)
 목적  하나의 목적을 수행함 : 메모리 구조에 대한 배타적인 접근을 위함 (오라클 9i부터 cache buffers chains latch 들은 읽기 전용시에 공유가 가능함)
-거의 독점적-
 두가지 목적을 수행함 : 락 모드가 호환 가능하면 다수의 프로세스가 동일한 리소스를 공유하는 것을 허용하며, 락 모드가 호환 가능하지 않으면 리소스에 대한 배타적인 접근만 허용함 (공유lock이 많음)
 사용범위  sga내부의 데이터 구조에만 적용.
메모리 오브젝트를 임시적으로 보호함.
단일 오퍼레이션으로 메모리 구조에 대한 접근 제어. 트랜잭션 단위가 아님.
 테이블, 데이터 블록 및 state object와 같은 오브젝트를 보호함.
 데이터베이스의 데이터 또는 메타데이터 접근제어. 트랜잭션 단위
 획득방식  두가지 모드로 요청이 가능
willing-to-wait 또는 no-wait
 6가지 모드로 요청가능 : null, row share, row exclusive, share, share row exclusive, 또는 exclusive
아래 표 참조.
 범위  sga내부에 정보가 존재하며, 로컬 인스턴스에만 볼 수 있음.
- 인스턴스 레벨로 작동-
 데이터베이스 내부에 정보가 존재하며, 모든 인스턴스에서 볼 수 있음. lock은 데이터 베이스 레벨에서 작동.
 복잡도  단순한 명령어를 사용하여 구현됨.
일반적으로 test-and-set, compare-and-swap 또는 단순한 cpu명령어. 구현이 쉬움
 문맥 교환(context switch)을 포함한 일련의 명령어들을 사용하여 구현됨. 구현이 복잡하다.
 지속기간  짧은 순간만 지속됨
(microsecond단위) = 100만분의 1초
 일정시간동안 지속
(트랜잭션 동안)
 큐(Queue)  프로세스가 래치 획득을 실패 한 후 슬립(sleep) 상태로 들어갈 때, 해당 요청은 큐(queue)로 관리되지 않으며, 요청한 순서대로 서비스 되지않음
(latch wait list를 이용하여 큐방식으로 사용되는 래치들은 예외)
 프로세스가 락 획득을 실패한 후, 해당 요청은 큐(queue)로 관리되며, 요청한 순서대로 서비스됨(nowait 모드는 예외)
 데드락(DEADLOCK)  데드락이 발생되지 않도록 구현됨
(레벨방식)
 락은 큐 방식을 사용하며, 데드락이 발생될 가능성이 높다. 데드락이 발생 될 때마다 트레이스 파일이 생성된다.

참조 : 조동욱님 OWI책 P49


 
LOCK 획득방식중 6가지 모드 표

 모드  설명
 0  None
 1  Null(N)
 2  Sub-Shared(SS) 또는 Row-shared(RS)
 3  Sub-Exclusive(SX) 또는 Row-Exclusive(RX)
 4  Shared(S)
 5  Shared-Sub-Exclusive(SSX)
 Shared-Row-Exclusive(SRX)
 6  Exclusive(X)


참조 : 조동욱님 OWI책 P70














출처 : http://baind.tistory.com/entry/LATCH-와-LOCK-분류표

'Database > Oracle' 카테고리의 다른 글

[펌] granularity 란?  (0) 2012.03.18
[펌] cardinality 란?  (0) 2012.03.18
[펌] Latch 란 무엇인가  (0) 2012.03.18
[펌] Lock 개요  (0) 2012.03.18
[펌] Cursor 란??  (0) 2012.03.18
Posted by 아로나
Database/Oracle2012. 3. 18. 10:36

래치란 무엇인가?

 래치란 빠르고 가볍게 특정 리소스에 대한 동기화를 구현하기 위한 객체(object)이다.

 특징
 1. 래치는 물리적으로 Shared Pool 영역에 존재하는 일종의 메모리 구조체이다.
 2. 래치는 매우간단하고 작은 메모리 영역을 사용하며, 래치를 획득(get)하고 해제(release)하는 작업들 또한 하드웨어에
     맞게 최적화 되어있다.
 3. 일반적으로 하드웨어 칩셋이 제공하는 TEST-AND-SET, COMPARE-AND-SWAP와 같은 명령을 사용하므로 래치를
     획득하고 해제하는 행위는 원자성(Atomicity)이 보장된다.
 4. 래치를 보호하기 위해 별도의 소프트웨어적인 동기화 장치가 필요없다


래치가 보호하는 리소스?

래치가 보호하는 리소스는 SGA다. SGA에 접근하는 모든 프로세스는 반드시 해당 영역을 관장하는 래치를 획득 한 후에만 접근이 허용하기 때문이다.

분석

SQL문을 실행하고자 하는 프로세서는 해당 SQL을 Share Pool의 library cache 영역에 올려야 한다. 이 때 필요한 힙(HEEP)-익스턴트 개념- 메모리 영역을 할당 받기 위해서는 반드시 Shared pool latch를 획득해야한다.

1. shared pool래치는 보통 전체 인스턴스에 하나만 존재한다.
2. 한번에 하나의 프로세스만이 힙으로 부터 **청크(chunk)**를 할당 받을 수 있다.
3. select 문을 통해서 특정 데이터 블록을 읽기 위해 해시 체인(Hash chain)에 접근하고자 하는 모든 프로세스는 반드시
    해당 체인을 관장하는 cache buffer chains 래치를 획득해야한다.
5. DML을 통해서 데이터를 변경한 모든 프로세스는 PGA영역에 redo데이터를 생성. 이 리두 데이터를 리두 버퍼(redo buffer)
   로 복사하기 위해 먼저 redo copy 래치를 획득해야 한다.

이렇듯 SGA의 특정영역을 탐색하거나 변경하고자 하는 프로세스는 반드시 해당 영역을 관장하는 래치를 획득해야한다. 이를 통해 SGA의 자원을 보호한다.

청크!! HEEP 구조!! library cache구조!!

 

Shared Pool Memory의 구조

 

 

~ 물리적인 관점에서 shared pool의 메모리는 그래뉼을 추가로 쌓는 형식으로 할당되기 때문에

   힙(Heap)이라는 용어를 사용한다. 이때 하나의 그래뉼이 하나의 extent가 된다.

~ Extent는 다양한 크기의 chunk로 나누어질 수 있다. chunk의 상태는 free, recreatable, freeable,

   permanent로 나누어지며 free와 recreatable(현재 사용중이지 않으면서 재생성 가능) chunk만

   재사용할 수 있다.

 

Shared Pool의 Heap 구조

 

 

~ Memory 공간 요청시 Chunk 단위로 할당

~ Freelist : Free Chunk의 목록

~ LRU List : 현재 사용중이지 않은 재생성 가능 Chunk 목록(Unpinned Recreatable Chunk)

~ Reserved Freelist : 최상위 Heap에만 존재, Shared Pool의 예약 영역에 대한 Freelist

~ Freelist에서 원하는 크기의 chunk 검색 -> LRU List 검색

    -> 특정 크기 이상이면 Reserved list 검색 -> 모두 실패하면 ORA-4031에러

 

Library Cache 구조

 

~ Shared Pool에서 가장 중요한 부분 중의 하나인 Library Cache 영역은 SQL문의 수행과 관련된 
   모든 정보들을 관리하는 영역이다. Library Cache 메모리는 Library Cache Manager(KGL, Kernel
   Generic Library Cache)에 의해 관리되는데, KGL은 KGH를 이용해서 필요한 메모리 청크를 
   할당 받는다.

~ Library Cache 메모리는 [해시 테이블 -> 버킷 -> 체인 -> 핸들 -> 오브젝트]의 구조로 되어 있다.

~ 오라클은 객체 이름(가령 SQL 텍스트)에 해시함수를 적용해 생성된 해시값을 이용해 적절한
   해시 버킷(Hash Bucket)을 할당하며, 같은 해시값을 지니는 객체들은 체인(리스트)으로 관리된다.

~ 하나의 Library Cache 핸들(이하 핸들)은 하나의 Library Cache Object(이하 LCO)를 관리한다. 
   핸들은 실제 LCO에 대한 메타정보 및 포인터 역할을 하며 LCO가 실제 정보를 담고 있다.

~ LCO가 포함하는 정보 중 중요한 것들은 다음과 같다. 
   - Dependency Table  
   - Child Table
   - Data Blocks  

Shred Pool 관련 latch

  

 

출처  : http://wiki.ex-em.com

참고  : Practical OWI in Oracle 10g(그림으로 명쾌하게 풀어쓴)  

출처 : http://blog.naver.com/gseducation?Redirect=Log&logNo=20099683486
                


                                            (주)엑셈

                        
                                              한민호님

'Database > Oracle' 카테고리의 다른 글

[펌] cardinality 란?  (0) 2012.03.18
[펌] Lock 과 Latch 분류표  (0) 2012.03.18
[펌] Lock 개요  (0) 2012.03.18
[펌] Cursor 란??  (0) 2012.03.18
[펌] Chunk 란?  (0) 2012.03.18
Posted by 아로나
Database/Oracle2012. 3. 18. 10:34

LOCK?

 latch가 SGA를 보호한다면, lock은 database 전체를 보호한다.
태이블, 트랜잭션, 언두 세그먼트, 테이블 스페이스, 잡(job) 등 데이터 베이스 단위에서
피요한 대부분의 리소스들은 락의 보호를 필요로 하며 복잡하다.

간략히 정리해보면

1. 데이터베이스 내부에 정보가 존재하며, 락은 데이터베이스 레벨에서 작동한다.
2. 문맥 교환을 포함한 일련의 명령어를 사용하여 구현되어져 복잡하고 무겁다.
3. 트랜젝션 동안 지속된다.
4. 프로세스가 락 획득을 실패한후, 해당 요청은 queue관리되며, 요청한 순서대로 서비스된다. nowait는 예외이다.
5. 6가지 모드로 요청이가능. [아래 표 참조]
   (null, row share, row exclusuve, share, share row exclusive, exclusive)
  *모드간의 호환성 관계 존재. [아래 표 참조]
  *매우 복잡한 작업에 대한 동기화 작업도 가능.


LOCK 획득방식중 6가지 모드 표
 
 모드  설명
 0  None
 1  Null(N)
 2  Sub-Shared(SS) 또는 Row-shared(RS)
 3  Sub-Exclusive(SX) 또는 Row-Exclusive(RX)
 4  Shared(S)
 5  Shared-Sub-Exclusive(SSX)
 Shared-Row-Exclusive(SRX)
 6  Exclusive(X)


락 모드 호환성 표

          N         SS      SX (RX)         S        SSX          X
 N         ○         ○         ○          ○          ○         ○
 SS         ○         ○         ○         ○         ○         X
 SX (RX)         ○         ○         ○          X         X         X
 S         ○         ○         X         ○         X         X
 SSX         ○         ○         X         X         X         X
 X         ○         X         X         X         X         X
                                                                   - 참조 : 조동욱님 OWI책 P70 -
 *붉은 색 표시된 부분은 유심히 볼 필요가 있다.




LOCK의 기본적인 분류

Enqueue lock

 
enqueue 구조로 관리되는 lock이다. 오라클 10g부터 대부분 enqueue락에 대해 개별 대기 이벤트가 등록되므로 V$event_name 뷰를 조회하면 어떤 종류의 enqueue락이 존재하는지 알 수 있다.

enqueue lock이 보호하는 리소스(resource)의 형태는??

 <<Resource = TYPE - ID1 - ID2 >>

구분

 user type lock     :  TX(트랜젝션), TM(테이블 리소스), UL(언두 세그먼트)
 system type lock :  HW, US, CI, TC, SQ.... (V$EVENT_NAME로 확인 가능)
 
 *V$LOCK_TYPE 뷰 참조10g*

  
일반 LCOK

 enqueue lock이 아닌 일반락인 경우에는 별도의 리소스 구조체가 존재하지 않기때문에 이를 구분하기 위한 리소스 구분자도 없다.
또한 V$LOCK과 같은 통합뷰로도 볼 수 없다.
일반 락의 발생여부 및 경합 여부를 알수 있는 가장 좋은 방법은  V$SESSION_WAIT 뷰에서 대기현상이 발생하는지 관찰하는 것이다.

EX>

 buffer lock 경합이 발생하면 buffer busy waitsread by other session 이벤트에 대한 대기현상이 발생한다.
 row cache lock 경합이 발생하면 row cache lock 대기현상 발생.
 library cache lock/pin 경합이 발생하면 library cache lock/pin 대기현상 발생.

구분

 row type lock
 library cache lock
 library cache pin
 buffer lock




 LOCK 획득 매카니즘

                                                                  - (주)엑셈 practical OWI 15P 참조-
 
순서

 1. Process A가 shared 모드로 락(lock)획득 시도
 2. 해당 락을 점유한 프로세스가 존재하지 않으므로 Process A가 shared 모드로 락 획득하며
    Process A를 보유프로세스 목록(OWNER LIST)에 등록 한다.
 3. Process W가 exclusive 모드로 락 획득 시도
 4. Process A가 shared 모드로 락을 획득하고 있으므로 락 획득 실패하며 Process W는
    대기 프로세스 목록에(Waiter list)에 등록 한다.
 5. 보유 프로세스목록에 등록되어 있는 프로세스가 작업을 완료(commit, roll back등)하면
     대기프로세스 목록에 존재하는 다른 프로세스를 깨운다.
 6. 대기프로세스 목록에 등록된 프로세스는 타임아웃 시간이 경과 후에도 깨워주지 않으면 스스로 깨어나서
     데드락(dead lock)이 발생했는지 여부를 확인 후 다시 대기 상태로 빠진다.


타임 아웃

데드락을 피하기 위해 대기목록의 프로세스는 3초마다 깨어남
데드락 체크 후 다시 대기목록에 들어감
데드락이 확인 되면, 락 요청은 취소되고 현재 SQL문을 roll back 한다.


타임 아웃 시간

enqueue lock : 3초
buffer lock  : 일반 1초, 연속적으로는 3초
row cache lock : 60초
library cache lock / pin : 일반프로세스3초. PMON은 1초

(주)엑셈 practical OWI 15P를 참조













출처 : http://baind.tistory.com/entry/LOCK

'Database > Oracle' 카테고리의 다른 글

[펌] Lock 과 Latch 분류표  (0) 2012.03.18
[펌] Latch 란 무엇인가  (0) 2012.03.18
[펌] Cursor 란??  (0) 2012.03.18
[펌] Chunk 란?  (0) 2012.03.18
[펌] 라이브러리 캐쉬 구조  (0) 2012.03.18
Posted by 아로나
Database/Oracle2012. 3. 18. 10:20

 CURSOR 란?

 오라클에서 CURSOR란 시스템 글로벌 영역의 공유 풀 내에 저장공간을 사용하여 사용자가 SQL 문을 실행시키면 결과값을 저장공간에 가지고 있다가 원하는 시기에 순차적으로 fetch해 처리하여 해당 결과 셋을 프로그래밍적으로 접근할수 있게 도와주는 기능이다.

 이해를 돕기위해 아래의 명시적 커서 예문을 보자.
 하단의 선언문(DECLARE)에서 SELECT한 결과값을 실행문(BEGIN)에서 FETCH 하여 한 결과값을 순차적으로 처리할 수 있다. 뭐 이해가 안가도 그냥 보자.


열심히 그렸다. 참견 말자.


CURSOR는 묵시적커서(Implicit Cursor)와 명시적커서(Explicit Curosr)로 나뉜다.



묵시적 커서 (Implicit Cursor)

 묵시적 커서는 각 SQL문장의 실행 결과에 접근하여 그 결과값을 이용하기 위한 내부적 커서이다. 간단히 변수를 이용한다고 생각해도 좋겠다. 일반적으로 SELECT문, 혹은 다른 속성에서 값을 얻어와 변수에 저장하는데 사용된다.

예문)
SELECT name
          into v_name
 FROM members
 WHERE student_no = 13;
 v_count = SQL%ROWCOUNT;

상단의 예문의 빨간 부분은 모두 묵시적 커서가 사용된 문장이다. 예문 내에는 커서가 선언된 부분이 없지만 v_name변수로 해당 SELECT문의 결과값이 (당연히 저 SELECT문의 결과는 1개여야 한다. 그 이상일 경우 에라.) 저장된다. 또 하단의 SQL%ROWCOUNT의 값이 v_count변수에 할당된다. 물론 SELECT문에서 나온 행수는 1개이므로 v_count에는 1이 들어간다.


묵시적 커서에서는 위에 사용된 SQL%ROWCOUNT와 같이 4가지 속성을 제공한다.

SQL%ROWCOUNT : 최근 실행된 SQL문의 결과 행 갯수를 리턴
SQL%FOUND : 최근에 실행된 SQL문의 결과 행 존재 유무, 결과값이 있을때 TRUE를 리턴.
SQL%NOTFOUND : SQL%FOUND와 반대
SQL%ISOPEN : 최근에 실행된 SQL문의 묵시적 커서의 종료 유무





명시적 커서 (Explicit Cursor)

 명시적 커서는 처음의 맨 상단의 예제와 같이 일반적으로 어떠한 결과값을 글로벌 영역에 저장해놓고 순차적으로 값을 Fetch해 이용하기 위해 사용된다. 명시적 커서라고 불리우는 이유는 묵시적 커서와는 다르게 명시적으로 CURSOR라고 선언하고 사용하기 때문에 누가봐도 커서니깐. 그렇게 불린다. 머. 아님말고.

 명시적 커서는 간단히 아래와 같이 4단계로 나뉜다.

 CURSOR :  커서 선언
 OPEN : 커서 열기
 FETCH ~ INTO : 커서가 가리키는 곳의 결과 값을 엑세스
 CLOSE : 커서 닫기


 다시 한번 상단의 그림으로 한단계씩 살펴보자.



1) DECLARE 
    CURSOR cursor_name IS 
    sql_statement;
커서를 선언하고 커서 선언문 내에 선언된 sql_statment를 실행하여 해당 결과값을 시스템 글로벌영역에 결과 값을 저장한다.



2) BEGIN
    OPEN cursor_name;
해당 커서 내음의 작업을 위해 커서 영역을 오픈한다.
이때 선언문에서 선언한 sql_statement를 실행해 해당 결과값을 구성한뒤 커서는 해당 결과값의 첫번째 행에 커서를 위치 시킨다.


3) FETCH cursor_name INTO variable1, variable2, ...;

cursor_name의 커서를 순차적으로 FETCH한다. 이때 cursor_name의 SELECT 문에 있는 컬럼 갯수와 variables의 갯수가 값아야 한다. 그 순서대로 variables에 값이 할당된다.



4) CLOSE cursor_name;

현재 오픈되어 있는 커서를 닫는다.



상단의 예에서 보듯이 CURSOR는 루프 문이 아니다. JAVA에서의 VECTOR등의 같이 결과값을 하나씩 순차적으로 FETCH할때만 사용된다. 적절히 사용하기 위해서는 LOOP문과 같이 사용하면 된다.




이상으로 간단하게 오라클의 CURSOR에 대하여 알아보았다. 많이 쓰이는 예이니 다들 꼭 기억해 두길 바란다. 지영옹.

출처 : http://freeend.tistory.com/entry/CURSOR-%EB%9E%80

'Database > Oracle' 카테고리의 다른 글

[펌] Latch 란 무엇인가  (0) 2012.03.18
[펌] Lock 개요  (0) 2012.03.18
[펌] Chunk 란?  (0) 2012.03.18
[펌] 라이브러리 캐쉬 구조  (0) 2012.03.18
[펌] SQL 처리과정  (0) 2012.03.18
Posted by 아로나
Database/Oracle2012. 3. 18. 10:13

Chunk

특징

  1. extent에 할당되는 메모리 조각. 블록보다 큰 단위
  2. X$KSMSP : Shared pool 메모리에 할당된 chunk와 상태, 사용현황 확인
  3. KSMCHCOM 컬럼 : 메모리 할당 목적 확인
  4. 고유한 이름을 갖고 있으며 view로 내용 확인 가능
  5. Chunk 종류

문서정보

'Database > Oracle' 카테고리의 다른 글

[펌] Lock 개요  (0) 2012.03.18
[펌] Cursor 란??  (0) 2012.03.18
[펌] 라이브러리 캐쉬 구조  (0) 2012.03.18
[펌] SQL 처리과정  (0) 2012.03.18
[펌] SQL과 옵티마이저  (0) 2012.03.18
Posted by 아로나
Database/Oracle2012. 3. 18. 10:08

Library Cache

1. System Global Area 구성

  1. SGA(System Global Area)
    1. 디스크에서 읽어온 데이터를 저장하는 메모리 영역
    2. 저장된 데이터를 읽거나 변경 작업에서 사용되는 공용 메모리 영역
    3. SGA사용 목적 : 메모리 사용을 최소화하면서 처리성능 최대화


  2. Shared Pool - SQL, PL/SQL 수행에 필요한 정보 저장
    1. 목적 : 한번 처리된 SQL의 실행 정보를 공유함으로써 자원의 사용을 최소화하고 SQL 수행속도 증가
    2. Variable 영역 : Shared Pool + Java Pool + Large Pool + Streams Pool
    3. Permanent Area(시스템 영역, 고정영역)ㅍㄷㄱ냐ㅐㅜ
      • SGA 관리 메커니즘 및 오라클 파라미터 정보 저장
      • 자동 할당, 사용자 지정 No
      • SGA구성 요소 중 Fixed Size에 해당
    4. Library Cache
      • PL/SQL, SQL에 대한 분석 정보(Parse Tree) 및 실행계획 저장
    5. Dictionary Cache
      • 테이블, 인덱스, 뷰, 함수 및 트리거 등의 사용자, 구조, 권한 등의 dictionary data 정보 저장
      • Row Cache : 참조 데이터를 row 단위로 가짐
    6. Reserved Area(예약 영역)
      • 크기가 큰 객체 저장
      • 동적 메모리 할당 시에 메모리 조각 부족으로 인한 SQL실행 실패(ORA-4031) 방지하기 위한 공간
    7. Spare Free Memory
      • 단편화 최소화를 위해 일정 크기를 고정 영역에 숨겨둠
      • 메모리 할당이 꼭 필요한 경우 이 영역에서 할당 받음

2. Library Cache 구성

  1. 특징
    1. SQL문 수행과 관련된 모든 정보 저장
    2. LRU 알고리즘을 사용하여 관리(Database Buffer Cache와 공통점)
    3. shared pool latch : shared pool에서 특정 object 정보 혹은 SQL 커서를 위한 free chunk 할당 받을 때 필요
      • 9i 이전 : 하나의 shared pool latch로 전체 관리
      • 9i 이후 : shared pool을 여러 개의 sub pool로 나누어 관리할 수 있게되면서 latch도 7개까지 사용 가능
      • 동시 사용자가 순간적으로 과도한 하드파싱 부하를 일으킨다면 shared pool latch에 대한 경합 현상 발생 가능
  2. 목적 : library cache에 저장된 정보를 빠르게 찾고 저장
  3. Library Cache Object(LCO) : 라이브러리 캐시에 저장되는 정보의 단위
    1. Caching 정보 분류 I
      • Library Cache 안에서 공유되는 부분 : SQL 텍스트, Execution Plan, Bind Variable Data Type과 Length 등
      • 실행가능한 LCO : 실행가능
        • Package
        • Procedure
        • Function
        • Trigger
        • Anonymous PL/SQL Block (여기에 속하는게 맞는지?? @.@)
      • Object LCO : object 정보
        • Shared Cursor
        • Table Definition
        • View Definition
        • Form Definition
          schema object information

          1. data dictionary cache에도 저장됨(저장 포맷이 다름)
          2. library cache에도 저장하는 목적 : LCO간 의존성을 관리하기 위함

    2. Caching 정보 분류 II
      분류 특징 종류
      Stored Object 생성 후 drop 하기 전까지 데이터베이스에 영구적으로 보관되는 object
      생성될 때부터 이름을 갖음
      테이블, 인덱스, 클러스터, 뷰, 트리거, 패키지, 사용자 정의함수, 프로시저
      Transient Object 실행시점에 생성돼서 인스턴스가 떠있는 동안에만 존재하는 일시적인 object
      별도로 이름을 지정하지 않음
      문장을 구성하는 전체 문자열 그대로가 이름 역할함
      커서, anonymous PL/SQL
  4. 작동 방법
    1. Heap Manager와 Library Cache Manager가 관리
    2. Library Cache Manager는 Hashing 기법 이용해서 Object에 대한 이름을 갖는 Handle을 찾고, 이 Handle은 다시 해당 Object를 가리킴
      Handle(= Library cache Handel)

      1. Library cache object(LCO) 관리
      2. 실제 정보가 있는 LCO에 대한 메타정보 및 위치값 저장
      3. SQL : SQL 텍스트를 상수로 변환해서 bucket결정
      4. SQL 이외(table, view etc) : "user + object name + DB link"를 상수로 변환해서 bucket결정

    3. Library Cache Manager가 object 찾는 순서
      1. 필요한 Object의 Namespace, Object Name, Owner, Database Link 값에 Hash Function 적용
      2. 해당 Object가 존재하는 Hash Bucket 찾기 (SQL 문장의 경우 앞뒤 64바이트의 글자 이용)
      3. Hash Bucket의 Linked List를 따라 원하는 Object의 실제 존재 유무 체크
      4. Object 존재 : 찾은 Object를 사용
          Object 존재하지 않음 : Library Cache Manager는 주어진 이름으로 Empty Object 생성
      5. 생성된 Empty Object를 Hash Table에 포함시킴
      6. 오라클 프로세스에게 해당 Object를 로드하도록 요청
      7. 오라클 프로세스가 해당 Object를 디스크에서 읽어, Heap Manager에 의해 새로이 할당된 메모리에 올려놓음
      8. 해당 Object 사용
        Child LCO

         ⓐ SQL 커서 : 부모 LCO 밑에 schema 별로 자식 LCO소유. version count = 자식 LCO수
         ⓑ table, procedure etc : schema명과 함께 저장되므로 유일성이 보장되어 자식 LCO가 없음


    4. SQL 문 찾는 순서
      • Bucket 찾기 : SQL 문에 Hash Function 적용 후 SQL 문의 Handle이 있는 Bucket 찾아감
      • 공유 가능한 SQL 문 찾기 : 해당 Bucket 안에는 다른 SQL 문이면서 Hash Function 값만이 같은 여러 SQL들이 있을 수 있으므로 이 Bucket List를 따라가면서 공유 가능한 같은 SQL이 있는지를 확인
      • 같은 문장을 발견하였지만 서로 다른 Version 존재 가능성 있음
        Version

        SQL 문은 같지만 서로 다른 유저의 Object를 사용한 경우, Bind Variable Data Type이 다른 경우, 서로 다른 Application Info를 사용하는 경우 서로 다른 Version으로 존재하며, 이는 공유되지 않는다.

      • 같은 문장을 찾지 못한 경우는 SQL 문은 다시 Parsing 됨
  5. Shared Pool Latch & Library Cache Latch
    1. Library Cache Latch : 라이브러리 캐시 체인을 탐색하고 변경할 때 획득
    2. latch:library cache 대기 이벤트 : Library Cache Latch 경합 발생 시
    3. Library Cache Latch 개수도 몇 개(CPU 개수에 근접)에 불과하므로 하드 파싱 및 소프트파싱이 많이 발생해도 이 latch에 대한 경합 증가 함

  6. Library Cache Lock & Library Cache Pin
    1. 목적 : LCO 보호
    2. 순서 : handle Lock 획득 ⇒ Pin 획득 : LCO의 실제 내용이 담긴 heap에서 정보를 읽거나 변경 시
      • pin 획득 목적 : LCO를 읽고 쓰고, 실행하는 동안 다른 프로세스에 의해 정보가 변경되거나 캐시에서 밀려나는 것 방지
Shared Pool Latch & Library Cache Latch 경합 Library Cache Lock & Library Cache Pin 대기 이벤트
소프트/하드 파싱을 동시에 심하게 일으킬 때 발생 1. SQL 수행 도중 DDL 문 실행 시 발생
2. 트랜잭션이 활발 할 때 DDL문을 실행하면 데이터베이스 object 정의를 변경하면 라이브러리 캐시에 심한 부하 발생
3. Parsing 과정에서 경합 발생하면 각각 "latch: library cache"(soft), "latch: shared pool"(hard) 이벤트를 대기
4. Hard parsing : 새로운 커서를 생성해서 library cache chain 길이가 증가되어 검색 시간이 증가 되므로 성능 저하

3. 라이브러리 캐시 최적화를 위한 개발자의 노력

  1. 커서 공유 가능한 형태의 SQL 작성 : 바인드 변수 사용으로 하드파싱 감소
  2. 세션 커서 캐싱 기능 활용 : 라이브러리 캐시에서 SQL 찾는 비용 감소
  3. 에플리케이션 커서 캐싱 이용 : Parse Call 발생 감소

참고 문서

문서정보

'Database > Oracle' 카테고리의 다른 글

[펌] Cursor 란??  (0) 2012.03.18
[펌] Chunk 란?  (0) 2012.03.18
[펌] SQL 처리과정  (0) 2012.03.18
[펌] SQL과 옵티마이저  (0) 2012.03.18
Oralce의 HOLD_CURSOR, RELEASE_CURSOR  (0) 2012.03.17
Posted by 아로나
Database/Oracle2012. 3. 18. 10:05

SQL 처리 과정


Fig. SQL 처리 단계

【예제】 emp_new테이블에 24522건 삽입하기 : 첫 번째 parse call 에서 hard parsing 수행

SQL> insert into emp_new select * from patient where coh_no='019';

24522 rows created.

Elapsed: 00:00:01.34

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.08       0.16          1          1          0           0
Execute      1      0.76       1.03       3830       5174      11390       24522
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.85       1.19       3831       5175      11390       24522

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 62  (NEWNC01)

Rows     Execution Plan
-------  ---------------------------------------------------
      0  INSERT STATEMENT   MODE: ALL_ROWS
  24522   TABLE ACCESS   MODE: ANALYZED (FULL) OF 'PATIENT' (TABLE)

I. SQL Parsing

1. SQL Parser의 역할

  1. SQL 문 ⇒ SQL Parser : SQL 문장의 분석하고 parsing(tokenize)해서 parsing tree 생성
    • SQL 문장 분석 : SQL 문법 오류 확인
  2. semantic 확인 : 존재하지 않거나 권한 없는 object 사용 혹은 존재하지 않은 컬럼 참조 등 확인
  3. SQL cursor가 shared pool에 caching되어 있는지 여부 확인
    1. 해싱 알고리즘 사용
    2. parsing 요청한 사용자, optimizer 관련 파라미터 설정 등 확인 ⇒ 하나라도 다르면 새로운 SQL cursor 생성
    • shared pool에서 정확히 일치하는 SQL cursor를 찾은 경우 : 실행단계
    • shared pool에서 매칭되는 SQL문을 못 찾았거나 새로운 SQL cursor 생성 : SQL Optimization 단계

II. Optimization

1. Query Transformation(쿼리 변환기)

  1. 사용자가 던진 SQL문을 최적화하기 쉬운 형태로 변환 수행
  2. 쿼리 변환 전후 결과가 동일할 경우에만 수행

2. Plan Generator(실행계획 생성기)

  1. 후보군 실행계획 생성

3. Estimator(비용계산기)

  1. 실행계획 전체에 대한 총 비용 계산
  2. 비용 측정 기준 : 선택도(selectivity), cardinality, 비용(cost)
    1. 선택도(selectivity) : 처리할 집합에서 해당 조건이 만족되는 row가 차지하는 비율
    2. cardinality : 판정대상이 가진 결과건수 혹은 다음단계로 들어가는 중간결과건수
    3. 비용(cost) : 실행계획상의 연산을 수행할 때 소요되는 시간비용을 상대적으로 계산한 예측치
      예제

      query】select * from where empno='0001';
      전제】emp 테이블의 전체 row수는 200, 그 중에서 empno='0001'인 row수는 10건
      선택도】5%
      cardinality】10 rows

  3. 예상치
    1. 목적 : 각 단계를 수행하는데 필요한 I/O, CPU, 메모리 사용량 등을 예측
    2. object 통계정보, 하드웨적인 시스템 성능 통계정보(CPU 속도, Single blcok read time, multiblock read time 등) 이용
    3. object 혹은 시스템 통계정보는 오라클이 자동 수집 혹은 정책에 따라 주기적으로 수집됨
  4. 최적화 소요 시간 단축 전략
    1. Adaptive search strategy : 예상 쿼리 수행 시간과 쿼리 최적화에 소요되는 시간이 일정비율을 넘지 않도록 적응적 탐색 전략 사용
    2. Multiple Initial orderings heuristic : 조인 순서는 최적의 실행계획을 발견할 가능성이 높은 순서대로 비용 산정해서 평가

III. Row-Source Generation

  1. 역할 : 생성된 실행계획을 실행 가능한 코드 또는 프로시저 형태로 포맷팅하는 작업을 담당
  2. Row-Source : 사용자가 요구한 최종 결과집합을 실제적으로 생성하는데 사용되는 제어 구조

참고 문서

문서정보

출처 : http://www.gurubee.net/pages/viewpage.action?pageId=4948273

'Database > Oracle' 카테고리의 다른 글

[펌] Chunk 란?  (0) 2012.03.18
[펌] 라이브러리 캐쉬 구조  (0) 2012.03.18
[펌] SQL과 옵티마이저  (0) 2012.03.18
Oralce의 HOLD_CURSOR, RELEASE_CURSOR  (0) 2012.03.17
[펌]oracle precomiler의 hold_cursor, release_cursor  (0) 2012.03.17
Posted by 아로나
Database/Oracle2012. 3. 18. 10:04

Optimizer

왜 우리는 CBO의 작동원리를 알아야하는가?

optimizer가 아주 잘못된 실행계획을 생성하여 어떤 문제가 발생했을 때, 그 문제를 제대로 파악하고 올바른 해결책을 제시하기 위함이다!!
CBO의 근본동작을 교정하면 한 번의 조치로 문제가 발생하는 모든 경우를 해결 할 수 있다.
          -- Jonathan Lowis【Cost-Based Oracle Fundamentals】

왜 optimizer에 대해서 알아야 할까?
CBO 작동의 핵심 기능인 optimizer를 알아야 문제를 파악하고 해결책을 제시할 수 있다!!
          -- 내 생각~~^^*

What's the Optimizer?

  • 최소비용, 최적의 경로를 선택해서 사용자가 원하는 작업을 가장 효율적으로 수행할 수 있는 프로시저를 자동으로 생성해는 DBMS의 핵심 기능
  • 목표 : 가장 효율적인 Execution Plan을 찾아내는 일
  • 한계
    1. Computing power의 부족
    2. Optimizing algorithm의 한계
    3. 제한된 시간 내에 방법 결정
    4. User data에 대한 이해 부족
    5. 실행방법을 결정하는데 있어서 오판이 많음
  • 실행계획(Execution Plan) : 옵티마이저에 의해 생성된 처리절차를 사용자가 확인할 수 있도록 트리구조로 표현한 것
  • 사람이 SQL 실행 ⇒ 옵티마이저가 결과를 얻기 위해 실행계획 및 프로시저(프로그래밍) 생성 ⇒ 사용자가 원하는 결과
  • 예제


최적화 수행 단계

  1. 실행계획 후보군 선별
  2. 실행계획의 예상비용 산정 : data dictionary에 미리 수집해 놓은 object 통계 및 시스템 통계정보 이용
  3. 최소비용의 실행계획 선정

참고 문서

문서정보

출처 : http://www.gurubee.net/pages/viewpage.action?pageId=4948105

Posted by 아로나
Database/Oracle2012. 3. 17. 15:27



The HOLD_CURSOR and RELEASE_CURSOR Options



HOLD_CURSOR와 RELEASE_CURSOR가 무엇인지를 알아보려고 한다.
이 OPTION은 Precompile된 모든 program의 implicit, expplicit cursor 에
모두 영향을 준다. (pro*ada의 경우는 약간의 예외가 있다.)
What exactly do we mean by CURSOR? Unfortunately, we mean two differ-
ent things:
CURSOR에는 두 가지가 있다.

1. program cursor - SQL문으로 인해 생기는 data 구조.

program cursor는 procompiler에 의해 발견된 각 SQL문 마다 선언된다.
다음의 문장이 program 안에 있다고 하자.
EXEC SQL DECLARE SEL_EMP_CURS CURSOR FOR...
EXEC SQL INSERT...
그렇다면 c1과 c2의 두개의 program cursor가 선언될 것이다.

2. Oracle cursor ( context area 라고도 한다.) - 이 작업 공간은 실행 중에
생성이 된다. 이 공간은 parse된 문장과, host 변수의 주소값, 그 외에
SQL문을 실행하기 위해 필요한 정보를 가지고 있다.

이 두 개의 cursor는 cursor cache를 통해서 서로 연결되어 있다. 이 cursor
cache의 초기 크기는 MAXOPENCURSORS option에 의해 결정이 된다.
아래의 그림은 이러한 연관 관계를 설명한다.

CURSOR CACHE
-----------------
EXEC SQL INSERT... | Cache entry | Oracle
Program cursor P(1) <----> | C(1) | <----> cursor
-----------------
EXEC SQL UPDATE... | Cache entry | Oracle
Program cursor P(2) <----> | C(2) | <----> cursor
-----------------
. . .
. . .
-----------------
EXEC SQL DELETE... | Cache entry |
Pgm cursor P(MAXOPENCURSORS) |P(MAXOPENCURSORS)|
-----------------
EXEC SQL SELECT...
Pgm cursor P(MAXOPENCURSORS+1)

etc...

이러한 관점에서 HOLD_CURSOR와 RELEASE_CURSOR는 연관 관계는 다음과 같다.

HOLD_CURSOR option는 program cursor와 해당 cache와의 관계를 다룬다
반면, RELEASE_CURSOR는 Oracle cursor와 cache와의 관계를 다룬다.

만약 자주 재사용되는 SQL문이 보다 빠른 속도를 갖게 하기 위해서는 이 SQL문
과 예상되는 Oracle cursor가 붙어 있도록 하는 것이 좋다.
SQL문이 Oracle cursor와 붙어있다는 말은 SQL문과 해당 Oracle cursor 사이의
연결이 지속적으로 유지되고 있는것을 의미한다. 위에서 언급한 바와 같이
Oracle cursor(context area)에서는 parse된 문장이나 host변수의 주소값 등과
같이 중요한 정보가 들어 있게 되므로 SQL문장과 Oracle cursor(context area)
를 붙여두는 것이 유용하다.
이와 같이 문장과 chche를 붙여두기 위해서 HOLD_CURSOR와 RELEASE_CURSOR가
사용된다.

HOLD_CURSOR=YES option이 사용되면 cache들은 재사용이 가능하도록 flag을 표시
할 수 없도록 한다. 이것은 매우 중요한 의미를 가지는데, 만약 cache들이 사용이
되어지고 새로운 SQL문마다 각기 새로운 cache들이 할당이 된다면, MAXOPENCURSORS
에 의해 결정된 수만큼의 cache가 할당된 후에 추가의 cache는 재사용이 가능하도
flag가 표시 된 cache를 사용하기 때문이다.
위의 그림을 참조로 예를 들면 다음과 같다. C(1) cache가 재사용이 사능하도록
표시가 되어있고 EXEC SQL SELECT 문이 실행이 된다고 가정을 할 경우,
program cursor P(MAXOPENCURSORS+1)가 생성되고 이것은 cache와 Oracle cursor가
필요하다. 그러나 이때 MAXOPENCURSORS에 의해 결정된 값만큼의 숫자의 cache가
이미 사용되어졌다면, 이 문장은 C(1)의 cache와 거기에 해당하는 Oracle cursor를
할당받는다. 그리고 이 cache과 Oracle cursor는 비워지고 새로운 SQL문으로 다시
parse가 되어진다.
위의 option과 함께 사용되는 것이 RELEASE_CURSOR=NO이다. 이것은 cache들과
Oracle cursor사이의 관계를 규정한다. 이 option은 parse된 문장이 실행하고 난후의
상태를 관리한다. 이때 할당된 memory는 사용가능한 상태로 유지 되어진다.

이 memory를 풀어주기 위해서는 RELEASE_CURSOR=YES를 사용한다. 이 option을 사용
하면 이 cache에 연결되어 있는 다음 문장들은 추가적으로 parse를 다시 해야하는 부
담이 있다.

Program cursor - - - - - [ Cursor cache entry ] - - - - - Oracle
for SQL statement cursor
^ ^
HOLD_CURSOR=YES RELEASE_CURSOR=NO
program cursor is permanently cache entry maintains the
linked to its cache entry. address of its context area.

HOLD_CURSOR와 MAXOPENCURSORS는 밀접한 관계를 가진다.
만약 모든 cursor cache들이 현재 "재사용 불가"로
표시되어있다면 ( 이런 경우는 explicit하게 열린 cursor가 close되지
않은 상태로 fetch를 진행하는 경우와 같이 cursor cache를 사용하는 모든
문장이 실행중인 경우와 HOLD_CURSOR option을 사용한 경우등이 있다.),
새로운 cursor를 위해서는 실행중에 cursor cache를 확장해야 한다. (즉,
MAXOPENCURSORS가 10이라면, 11번째의 cursor cache를 생성한다.) 이때 11
번째 생성된 cache는 cursor가 close되어도 제거되지 않는다. MAXOPENCURSOR를
작게 잡는 것은 memory를 절약 할수있으나 cache가 추가될때는 비용이 많
이든다. 반면, 높게 잡을 경우는 추가 비용에 대한 부담이 줄어드는 많큼
필요이상의 memory를 사용하게 된다. 그리고 무조건 가장 오래된 cache를
재사용하도록 허용하는 것이 옳바른 것은 아니다. 만약 10개의 explicit
cursor를 선언해서 open한 user가 11번째의 cursor를 사용하기 위하여 가장
오래된 program cursor를 재사용하게 된다면 user는 첫번째 cursor에 대한
위치를 잃어버리게 되어 이 곳에서 fetch를 수행할 수 없게 된다.

만약 program 안에서 문장의 재사용이 일어나지 않을 경우는 HOLD_CURSOR=NO,
RELEASE_CURSOR=YES를 사용한다. HOLD_CURSOR=NO 는 cache들이 필요에 따라
자동적으로 "재사용"으로 표시되게 한고, RELEASE_CURSOR=YES는 Oracle cursor
가 자동적으로 해제되고 parse된 문장을 잃어 버리게 한다. site의 memory에 대한
문제로 인해 Oracle cursor들의 숫자가 제한을 받을 경우는 이 option을 사용
해야 한다.

이 때 만약 RELEASE_CURSOR=YES를 사용하게되면 자동적으로 HOLD_CURSOR=YES는
사용할수 없게 된다. RELEASE_CURSOR=YES가 Oracle cursor와 cache사이의 연결
을 끊어 버리고 Oracle cursor를 해제 시켜 버린다. 그러므로 심지어 program
cursor가 cache와 HOLD_CURSOR=YES에 의해 연결되어 있어도 memory를 다시
할당하고 다시 parse를 해야 한다.그러므로 RELEASE_CURSOR=YES를 주면
HOLD_CURSOR=YES를 준 이점이 하나도 없다.


출처 : https://kr.forums.oracle.com/forums/thread.jspa?threadID=468597
Posted by 아로나
Database/Oracle2012. 3. 17. 15:25
Posted by 아로나