오라클 래치(Latch)

오라클 데이터베이스의 성능을 논할 때, 내부적으로 발생하는 경합(Contention)은 피할 수 없는 주제다. 특히 다수의 프로세스가 공유 메모리 영역인 SGA(System Global Area)에 동시에 접근하려 할 때 데이터 구조의 일관성을 유지하기 위한 직렬화 메커니즘이 필수적이다. 이 핵심적인 역할을 수행하는 것이 바로 래치(Latch) 다.

1. 래치(Latch)란 무엇인가?

래치는 SGA 내 공유 데이터 구조(예: 버퍼 캐시, 라이브러리 캐시 등)를 보호하기 위한 저수준(low-level) 직렬화 잠금(Lock) 메커니즘이다. 여러 프로세스가 동시에 동일한 메모리 구조를 변경하여 데이터가 깨지는 것을 방지하는 역할을 한다.

래치의 가장 큰 특징은 매우 짧은 시간 동안만 점유된다는 점이다. 메모리 연산은 나노초(nanoseconds) 단위로 매우 빠르기 때문에, 래치 획득 및 해제 과정 또한 가볍고 신속하게 설계되었다. 프로세스는 래치를 획득한 후 SGA 내 특정 구조에 대한 작업을 수행하고 즉시 래치를 해제하여 다른 프로세스가 사용할 수 있도록 한다.

만약 특정 프로세스가 래치를 얻으려 할 때 다른 프로세스가 이미 점유 중이라면, 해당 프로세스는 즉시 대기 상태로 들어가지 않고 잠시 대기하며 래치가 해제되었는지 확인하는 스핀(Spin) 과정을 거친다. 정해진 횟수만큼 스핀해도 래치를 얻지 못하면, 비로소 대기(sleep) 상태로 전환된다. 이는 래치가 곧 해제될 것이라는 가정 하에 CPU를 양보하지 않고 최대한 빠르게 작업을 재시도하기 위한 효율적인 방식이다.

2. 래치와 락(Lock)의 차이점

래치와 락은 모두 동시성 제어를 위한 메커니즘이지만, 그 성격과 작동 방식에서 명확한 차이를 보인다.

보호 대상SGA 내 공유 메모리 구조데이터베이스 객체 (테이블, 로우 등)
점유 시간매우 짧음 (마이크로초, 나노초)상대적으로 김 (트랜잭션 단위)
대기 방식큐(Queue)가 없음. 먼저 요청한 프로세스가 아닌, 래치가 해제된 직후 요청하는 프로세스가 획득 (Spin 후 Sleep)큐(Queue)가 존재. 요청한 순서대로 대기 목록에 등록되어 순차적으로 획득
교착상태내부적인 래치 레벨(Level)을 통해 교착상태(Deadlock)를 방지교착상태 발생 가능. 오라클이 이를 감지하고 한쪽 트랜잭션을 롤백하여 해결

요약하자면, 래치는 단기적이고 순서가 없는 메모리 보호 메커니즘이며, 락은 장기적이고 순서가 보장되는 데이터 보호 메커니즘이라고 할 수 있다.

3. 주요 래치의 종류

오라클에는 수백 종류의 래치가 존재하며, 각기 다른 SGA 영역을 보호한다. 성능에 큰 영향을 미치는 대표적인 래치는 다음과 같다.

  • Cache Buffers Chains Latch: 데이터베이스 버퍼 캐시에 있는 동일한 해시 체인(Hash Chain)에 연결된 버퍼 블록들을 보호한다. 동일한 블록에 대한 동시 액세스가 많아질 때 경합이 발생할 수 있다.
  • Library Cache Latch: 라이브러리 캐시 내에 있는 SQL 커서, 실행 계획 등의 객체를 보호한다. 바인드 변수를 사용하지 않는 하드 파싱(Hard Parsing)이 빈번할 경우 이 래치에 대한 경합이 심해질 수 있다.
  • Shared Pool Latch: 라이브러리 캐시를 포함하는 더 큰 구조인 공유 풀(Shared Pool)에 대한 메모리 할당 및 해제 작업을 보호한다. 공유 풀의 파편화가 심하거나 큰 객체를 자주 로드할 때 경합이 발생한다.
  • Redo Copy Latch: 프로세스가 리두 로그 버퍼(Redo Log Buffer)에 리두 레코드(Redo Record)를 복사할 때 사용된다. DML 작업이 매우 빈번하게 발생할 경우 경합이 나타날 수 있다. (최신 버전에서는 redo allocation latch와 통합되거나 다른 메커니즘으로 대체되는 경향이 있다.)

4. 래치 경합 진단

과도한 래치 경합은 시스템 전반의 성능 저하를 유발한다. 래치 경합은 주로 latch free 대기 이벤트로 나타나며, 특정 래치에서 경합이 심화될 경우 latch: <latch name> 형태의 세부적인 대기 이벤트로 관찰될 수 있다.

