RAC (Oracle Real Application Clusters)
미들웨어 주제에서 다뤘던 세션 클러스터링을 적용하면 특정 WAS 서버에 장애가 발생하더라도 사용자는 세션이 유지된 상태로 서비스를 무중단 운영할 수 있습니다. 그러나 데이터를 실제로 처리하는 DB가 단일 인스턴스라면 어떨까요? 아무리 WAS 계층이 정상적으로 동작하더라도 DB에 장애가 발생하는 순간, 전체 서비스는 중단될 수밖에 없습니다.
진정한 가용성은 App(WAS)과 Data(DB) 모든 계층이 끊김 없이 유기적으로 연결될 때 비로소 완성됩니다. 세션 클러스터링이 WAS 계층의 고가용성을 책임진다면, DB 계층에서는 이를 완성하는 기술로서 Oracle RAC와 같은 구조가 필요합니다.
DB 가용성을 확보하는 방식은 크게 Active-Standby와 Active-Active 두 가지로 나눌 수 있습니다.
👉 Active-Standby (전통적 방식)
한쪽 DB가 실제 서비스를 처리하고, 다른 한쪽은 대기 상태로 있다가 장애 발생 시 전환(Failover)되는 구조입니다. 대표적으로 Oracle Data Guard와 같은 방식이 이에 해당합니다. 이 경우 전환 과정에서 일정 시간의 서비스 중단이 발생할 수밖에 없습니다.
👉 Active-Active (RAC 방식)
모든 노드가 동시에 서비스를 처리합니다. 특정 노드에 장애가 발생하더라도 나머지 노드가 즉시 부하를 이어받아 서비스를 지속합니다. 마치 애플리케이션 서버가 클러스터링되어 하나의 논리적 자원처럼 동작하듯, DB 서버들도 하나의 거대한 통합 리소스로 동작하는 구조입니다.
Active-Standby가 "대기 후 교체"의 개념이라면, Active-Active는 "동시 처리와 즉시 분산"의 개념이라고 볼 수 있습니다. DB 이중화 전략은 단순히 장애 대비 차원이 아니라, 서비스 특성 / 트래픽 규모 / SLA 요구 수준 / 비용 구조까지 종합적으로 고려해 선택해야 하는 아키텍처 요소입니다.
RAC의 생태계
RAC에 대해 좀더 깊숙하게 들어가보겠습니다. Oracle RAC는 여러 개의 인스턴스가 하나의 Database를 엑세스 할 수 있으며, 이는 Application에서 접속할 수 있는 통로는 여러 개이며 Database는 하나인 형태입니다.

RAC로 연결된 N개의 Instance에서 동일한 Datafile을 공유하여 액세스 하지만 Database 작업에 사용할 수 있는 CPU나 메모리 등의 Resource는 서로 공유되지 않으며 해당 Node의 Resource만을 사용합니다.
여기서 노드란 Oracle RAC 인스턴스가 실행되고 있는 하나의 서버(운영체제 단위) 를 의미합니다.
RAC 구성을 자세히 보면, 각 노드의 로컬 디스크를 사용하는 것이 아니라, 데이터 파일을 저장하는 스토리지가 별도로 분리되어 있다는 점 입니다. Oracle RAC에서는 여러 노드가 하나의 동일한 Database를 동시에 접근해야 하기 때문에, 데이터 파일은 특정 노드에 종속되면 안 됩니다. 따라서 각 노드는 로컬 디스크가 아닌, 모든 노드가 함께 접근할 수 있는 공유 스토리지를 사용합니다.
👉 Cache Fusion (캐시 퓨전): RAC의 꽃

각 RAC 노드는 CPU와 메모리(SGA)를 서로 공유하지 않습니다. 즉, 물리적으로는 완전히 독립된 인스턴스입니다. 여기서 중요한 질문이 발생합니다. 만약 1번 노드가 특정 데이터 블록 A를 수정하여 자신의 SGA Buffer Cache에 보관하고 있는 상황에서, 2번 노드가 동일한 데이터 블록 A를 읽으려 한다면 어떻게 될까요?
과거의 단순한 공유 디스크 기반 구조에서는, 1번 노드가 수정한 블록을 디스크에 먼저 기록하고, 2번 노드가 그 디스크 블록을 다시 읽어오는 방식이 필요했습니다. 이 과정은 디스크 I/O를 수반하기 때문에 지연(latency)이 매우 크고, 고성능 트랜잭션 처리 환경에서는 병목이 될 수 있어 부적합함을 느낍니다.
Oracle RAC는 이러한 비효율을 제거하기 위해 Cache Fusion이라는 메커니즘을 사용합니다. 수정된 데이터 블록은 디스크를 경유하지 않고, 노드 간 전용 고속 네트워크인 Interconnect(Private Network)를 통해 메모리에서 메모리로 직접 전송됩니다.
즉, 데이터 블록이 디스크를 거치지 않고 SGA 간에 실시간으로 공유되는 구조입니다. 이를 통해 RAC는 다중 인스턴스 환경에서도 단일 인스턴스와 유사한 수준의 일관성과 성능을 유지할 수 있습니다.

