[2015-06-05] oracle tx lock
Post on 06-Aug-2015
75 Views
Preview:
TRANSCRIPT
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
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는 안전하게 저장되는 것이 보장됨
(나머지는 정상적으로 완료되지 않을 수 있음)
top related