3. Library Cache 구조


1) Library cache 개요

  • 위치 : Shared Pool 내부
  • 용도 : SQL 커서, DB Object 등에 대한 정보 관리(컴파일된 함수, 프로시져, 패키지 등등)
    --> Library cache 안의 위 정보들을 LCO(Library Cache Object) 라고 지칭
  • 분류1 : 실행 가능 LCO - 오브젝트 LCO
  • 분류2 : 영구 보관되는 LCO와 인스턴스 떠 있는 동안만 존재하는 임시 LCO 로도 구분 가능(커서 등)
  • 옵젝트 정보가 딕셔너리 캐시에도 있는데 LC 에도 있는 이유는 의존성(Dependency) 관리 때문
    --> LCO 각각은 자신을 참조하는 다른 실행가능 LCO 목록을 가진다








2) Library cache 특성

  • 쉐어드 풀 안의 할당된 공간 사용, LRU 알고리즘으로 관리 됨
  • 버퍼 캐시처럼 해시 구조로 관리
  • 해시 버킷에 LCO 핸들이 체인 구조로 연결되며, 각 핸들이 힙 메모리 안의 실제 옵젝트를 지정
  • 힙 메모리 안의 커서 Object 에는 딸려 있는 차일드 커서 정보 가지고 있음



Library cache 관리를 위한 보호 메커니즘
  • Shared pool latch: 쉐어드 풀 안의 프리청크 할당받을 때 필요한 래치
    7개의 래치가 여러개의 서브 풀을 관리한다
  • Library cache latch: 라이브러리 캐시 체인탐색 및 변경을 위해 필요한 래치
  • Library cache lock: 해시 체인의 LCO 핸들 각각에 거는 락, 이 락을 걸어야 실제 힙 메모리에 접근 가능
  • Library cache pin: 힙 안의 실제 LCO 를 읽거나 변경할 때 이용
    타 세션에 의한 변경이나 캐싱에서 밀려나는것 방지
Shared pool latch/Library cache latch 경합은 는 하드/소프트 파스 경합에 의해
Library cache lock/Library cache pin 경합은 SQL 수행 도중 DDL 동시 수행 시 발생






3) 결론은...


  • 커서 공유가 가능하 형태로 SQL 작성 할 것
  • 세션 커서 캐싱 기능 이용해 LC 에서 SQL 찾는 비용 줄일 수 있음
  • 어플리케이셔 커서 캐싱 이용해 Parse Call 발생량을 줄일 수 있음









부록

Library cache lock/pin

Library cache Lock

  • 역할: LCO 핸들을 보호
  • LC Lock의 세 가지 모드
    Shared : 읽기 작업 시 획득
    Exclusive : LCO 생성/변경 시 획득
    Null : Object 간 의존성 관리에 사용, Lock 을 장시간 유지 가능함










Null Mode Lock?
  • Parse Lock 이라고도 함
  • 실행 가능 LCO 에 대해서만 설정 가능
  • 대기 없이 바로 해제할 수 있다
  • 실행 가능 LCO 는 참조하는 각 LCO 에 대해 Null mode 의 락을 걸고 있으며
    Schema Object 변경 시 참조하는 LCO 에 설정 된 Lock 을 해제 함으로써 Invalidation 되었다고 알려주는 역할
  • SQL, PL/SQL 이 처음 수행되며 파싱 되는 시점에 걸리고
    Shared SQL area 가 Shared pool 에 남아 있는 한 계속 유지 됨

Library cache Pin

  • 역할: LCO 핸들이 아닌 실제 힙 영역을 보호함
    핀을 획득해야 읽기, 실행, 변경 가능함(정보를 새로 가져올 때도 Pin 획득 필요)
  • LC Pin 의 두 가지 모드
    Shared : 힙 영역의 읽기 작업 시 획득
    Execlusicve : 힙 경역의 변경, 신규 생성 시 획득(Shared 모드 잠깐 획들 했다가 Execlusive 모드로 변경 한다고 함)
  • Pin은 힙 영역에서 관리 하지만 Pin 소유자/대기자 목록은 핸들 쪽에서 관리






SQL> alter session set events '10046 trace name context forever, level 12';

Session altered.

SQL> var v1 number;
SQL> begin :v1 := 1983; end;
  2  /

PL/SQL procedure successfully completed.

SQL> select b from pin_test where b = :v1;

         B
----------
      1983
      1983

SQL> begin :v1 := 1984 ; end;
  2  /

PL/SQL procedure successfully completed.

SQL> select b from pin_test where b = :v1;

         B
