h1.(1)라이브러리 캐시 LOCK & Pin : 라이브러리 캐시 오브젝트(테이블, 인데스, 뷰, 트리거, 함수/프로시저, 패키지)에 대한 핸들을 보호할 목적
Lock 모드 | Null | Shared | Exclusive |
---|---|---|---|
Null | O | O | O |
Shared | O | O | X |
Exclusive | O | X | X |
1번 세션
SQL> create table t( id number, name char(10))
SQL> /
테이블이 생성되었습니다.
SQL> insert into t
select rownum, lpad( rownum, 10, '0' ) from dual
connect by level <= 1000000
SQL> /
1000000 개의 행이 만들어졌습니다.
SQL> alter table t modify name char(20)
SQL> /
테이블이 변경되었습니다.
exclusive lock mode
2번 세션
SQL> select sid from v$mystat where rownum = 1;
SID
----------
161
SQL> select count(*) from t <= 1번 세션에서 alter table t modify name char(20) 실행 후
SQL> /
COUNT(*)
----------
1000000
shared lock mode
3번 세션
2번 세션 실행 후 대기 상태 확인 후 실행
SQL> select event
2 ,wait_time
3 ,seconds_in_wait
4 ,state
5 from v$session_wait where sid = '161';
EVENT WAIT_TIME SECONDS_IN_WAIT STATE
-------------------- ---------- --------------- -------------------
library cache lock 0 63 WAITING
Exclusive와 Shared모드는 서로 호환이 되지 않아 결국 두 번째 세션은 라이브러리 캐시 lock을 대기 한다.
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
h1.(2)라이브러리 캐시 Pin :
SQL> select e.ename, d.dname from emp e, dept d where d.deptno = e.deptno
2 /
ENAME DNAME
---------- --------------
CLARK ACCOUNTING
-생 략 -
WARD SALES
13 개의 행이 선택되었습니다.
SQL> select e.ename, d.dname, d.loc from emp e, dept d where d.deptno = e.deptno
SQL> /
ENAME DNAME LOC
---------- -------------- -------------
CLARK ACCOUNTING NEW YORK
-생략-
WARD SALES CHICAGO
13 개의 행이 선택되었습니다.
SQL> SELECT HASH_VALUE, ADDRESS ,PLAN_HASH_VALUE
2 FROM V$SQL
3 WHERE SQL_TEXT LIKE 'select e.ename, d.dname from emp e, dept d where d.deptno = e.deptno%'
SQL> /
HASH_VALUE ADDRESS PLAN_HASH_VALUE
---------- -------- ---------------
2776686202 690E4470 3191017203
SQL> SELECT HASH_VALUE, ADDRESS ,PLAN_HASH_VALUE
2 FROM V$SQL
3 WHERE SQL_TEXT LIKE 'select e.ename, d.dname, d.loc from emp e, dept d where d.deptno = e.deptno%'
SQL> /
HASH_VALUE ADDRESS PLAN_HASH_VALUE
---------- -------- ---------------
2946835987 68E47DE8 3191017203
SQL커서를 찾지 못해 Parse단계에서 하드파싱을 한다. 하드파싱한 결과 같은 실행계획이 이미 라이브러리 캐시에 공유된 것이 확인되었다. 그래서 그 실행계획에 대한 포인터만 LCO에 담고 Parse단계를 마친다.
이제 실행 단계로 넘어가서 커서를 오픈하려고 LCO힙에 저장된 포인터를 실행계획을 찾아가 보니 그 실행계획에 대한 핸들은 캐싱돼 있는데, 그 실제 내용에 해당하는 힙 영역은 사라지고 없었던 것이다.
1번 세션
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
SQL> /
TEST_PIN(30)
------------
10
2번 세션
SQL> select sid from v$mystat where rownum = 1
SQL> /
SID
----------
155
SQL> alter table dept modify deptno number(3) <= 1번 세션에서 함수 실행 중 일 때
SQL> /
테이블이 변경되었습니다.
SQL> alter function test_pin compile <= 1번 세션에서 함수 실행 중 일 때
SQL> /
함수가 변경되었습니다.
3번 세션
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 = '155'
SQL> /
EVENT WAIT_TIME SECONDS_IN_WAIT STATE
------------------------ --------------- ----------------- ---------
library cache pin 0 16 WAITING