공유 풀 (Shared Pool)

  • SQL수행 관련 정보, SGA관리 아키텍쳐, DB설정 정보 저장
  • 정적영역
    • 오라클 파라미터 설정 값, 워킹셋, 자원테이블, SGA관리 아키텍쳐 및 기타정보 저장
    • 사용자 정의불가. 고정된 크기로 자동설정됨.
  • 동적영역
    • 라이브러리 캐시, 딕셔너리(로우) 캐시 영역으로 구성
    • SHARED_POOL_SIZE 파라미터값으로 설정
    • SGA 자동관리(ASMM) 기능 사용 시,
      SGA_TARGET 값 이내의 범위에서 MMAN 프로세스에 의해 동적으로 사이즈 변경됨
    • OS 메모리의 heap 영역으로 구성되어있음
      {note}
      heap영역 : 헤더와 하나이상의 메모리 익스텐트들로 구성
  • 메모리 익스텐트들은 지속적으로 할당, 반납되면서 작은 조각(청크,chunk)으로 나눠진다.
    이런 현상을 공유풀 공간의 단편화(fregmentation)라 한다.
  • 청크(chunk)는 free list 에 의해 관리된다.
  • 청크 재사용률을 높이기 위해 한 번 사용된 청크는 다시 free list 에 등록되기 전까지
    공유 풀 LRU 리스트에 의해 관리
    {note}
  • 공유 풀에 메모리 할당 과정
    (신규 SQL 파싱 시 256 byte공간이 필요하다고 가정)
  1. 메모리 공간 할당을 위해, shared pool latch를 획득하고 free list 에서 256 byte free chunk를 찾는다.
  2. latch 획득 후 free list에서 256 byte의 free chunk 존재 시 해당 chunk를 익스텐트에 할당
    1. latch 획득하지 못하면 latch: shared pool 대기 이벤트를 발생시키며 대기
    2. 필요한 chunk보다 큰 사이즈의 chunk를 획득할 경우, 필요한 사이즈를 쪼갠 후 나머지는 free list에 등록된다
  3. free list에서 free chunk 가 없다면
    1. 공유 풀의 LRU 리스트에서 재사용가능한 chunk를 찾아 free list로 등록 후 메모리 할당한다.
    2. 없으면 ORA-4031 unable to allocate %s bytes of shared memory 에러 발생, 파싱 실패
라이브러리 캐시
  • 공유 커서, 파스 트리, 실행 계획 및 테이블, 시퀀스 등 DB오브젝트 정보 저장 및 관리
  • 공유 커서 : 메모리 영역에 저장되어 있는 SQL, PL/SQL 정보를 찾기위한 가상의 주소
  • SQL과 관련된 정보를 저장하므로 성능 관점에서 가장 중요한 부분
  • 라이브러리 캐시 구성요소

  1. 힙 오브젝트(Heap Object)
    1. 공유 커서 및 DB오브젝트 정보 저장
    2. 최종적으로 SQL 수행에 필요한 정보를 저장
    3. 저장 정보 종류에 따라 0~11번 번호를 가짐
    4. 0번 Heap은 Heap object 에 저장된 공유 커서, DB오브젝트의 기본정보 및 1~11번 힙 메모리 주소 값 저장
  2. 오브젝트 핸들(Object Handle)
    1. Heap object관리
    2. 공유 커서 문장, DB오브젝트 이름, 네임스페이스 정보, 락/핀 관련 정보, 오브젝트 핸들 상태 저장하는 플래그, 0번 힙 오브젝트 저장
    3. 인스턴스 시작 시 생성된 오브젝트 핸들은 인스턴스 종료 시까지 라이브러리 캐시에 남아있다
    4. 네임스페이스 (힙 오브젝트에 저장된 데이터 종류)
      • BODY/TYBD - 프로시저, 함수, 매키지, 타입 바디
      • CLST- 클러스터
      • CRSR 공유커서(SQL문장)
      • INDX 인댁스
      • TABL/TYPE- 테이블, 뷰, 시뭔스, 동의어
      • TRGR- 트리거
  3. 해시 버킷(Hash Bucket)
    1. 오브젝트 핸들 관리
    2. 라이브버리 캐시 매니저로 공유 커서 및 DB오브젝트 이름에 해시 알고리즘 적용
    3. 하나의 해시 버킷은 하나 이상의 오브젝트 핸들을 관리한다
  • 라이브러리 캐시 영역의 각 구조는 동시 세션 및 동시요청에 의해 정보 공유
    => 동시성 제어와 일관성 유지를 위해 락/핀 알고리즘 을 사용한다.