데이터 전송의 주체: LMS (Lock Manager Server Service )
다이어그램에서 단순한 화살표로 표현되는 블록 전송을 실제로 수행하는 프로세스가 LMS(Global Cache Service Process)입니다. 다른 노드에서 특정 블록에 대한 요청이 발생하면, LMS는 자신의 Buffer Cache(SGA)에서 해당 블록을 찾아 인터커넥트를 통해 직접 전달합니다. 즉, Cache Fusion의 실질적인 실행 엔진이 LMS입니다. LMS프로세스는 디스크를 거치지 않아도 안전한 Past Image(PI) 기술을 제공합니다.
디스크에 쓰지 않고 메모리끼리만 주고받으면, 중간에 노드가 죽으면 데이터가 날아가는 것 아닌가? DB를 심도 깊게 학습했다면 충분히 궁금할 법한 이야기 입니다. 이를 구조적으로 해결하는 기술이 Past Image(PI)입니다.
PI 동작 원리
1번 노드가 수정한 블록을 2번 노드로 전달할 때, 1번 노드는 해당 블록의 이전 버전(복사본)을 자신의 메모리에 유지합니다. 이것이 PI입니다.
만약 2번 노드가 해당 블록을 디스크에 기록하기 전에 장애가 발생하면,
- 다른 노드에 남아 있는 PI
- Redo 로그
두가지를 결합해 데이터를 복구합니다.
즉, Checkpoint 없이도 데이터 일관성을 유지할 수 있도록 설계된 메커니즘입니다. Cache Fusion은 단순한 “빠른 전송 기술”이 아니라, 장애 상황까지 고려된 복구 가능한 전송 체계라는 점 입니다.
RAC의 교통 관제 시스템 : GCS & GES
데이터를 주고받는 것보다 더 복잡한 문제는 지금 이 블록을 누가, 어떤 권한으로 사용하고 있는가?에 대한 동시성 문제입니다
👉 GCS (Global Cache Service)
: 데이터 블록의 이동과 상태를 관리
: 공유 모드(Shared) / 독점 모드(Exclusive) 제어
: Cache Fusion의 실질적 운영 체계
👉 GES (Global Enqueue Service)
: 블록 외 자원 관리
: 트랜잭션 락
: 딕셔너리 락
: 기타 글로벌 리소스 동기화
해당 프로세스는 각 담당 영역에서 핵심적인 역할을 수행합니다.
| LMS | GCS (Global Cache Service) | 메모리의 데이터 블록을 다른 노드로 전송 |
| LMD | GES (Global Enqueue Service) | 자원과 락(Lock)의 소유권 조정 |
| LMON | Cluster Manager | 노드 상태 감시 및 장애 시 재구성 |
RAC 환경에서 Global Lock은 데이터 무결성을 지키는 최후의 마지노선이자, 성능 튜닝의 핵심 포인트입니다. 단일 인스턴스에서는 Latch와 Enqueue로 메모리와 자원을 보호하면 끝이었습니다만, RAC는 "서로 다른 메모리(SGA)를 가진 노드들이 동일한 디스크를 바라보는" 구조입니다. 누군가 교통 정리를 안 해주면 데이터가 깨집니다.