래치 관련 통계 정보는 다음과 같은 동적 성능 뷰(Dynamic Performance Views)를 통해 확인할 수 있다.

  • V$LATCH: 시스템 전체의 래치 종류별 통계 정보를 보여준다. GETS(성공적인 획득), MISSES(획득 실패 후 대기), SLEEPS(대기 중 슬립 상태 전환 횟수) 등의 컬럼을 통해 경합이 심한 래치를 식별할 수 있다.
  • V$LATCH_CHILDREN: 특정 부모 래치에 속한 자식 래치들의 통계 정보를 제공한다. cache buffers chains 래치처럼 여러 개의 자식 래치를 갖는 경우, 어떤 자식 래치에서 경합이 집중되는지 파악하는 데 유용하다.
  • V$LATCH_HOLDER: 현재 특정 래치를 점유하고 있는 세션의 정보를 보여준다. 실시간으로 래치 경합 문제를 분석할 때 활용된다.
  • AWR(Automatic Workload Repository) 리포트: Latches 섹션에서 시스템 운영 기간 동안 누적된 래치 통계와 경합 순위를 확인할 수 있어, 문제의 원인이 되는 래치를 장기적인 관점에서 파악하는 데 효과적이다.

래치 경합이 확인될 경우, 해당 래치의 종류와 특성을 파악하고 그 원인이 되는 SQL이나 애플리케이션 로직을 수정하는 방향으로 튜닝을 진행해야 한다. 예를 들어, library cache 래치 경합은 바인드 변수 사용을 통해, cache buffers chains 래치 경합은 SQL 튜닝이나 파티셔닝 등을 통한 I/O 분산으로 완화할 수 있다.

5. 버퍼 락(Buffer Lock)과 래치(Latch)의 명확한 구분

오라클 성능 분석에서 자주 혼용되는 버퍼 락(Buffer Lock)과 래치(Latch)는 보호하는 대상과 작동 방식에서 명확한 차이를 보인다. 결론적으로, 버퍼 락은 개별 데이터 블록(버퍼)에 대한 접근을 제어하는 반면, 래치는 이 버퍼들을 관리하는 메모리 구조에 대한 접근을 제어하는 더 넓은 개념의 잠금 메커니즘이다.

5-1. 핵심 개념 비교

보호 대상SGA 내 공유 메모리 구조 (예: 버퍼 헤더들의 연결 리스트인 ‘캐시 버퍼 체인’)버퍼 캐시 내의 개별 데이터 블록(버퍼)
역할여러 프로세스가 동시에 메모리 구조를 변경하는 것을 방지하는 ‘문지기’특정 버퍼에 대해 여러 프로세스가 동시에 읽거나 쓰는 것을 방지하는 ‘점유 표시’
점유 시간매우 짧음 (마이크로초 이하)상대적으로 김 (I/O 등 작업이 완료될 때까지)
대기 이벤트latch: cache buffers chainsbuffer busy waits

5-2. 작동 방식의 차이: 단계별 분석

프로세스가 특정 데이터를 읽기 위해 버퍼 캐시에 접근하는 과정을 통해 둘의 관계를 명확히 알 수 있다.

  1. 래치 획득 (Latch Get): 프로세스는 먼저 원하는 데이터 블록이 어느 버퍼에 있는지 찾아야 한다. 이를 위해 버퍼들의 주소 목록이 담긴 ‘캐시 버퍼 체인(Cache Buffers Chain)’이라는 메모리 구조를 스캔해야 한다. 이 체인에 동시 접근하는 것을 막기 위해, 프로세스는 cache buffers chains 래치를 먼저 획득한다.
  2. 래치 점유 및 스캔: 래치를 획득한 프로세스는 아주 짧은 시간 동안 체인을 스캔하여 원하는 데이터 블록이 담긴 버퍼의 주소(버퍼 헤더)를 찾는다.
  3. 래치 해제 (Latch Release): 버퍼 주소를 찾으면, 다른 프로세스가 체인을 스캔할 수 있도록 즉시 래치를 해제한다.
  4. 버퍼 락 획득 (Buffer Lock Get): 이제 프로세스는 찾은 특정 버퍼에 접근해야 한다. 만약 다른 프로세스가 이 버퍼를 사용 중(변경 중)이라면 충돌이 발생하므로, 해당 버퍼에 대한 버퍼 락을 획득하려고 시도한다.
  5. 버퍼 락 대기: 만약 다른 프로세스가 이미 버퍼 락을 점유하고 있다면, 현재 프로세스는 buffer busy waits 이벤트를 발생시키며 대기한다.
  6. 버퍼 작업 및 락 해제: 버퍼 락을 성공적으로 획득한 프로세스는 버퍼에 대한 읽기/쓰기 작업을 수행한 뒤 버퍼 락을 해제한다.

5-3. 결론: 상하 관계의 메커니즘

요약하자면, 래치는 버퍼 락보다 상위 레벨에서 작동하는 더 빠르고 광범위한 보호 장치다. 수많은 버퍼들을 관리하는 ‘도로’에 진입하기 위해 잠시 획득하는 것이 래치라면, 그 도로를 통과해 도착한 특정 ‘주차 공간(버퍼)’을 점유하는 것이 버퍼 락이다.

따라서 latch: cache buffers chains 대기가 빈번하다면 특정 블록이 아닌 버퍼 캐시의 체인 구조 자체에서 경합이 심하다는 의미이며, buffer busy waits 대기가 빈번하다면 소수의 특정 ‘핫 블록(Hot Block)’에 대한 동시 접근이 과도하게 일어나고 있음을 시사한다. 이 두 대기 이벤트를 명확히 구분하는 것이 정확한 성능 진단의 첫걸음이다.

Leave a Comment