프로젝트/데이터베이스

디비 아키텍처 - 버퍼 LOCK

쿠키담임선생님 2025. 8. 19. 12:37

버퍼 상태는 총 3가지가 있다

  1. 프리 버퍼 = 말그대로 프리함. 비어있다는 뜻. 여기에 이제 데이터를 언제든지 덮어써도 무방한 버퍼임.
  2. 더티 버퍼 = 사용자가 무엇인가 수정했다? 그러면 일단 버퍼 캐시에 수정이 되잖슴? 그런데 아직 데이터파일에는 반영이 안된 상태임.
  3. 핀 버퍼 = 읽기 쓰기 작업을 위해 현재 엑세스 되고 있는 버퍼 블록임. 앞에서 말햇듯 sga영역은 여러 서버 프로세스가 공유하기에 래치라는 블락 매커니즘을 적용함. 이때 버퍼 상태는 핀 버퍼 상태임!!! ㅇㅋ?

버퍼 Lock ( 다른 말로 버퍼 핀 ) pin 꼿앗다 할때 그거


버퍼 캐시에서 버퍼 블록을 찾으면 빨리 래치 해제해야함.

안그러면 래치에 여러 해시 체인이 달렸으니까 래치 경합 발생!!!

아니 근데 왜 버퍼락이 필요한거지… 래치를 통해서 어차피 동시성 접근 막지 않나….


좋은 질문이야. (좋은질문이라고 지피티한테 칭찬받음)

래치(latch)와 버퍼 락(buffer lock)은 둘 다 동시성 제어를 위한 메커니즘이지만, 목적과 사용 시점이 다르기 때문에 둘 다 필요


🔒 래치(Latch): 메모리 구조 보호용 "경량 잠금"

  • 목적: SGA 내부 구조(버퍼 캐시 등)의 무결성을 보장하기 위해 사용돼.
  • 특징:
    • 매우 짧은 시간 동안만 보유.
    • OS 커널 수준의 락이 아닌, 사용자 수준의 spin lock. (커널수준의 락이 얼마나쌘지 사실모르겟음)
    • 예: 버퍼 체인을 따라가면서 블록을 찾을 때, 그 체인 구조가 중간에 바뀌면 안 되므로 래치로 보호. = 즉 체인 구조를 보호한다!!!

✅ 예시

버퍼 캐시에서 어떤 블록을 찾기 위해 해시 체인을 따라갈 때:

"체인 구조 자체를 수정/읽는 동안은 중간에 다른 프로세스가 이 구조를 바꾸면 안 되므로 래치를 잠깐 잡는다."


🔐 버퍼 락(Buffer Lock): 데이터 보호용 "장기 잠금"

  • 목적: 데이터 블록 수준에서의 읽기/쓰기 충돌 방지.
  • 특징:
    • 데이터 조작 중에는 버퍼 락을 통해 사용자 트랜잭션 간 충돌 방지.
    • 공유 모드(S)와 배타 모드(X) 등으로 세분화 가능.
      • 공유모드 = 쉐어 모드는 읽기 작업일때
      • 베타모드 = 익스클루시브 모드는 쓰기 작업일때
    • 래치보다 보유 시간이 길다.

✅ 예시

사용자 A가 블록을 수정 중인데 사용자 B도 같은 블록을 읽으려 하면:

"버퍼 락을 확인해서 아직 A가 X모드로 보유 중이니까 대기하거나 S 모드로 접근 제한."


🧠 왜 래치만으로는 부족할까?

  • 래치는 내부 구조 보호(예: 해시 체인 따라가기, 버퍼 캐시 배열 등)의 "짧고 빠른 락".
  • 버퍼 락트랜잭션 간 충돌 방지를 위한 "데이터 보호 목적의 락".
  • 래치는 구조의 무결성을 지키고,
  • 버퍼 락은 데이터 자체의 정합성을 지켜.

🔄 정리 요약

구분 래치 (Latch) 버퍼 락 (Buffer Lock)

보호 대상 내부 구조(SGA 구조체 등) 데이터 블록
유지 시간 짧다 (ms 단위) 상대적으로 길다
충돌 주체 시스템 내부 처리 간 사용자 트랜잭션 간
주요 목적 구조의 무결성 보장 데이터 정합성 보장

결국 래치와 버퍼락 두개 순차적으로 같이 사용한다.

이해를 돕기위한 예시 시나리오(블록 하나를 읽을때 일어나는 일들)


🔄 하나의 데이터를 읽을 때 흐름

✅ 1. 래치 획득 (구조 보호)

  • 먼저 버퍼 캐시의 해시 체인을 따라가서 원하는 블록이 메모리에 있는지 찾아야 한다!
  • 이 과정에서 해시 체인 구조가 바뀌면 안 되므로, 래치를 획득
  • 이건 아주 짧게만 잡아. 구조만 안전하게 읽고 나면 바로 해제