로우/딕셔너리 캐시
  • 데이터 딕셔너리를 저장하는 영역은 Dictionary cache라 불리고, 저장 영역이 row 단위로 저장되기 때문에 Row cache라 불린다.
  • SQL 파스 단계에서 라이브러리 캐시와 함께 반드시 액세스가 필요

  • Row cache도 해시 버킷 구조에 의해 관리된다.
  • SQL 파스 단계에서 딕셔너리 정보 획득하기 위해 참조
  • Row cache에 필요한 데이터 없는 경우, 딕셔너리 테이블에 저장된 데이터를 Row cache로 복사,
  • Row Cache Object (RCO) 를 생성한다.
  • shared pool 내 딕셔너리 캐시가 차지하는 공간 확인

공유 커서
  • Shared Cursor는 여러 사용자에 의해 공유되어 사용되는 SQL, PL/SQL문을 의미
  • Cursor공유 시, 새로운 오브젝트 핸들, 힙 오브젝트 생성 과정이 생략되어 수행속도 향상 및 메모리 단편화 방지

SQL 처리단계

  1. 구문분석 - SQL문 해석 및 실행계획 생성
    1. 라이브러리 캐시 검색 -> 구문 오류 확인 -> 참조 오브젝트 확인 -> 권한 확인 -> 쿼리 변환 -> 실행 계획 생성
  2. 바인드 - 조건절에 사용된 바인드 변수를 주어진 상수 값으로 치환
  3. 실행 - 구문분석 단계에서 생성된 실행계획에 따라 SQL문 실행
  4. 패치 - 실행에서 추출된 결과 반환

_OPTIM_PEEK_USER_BINDS
: 처음 수행되는 바인드 변수 값을 참조하여 실행 계획을 생성할 수 있는 히든파라미터로,
Default 값이 TRUE 이며, FALSE 값일 경우 바인드 변수 값을 참조하지 않고 실행계획을 생성
10g 에서는 FALSE로 변경 후 평균적인 통계 정보를 통해 실행계획을 생성하는 것을 권장.

  • 라이브러리 캐시의 부모커서, 자식커서가 모두 공유되어야 완전한 커서 공유가 가능함.
    1. 부모 커서 : 수행된 SQL문 저장
    2. 자식 커서 : 수행된 SQL문의 실행계획 저장
  • 부모커서, 자식커서 공유 예제

< 1. 부모커서, 자식커서를 모두 공유하는 경우 >

  • 바인드 변수를 사용한 SQL의 경우 변수 값이 달라지더라도, 동일한 SQL로 인식하므로 부모커서, 자식커서를 모두 공유한다.
  • SQL은 ASCII값으로 변환되어 인식되므로, 대소문자, 공백이 모두 동일하게 수행되어야 한다.

< 2. 부모커서는 공유, 자식 커서를 공유하지 못하는 경우 >

  • 수행한 SQL은 동일하므로 부모 커서 공유
  • SQL이 각 사용자가 소유한 테이블을 호출하여 각각 소유의 테이블에 대한 실행계획을 갖는 자식커서 공유
  • V$SQL에서 커서 공유 여부 확인이 가능하다.

  • 바인드 변수를 사용하지 않는 리터럴(Literal) SQL의 경우 커서를 공유하지 않는다
  • 잦은 파싱으로 성능상 영향이 있으므로, 바인드 변수를 사용하도록 변경한다.

데이터 분포와 SQL용도에 따라 바인드 변수 사용 여부를 결정해야 한다.

  • OLTP 시스템에서 사용 빈도가 높은 SQL
    • 하드 파스로 인한 성능이슈가 있으므로, 바인드 변수를 사용
  • 편중된 데이터를 조회하는 SQL, DW시스템과 같이 SQL사용 빈도가 높지 않은 시스템일 경우
    • 리터럴SQL사용, 통계정보 갱신
예약 풀
  • 기본 값으로 4,400 byte가 넘는 SQL은 shared pool 내 예약풀(Reserved Pool)에 저장
  • 4,400 byte 이하로 단편화 되지 않으므로 ORA-4031에러 발생 빈도가 적다.
  • SHARED_POOL_RESERVED_SIZE 파라미터로 설정 ( SHARED_POOL_SIZE 설정된 풀에서 메모리를 할당받음 )
  • 예약 풀 기본크기는 shared pool 크기의 5% , 50%이상은 초과 불가
  • SQL 사이즈 임계값은 _SHARED_POOL_RESERVED_MIN_ALLOC 값으로 변경 가능
  • 예약풀 크기 확인은 V$SHARED_POOL_RESERVED 뷰 조회

  • REQUEST_MISSES 값이 0이면 충분함. 해당 값이 증가 시 예약 풀 크기가 부족하므로 더 크게 변경해야 함.
대기 이벤트
  • shared pool 에서 발생 가능한 대표적인 대기이벤트(wait event)

  • 공유 풀의 성능 향상을 위해서는 리터럴SQL에 의한 하드파스를 없애는 것!