1. Lock 분류
1) Lock 개념
- 오라클은 Enqueue 락을 이용해 오브젝트를 보호한다.
- 오라클은 특정 오브젝트를 사용하기 위해 반드시 해당 오브젝트를 보호하는 Enqueue 락을 획득해야 한다.
- 만일 Enqueue 락을 획득하지 못하면 enqueue 이벤트를 대기한다.
- enqueue 대기 이벤트는 오라클 9i까지만 사용되며, 오라클 10g부터는 Enqueue 락에 의한 대기현상들은 모두 개별 대기이벤트로 나뉘어서 정의되었으며 심지어 락 경합이 발생하는 상황 별로 나누어진 경우도 있다.
- 가령 TX 락에 의한 대기현상은 enq: TX - row lock contention, enq: TX - allocate ITL entry, enq: TX - index contention, enq: TX - contention 네 개의 이벤트로 구분되었다.
- V$SESSION_WAIT 뷰나 V$SESSION 뷰를 이용하면 현재 어떤 락에 대한 경합이 발생하고 있는지 정확하게 알 수 있다.
- EVENT 컬럼의 값이 "enqueue"이거나 "enq: XXX"이면 Enqueue 락에 의한 경합이 발생한다는 의미이다.
- V$SESSION_WAIT 뷰의 P1 컬럼 값이 Enqueue 락의 "name|mode"를 의미한다.
- 다음과 같은 SQL문을 이용해 판독 가능한 값으로 변환할 수 있다.
SELECT CHR(BITAND(P1, -16777216) / 16777215) ||
CHR(BITAND(P1, 16711680) / 65535) "Name",
BITAND(P1, 65535) "Mode"
FROM DUAL;
2) Lock 분류
- Enqueue Lock
☞ Enqueue 락은 Enqueue 구조로 관리되는 락을 말한다.
☞ 오라클 10g부터는 대부분의 Enqueue 락에 대해 개별 대기이벤트가 등록되므로 v$event_name 뷰를 조회하면 어떤 종류의 Enqueue 락이 존재하는지 알 수 있다.
☞ Enqueue 구조체는 Shared Pool 영역에 저장된다.
☞ 가령 하나의 TM 락은 하나의 테이블을 보호하는데 이 테이블을 유일하게 구분하는 리소스 구분자(Resource Idenitifer)로 <TM-Tables object id-0>의 값을 사용한다.
☞ 하나의 인스턴스에 수많은 Enqueue 락이 존재할 수 있기 때문에 해시 체인(Hash chain) 구조를 사용한다.
☞ 즉 <ResourceType-ID1-ID2>의 리소스 구분자에 해시함수를 적용해서 버킷(Bucket)을 할당하고, 하나의 버킷은 해시 체인 형태로 여러 개의 리소스 구조체를 거느린다.
☞ 각 리소스 구조체는 리소스 자체에 대한 정보와 이 리소스에 대한 락을 보유한 프로세스 목록, 대기하고 있는 프로세스 목록, 락 모드를 변경한 프로세스 목록을 거느린다.
☞ 이 구조를 이용해서 오라클은 특정 리소스에 대해 정밀한 동기화 메커니즘을 구현한다.
① User Type : TX, TM, UL
② System Type : US, HW, SQ, SV, TT, WF, ..
③ V$LOCK_TYPE 뷰 참조(10g)
- 기타 LOCK
☞ 반면, Enqueue 락과 동일한 목적을 가지면서도 다른 방식으로 구현되는 락들이 있다.
☞ row cache lock이 대표적인 경우이다.
☞ Shared Pool의 Row Cache 영역을 보호하기 위해 오라클은 row cache lock을 사용하는데,
☞ row cache lock은 Enqueue 영역에서 통합 관리하지 않고 개별 Row Cache 메모리 영역 자체에 보유프로세스목록(Owner List)과 대기프로세스목록(Waiter List)을 관리한다.
☞ 이런 방식으로 작동하는 락들에는 row cache lock, library cache lock, library cache pin, buffer lock 등이 있다.
① row cache lock
② library cache lock/pin
③ dml lock
④ buffer lock
⑤ sort lock
2. Lock 획득 Mode
1) 6단계의 Mode 정의
0 | None | |
1 | NULL(1, N) | |
2 | Sub-SHARED(2, SS, RS) | - Row share table lock(내부적으로 sub-share table lock, SS라고 불리기도 함)은 테이블에 락을 걸려는 트랜잭션이 테이블 안에 락 된 로우가 있고 그 로우를 변경시키고자 하는 것을 가리킴
|
3 | Sub-Exclusive(3, SX, RX) | - Row exclusive table lock(내부적으로 sub-exclusive table LOCK, SX라 불리기도 함)은 락에 걸린 트랜잭션이 그 테이블에 있는 로우들에 대해 하나 이상의 변경(UPDATE)을 수행 하고 하는 것을 가리킴
|
4 | Shared(4, S) | - Shared table lock
- 트랜잭션에 의해서 걸리는 share table lock은 다른 트랜잭션들이 단지, 테이블에 대한 쿼리(query), SELECT .. FOR UPDATE를 이용한 특정 로루에 대한 락, LOCK TABLE .. IN SHARE MODE 문들을 성공적으로 수행하기 위해서 허용함
- 다른 트랜잭션에 의한 갱신은 허용하지 않음. 여러 트랜잭션이 동일한 테이블에 대해 동시에 share table lock을 수행할 수 있다. 이 경우에 어떠헌 트랜잭션도 테이블을 갱신할 수 없음
|
5 | Shared-Sub-Exclusive(5, SSX, SRX) | - Share row exclusive table LOCK(내부적으로 Share-sub-exclusive table lock, SSX라고 불리기도 함)은 share table lock보다 좀 더 제한적임
|
6 | Exclusive(6, X) | - Exclusive table lock은 락을 건 트랜잭션이 테이블에 대한 액세스를 exclusive write로 허용하는 테이블 락의 제한적인 모드
|
3. Lock Mode 호환성
1) 6단계 Mode 호환성
구분 | N | RS | SX | S | SRX | X |
N | O | O | O | O | O | O |
RS | O | O | O | O | O | X |
SX | O | O | O | X | X | X |
S | O | O | X | O | X | X |
SRX | O | O | X | X | X | X |
X | O | X | X | X | X | X |
- 락에 대한 경합을 이해하려면 락의 모드 및 호환성에 대한 정확한 이해가 필요하다.
- 가령 특정 프로시저를 실행하는 프로세스는 프로시저에 해당하는 Library Cache Object에 대해 library cache pin을 Shared 모드로 획득해야 한다.
- 반면 프로시저를 컴파일하려는 프로세스는 library cache pin을 Exclusive하게 획득해야 한다.
- Shared 모드와 Exclusive 모드는 호환성이 없기 때문에 트랜잭션이 왕성한 시스템에서 프로시저를 컴파일하게 되면 library cache pin에 의한 경합이 발생하게 된다.