h2.Global Lock 동기화 Mechanism
참고) PCM락 http://forums.oracle.com/forums/thread.jspa?threadID=469173
h2.Global Lock 동기화 Mechanism - Examples
1) 테이블을 update하기 위해 인스턴스1이 해당 블록의 락 마스터인 인스턴스 2에게 TM락을 SX모드로 요청
2) 인스턴스2는 락의 홀더는 인스턴스3 이고, 현재 X모드로 락을 획득함을 확인하고 인스턴스3 에게 락의 허용을 요청
3) 락의 전송이 가능하면, 인스턴스3은 인스턴스1에 SX모드로 락을 허용하고, X에 N모드로 모드를 변경
4) 락을 허용받은 인스턴스1은 TM락을 SX모드로 획득하고, GRD를 갱신
h2.Lock Database
구분 | BL락 관리 방법 |
---|---|
OPS | 하나의 PCM락, 즉 BL락이 여러 개의 버퍼를 관리함 |
RAC | 하나의 BL락이 하나의 버퍼를 관리함 |
구조체 | 정의 | 뷰 |
---|---|---|
리소스 구조체 | 락이 보호하는 자원에대한 정보를 관리 | V$GES_RESOURCE |
락 구조체 | 자원에 허용된 락의 목록을 관리 | V$GES_ENQUEUE |
포로세스 구조체 | 락을 보유한 프로세스 목록 관리 |
참고) GV$LOCK은 글로벌 락의 모니터링이 가능하지만 row cache, library cache lock을 모니터링 할 수는 없음
h2.V$GES_RESOURCE
목록 | 내용 |
---|---|
리소스명(resname) | id1,id2,type형식으로 정의도는리소스명 또는 리소스 아이디 |
마스터 노드 (master_node) | 리소스의 마스터 노드 번호를 가르킨다. 노드 번호는 0부터 시작함 |
그랜트 규(grant queue) | 현재 리소스에 대해 허용된 락들의 리스트, 락 구조체에 대한 포인터들의 리스트 |
컨버트 큐(converet queue) | 현재 리소스에 모드를 변환하기 위해 대기하는 락들의 리스트, 락 구조체에 대한 포인터들의 리소스 |
락값블록(valblk) | 16바이트의 락 값 블록, 락 변환이나 획득 과정에서 데이터 교환이 필요한 경우에 사용됨 |
h2.V$GES_ENQUEUE
목록 | 내용 |
---|---|
소유노드(owner node) | 현재 락을 소유중인 노드 번호, 노드 번호는 0 부터 시작함 |
그랜트 레벨(grant level) | 락이 허용된 레벨(모드)를 의미함 |
프로세스 포인터(procp) | 락을 보유한 프로세스에 대한 포인터, 프로세스 구조체에 대한 포인터 값 |
Pid | 대부분 LCK프로세스의 id임 (LCK, LMD) |
h2.Global Enqueue
예제)
인스턴스 | 테스트 시나리오 설명 |
---|---|
2번 인스턴스 | 129번 세션이 특정테이블의 특정 로우를 변경함 |
1번 인스턴스 | 18번 세션이 같은 로우를 변경하고자 하는 상황에서 발생하는 TX락 경합현상 |
GV$LOCK 뷰의 조회 결과
인스턴스 | 뷰 조회 결과 설명 |
---|---|
2번 인스턴스 | 129번 세션이 2359348+15363 트랜잭션에 대해 독점모드(6)로 TX락을 획득 중 |
1번 인스턴스 | 18번 세션이 2359348+15363 트랜잭션에 대해 독점모드(6)로 TX락을 획득하기위해 대기하는 것을 알수 있음 |
h2.Library Cache Lock
Library cache lock은 LCO의 정의를 보호하는 락(DDL락)
LCO정의를 참조하는 작업이 대부분 파싱단계에서 발생하기 때문에 parse lock이라고도 부름
일반 SQL문을 파싱하는 세션은 팡싱 시간 동안 해당SQL 문장과 SQL문장이 참조하는 오브젝트의 LCO대해 library cache lock을 공유모드로 획득해야 함
파싱시간 동안 DDL등에 의해 오브젝트의 정의가 변경되는 것을 방지하기 위해서임
DDL문장을 수행하는 세션은 수행이 완료될 때까지 해당 오브젝트의 LCO에 대해 library cache lock을 독점모드로 획득해야 함
DDL이 수행되는 동안 해당 객체에 대한 어떠한 종류의 참조도 원천적으로 방지하기 위해서임
SQL문장의 파싱을 완료한 세션은 SQL 커서 및 커서가 참조하는 LCO에 대해 library cache lock을 해제하지 않고 널(null)모드로 계속 유지됨
널 모드로 유지되는 상태의 library cache lock을 breakable parse lock이라고 부름
DDL에 의해 커서가 참조하는 객체가 무효화(invalidation)되면, 개별 서버 프로세스가 보유한 정보를 무효화 시킴
breakable parse 락을 GRD에서는 IV락이라 하며, IV 락의 홀더는 항상 LCK 프로세스임
RAC에서 library cache의 획득 여부는 X$KGLLK뷰와 같은 로컬 뷰와 V$GES_ENQUEUE뷰와 같은 글로벌 락 뷰를 통해 확인 가능
Library cache lock은 GRD에서는 L[A-Z], E[A-Z], V[A-Z]유형의 락으로 관리함
L*, E*, V*는 각각 이름 공간(namespace)을 의미함
h2.Library Cache Pin
Library cache pin의 LCO의 정의를 보호하는 반면, library cache pin은 LCO의 실행정보를 보호함
SQL문을 수행하는 세션은 SQL커서에 해당하는 LCO에 대해 library cache pin을 공유모드로 획득함
실행시간 동안 LCO의 실행정보가 변경되는 것을 방지하기 위해서임
프로시저나 함수에 대해서도 동일한 원리가 적용됨
하드파싱이 발생하는 경우에는 SQL커서에 해당하는 LCO에 대해 library cache pin을 독점모드로 획득함
하드파싱이란 실행 정보를 새로 생성하는 과정이기 때문에 독점모드의 library cache pin을 필요로 함
프로시저를 컴파일하는 경우에는 프로시저에 해당하는 LCO에 대해 library cache pin을 공유 모드로 획득해야 하기 때문에, 현재 컴파일 중인 프로시저는 수행할수 없음
기타 실행정보를 변경해야 하는 모든 DDL 작업들은 항상 library cache pin을 독점모드로 획득함
RAC에서 library cache pin의 획득여부는 X$KGLPN뷰와 같은 로컬뷰와 V$GES_ENQUEUE뷰 와 같은 글로벌 락 뷰를 통해 확인 가능함
Library Cache pin은 GRD에서는 N[A-Z], G[A-Z], Y[A-Z]유형의 락으로 관리함
N*, G*, Y*는 각각 이름 공간(namespace)을 의미함
h2.Row Cache Lock
Row cache lock은 로우 캐시 영역을 보호하는 락임
로우 캐시 혹은 딕셔너리 캐시 영역은 오라클의 딕셔너리 정보를 보관하는 공유메모리 영역으로, 많은 프로세스가 동시에 딕셔너리 정보를 참조하거나 변경하면 로우캐시에서의 경합이 발생함
V$ROWCACHE뷰를 참조하면 어떤종류의 데이터가 로우 캐시 영역에서 관리되고 있는지 확인가능
Row cache object(이하 RCO)는 개별 딕셔너리 객체를 의미함
예를 들어, 하나의 시퀀스 A가 있음
시퀀스 A는 물리적으로 SYSTEM테이블스페이스의 SYS.SEQ$ 테이블에 저장되어 있음
사용자가 시퀀스 A를 참조하면 SYS.SEQ$ 테이블에서 시퀀스 A에 해당하는 로우를 로우캐시영역으로 읽어 들이고
이과정에서 시퀀스 A에 해당하는 RCO가 생성됨
RCO를 변경하고자 하는 프로세스는 반드시 row cache lock을 획득해야함
alter 문을 이용해 테이블을 변경하는 프로세스는 테이블에 대해 row cache lock을 독점(X)모드로 획득해야함
Row cache lock은 글로벌하게 동기화 되며, GRD에서는 Q[A-Z]의 유형으로 관리됨
h2.SQL Cursor 동기화
IV Lock은 Library cache lock이며, 글로벌 커서의 무효화(invalidation)를 담당함
1) 인스턴스A는 select * from ges_test 를 수행하였고, 이 커서에 대하여 IV락이 보호함
2) 인스턴스B도 select * from ges_test 를 수행하였고, 이 커서에 대하여 IV락이 보호함
3) 이때 alter table ges_test ... 를 인스턴스B에서 수행하면, 인스턴스B의 ges_test를 참조하는 SQL문을 IV락이 무효화 시키며,
인스턴스A에게 ges_test 테이블이 변경되어 해당 테이블을 참조하는 SQL문이 무효화 됨을 전달함
4) 인스턴스A는 신호를 받아 해당 SQL문을 무효화 시킴