GCS(Global Cache Service)
- 노드간의 데이터를 전송하는 서비스
- 데이터(블록) 전송 데몬 : LMS
show parameter gcs_server_processes
cpu 개수가 4개마다 1개의 LMS 프로세스 사용

GES(Global Enqueue Service)
- 노드간의 발생하는 락을 관리하는 서비스
- 글로벌 enqueue를 담당하는 데몬 : LMD, LCK
CGS(Cluster Group Service)
- 클러스터의 멤버십을 관리
- 클러스터를 모니터링하면서 노드의 가입이나 탈퇴에 따른 클러스터의 상태를 관리
- 데몬 : LMON
hr 유저계정 상태 확인
select username, account_status from dba_users where username='HR';

계정정보 변경
alter user hr identified by hr account unlock;

변경정보 확인
select username, account_status from dba_users where username='HR';

찾고자 하는 데이터의 파일 id, block id 확인
select
dbms_rowid.rowid_relative_fno(rowid) as file_no,
dbms_rowid.rowid_block_number(rowid) as block_no
from hr.employees
where employee_id = 100;

select b.lock_element_addr, b.status, e.mode_held, e.local
from v$bh b, v$gc_element e
where b.lock_element_addr = e.gc_element_addr
and b.file# = 5
and b.block# = 207;


쿼리 실행 및 블록 요청:
SELECT * FROM hr.employees WHERE employee_id = 100; 쿼리를 실행하며, [5,207] 블록을 요청합니다.Null 모드로 블록 할당:
마스터 노드에 요청:
gc cr request wait event 상태에서 응답을 기다립니다.마스터 노드에서 GRD 정보 확인:
gc cr/current grant 2-way wait event가 발생할 수 있습니다.1번 노드에서 디스크 I/O 수행:
db file sequential read wait event가 발생할 수 있습니다.Shared 모드로 블록 변경 및 GRD 업데이트:
1번 노드는 블록을 Null 모드에서 Shared 모드(SCUR)로 변경하고, Buffer Cache Lock도 Shared 모드로 전환합니다. 이를 통해 1번 노드에서 해당 블록에 읽기 전용 접근이 가능해지며, 다른 노드와의 동시 읽기 공유가 허용됩니다.
마지막으로, GRD 정보를 업데이트하여 [5,207] 블록이 1번 노드의 Shared 모드로 존재함을 기록합니다.
결과
1번 노드의 캐시에 [5,207] 블록이 Shared 모드(SCUR)로 적재되며, Buffer Cache Lock도 Shared 모드로 설정되어 읽기 전용 접근이 가능해집니다. 이는 이후 다른 노드가 동일한 블록에 접근할 때 동시 읽기 공유가 가능하도록 지원하는 설정입니다.
**
[1번 노드]
select b.lock_element_addr, b.status, e.mode_held, e.local
from v$bh b, v$gc_element e
where b.lock_element_addr = e.gc_element_addr
and b.file# = 5
and b.block# = 207;

쿼리 실행 및 블록 요청
SELECT * FROM hr.employees WHERE employee_id = 100; 쿼리를 실행하며, [5,207] 블록을 요청합니다.마스터 노드에 요청
GRD 정보 확인 및 블록 전송 요청
2번 노드의 대기 상태
gc cr request wait event가 발생합니다.1번 노드의 블록 전송 (Select-Select Cache Fusion)
gc cr/current block 2-way wait event가 발생합니다. (3개 이상의 노드에서는 3-way로 나타납니다)Shared 모드로 변경 및 GRD 갱신 요청
2번 노드는 블록을 Null 모드에서 Shared 모드(SCUR)로 변경하고, Buffer Cache Lock도 Shared 모드로 전환합니다. 이를 통해 2번 노드의 버퍼 캐시에서 해당 블록에 읽기 전용 접근이 가능해지며, 다른 노드와의 동시 읽기 공유가 가능합니다.
또한, GRD에 이 정보를 갱신하도록 요청하여 블록이 Shared 모드로 적재되었음을 알립니다.
결과
[5,207] 블록이 1번 노드와 2번 노드 모두의 Shared 모드(SCUR)로 존재하며, 각 노드는 동일한 블록을 읽기 전용으로 접근할 수 있습니다. 이때 Buffer Cache Lock도 Shared 모드로 설정되어, 다중 노드에서의 동시 읽기 공유를 지원하게 됩니다.
[2번 노드]
select b.lock_element_addr, b.status, e.mode_held, e.local
from v$bh b, v$gc_element e
where b.lock_element_addr = e.gc_element_addr
and b.file# = 5
and b.block# = 207;

