[2015-06-05] oracle tx lock

16
WareValley http://www.WareValley.com WareValley Oracle TX Lock 오렌지팀 윤석준 선임연구원

Upload: seok-joon-yun

Post on 06-Aug-2015

75 views

Category:

Software


2 download

TRANSCRIPT

WareValleyhttp://www.WareValley.com

WareValley

Oracle TX Lock오렌지팀 윤석준 선임연구원

TX Lock : 무결성 제약 위배 가능성

Row Lock 경합은 UPDATE, DELETE 시에만 발생

But, Unique Index가 정의되어 있을 경우에는 INSERT 에서도 발생 할 수 있음 (사례1)

FK 로 연결된 Table에서 INSERT 할 경우에도 발생 할 수 있음 (사례2)

Bitmap index인 경우 1개의 엔트리에 여러 레코드가 있으므로 자주 발생

1. TX1에서 dept 테이블에 deptno = 40 인 레코드 입력

2. TX2도 deptno = 40을 입력하면, Shared 모드로

enq:TX – row lock contention 대기 이벤트 발생

3. TX1이 commit 하면 TX2는 ora-00001 (무결성 제약

조건 (PK_DEPT)에 위배)

4. TX1이 rollback 하면 TX2는 정상적으로 입력 완료

사례 1

1. TX1에서 dept 테이블에 deptno = 40 인 레코드 삭제

2. TX2에서 deptno = 40인 레코드 입력하면, Shared 모

드로 enq:TX – row lock contention 대기 이벤트 발생

3. TX1이 commit 하면 TX2는 ora-02291 (무결성 제약

조건 (FK_EMP_DEPT)에 위배)

4. TX1이 rollback 하면 TX2는 정상적으로 입력 완료

사례 2

Block에 레코드 추가/갱신/삭제 할 때 ITL 슬롯을 할당받고, TX ID를 기록해야 함

- 하지만, 비어있는 ITL slot이 없다면 ? Shared 모드 enq: TX – allocate ITL entry 대기 이벤트 발생

- ITL slot 하나당 24 bytes 공간필요

- ITL slot 개수는 INITRANS 로 설정 (9i부터는 3 이하로 설정 불가)

CREATE TABLE T ( … ) INITRANS 5 MAXTRANS 255 PCTFREE 30;

- PCTFREE : UPDATE를 위해 예약된 공간, 하지만 ITL slot이 부족할 경우 활용 가능

- MAXTRANS : 최대 생성 가능한 ITL slot 개수 (10g부터는 255로 고정)

9i부터는 Table에 INSERT시 ITL 경합 없음. Index에 INSERT 할 땐 발생

TX Lock : ITL slot 부족

ITL 경합이 자주 발생 하는 segment는 확인하여 INITRANS를 늘려주어야 함

- 하지만, 새로 할당되는 Block만 적용.

- 기존 Block을 수정하려면 해당 Table 이나 Index 전체를 재생성 해야 함

TX Lock : ITL slot 부족 (계속)

ALTER TABLE scott.dept MOVE INITRANS 5; -- INDEX가 모두 unusable 됨ALTER INDEX scott.PK_DEPT REBUILD INITRANS 5;

2-Phase commit을 위한 PREPARED TX Lock에 대하여

shared 모드 enq:TX – contention 대기 이벤트가 발생 할 수 있음

Tablespace를 read-only로 전환 할 때도 발생 할 수 있음

TX Lock : 기타 Lock 발생

ALTER TABLESPACE TB_SPACE READ ONLY;

Oracle에서는 Row-level Lock 과 TX Lock을 조합

- Row-level Lock : Block header ITL과 Row header Lock Byte 설정

- TX-Lock : Enqueue 리소스를 통해 TX Lock을 설정

SELECT 작업에 대해서는 절대 Lock에 의한 대기 이벤트가 발생하지 않음

- 단, SELECT FOR UPDATE는 예외

- 분산 Transaction도 예외

같은 Row에 대한 DML , DDL 작업에 대해서는 Exclusive 모드의

enq:TX – row lock contention 대기 이벤트가 발생

TX Lock : DML Row Lock

Row-level Lock 획득시 Table Lock도 동시에 획득

- Table 구조를 변경하지 못하도록 막는 것이지, 액세스 자체를 막는 것은 아님

- TX-Lock : Enqueue 리소스를 통해 TX Lock을 설정

LOCK TABLE 명령어를 이용하여 명시적으로 설정 가능

TX Lock : DML Table Lock