----------
      1984
      1984

SQL> begin :v1 := 1985 ; end;
  2  /

PL/SQL procedure successfully completed.

SQL> select b from pin_test where b = :v1;

         B
----------
      1985
      1985

SQL> exit

[TEST10]/lim/admin/TEST10/udump> tkprof test10_ora_13844.trc
output = lc_test.txt

TKPROF: Release 10.2.0.4.0 - Production on Sat May 12 02:12:27 2012

Copyright (c) 1982, 2007, Oracle.  All rights reserved.


[TEST10]/lim/admin/TEST10/udump> vi lc_test.txt

********************************************************************************

select b
from
 pin_test where b = :v1


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        3      0.00       0.00          0          0          0           0
Execute      3      0.00       0.00          0          1          0           0
Fetch        6      0.41       0.40        838      24990          0           6
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       12      0.41       0.40        838      24991          0           6

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 58

Rows     Row Source Operation
-------  ---------------------------------------------------
      2  TABLE ACCESS FULL PIN_TEST (cr=8330 pr=191 pw=0 time=33841 us)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       6        0.00          0.00
  db file sequential read                       207        0.00          0.00
  db file scattered read                        189        0.00          0.00
  SQL*Net message from client                     5       13.59         25.13
********************************************************************************





LCO 핸들과 힙 영역의 구분으로 인해 발생 가능한 예외 상황 1
  • LCO 핸들을 해시 버킷에서 존재하지만 실제 Pointer 가 가르키는 힙 영역에는 내용이 없는 경우
    --> 힙 영역은 LRU 알고리즘에 의해 관리되어 정보가 밀려날 수 있음
    --> LCO 핸들에 대해 Lock 획득은 성공, 실행 단계에서 LC Pin 획득 후 새로 캐싱
  • 위와 같은 상황이 발생하고 Execution 단계에서의 블록 읽기가 과도한 경우는
    메모리 사이즈가 작거나 잦은 하드 파싱으로 인해 힙 영역에서 LC Object 가 자주 밀려나는 경우
LCO 핸들과 힙 영역의 구분으로 인해 발생 가능한 예외 상황 2
  • Parse 단계에서 LCO 핸들에 대한 조회 실패/Execute 단계에서 SQL 힙 영역의 Object 조회 실패 동시 발생
  • Parse 단계에서 LCO 핸들 조회 실패 시 핸들/힙 정보를 새로 캐싱하므로 일반적인 상황에서는 발생하지 않음
서로 다른 SQL 커서 LCO 간 '실행계획' 의 공유로 인해 발생하는 현상
  • SQL 커서와 SQL 실행 계획은 Library cache 에서 별도로 관리 됨
  • 첫 하드 파싱 때 SQL 커서를 새로 캐싱 하였으나 기존에 존재하는 실행계획의 재 사용이 가능하여
    실행 계획 LCO 핸들에 대해 Pointer 를 연결 하였으나 힙 영역 안의 실행 계획은 밀려나고 없을 경우 (예외 1번 상황)







Lock 과 pin 을 별도로 사용하는 이유?

Handle 은 Fixed 영역이나 Heap 은 동적으로 관리되므로 밀려날 가능성 존재

의존 관계에 있는 Object 들 간에 동시성 보장 가능

  • SQL이나 PL/SQL 실행 시 참조하는 오브젝트의 의존성 정보는 LCO 핸들의 Parse Lock 으로 관리
  • SQL이나 PL/SQL 실행 시 참조하는 오브젝트의 읽기(혹은 실행)는 힙 영역에 Pin 으로 관리
  • Pin걸고 사용중인 LCO 간에도 Parse Lock 해제는 자유롭게 가능하다
    --> SQL 실행 중에도 참조하는 오브젝트에 대한 DDL 이 가능




create table pin_test (b number);

begin
for i in 1 .. 1500000 loop
insert into pin_test (b) values ( i);
end loop;
commit;
end;

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

*[Session 1]*

create or replace function pin_test_f
return number
is
v_rslt number ;
begin
select sum((q.b + t.b)/(q.b*t.b) + (q.b*t.b)/(q.b/t.b)) into v_rslt from
(select b from pin_test) q,
(select b from pin_test) t
where q.b=t.b+1;
return v_rslt;
end;
/

SQL> select pin_test_f from dual;

PIN_TEST_F
----------
1.1250E+18

SQL>




*[Session 2]*

SQL> alter table pin_test add (d number(5));

Table altered.

SQL> alter table pin_test modify b number(10);

Table altered.

SQL>