본문 바로가기

# 미사용

오라클 Buffer Lock

Buffer Lock

버퍼 락은 오브젝트의 제어권한을 얻기 위한 잠금장치이며,

DB Buffer Cache에서의 락은 특별하게 Pin이라고 불린다.


저번 장에서 설명했던 Pinned Buffer가 바로 그것이며,

락을 얻은 세션만이 해당 버퍼를 수정할 수 있는 권한을 얻는다.


특정 오브젝트의 락을 얻기 위해서는 먼저 접근권한부터 얻어야 하는데,

다음과 같은 매커니즘으로 이루어진다.

Lock 획득과정

  • 래치 획득  (접근권한 획득)
  • 락 획득     (제어권한 획득)
  • 래치 해제  (접근권한 해제)


다시 락을 해제할 때에도 먼저 접근권한부터 얻어야 하는데,

락을 푸는 도중에 다른 프로세스가 버퍼 헤더에 접근할 수 있기 때문이다.

Lock 해제과정

  • 래치 획득
  • 락 해제
  • 래치 해제


하지만 항상 위의 프로세스를 따르는 것은 아니다.


래치를 놓을 필요가 없는 일부 오퍼레이션에서는 

해당 작업이 끝날 때 까지 래치가 반환되지 않는다는 사실을 기억해두길 바란다.


Note.

래치를 해제하지 않는 트랜잭션.


래치를 놓을 필요가 없는 일부 트랜잭션에서는

해당 트랜잭션이 끝날 때 까지 래치를 반환하지 않을 수 있다.


여기서는 자세하게 다루지 않는다.



Note.

락을 해제하지 않는 트랜잭션.


락을 놓을 필요가 없는 일부 오퍼레이션에서는

해당 트랜잭션이 끝날 때 까지 락을 해제하지 않을 수 있다.


한 트랜잭션이 동일한 블럭을 반복해서 읽을 가능성이 있는 경우,

해당 블럭에 대한 락을 유지하는 것이 성능상 유리하기 때문이다.

→ 반복되는 래치 경합을 줄여주기 때문.


위처럼 락을 유지하는 매커니즘을 Buffer Pinning 이라고 하며,

관련있는 데이터를 최대한 가까운 블럭에 모을 수 있다면 큰 성능향상을 노릴 수 있다.


자세한 내용과 예제상황은 아래 노트에서 설명한다.



Note.

Buffer Pinning과 물리적 읽기/논리적 읽기


저번장에서 SQL의 성능을 판단하는 가장 큰 판단지표는 "읽은 블럭의 수" 라고 하였지만,

좀 더 구체적으로 설명하자면 "물리적으로 읽은 블럭의 수" 이다.


예를들어 1부터 10까지 순서대로 읽어야 하는 트랜잭션이 있다고 가정하고,

다음 상황에서의 읽은 블럭 수를 예상해보자.


Case A ) 관련된 데이터가 흩어져 있는 상황.










9


7



3


6


2



4





8



5





10


Case B) 관련된 데이터가 모여 있는 상황.















1 2 3 4 5













6 7 8 9 10










이제, 해당 트랜잭션이 각각의 상황에서 총 몇 개의 블럭을 읽었는지 생각해보자.



Buffer Lock을 설명하기 전에,

그리 놀라운 사실은 아니지만 블럭을 읽을 때도 Lock이 필요하다.


조금만 생각해보면 왜 그런지 알 수 있는데,

블럭을 읽는 도중에 블럭의 내용이 변경되면 안되기 때문이다.


즉, 읽기동작이 진행되는 도중에는 쓰기동작이 허용되면 안된다는 것을 의미하며,

읽기와 쓰기는 서로 배타적인 동작이라는 것이 된다.


그렇다면 여기서 몇 가지 의문점이 생기는데,

다음의 경우는 배타적으로 동작되어야 하는지 곰곰히 생각해보기 바란다.

  • 쓰기작업과 읽기작업
  • 쓰기작업과 쓰기작업
  • 읽기작업과 읽기작업