1번 노드 버퍼캐시에 있던 블록이 2번노드 버퍼캐시로 블록이미지가 이동되었다.
[1번 노드]
select b.lock_element_addr, b.status, e.mode_held, e.local
from v$bh b, v$gc_element e
where b.lock_element_addr = e.gc_element_addr
and b.file# = 5
and b.block# = 207;

쓰기(DML) 요청
GRD 정보 확인
Shared 모드에서 Null 모드로 다운그레이드 요청
Exclusive 모드로 전환
GRD 정보 갱신
[1번 노드]
select b.lock_element_addr, b.status, e.mode_held, e.local
from v$bh b, v$gc_element e
where b.lock_element_addr = e.gc_element_addr
and b.file# = 5
and b.block# = 207;

[2번 노드]
select b.lock_element_addr, b.status, e.mode_held, e.local
from v$bh b, v$gc_element e
where b.lock_element_addr = e.gc_element_addr
and b.file# = 5
and b.block# = 207;

- 업데이트
update hr.employees
set salary = 20000
where employee_id = 101;
- rac2에서 확인
select b.lock_element_addr, b.status, e.mode_held, e.local
from v$bh b, v$gc_element e
where b.lock_element_addr = e.gc_element_addr
and b.file# = 5
and b.block# = 207;

[1번 노드]
- null모드로 다운그레이드되어서 조회되지 않는다.
select b.lock_element_addr, b.status, e.mode_held, e.local
from v$bh b, v$gc_element e
where b.lock_element_addr = e.gc_element_addr
and b.file# = 5
and b.block# = 207;

