h2.Enq: TX - row lock contention,Enq: TX - allocate ITL Entry,Enq: TX - Index contention

  • 오라클 10g부터는 TX락이 사용되는 상황에 따라 적절한 이름의 대기이벤트 이름이
    부여되었다.
  • TX 락은 트랜잭션을 보호하는 것이므로, 트랜잭션이 종료될 때 해제 된다.
  • TX 락을 획득 하기 위해 대기하는 세션은 락을 보유하고 있는 세션의 트랜잭션이 종료
    될 때까지 기다려야 한다.

주요 대기 현상

1. 특정 로우를 변경하고자 하는 경우
enq:TX - row lock contention
2. 특정 로우에서 Unique key나 Primary Key에 해당하는 컬럼을 변경하고자 하는 경우
enq: TX - row lock contentiion
3. 변경하고자 하는 블록의 ITL 에 자신에 해당하는 트랜잭션 엔트리(Transaction Entry)
를 등록하고자 하는 경우.
Enq: TX - allocate ITL entry
4. 비트맵 인덱스(Bitmap Index)가 생성되어 있는 컬럼 값을 변경하고자 하는 경우
Enq; TX - allocate lock contention
5. 인덱스 리프 노드(Index Leaf Node)에서 Split이 발생하는 경우
Enq: TX - Index contention
6. 기타의 경우
Enq: TX - Contention

여러 세션이 동일 로우를 변경하는 경우

( enq: TX - row lock contention, mode = 6 )

  • 오라클은 "로우 자에의 변경사실 + ITL + 트랜잭션 테이블 슬롯 + TX 락"을 이용해서
    로우 레벨 락을 구현한다.

여러 세션이 Unique Key 충동을 일으키는 경우

(enq: TX - row lock contention, mode=4 )

  • Unique Key 또는 Primary Key 충돌이 발생할 때도 TX 락 경합이 발생
  • 프로세스 A 가 Insert 를 수행한 후, 프로세스 B가 Unique Key 충돌이 발생하게끔
    Insert를 수행하며, 프로세스 B는 TX 락을 Shared 모드로 획득하기 위해 대기한다.
  • 프로세스 B는 프로세스 A가 커밋 하거나 롤백할 때까지 대기
  • 프로세스 A에서 커밋이 이루어지면, ORA-0001 에러 상황이 되며,
    롤백이 이루어지면 프로세스 B의 insert 는 성공적으로 이루어지게 된다.

  • 이 결과에서 오라클이 Unique Key 를 보호하기 위해서 어떤 방법을 사용하는지
    간접적으로 추론할 수 있다. 오라클은 테이블에 로우를 추가한 후 인덱스도 함께 추가하게
    되는데 인덱스를 추가하는 과정에서 Unique 속성을 위반하는지 확인 한다.
    최선의 해결책은 시퀀스(Sequence)를 사용해서 Unique Key 를 생성하는 것이다.

h2.ITL 엔트리 부족(enq:TX - allocate ITL entry, mode = 4)

  • 모든 트랜잭션은 블록을 변경시키기 전에 블록 헤더의 ITL에 엔트리를 등록해야 한다.
  • 만일 ITL이 약속된 최대치, 즉 MAXTRANS에 의해 지정된 값을 초과하거나 블록 내의
    여유공간이 부족해서 엔트리를 등록하는 것이 불가능한 경우, 프로세스는 이미 ITL에
    엔트리를 등록한 프로세스가 Exclusive 하게 획득한 TX 락을 Shared 모드로 획득하기
    위해 대기 하게 된다.이때 enq: TX - allocate ITL entry 이벤트가 발생
  • INITRANS : 블록 헤더마다 몇 개의 ITL 엔트릴를 마리 확보할 지를 결정
  • MAXTRANS : 최대 몇 개의 ITL 엔트리를 허용할지를 결정
    오라클 10g 부터는 MAXTRANS 255 로 고정된다.
    즉. MAXTRANS 값을 지정해도 오라클은 이 값을 무시하며 항상 255 !!!
  • PCTFREE : 블록이 최초 생성될 때는 INITRANS 에 지정된 값 만큰 ITL 엔트리가 확보
    되지만, 동시 트랜잭션이 증가하면 PCTFREE 로 확보된 영역 내에서
    MAXTRANS만큼 추가로 확장

  • 만일 동시 트랜잭션이 왕성할 것으로 예상되는 테이블이라면 INITRANS 를 충분히
    주는 것이 좋다. INITRANS 를 충분히 주면 동적으로 공간을 확보하는 오버헤드가 줄어들며,
    ITL 엔트리 부족에 따른 TX 락 경합이 발생할 확률도 줄어든다.
    또한 PCTFREE 값을 비정상적으로 작게 설정하는 경우 ITL 을 동적으로 확장할 여유 공간이
    부족하여 문제가 될 수 있다.

