by-nc-sa     개발자, DBA가 함께 만들어가는 구루비 지식창고!

TM Lock




1. TM Lock

  • Table을 보호하는 락
  • 경합 발생시 enq:TM - contention 대기

2. TM Lock MODE

구분 모드 Ex
LEVEL 2 RS(ROW Shared Table Locks), SS(Subshare Table Locks) LOCK TABLE EMP IN ROW SHARE MODE;
LEVEL 3 RX(ROW Exclusive Table Locks), SX(Subexclusive Table Locks) LOCK TABLE EMP IN ROW EXCLUSIVE MODE;
LEVEL 4 S(Share Table Locks), SS(Subshare Table Locks) LOCK TABLE EMP IN SHARE MODE;
LEVEL 5 SRS(Share Row Exclusive Table Locks), SSX(Share-Subexclusive Table Locks) LOCK TABLE EMP IN SHARE ROW EXCLUSIVE MODE;
LEVEL 6 X(Exclusive Table Locks) LOCK TABLE EMP IN EXCLUSIVE MODE;

3. 요청되는 Lock Mode

구분 MODE REQUESTED RS SX S SRX X
SELECT N Y Y Y Y N
SELECT... FOR UPDATE RS Y Y N N N
INSERT RX Y Y N N N
UPDATE RX Y Y N N N
DELETE RX Y Y N N N
CREATE INDEX S Y N Y N N
ALTER X N N N N N
DROP X N N N N N

4. TX Lock 테스트

1) SELECT 중인 Table에 DROP 실행
  • Lock Mode
      N RS RX S SRX X
    N O O O O O O
  • Sesssion-1에서 SELECT 중일 때 Session-2에서 DROP을 하면 Sesssion-1은 NULL 모드이므로 Sesssion-2의 DROP 명령이 가능함
  • 그러나 Sesssion-1은 도중에 Object가 제거되었기 때문에 'ORA-08103 : object no longer exists' 에러가 난다고 하지만 에러는 안남 _
  • 테스트
    
    --1. 테이블 생성
    CREATE TABLE TEST_T AS
    SELECT LEVEL CNT
    FROM   DUAL
    CONNECT BY LEVEL <= 10000
    ;
    
    -- 2. Session-1에서 TEST_T 테이블 SELECT
    SELECT *
    FROM   TEST_T
    ;
    
           CNT    
    ----------    
             1    
             2    
             3    
             4    
    ..........
          9995          
          9996          
          9997          
          9998          
          9999          
         10000          
    
    10000 rows selected.
    
    -- 3. Session-2에서 TEST_T 테이블 DROP(Session-1에서 SELECT 하는 도중)
    DROP TABLE TEST_T;
    
    Table dropped.
    
  • 결론 : 에러 안남 ㅎㅎ ㅡㅡ;
2) SELECT FOR UPDATE 수행 중인 Table에 DROP 실행
  • Lock Mode
      N RS RX S SRX X
    RS O O O O O X
  • Sesssion-1에서 SELECT FOR UPDATE 중일 때 Session-2에서 DROP을 하면 Sesssion-1은 RS 모드이므로 Sesssion-2의 DROP 명령 불가
  • 테스트
    
    --1. 테이블 생성
    CREATE TABLE TEST_T AS
    SELECT LEVEL CNT
    FROM   DUAL
    CONNECT BY LEVEL <= 10000
    ;
    
    -- 2. Session-1에서 SELECT FOR UPDATE
    SELECT *
    FROM   TEST_T
    WHERE  CNT = 1
    FOR UPDATE
    ;
    
    -- 3. Session-2에서 TEST_T 테이블 DROP 수행
    DROP TABLE TEST_T;
    
    ERROR at line 1:
    ORA-00054: resource busy and acquire with NOWAIT specified 
    
