h3.1) 라이브러리 캐시 Lock
h5.예제)라이브러리 캐쉬 Lock 설정
(s1)
create table t ( id number, name char (10) );
테이블이 생성되었습니다.
insert INTO t
select rownum, lpad (rownum, 10, '0' ) from dual
connect by level <= 1000000;
1000000 개의 행이 만들어졌습니다.
alter table t modify name char (24);
(s2) s1 ING....
select sid from v$mystat where rownum = 1;
SID
----------
19712
select count(*) from t;
(s3)
SELECT * FROM v$session_wait WHERE sid=19712;
SID SEQ# EVENT WAIT_CLASS_ID WAIT_CLASS# WAIT_CLASS WAIT_TIME SECONDS_IN_WAIT STATE
---------- ---------- -------------------------------- ----------- ---------------------- --------------- -----------
19712 166 library cache lock 3875070507 4 Concurrency 0 33 WAITING
h5.라이브러리 캐시 Lock : NULL 모드
Lock을장시간유지하려 할때 사용하며, 커서, 프로시저, 함수, 패키지처럼 실행 가능한 오브젝트에는 Lock을 Null 모드로 설정할 수 있다.
특히, 커서는 항상 Null 모드만을 사용된다.
'라이브러리 캐시 Lock' 을 Breakable Parse Lock' 이라고 언급하고 있는데 이는 NULL 모드의 Parse 1ρck은 대기없이 언제든 해제 될수 있기 때문에 붙여진 이름이다.
h3.특징
예제)
SQL> create table emp_t as select * from emp;
테이블이 생성되었습니다.
SQL> create table dept_t as select * from dept
SQL> /
테이블이 생성되었습니다.
SQL> alter system flush shared_pool
SQL> /
시스템이 변경되었습니다.
SQL> select * from emp_t e, dept_t d where d.deptno = e.deptno
SQL> /
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO DEPTNO DNAME LOC
---------- ---------- --------- ---------- -------- ---------- ---------- ---------- ---------- -------------- -------------
7499 ALLEN SALESMAN 7698 81/02/20 1600 300 30 30 SALES CHICAGO
7521 WARD SALESMAN 7698 81/02/22 1250 500 30 30 SALES CHICAGO
7566 JONES MANAGER 7839 81/04/02 2975 20 20 RESEARCH DALLAS
- 생략 -
7934 MILLER CLERK 7782 82/01/23 1300 10 10 ACCOUNTING NEW YORK
13 개의 행이 선택되었습니다.
SQL> select count(*) from emp_t e
SQL> /
COUNT(*)
----------
14
SQL> select INVALIDATIONS from v$sql where SQL_TEXT like 'select * from emp_t e, dept_t d where d.deptno = e.deptno%'
SQL> /
INVALIDATIONS
-------------
0
SQL> select INVALIDATIONS from v$sql where SQL_TEXT like 'select count(*) from emp_t e%'
SQL> /
INVALIDATIONS
-------------
0
SQL> alter table emp_t modify EMPNO number(5);
테이블이 변경되었습니다.
SQL> select INVALIDATIONS from v$sql where SQL_TEXT like 'select * from emp_t e, dept_t d where d.deptno = e.deptno%'
SQL> /
INVALIDATIONS
-------------
1
SQL> select INVALIDATIONS from v$sql where SQL_TEXT like 'select count(*) from emp_t e%'
SQL> /
INVALIDATIONS
-------------
1
라이브러 리 캐시 Pin은 LCO의 실제 내용이 담긴 힙 을 보호한다.
h3.Pin획득
라이브러리 캐시 Miss가 발생하는 경우에 나타나는 현상
경우 1)
- Misses in library cache during parse : 0
- Misses in library cache during execute : 1
_parse에서는 라이브러리 캐시 Miss가 0 인데 Execute에서는 1로 나타나고 있다._
현상 : Parse 단계에서 커서 LCO 핸들을 찾았는데 실행 시점에 커서를 오픈하려고 LCO 힙을 확인해 보니
캐시에서 밀려나고 없어 실행단계에서 하드파싱을 하는 현상
이유 : LCO 힙을 영구적으로 Pin 해 둘 수는 없으므로 언제든 이런 현상을 만날 수 있다.
LCO는 LRU 알고리즘과 같은 관리구조를 가지기 때문에
경우 2)
- Misses in library cache during parse : 1
- Misses in library cache during execute : 1
_파싱과 실행 단계 모두에서 라이브러 리 캐시 Miss가 발생하고 있다._
현상 : 실행계획이 내부적으로는 커서 LCO 힙과는 별도의 힙 영역에 저장되기 때문에 생기는 현상(필자의 생각)
이유 : 새로운 SQL문이 수행이 되면서 SQL 커서를 찾지 못해 하드파싱이 되어 실행계획을 만들고 보니 라이브러리 캐쉬 영역에 동일한
실행계획을 가진 LCO를 확인하고 LCO에 해당 실행계획에 대한 포인터만 입력하고 공유되어 있는 LCO 힙을 들여다 보니 힙의 내용이
캐시에서 밀려나고 없어 실행단계에서 다시 하드파싱을 하는 현상
*이러한 현상이 자주 일어난다면 메모리크리가 작거나 잦은 하드 파싱으로 인해 커서 힙영역이 캐시에서 밀려나는 일이 자주 발생하는 경우를 의미함*
h3.3) 라이브러리 캐시 냐ck과 Pin , 두 개의 직렬화 장치를 따로 두는 이유
상황 시나리오
1. dept 테이블에 변경작업이 수행중
2. get_dname 함수에 설정된 Parse Lock 해제
3. dependency 체인을 따라 select문 커서에 대한 Parse Lock까지 해제
4. get_dname 함수를 Pin하고 있는 프로세스가 없으므로 이후에 이 함수를 컴파일하려는 세션은 이상없이 작업이 수행된다.
상황 시나리오
1. cursor의 select문이 수행중
2. select문이 수행중으로 인해 shared모드로 해당 select 문과 function의 힙에 Pin이 잡혀있음
3. dept 테이블에 변경작업이 수행
4. select 문과 Function의 핸들에 걸린 락이 해제(라이브러리 캐시 lock:null모드이기 때문에 대기없이 바로 해제됨)
5. 다른세션에서 펑션 컴파일 수행(Exclucive모드)
6. 핸들에 걸린 Parse Lock는 해제가 되었으나 cursor의 select문이 수행중으로 Function과 select문에 Shared 모드로 Pin이
설정되어 있기때문에 library cache pin 대기 이벤트 발생
수행예제
*S1)*
SQL> create or replace function test_pin( v_loop in number )
2 return number
3 is
4 v_deptno number;
5 begin
6 select deptno into v_deptno from dept where deptno = 10;
7 for count in 1..v_loop
8 loop
9 dbms_lock.sleep(10);
10 end loop;
11 return v_deptno;
12 end;
13 /
함수가 생성되었습니다.
SQL> select test_pin(10) from dual - S1에서 함수를 수행
SQL> /
*S2)*
SQL> select sid from v$mystat where rownum = 1
SQL> /
SID
----------
19712
SQL> alter table dept modify deptno number(3) <= 1번 세션에서 함수 ing...
SQL> /
테이블이 변경되었습니다.
SQL> alter function test_pin compile <= 1번 세션에서 함수 ing...
SQL> /
*S3)*
2번 세션에서 alter function test_pin compile 구문 실행 후 수행.
SQL> select event
2 ,wait_time
3 ,seconds_in_wait
4 ,state
5 from v$session_wait where sid = '19712'
SQL> /
EVENT WAIT_TIME SECONDS_IN_WAIT STATE
------------------------ --------------- ----------------- ---------
library cache pin 0 16 WAITING