RAC1 노드의 블록이 Null 모드로 변경되더라도 해당 블록은 여전히 RAC1의 데이터 버퍼 캐시에 남아 있습니다. 단, 이 블록은 읽기 또는 쓰기 작업에 사용할 수 없는 상태이며, 이후 다시 요청이 발생하면 필요한 권한을 부여받아 활성화될 수 있습니다.
이유
버퍼 캐시에 남아 있는 이유: RAC는 캐시 메모리 사용을 최적화하기 위해 버퍼 캐시에 있는 블록을 완전히 제거하지 않고 Null 모드(NL0)로 전환하여 일시적으로 비활성화하는 방식을 사용합니다. 필요 시 해당 블록을 다시 활성화하기 위해 재활용할 수 있기 때문입니다.
상태 변화만 발생: RAC1의 [5,207] 블록이 Null 모드가 되어도, 데이터는 여전히 버퍼 캐시에 남아 있으며, 상태가 Shared 또는 Exclusive 모드로 전환되면 다시 접근 가능해집니다.
Null 모드의 의미
- Null 모드는 해당 블록에 대한 권한을 해제한 상태이므로, 다른 노드가 독점 권한을 가져갈 수 있습니다.
- 데이터가 캐시에서 사라지는 것은 아니며, 필요 시 빠르게 다시 활성화할 수 있도록 캐시에 남아 있게 됩니다.
따라서, Null 모드로 전환되더라도 블록 자체는 버퍼 캐시에 남아 있으며, 추가 요청에 대비하는 방식으로 Oracle RAC는 캐시 효율성을 높이고 있습니다.
Oracle RAC에서 RAC2 노드가 롤백을 하더라도 RAC1의 Null 모드가 자동으로 Shared 모드로 돌아오지 않고, RAC2의 Exclusive 모드 역시 자동으로 Shared로 변경되지 않습니다. 이는 RAC의 락 모드와 블록 상태 관리 방식에 따른 것으로, 다음과 같은 이유가 있습니다.
이유
1. 블록 상태의 명시적 요청 필요:
- 블록 상태는 각 노드가 명시적으로 해당 블록을 요청할 때마다 업데이트됩니다. RAC1의 Null 모드 블록이 자동으로 Shared로 돌아오지 않는 이유는, RAC1이 명시적으로 다시 블록을 요청하지 않았기 때문입니다.
- 동일하게, RAC2의 Exclusive 모드 역시 RAC1이나 다른 노드가 다시 요청하지 않으면 Shared로 변경되지 않고 그대로 유지됩니다.
- 락 모드 효율성:
- 블록을 롤백했을 때 자동으로 다른 노드가 해당 블록을 Shared 모드로 가져가게 하면, 불필요한 락 모드 전환이 자주 발생하여 성능에 영향을 줄 수 있습니다.
- Oracle RAC는 필요한 경우에만 명시적으로 요청이 들어오면 상태를 변경하도록 설계되어, 불필요한 자원 소모를 줄입니다.
- GRD 관리 방식:
- GRD(Global Resource Directory)는 노드의 명시적 요청에 따라 락 모드를 전환하며, 자동으로 상태를 되돌리는 방식이 아니라 요청 기반의 효율적인 락 관리를 수행합니다.
요약
RAC 환경에서 롤백 후 블록 상태가 자동으로 변경되지 않는 것은 락 관리와 성능 최적화에 따른 결과입니다. 이후 RAC1이나 다른 노드가 [5,207] 블록을 다시 요청하면, 필요한 권한(Shared 또는 Exclusive)에 따라 GRD가 적절히 상태를 조정하게 됩니다.
RAC1에서 블록 요청 (SELECT)
SELECT * FROM hr.employees WHERE employee_id = 100; 쿼리를 실행하며, [5,207] 블록을 요청합니다.마스터 노드로 요청 전달
gc cr request wait event가 발생하여 응답을 기다리게 됩니다.GRD 정보 확인
Exclusive 모드 해제 및 Shared 모드로 다운그레이드
RAC1에 Shared 모드로 블록 전송
gc cr/current block 2-way wait event가 발생합니다.RAC1에서 Shared 모드로 블록 캐싱 및 GRD 갱신
update hr.employees
set salary = 20000
where employee_id = 101;
SELECT * FROM hr.employees WHERE employee_id = 100;select b.lock_element_addr, b.status, e.mode_held, e.local
from v$bh b, v$gc_element e
where b.lock_element_addr = e.gc_element_addr
and b.file# = 5
and b.block# = 207;
COMMIT이 이루어지지 않았으므로, 언두(Undo)에 저장된 이전 블록 이미지를 사용해 CR 블록을 생성해야 합니다.RAC1에서 블록 읽기 요청 (SELECT)
GRD에서 최신 정보 확인
트랜잭션 상태 및 모드 확인 후 다운그레이드
RAC2에 블록 전송 요청
RAC2에서 RAC1로 블록 전송 (LMS 작업)
RAC1에서 블록 모드 변경
GRD 정보 갱신 요청
RAC1과 RAC2 모두 [5,207] 블록을 Shared 모드(SCUR)로 보유하게 되어, 두 노드 모두 해당 블록에 대해 읽기 전용 접근이 가능해집니다.
상황 요약
RAC1 노드에서 특정 행(예: 100번 행)을 변경한 후, RAC2 노드가 동일한 블록([5,207])의 다른 행(예: 101번 행)에 대해 Write 작업을 수행하고 Exclusive 모드를 보유한 상태입니다. 이후 RAC1 노드에서 변경된 100번 행의 값을 다시 조회하려고 할 때 Redo 로그를 사용하는 과정을 설명합니다.
RAC2에서 [5,207] 블록 쓰기 요청
GRD에서 Exclusive 모드 확인
RAC1의 PI(Past Image) 블록 생성 및 전송 준비

RAC2에서 Exclusive 모드로 블록 획득
RAC1에서 변경된 데이터 조회 요청
RAC2가 Exclusive 모드로 보유 중 확인
Redo 로그와 Undo 로그 활용하여 CR 블록 생성
RAC1에서 완성된 CR 블록으로 조회