Global Lock Ping 병목
RAC환경에서 종종 있는 성능 이슈로 "노드를 추가했는데 왜 더 느려졌지?"하는 경우가 있습니다. RAC에서 성능 병목의 1차 원인은 디스크 I/O가 아닙니다. 진짜 비용은 노드 간 Lock 상태 변경(Conversion) 과정에서 발생하는 합의 비용입니다.
즉, 병목은 스토리지가 아니라 Interconnect 위에서 발생하는 글로벌 동기화 오버헤드입니다.
Lock Convert가 만들어내는 4단계 지연
Step 1. X → S Downgrade 요청
- Instance A가 블록을 X(Exclusive) 모드로 보유 중
- Instance B가 해당 블록을 읽기(S) 모드로 요청
→ A는 현재 작업을 정리하고 Lock 상태를 낮출 준비를 합니다. 이 시점부터 이미 지연이 시작됩니다.
Step 2. Redo Flush 및 GRD 업데이트
- A는 수정 내용을 Redo에 기록
- Global Resource Directory(GRD) 상태 변경
- 글로벌 소유권 정보 갱신
이 단계는 단순한 상태 플래그 변경이 아니라, 일관성을 보장하기 위한 안전 확보 절차입니다.
Step 3. 메시지 교환 및 CPU Context Switch
- Interconnect를 통한 메시지 왕복
- GCS/GES 레벨의 상태 동기화
- CPU Context Switching 발생
네트워크 지연과 CPU 스케줄링 비용이 동시에 발생합니다.
Step 4. Block Transfer (Ping)
- LMS 프로세스가 블록을 Interconnect로 전송
- 대상 노드가 블록을 수신
이 순간을 흔히 “Ping이 났다”고 표현합니다.
하지만 실제 비용은 데이터 전송 그 자체보다 앞선 Convert 과정에 더 많이 존재합니다.
Step4. 앞서 배웠던 AWR에서 보이는 결과: GC Wait Events
이 과정 동안 세션은 대기 상태에 들어가며, AWR 리포트에는 다음과 같은 이벤트가 나타납니다.
- gc buffer busy acquire
- gc current block busy
- gc cr request
이 이벤트들은 단순 네트워크 지연이 아니라, Lock Convert 과정이 길어지고 있다는 신호입니다.
다음과 같은 환경에서는 Ping이 급증합니다
: 동일한 Hot Block을 여러 노드가 번갈아 수정
: Index Root Block 경합
: Sequence 경쟁
: 집중된 UPDATE 워크로드
이 경우 노드를 추가할수록
: Lock Convert 횟수 증가
: Interconnect 트래픽 증가
: LMS CPU 사용률 상승
: 전체 지연 확대
즉, 확장이 아니라 동기화 비용만 증가합니다. 왜 노드를 늘렸는데 느려지지? RAC는 병렬 확장을 제공하지만,
그 전제 조건은 노드 간 경합이 적어야 한다는 것입니다.
RAC 성능은 다음 공식으로 이해할 수 있습니다.
성능 = (데이터 처리 속도) − (Lock Convert 합의 비용)
그리고 그 합의 비용의 중심에는 아래 3개지의 합의 비용이 발생합니다.
LMS (데이터 전송)
LMD (Lock 조정)
Interconnect 지연
Database만 알면 끝인가?

RAC의 성능 산정 공식은 성능 = (데이터 처리 속도) − (Lock Convert 합의 비용) 이라고 설명한 바 있습니다.
그렇다면 Lock Convert는 데이터베이스 차원의 튜닝으로 어느 정도 개선이 가능하겠지만, 네트워크 처리 속도는 어떻게 접근해야 할까요? RAC에서 데이터 블록을 다른 노드로 전송할 때, Oracle의 LMS 프로세스가 패킷을 생성하고 OS 네트워크 스택을 통해 이를 전달합니다. 이 지점에서 OSI 7 Layer의 중요성이 현실적인 성능 변수로 작용합니다.
응용 계층 아래의 네트워크 계층에서 병목이나 지연이 발생한다면, 아무리 디스크 I/O를 줄이고 내부 경합을 최소화하더라도 전체 성능은 개선되지 않고 Oracle 내부 튜닝만으로는 충분하지 않습니다.
네트워크 인프라에서 인터링크가 두 스위치를 하나처럼 묶어 트래픽을 처리하듯, RAC 환경에서도 인터커넥트의 패킷 처리 성능이 확보되지 않으면 데이터베이스 수준의 튜닝은 실질적인 효과를 내기 어렵습니다. 일반적인 네트워크 환경에서 인터링크는 헬스 체크나 VRRP와 같은 제어 패킷을 교환하는 용도로 사용되지만, RAC의 인터커넥트는 데이터 블록 자체가 오가는 핵심 경로입니다. 즉, 단순 관리 트래픽이 아니라 실질적인 트랜잭션 성능을 좌우하는 통신 구간입니다.
따라서 RAC 설계 시에는 데이터베이스 관점만을 고려하지 않습니다. RAC를 구성하려면 모든 노드가 동시에 접근 가능한 공유 스토리지가 필수이며, 이를 위해 기업들은 보통 고성능 SAN(Storage Area Network)을 별도로 도입하여 그 위에 RAC를 구성합니다.
이와 함께 노드 간 인터커넥트 또한 저지연 / 고대역폭 환경으로 설계해야 합니다. 네트워크 레이턴시, 스위치 구조, NIC 성능, 패킷 처리 능력까지 포함해 전체 인프라를 설계해야만 Lock Convert 비용을 최소화할 수 있습니다.
결국 RAC의 성능은 단순히 데이터베이스 내부 구조에 의해 결정되지 않습니다. DB, 스토리지, 네트워크가 하나의 시스템으로 동작할 때 비로소 기대하는 확장성과 성능이 실현됩니다.
'데이터베이스' 카테고리의 다른 글
| [데이터베이스] Library Cache 탐색 원리와 Parsing (1) | 2026.03.03 |
|---|---|
| [데이터베이스] ASM(Automatic Storage Management)의 구조와 동작 메커니즘 (0) | 2026.02.24 |
| [데이터베이스] 오라클의 타임머신과 블랙박스 Undo와 Redo (0) | 2026.02.12 |
| [데이터베이스] SQL 성능의 나침반, 오라클 옵티마이저(Optimizer)와 통계 정보의 중요성 (0) | 2026.02.03 |
| [데이터베이스] DBA의 필수 역량: 솔루션 없이 AWR 스냅샷으로 DB 병목 지점 추적하기 (0) | 2026.02.03 |