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 |