LOCK TABLE emp IN ROW SHARE MODEROW EXCLUSIVE MODESHARE MODESHARE ROW EXCLUSIVE MODEEXCLUSIVE MODE

Table Lock Mode 간의 호환성

- 선행 TX와 호환되지 않는 Mode인 경우 후행 TX는 대기하거나 작업을 포기해야 함

- INSERT, UPDATE, DELETE, MERGE : RX Lock

- SELECT FOR UPDATE : RS Lock

Table Lock은 Enqueue로 구현 (TM Enqueue를 이용하므로 TM Lock이라 부름)

TX Lock : DML Table Lock (계속)

RS RX S SRX X

RS O O O O

RX O O

S O O

SRX O

X

• TYPE : TM• ID1 : Object ID• ID2 : 0

예제에서 사용할 Lock 모니터용 Script

TX Lock : DML Table Lock (예제)

SELECT L.SESSION_ID SID,DECODE(LOCK_TYPE,'Transaction','TX','DML','TM') TYPE,MODE_HELD,MODE_REQUESTED MODE_REQD,DECODE(LOCK_TYPE,'Transaction',TO_CHAR(TRUNC(LOCK_ID1/POWER(2,16))),

'DML', (SELECT OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_ID = L.LOCK_ID1)) "USN/TABLE",DECODE(LOCK_TYPE,'Transaction',BITAND(LOCK_ID1, TO_NUMBER('ffff','xxxx')) + 0) SLOT,DECODE(LOCK_TYPE,'Transaction',TO_NUMBER(LOCK_ID2)) SQN,DECODE(BLOCKING_OTHERS,'Blocking','<<<<<') Blocking

FROM DBA_LOCK LWHERE LOCK_TYPE IN ('Transaction', 'DML')ORDER BY SESSION_ID, LOCK_TYPE, LOCK_ID1, LOCK_ID2

예제에서 사용한 Orange 의 모니터링 Tool : Lock Monitor

1. SID 14 : TM Lock X Mode 수행

TX Lock : DML Table Lock (예제)

INSERT /*+ append */ INTO SCOTT.EMP_R SELECT * FROM SCOTT.EMP;

Script

Lock Monitor

2. SID 132 : 해당 Table에 UPDATE 시도 -> Lock 발생

TX Lock : DML Table Lock (예제)

Script

Lock Monitor

UPDATE SCOTT.EMP_R SET SAL = SAL + 1 WHERE EMPNO = 7369;

v$session_wait

3. SID 14 : commit

TX Lock : DML Table Lock (예제)

Script

Lock Monitor

4. SID 14 : RX Lock이 걸려있는 Row에 INSERT 시도 -> Lock 발생

TX Lock : DML Table Lock (예제)

Script

Lock Monitor

UPDATE SCOTT.EMP_R SET SAL = SAL + 1 WHERE EMPNO = 7369;

Lock에 대한 대처법

3가지 옵션중 선택이 가능

1. 기다린다 : SELECT ... FOR UPDATE

(default option)

2. 조금만 기다린다 : SELECT ... FOR UPDATE WAIT 3

ORA-30006 : resource busy; acquire with WAIT timeout expired

3. 안 기다린다 : SELECT ... FOR UPDATE NOWAIT

ORA-00054 : resource busy and acquire with NOWAIT specified

Lock을 푸는 방법, Commit

Blocking : 그냥 Lock을 기다리는 거

Deadlock : 두 세션이 Lock을 설정한 뒤 서로의 Lock을 기다리는 거

Oracle은 Deadlock을 인지하여 해당 문장만 rollback 시킴

ORA-00060 : deadlock detected while waiting for resource

위 메시지를 받은 세션은 commit 또는 rollback 한 후 진행해야 함

비동기식 Commit

10gR2 부터 지원

사용법

COMMIT WRITE [ IMMEDIATE | BATCH ] [ WAIT | NOWAIT ] ;

- WAIT (default) : LGWR가 로그버퍼를 파일에 기록했다는 완료 메시지를 받을 때까지 대기

(log file sync 대기 이벤트 발생)

- NOWAIT : LGWR의 완료 메시지를 기다리지 않고 바로 다음 트랜잭션 진행

- IMMEDIATE (default) : commit 명령을 받을 때마다 LGWR가 로그 버퍼를 파일에 기록

- BATCH : 세션 내부에 트랜잭션 데이터를 일정량 버퍼링 했다가 일괄 처리

default인 IMMEDIATE WAIT는 안전하게 저장되는 것이 보장됨

(나머지는 정상적으로 완료되지 않을 수 있음)