블럭의 내용이 변경되지 않는 가정하에서

여러 읽기작업이 동시에 진행되어도 딱히 상관없으며,

오히려 병렬성을 증가시켜 DBMS의 성능을 향상시키는 결과를 가져온다.


위의 동시-읽기작업 매커니즘은 DBMS의 병렬성을 향상시키는 핵심 기능이며,

상용가능한 DBMS는 모두 이 매커니즘을 사용한다는 것을 기억해두기 바란다.


정리하자면 다음과 같다.

  • 쓰기작업과 읽기작업은 락이 필요한 동작이다.
  • 쓰기작업과 읽기작업은 서로 배타적인 동작이다.
  • 쓰기작업이 진행되면 쓰기작업이나 읽기작업이 진행되지 못한다.
  • 쓰기작업만 없다면 여러개의 읽기작업이 동시에 진행되어도 상관없다.


위의 사항에서 도출 가능한 디자인은 다음과 같다.

  • 쓰기작업과 읽기작업은 서로 다른 성질의 락을 사용한다. → Lock 모드
  • 하나의 오브젝트는 여러개의 락을 동시에 가질 수 있다. → Buffer 핸들


이제 서론은 끝났다.

위의 매커니즘을 차례차례 살펴보자.


Lock Mode

위에서 설명했듯이 읽기작업과 쓰기작업은 서로 다른 종류의 락이 필요하다.

즉, 다음의 조건을 만족하도록 락을 구현해야 한다.

 

 쓰기 Lock

 읽기 Lock

 쓰기 Lock

불가

불가

 읽기 Lock

불가

가능


오라클은 위의 형태를 만족하는 락을 설계했다.

각각의 이름은 다음과 같으며,

  • 쓰기 Lock  → 배타적 락, X Lock,  Exclusive Lock
  • 읽기 Lock  → 공유적 락, S Lock,  Share Lock 

보편적으로 X-Lock,  S-Lock 이라고 한다.


이외에도 다양한 모드의 락이 존재하지만,

지금 우리는 쓰기와 읽기에만 관심이 있기 때문에, 

이외의 동작에서 사용되는 락은 무시하도록 한다.


또한 서로 다른 두 성질의 락이 공존 가능할 때, 호환성이 있다고 표현하며.

X-Lock과 S-Lock의 호환 여부는 다음과 같다.

 

 X Lock

S Lock

 X Lock

호환불가

호환불가

 S Lock

호환불가

호환가능


Buffer Handle

락을 설정했다는 것은 자신이 현재 그 버퍼 블럭을 사용중임을 표시해두는 것으로 Pin 이라고도 불리며, 

위에서 설명했듯이 하나의 블럭이 여러개의 락을 동시에 가질 수 있다.


버퍼 블럭에 락을 걸기 위해서는 (사용중임을 표시하기 위해서는)

버퍼 헤더에 있는 "블럭 소유자 목록"에 Lock Object를 연결해야 하며,

이 때 필요한 락 오브젝트를 Buffer Handle 이라고 한다.


버퍼 핸들은 공유자원이지만 프로세스마다 _db_handles_cached개 만큼 캐시되어 있다. (기본값 5)

다만, 추가적으로 버퍼 핸들을 얻기 위해서는 cache buffer handles latch를 얻어야 한다.


시스템적으로 사용할 수 있는 버퍼 핸들의 전체 개수는 

process 파라미터와 _db_handles_cached 파라미터의 곱으로 결정되며,


Pin을 설정하려는 세션이 많을수록 cache buffer handles latch가

경합지점이 될 수 있다는 것을 기억하기 바란다. 


'# 미사용' 카테고리의 다른 글

Router : 재사용 가능성  (0) 2018.06.28
오라클 Redo  (0) 2018.05.21
오라클 DB Buffer Cache  (0) 2018.05.17
오라클 기본 아키텍쳐  (0) 2018.05.15
알고리즘 개요  (0) 2018.05.04