05.오라클 LOCK

h3.(1) Enqueue Lock

  • Enqueue는 공유 리소스에 대한 액세스를 관리하는 Lock 메커니즘이다.
  • Enqueue에의해 보호되는 공유 리소스로는 태이블,트랜잭션,태이블스페이스,시권스, Temp 세그먼트 같은 것들이 있다
  • Enqueue Lock은 래치와 달리 순서가 보장되는 큐(Queue) 구조를 사용한다.
  • Enqueue Lock으로 관리되는 공유 리소스에 대해 Lock을 획득하려면 먼저 'Enqueue 리소스' 를 할당받아야 한다.
  • Enqueue 리소스는 소유자(owner), 대기자(waiter) 목록을 관리할 수 있는 구조체(Structure)를 말한다.
  • 소유자가 Exclusive 모드일 때는 한 순간에 하나의 세션만 Lock을 획득할 수 있지만 , Shared 모드일 때는 여러 세션이 동시에 Lock을 획득할 수 있다.

Enqueue Lock의 작동 메커니즘

1. A 세션이 Shared 모드로 Lock을 획득한다.
2. B 세션이 Shared 모드로 Lock을 획득하려고 한다. 먼저 Lock을 소유한 A 세션과 호환되므로 정상적으로 Lock을 획득한다. 이제 소유자 목록에는 두 개 세션이 달려있다.
3. C 세션이 Exclusive 모드로 Lock을 획득하려고 한다. Shared 모드와 Exclusive 모드 간에 호환성이 없으므로 대기자 목록에 자신을 등록하고 대기한다.
4. 소유자 목록에 Shared 모드로 달려 있던 AB 두 세션이 모두 Lock을 해제하면 C세션이 Exclusive 모드로 소유자 목록에 등록된다.
5. A 세션이 Exclusive 모드로 다시 Lock을 획득하려고 하면, Exclusive 모드와 호환되지 않으므로 대기자 목록에 자신을 등록하고 대기한다.
6. B 세션이 다시 Shared 모드로 Lock을 획득하려고 할 때도 Exclusive 모드와 호환되지 않으므로 대기자 목록에 자신을 등록하고 대기한다.
7. Enqueue Lock은 순서가 보장되므로 C 세션이 Lock을 해제하면 A 세션이 가장 먼저 Exclusive 모드로 Lock을 획득한다.

  • TM Lock 구조체 식별자
TYPEID1ID2
TX오브젝트 ID0

