[1) 데이터 모델링의 이해]3.버퍼 Lock

Yu River·2022년 5월 31일
0

버퍼 Lock


이미지출처

버퍼 Lock이란?

  • 자신이 현재 그 버퍼를 사용 중임을 버퍼 헤더에 Pin을 설정하여 표시하는 것이다.
  • 캐쉬된 버퍼 블록을 읽거나 변경하려는 프로세스는 버퍼 헤더로부터 버퍼 Lock을 획득해야 한다.
  • Oracle은 Row level로 Lock을 제공한다. 따라서 서로 다른 Row를 변경하는 것은 문제가 되지 않는다. 하지만.....하지만...!!

    🤔 하지만.. 두개의 Row가 같은 블록 안에 있다면 ?

    • 1개의 블록을 동시에 변경하는 것은 안된다.
    • 각 사용자는 개별적으로 Row 변경을 위해 TX Lock을 Exclusive하게 획득해도 한명의 사용자 만이 블록을 변경하고 있다는 것을 보장받아야 한다.
      따라서 !! 이 경우에 획득해야 하는 Lock이 바로 버퍼 Lock인 것이다!
  • 하나의 cache buffers chains Latch를 통해 여러 해시 체인이 보호 되고 있다.
  • 동시에 하나의 버퍼 블록을 접근 할 경우 정합성 문제가 발생할 수 있어 Latch를 통해 직렬화를 수행한다.
  • 버퍼 블록을 찾으면 버퍼 Lock 설정 후 Latch를 해제하고 버퍼 Lock을 못 얻으면 Lock을 획득할 때까지 대기한다.
  • 버퍼 블록 Lock 해제 시 Latch를 다시 획득해야 한다.
    • 😮‍💨 한 개 블록 읽기가 이렇게나 고비용인 것이다ㅜㅜ

버퍼 Lock 상태

Share 모드 Lock

  • 버퍼 내용을 읽기만 할 때 사용한다.

Exclusive 모드 Lock

  • 버퍼 내용을 변경할 때 사용한다.
  • buffer busy waits 대기 이벤트
    • 버퍼가 Exclusive모드로 점유되어 있다면 버퍼 헤더의 Lock 대기자 목록(Waiter List)에 등록 후 래치를 해제한다.(래치와 락은 다르다 ! 공부할 때 항상 헷갈렸던 ..😥)
    • 선행 버퍼 Lock이 해제되면 그 때 버퍼 Lock을 획득할 수 있다.

버퍼 Lock 설정시 래치 획득

  • 블록 읽을 때 대부분 두번 래치를 획득한다.
    • 블록을 찾을 때 Pin 설정하기 위해 래치 획득 => 다쓰고 Pin 해제할 때 래치 획득
  • 몇몇 오퍼레이션은 한번만 래치를 획득한다.
    • consistent gets ( 문장 일관성 읽기 )

버퍼 LOCK 획득/해제 과정

  1. 변경하고자 하는 Row에 해당하는 Block이 존재하는 위치에 찾아가기 위해 cache buffer chains latch를 획득한다.
  2. Block을 찾은 해당 Buffer에 대해 Buffer Lock을 획득하고, cache buffers chains latch를 해제한다.
  3. 해당 Row에 대해 TX Lock을 획득하고 Row를 변경한다.
  4. Buffer Lock을 해제하기 위해 래치를 획득하여 PIN을 해제한다.

버퍼 핸들

  • 버퍼 헤더에 Pin을 설정하려고 사용하는 오브젝트이다.
  • 버퍼 핸들을 얻어 버퍼헤더에 있는 소유자 목록에 연결 시켜 Pin을 설정한다.
  • 버퍼 핸들을 얻으려면 cache buffer handles 래치가 필요하다.
  • 각 프로세스 마다 _db_handles_cached(5) 개수 만큼 버퍼 핸들을 미리 할당한다.

Pinned 버퍼

  • 버퍼 헤더에 Pin을 설정하여 버퍼 Lock을 걸고 버퍼 사용중을 표시한 것이다.
  • 하나의 프로세스만 Pin이 가능하며 읽기는 여러 프로세스가 동시에 Pin이 가능하다.

버퍼 Lock의 필요성

  • 오라클의 I/O , 레코드 갱신은 블록 단위로 진행된다.
  • 정합성 유지를 위해 블록 자체로의 진입을 직렬화 해야한다.
    • 예를들어 버퍼 락이 없는 경우.. 블록 내 10개 레코드를 읽는 순간 다른 프로세스에 의해 변경이 발생 하면 잘못된 결과를 초래할 수 있다.
  • 로우 단위 Lock 설정도 레코드 속성 변경이므로 동시 수행은 문제가 된다.
  • 블록 헤더 변경(블록 SCN, ITL 슬롯 등)도 동시 수행은 문제가 된다.
  • 동시 수행(update)의 경우 Lost Update가 발생할 수도 있다.

    ✅ Lost Update란?

    다수의 transaction이 동시에 실행되는 환경에서 서로 다른 transaction이 UPDATE 연산을 연속으로 수행하면, 먼저 실행된 UPDATE 연산이 overwriting 되는 현상

버퍼 Pinning

  • 버퍼를 읽고 나서 버퍼 Pin을 즉각 해제하지 않고 데이터베이스 Call이 진행되는 동안 유지하는 기능이다.
  • 하나의 데이터베이스 Call 내에서만 유효하다.

    데이터 베이스 Call의 종류

    • Parse Call
    • Execute Call
    • Fetch Call
  • Pin된 버퍼 블록은 alter system flush buffer_cache; 에도 밀려 나지 않는다.
    • alter system flush buffer_cache 명령어를 사용하여 버퍼 캐시 전체를 비울 수 있다.
    • 9i에서는 alter system set events 'immediate trace name flush_cache'; 를 통해 버퍼캐시를 비울 수 있다.
  • 같은 블록을 반복적으로 읽을 때 버퍼 Pinning을 이용해 래치 획득 과정을 생략하여 논리적 블록읽기 횟수를 획기적으로 줄일 수 있다.
  • 같은 블록을 재방문할 가능성이 큰 오퍼레이션을 수행할 때만 사용하도록 한다.
  • 버퍼 Pinning을 통한 블록 I/O 감소효과는 SQL 튜닝의 중요한 부분이다.
  • Reorg 를 통한 인덱스 클러스터링 팩터를 높여 버퍼 Pinning 개선이 가능하다.

버퍼 Pinning 발생 지점

  • 인덱스를 경유해 테이블을 액세스 할 때 인덱스 클러스트링 팩터가 좋다면 같은 테이블 블록을 반복 액세스할 가능성이 크다. (Oracle 8i)
  • 테이블에 액세스할 때 인덱스를 스캔하여 인덱스 리프 블록을 방문할 때 전통적으로 버퍼 Pinning이 발생한다.
  • 인덱스로부터 액세스되는 하나의 테이블 블록에서 발생한다. (8i)
  • NL 조인 시 Inner 테이블을 Lookup 하기 위해 사용되는 인덱스 루트 블록에 발생한다. (9i)
  • Index Skip Scan 시 브랜치 블록을 거쳐 리프 블록을 액세스 하는 동안 발생한다. (9i)
  • NL 조인 시 Inner 테이블의 루트블록 뿐만 아니라 다른 인덱스 블록에 대해서도 Pinning을 하기도 한다. (11g)
  • DML 수행 시 Undo 레코드를 기록하는 Undo 블록에 발생한다.

) 참고 출처 1
) 참고 출처 2

profile
도광양회(韜光養晦) ‘빛을 감추고 어둠속에서 힘을 기른다’

0개의 댓글