row cache lock
오라클은 - 딕셔너리의 정보를 SGA내의 Row Cache(혹은 dictinary cache) 영역에 저장한다 -> 딕셔너리의 내용을 변경하고자 하는 프로세스는 그에 해당하는 row cache object에 대해서 row cache lock을 획득해야 한다.
ex 시퀀스 - nextval을 획득하는 과정에서 딕셔너리 정보의 변경이 필요할떄 - 시퀀스에 해당하는 cache object에 대해 row cache lock을 SSX모드로 획득
SSX모드는 상호 호환성 없다 -> 동시에 여러 프로세스가 같은 시퀀스 호출한다면 nextval때문에 row cache lock에 대한 경합이 발생하게 된다.
row cache lock은 Enqueue 구조를 사용하지 않는다 -> row cache object 정보 안에 존재하는 락 보유 목록, 락 대기 목록을 통해 구현된다. (library cache lock, library cache pin, buffer lock도 마찬가지)
V$ROWCACHE, V$ROWCACHE_PARENT를 통해 경합에 대한 분석이 가능하다.
시퀀스를 제외하고는 row cache의 정보를 자주 변경하는 일이 거의 없음 -> 따라서 row cache lock 대기 이벤트 발생시 NOCACHE 속성의 시퀀스를 사용하는 것은 아닌지 알아보도록한다.


enq: SQ - contention, DFS lock handle(SV)
시퀀스를 관리하기 위한 세가지 락
- row cache lock : Sequence.nextval 호출시 - 딕셔너리 정보를 물리적으로 변경한다면 획득한다 -> NOCACHE 속성의 시퀀스에서 사용
- SQ 락 : 메모리에 캐시되어 있는 범위안에서 Sequence.nextval을 호출하는 동안 획득 -> CACHE 속성의 시퀀스에서 사용
- SV 락 : RAC에서 노드간에 순서가 보장된 상태로 Sequence.nextval을 호출하는 동안 획득 -> CACHE + ORDER 속성의 시퀀스에서 사용
-> NOCACHE라면 ORDER속성이라도 그냥 row cache lock 사용한다 : row cache lock은 싱글 인스턴스가 아니어도 글로벌하게 사용 가능하다.

CACHE 속성이 부여된 시퀀스에 대해 nextval을 호출하는 동안 SQ락을 SSX모드로 획득 -> 동시에 여러 세션이 SQ락 획득 시도시 enq:SQ - contention -> 캐시 크기가 작을 때도 발생할 수 있다.
CACHE+ORDER이면 SQ 락이 아닌 SV락을 획득함 - 경합시 DFS lock handle이라는 대기 이벤트 -> RAC환경에서 버퍼 캐시 동기화를 제외한 row cache나 library cache 동기화를 위해 락 획득시 대기하는 이벤트