☑️ 목적: 내부 구조(SGA 버퍼 캐시 체계) 보호

✅ 2. 버퍼가 있으면 → 버퍼 락 획득 (데이터 보호)

  • 원하는 블록이 메모리에 이미 올라와 있다면, 그 블록의 데이터 자체에 대해 버퍼 락을 잡는다.
  • 버퍼 락을 잡는과 동시에 래치는 해제한다. (중요)
  • 버퍼 락은 공유 모드(S)로 잡아서 다른 트랜잭션도 동시에 읽을 수 있게 해.

☑️ 목적: 데이터 충돌 방지, 정합성 보장

✅ 3. 읽기 수행

  • 이제 버퍼에서 데이터를 읽고 트랜잭션 레벨의 작업을 진행함.

✅ 4. 버퍼 락 해제

  • 읽기 작업이 끝나면 버퍼 락은 해제함.

✅ 5. 래치 해제

  • 버퍼 락을 해제할때 버퍼 헤더를 엑세스하는 다른 프로세스와 충돌이 생길 수 있으니까 해당 버퍼가 속한 체인 래치를 다시 획득.

만약 래치를 획득하고 버퍼를 찾았는데 그 버퍼에 락걸려있으면?


이때 버퍼 헤더에 있는 버퍼 Lock 대기자 목록에 자신을 등록 후 래치는 일단 해제.

이때 버퍼 lock 대기자 목록에 등록되어 있는 동안 buffer busy waits 대기 이벤트가 발생한다.

기다리다가 버퍼 lock이 해제되면 버퍼 lock을 획득하고 작업 진행한다.

버퍼 핸들


버퍼 락을 버퍼 핀이라고도 한다.

핀을 걸엇음을 의미함

아까 위에서 말햇듯이 읽기 작업은 쉐어드 모드로 걸린다.

즉 변경할때는 하나의 프로세스만 핀 설정.

읽기작업만일때는 여러 프로세스가 동시에 핀 설정 가능.

버퍼 헤더에 핀을 설정하려고 사용하는 오브젝트를 버퍼 핸들 이라고 부른다.

그런데 버퍼 핸들도 리소스임. 즉 버퍼 핸들을 또 얻으려면 다른종류의 래치가 필요.

이 래치의 이름은 “캐시 버퍼 핸들 래치”

결국 버퍼 핸들도 동시성으로 경합지점이 됨.

이를 방지하기 위해 오라클에서는 버퍼 핸들을 미리 5개 만들어둠.

물론 더 필요하면 추가로 버퍼 핸들이 할당되긴함.

버퍼락의 필요성


어차피 dml 락으로 사용자 데이터 변경 함부로 못하게 막는데 왜 또 다른 버퍼락이 필요한걸까…?

이유는 하나의 row 즉 하나의 레코드를 갱신하더라고 블록 단위로 IO가 발생하기 때문이다.

이해를 위해 또 예시상황을 가져왓다.

상황 비유: 공동 작업하는 회사 문서 수정

👥 등장인물

  • A, B 직원: 동시에 일하는 사용자들
  • 문서: 우리가 수정하려는 사용자 데이터 (테이블의 행, Row)
  • 문서함: 문서가 담긴 캐비닛 (버퍼 캐시의 데이터 블록)
  • 사물함 자물쇠: 버퍼 락 (buffer lock)
  • "수정 중" 포스트잇: DML 락 (row lock)

📦 시나리오

✅ Step 1. A가 문서(id=1)를 수정하려고 함

  1. A가 문서함(=버퍼 블록)에서 해당 문서를 꺼내려 해.
  2. 먼저 문서함이 안전하게 열려 있는지 확인하고, 자물쇠를 건다. → 🟦 buffer lock 획득
  3. → 문서함 안의 물리적인 내용물을 안전하게 꺼내기 위한 잠금
  4. 문서를 꺼내서 책상에 올리고, 수정하기 시작함
  5. 동시에 "수정 중" 포스트잇을 붙임 → 🟨 DML lock
  6. → 다른 사람이 이 문서를 건드리지 않도록 논리적 보호

이걸 보면 이해가 쏙쏙~

즉 두가지 락이 동시에 걸려있는 상황이 있을 수 있다~~~ 명심~~~

버퍼 pinning 기능


버퍼를 읽고 나서 버퍼 pin을 즉각 해제하지 않고 데이터베이스 call 이 진행되는 동안 유지하는 기능을 말한다.

그리고 버퍼 pinning 을 사용하면서 블록 I/O 감소효과가 있음.