3) Transaction 중인 Table에 DROP 실행
  • Lock Mode
      N RS RX S SRX X
    RX O O O X X X
  • Sesssion-1에서 UPDATE 중일 때 Session-2에서 DROP을 하면 Sesssion-1은 RX 모드이므로 Sesssion-2의 DROP 명령 불가
  • Sesssion-1에서 UPDATE 명령어가 끝나도 COMMIT을 안찍고 대기하면 Sesssion-2에서는 DROP 불가
  • 테스트
    
    --1. 테이블 생성
    CREATE TABLE TEST_T AS
    SELECT LEVEL CNT
    FROM   DUAL
    CONNECT BY LEVEL <= 10000
    ;
    
    -- 2. Session-1에서 SELECT FOR UPDATE
    UPDATE TEST_T
    SET    CNT = 100000
    ;
    
    -- 3. Session-2에서 TEST_T 테이블 DROP 수행
    DROP TABLE TEST_T;
    
    ERROR at line 1:
    ORA-00054: resource busy and acquire with NOWAIT specified 
    
4) Index 생성 중인 Table에 DML 실행
  • Lock Mode
      N RS RX S SRX X
    RX O O X O X X
  • Sesssion-1에서 INDEX 생성 중일 때 Session-2에서 DELETE를 하려고 하면 S 모드이기 때문에 DELETE 가능
  • 테스트
    
    --1. 테이블 생성
    CREATE TABLE TEST_T AS
    SELECT LEVEL CNT
    FROM   DUAL
    CONNECT BY LEVEL <= 10000
    ;
    
    -- 2. Session-1에서 INDEX 생성
    CREATE INDEX TEST_T_N1 ON TEST_T(CNT);
    
    Index created.
    
    -- 3. Session-2에서 TEST_T 테이블 DELETE 수행
    DELETE FROM TEST_T WHERE CNT = 1;
    
    1 row deleted.
    
5) APPEND INSERT 수행 중인 Table에 DML 실행
  • Lock Mode
      N RS RX S SRX X
    RX O X X X X X
  • Sesssion-1에서 APPEND INSERT 생성 중일 때 Session-2에서 DELETE를 하려고 하면 X 모드이기 때문에 DELETE 불가
  • 라고 책에 써져있지만 DELETE 가능함 ㅡㅡ;
  • 테스트
    
    --1. 테이블 생성
    CREATE TABLE TEST_T AS
    SELECT LEVEL CNT
    FROM   DUAL
    CONNECT BY LEVEL <= 10000
    ;
    
    -- 2. Session-1에서 APPEND INSERT
    INSERT /*+ APPEND */ 
           INTO TEST_T
    SELECT COL1
    FROM   BIG_TABLE
    ;
    
    -- 3. Session-2에서 DELETE
    DROP TABLE BIG_TABLE WHERE COL1 = 1060;
    
    1 row deleted.
    
6) INDEX REBUILD 중 DML 실행
  • Lock Mode
      N RS RX S SRX X
    S O O X X X X
  • Sesssion-1에서 INDEX REBUILD 중일 때 Session-2에서 DELETE를 하려고 하면 S 락을 걸어 DML이 불가능하게 됨
  • 테스트
    
    --1. 테이블, 인덱스 생성 
    CREATE TABLE TEST_T AS
    SELECT LEVEL CNT
    FROM   DUAL
    CONNECT BY LEVEL <= 1000000000
    ;
    
    CREATE INDEX TEST_T_N1 ON TEST_T(CNT);
    
    -- 2. Session-1에서 INDEX REBUILD
    ALTER INDEX TEST_T_N1 REBUILD;
    
    -- 3. Session-2에서 DELETE
    DROP TABLE TEST_T WHERE CNT1 = 1;
    
    -- 4. Lock 모니터링
    @lock
    
    (Node)H-Sid (Node)W-Sid Lock Status  W-Time Lock Type H L-Mode R L-Mode LOCKED_OBJ   SID/SER#     S TR/w/b MODULE    PGM      W_T WAIT_EVENT                 
    ----------- ----------- ----------- ------- --------- -------- -------- ------------------------- - ------ --------- ---- ------- ------------------------- 
    (1)9977     ▽          holding           0 TM        Share    None     TEST_T_N1(I) 9977,47      A DI/F/F SQL*Plus  sqlp       0 db file scattered read     
                                                                                                                                                                 
                (1)9867     waiting          18 TM        None     Row Ex                9867,35089   A DI/F/F SQL*Plus  sqlp      18 enq: TM - contention       
    

문서정보

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.