h3.(2)TX Lock(=트랜잭션 Lock)

  • 트랜잭션을 시작하려면 먼저 Undo 세그먼트 헤더에 위치한 트랜잭션 테이블로부터 슬롯{SI이)을 하나 할당받아야 한다
  • 변경 블록에 대한 다른 트랜잭션은, 트랜잭션 슬롯에 기록된 상태 정보를 확인 , CR 블록을 생성해서 읽기도 한다.
  • 변경 중인 레코드(또는 기타 리소스〉를 동시에 변경하려는 트랜잭션에 대 해서는 액세스를 직렬화 메카니즘
  • TX Lock 구조체 식별자
TYPEID1ID2
TXUndo 세그먼트 + 트랜잭션 슬롯번호트랜잭션 슬롯 Sequence 변호

Enqueue Lock의 작동 메커니즘

1. TXl 트랜잭션은 Undo 세그먼트에서 트랜잭션 슬롯을 할당 받고, Enqueue 리소스를 통해 TX Lock을 설정한다. 이 상태에서 r1부터 r5까지 5개 레코드를 변경하고,아직 커밋은 하지 않았다.
2. TX2 트랜잭션도 트랜잭션 테이블에서 하나의 슬롯을 할당 받고, Enqueue 리소스를 통해 TX Lock을 설정한 후 r6 레코드를 변경한다.
3. 이제 TX2가 r3 레코드를 액세스하려는 순간 호환되지 않는 모드로 Lock이 걸려 있음을 인지하고 TX1의 트랜잭션 슬롯 상태를 확인한다.
4. TX1 이 아직 커밋되지 않은 Active 상태이므로 TX2는, TX1이 Lock을 설정한 Enqueue 리소스 구조체 대기자 목록에 자신을 등록하고, 대기 상태로 들어간다.
4. TX2는 대기하면서 3초마다 한번씩 TX1이 설정한 TX Lock의 상태를 확인한다. 교착상태 (Deadlock)발생 여부를 확인하기 위함이다.
5. TX1 이 커빗 또는 롤백하면 TX1이 설정한 Tx Lock의 대기자 목록에서 가장 우선순위가 높은 TX2 트랜잭션을 깨워 트랜잭션을 재개하도록 한다.
6. TX2는 r3 레코드를 변경한다.

  • 발생원인
    ① DML 로우 Lock
    ② 무결성 제약 위 배 가능성
    ③ 비 트뱀 인텍스 엔트리 갱신
    ④ ITL 슬롯부족
    ⑤ 인텍스분할
    ⑥ 기타

h3.(3)TX Lock ▶ 무결성 제약 위배 가능성 또는 비트맙 인텍스 엔트리 갱신

  • 로우 Lock 경합은 일반적으로 update나 delete 시에만 발생한다.
  • insert는 로우 Lock 경합이 발생하지 않지만 Unique 인텍스가 정의되어 있을 때는 insert에 의한 로우 Lock 경합이 생길수 있다.

h3.(4)TX Lock ▶ITL 슬롯 부족

  • 블록에 레코드를 추가/갱신/삭제하려면 ITL 슬롯을 먼저 할당 받고 그 곳에 트랜잭션ID를 먼저 기록해야 한다.
  • 비어 있는 ITL 슬롯이 없다면 Shared 모드 enq: TX-allocate ITL entry 대기 이벤트가 발생한다

h3.(5)TX Lock ▶ 인텍스 분할

  • 인텍스는 정렬된 상태를 유지해야 한다.
  • 따라서 값을 입력할 위치에 빈 공간이 없으면 인텍스 분할(Split)을 실시해 새 값을 입력할 공간을 확보하게 되며 Lock 경합이 발생할수있다.

h3.(6)TX Lock ▶ 기타 트랜잭션 LocK

  • 분산 트랜잭션에서 2-Phase 커맛을 위한 PREPARED TX Lock을 대기할 때 발생한다 (오라클 메뉴얼)
  • 읽기 전용 태이블스페이스로 전환할 때도, 이 TX Lock 경합이 발견된다.

h3.(7)TX Lock ▶ DML 로우 Lock

  • DML Lock은, 다중 사용자에 의해 동시에 액세스되는 사용자 데이터의 무결성을 보호 해 준다
  • 오라클은 로우 Lock을,①로우 단위 (row-Ievel Lock과 ②Tx Lock을 조합해서 구현하였다.
    • 로우 단위 Lock: 블록 헤더 IT피+ 로우 헤더 Lock Byte 설정을 의미함. 이를 통해로우를 갱신 중인 트랜잭션 상태를 확인하고 액세스 가능 여부를 결정함
    • TX Lock : Enqueue 리소스를 통해 TXLρck을 설정하는 것을 의미함. Lock이 설정된 레코드를 갱신하고자 할 때 Enqueue 리소스에서 대기함

h3.(8)TX Lock ▶ DML 테이블 Lock

  • 오라클은 로우 Lock 획득 시, 해당 테이블에 대한 테이블 Lock도 동시에 획득한다.
  • 현재 트랜잭션이 갱신 중인 테이블에 대한 호환되지 않는 DDL 오퍼레이션을방지한다.
  • Lock Table 명령어
    • lock table emp in row share mode
    • lock table emp in row exclusive mode
    • lock table emp in share mode
    • lock table emp in share row exclusive mode
    • lock table emp in exclusive mode
  • Lock 모드간 호환성
  • Lock 모드간 호환성
NullRSRXSSRXX
NulOOOOOO
RSOOOOO
RXOOO
SOOO
SRXOO
XO
    • RS : row share (또는 SS : sub share)
    • RX : row exclusive (또는 SX : sub exclusive)
    • S : share
    • SRX : share row exclusive (또는 SSX : share/sub exclusive)
    • X : exclusive

h3.(9) Lock을 푸는 열쇠 , 커밋

  • 오라클에서 교착상태가 발생하면 이를 먼저 인지한 세션이 문장 수준 롤백을 진행한 후에 아래 에러 메시지를 던진다. 교착상태를 발생시킨 문장 하나만 롤백하는 것이다
    • ORA- 00060 : deadl ock detected while wait ing for resource
    • 에러에 대한 예외 처리 (커밋 또는롤백)를하지 않는다면 대기 상태를 지속하게 되므로주의가 필요하다.
  • 불필요하게 커밋을 너무 자주 수행하면 Snapshot too old(ORA-01555) 에러를유발할 가능성이 높아진다.
  • 비동기식 커밋기능
    • WAIT(Defualt) : LGWR가 로그버퍼를 파일에 기록했다는 완료 메시지를 받을 때까지 대기하며, 그 동안 log fjle sync 대기 이벤트가 발생한다(동기식 커밋).
    • NOWAIT : LGWR의 완료 메시지를 기다리지 않고 바로 다음 트랜잭션을 진행하므로, log fjle sync 대기 이벤트가 발생하지 않는다(비동기식 커밋).
    • IMMEDIATE(Defualt) : 커빗 명령을 받을 때마다 LGWR가 로그 버퍼를 파일에 기록한다 .
    • BATCH : 세션 내부에 트랜잭션 데이터를 일정량 버퍼링했다가 일괄 처리한다.

SQI> COMMMIT WRITE IMMEDIATE WAIT 
SQI> COMMMIT WRITE IMMEDI ATE NOWAIT
SQI> COMMMIT WRITE BATCH WAIT 
SQI> COMMMIT WRITE BATCH NOWAIT