여러 세션이 비트맵 인덱스(Bitmap Index) 충돌을 일으키는 경우

( enq: TX - row lock contention, mode=4 )

  • BTREE 인덱스의 Leaf Node 는 정렬된 형태로 인덱스 엔트리 들을 저장하며
    개개의 인덱스 엔트리는 하나의 ROWID를 가리킨다.
    따라서, Unique Key 충돌을 제외하고는 인덱스 엔트리 간에는 경합이 발생하지 않는다.
  • Bitmap 인덱스의 Leaf Node 는 "Column의 값 + Start rowid + End rowid + Bitmap 값
    형태를 지닌다. 즉, 하나의 Leaf Node 가 넓은 범위의 ROWID를 관리 한다.
    테이블 로우가 변경될때마다 비트맵 인덱스에 해당하는 컬럼값에 대해 로우가 속한
    Leaf Node 의 Bitmap 을 매번 새로 계산해주어야 한다. 따라서 동시에 두 세션이
    같은 Lead Node에 대해 Bitmap 연산을 수행할 경우, 순서를 보장하기 위해 TX 락을
    획득해야 한다.

  • 상기 현상은 Unique Key 충돌에 의한 대기현상과 완전히 동일하다.
    대기 현상만으로는 Unique Key 충돌과 Bitmap Index 충돌간의 차이를 구별할 수 없으며,
    테이블에 대해 생성된 인덱스의 정확한 정보와 SQL 문장을 같이 고려해야만 정확한
    원인을 밝힐 수 있다. 비트맵 인덱스는 읽기작업은 빈번하고, 쓰기 작업은 드문 테이블에
    대해 DSS성 SELECT 문의 성능을 극대화하기 위해 고안된 것이다.

인덱스 Lead Node에서 Split 이 발생하는 경우

(enq: TX - Index contention, mode = 4 )

  • B*Tree 인덱스는 데이터를 추가하는 과정에서 Lead Node 꽉차면 Split 함으로써
    균형(Balance)를 맞추게 된다.
  • 세션 A가 TX 락을 Exclusive 하게 획득한 상태에서 Split 를 수행하는 도중에
    세션 B는 세션 A가 획득 중인 TX 락을 Shared 모드로 획득하기 위해 기다려야하며
    그 동안 enq: TX - index contention 이벤트 발생
  • 자주 발생하지 않으만, 생성된 인덱스의 수가 많고 인덱스를 이루는 컬럼들의
    값이 커서 Leaf Node 블록이 빈번하게 Split 되는 경우에는 상당한 성능 저하의
    원인이 된다. 특히 시퀀스 등을 사용해서 값을 생성하는 현상이 생겨 인덱스
    Split 이 자주 발생할 수 있다.
  • 인덱스 Split 에 의해 발생하는 경합을 줄이는 기본적인 방법은 동일한 Leaf Node 블록에
    집중적으로 데이터가 추가되는 현상을 막는 것이다. 가령 파티셔닝 기법을 적용해서
    물리적으로 분산을 시키거나 인덱스를 구성하는 컬럼의 순서을 변경하여 자연스럽게
    흩어지게 만드는 방법 등을 사용할 수 있다.
    인덱스의 블록 크기를 크게 설정하는 것도 하나의 해결책이 된다.

기타(enq: TX - Contention )

1. 분산 트랜잭션(Distributed Transaction) 환경에서 Prepared Transaction에 의해
락이 획득된 로우를 읽는 경우, 트랜잭션이 종료(rollback, commit 또는 in-doubt)
될때까지 TX락을 Shared 모드로 획득하기 위해 대기해야 한다.
2. FLM(FreeList Management)을 세그먼트 공간관리기법으로 사용하는 경우,
TFL(Transaction FreeList)을 확보하려는 프로세스는 TFL을 확보하지 못한 경우
이미 TFL을 확보한 Transaction 의 TX 락을 Shared 모드로 확보하기 위해 대기
3. 언두 세그먼트 헤더의 트랜잭션 테이블에서 새로운 슬롯을 할당받고자 하는 경우
TX 락을 Exclusive 하게 획득