대기와 Lock 대기

Idle 대기

what? 처리할 것이 없어서 쉬는 대기 e.g, 서버 프로세스가 SQL문이 도착하기 전까지 Idle 대기 이벤트인 'SQL*Net message from client' 상태로 대기, 'smon timer', 'pmon timer', 'rdbms ipc message', 'wakeup time manager', 'Queue Monitor Wait' 등

Non Idle 대기

(1) 이유가 있어서 어쩔 수 없이 하는 대기.

Why? SQL 처리를 위해 필요한 대기가 존재합니다. SQL 처리 도중 데이터가 필요할 때 디스크에서 블록을 읽어오며 대기가 발생할 수 있습니다.

e.g, 데이터 파일에서 데이터를 읽어오는 'db file sequential read', 'db file scattered read', Lock을 기다리는 'enqueue', 내부 Lock을 기다리는 'latch free'

(2) 이상 상태 등 쓸데없이 SQL을 기다리게 하는 대기.

Why? 사용자가 특정 테이블에 Lock을 걸어두고는 계속 잡고 놓아주지 않는 경우 발생할 수 있습니다.

Lock에 의한 대기

Lock에 의한 대기는 Lock 걸려있는 대상에 다시 Lock을 걸려고 할 때 대기가 발생합니다. image

Deadlock

image

Deadlock(고장난 열쇠)의 경우 서로가 상대방이 보유하고 있는 Lock을 기다리느라 영원히 작업을 진행할 수 없는 상태를 의미합니다.

사용자1 SQL 수행

SQL> update T set n1 = 2 where id = 1;

1 row updated.

SQL> update T set n1= 4 where id = 2;

사용자2 SQL 수행

SQL> update T set n1 = 3 where id = 2;

1 row updated.

SQL> update T set n1 = 5 where id = 1;

사용자1 세션에서 ORA-00060 deadlock 발생

update T set n1= 4 where id = 2
             *
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource

Lock 걸린 테이블의 sid, serial 조회

SQL>
SELECT A.SID
     , A.SERIAL#
     , C.OBJECT_ID
     , c.OBJECT_NAME
  FROM V$SESSION A
 INNER JOIN V$LOCK B
    ON A.SID = B.SID
 INNER JOIN DBA_OBJECTS C
    ON B.ID1 = C.OBJECT_ID
 WHERE B.TYPE  = 'TM'
    ;

       SID    SERIAL#  OBJECT_ID OBJECT_NAME
---------- ---------- ---------- --------------------------------------------------------------------------------------------------------------------------------
       136	39548	   73348 T
       254	45859	   73348 T

Lock 상세 정보 조회

SELECT /*+ ORDERED */
     S.USERNAME
     , S.SID
     , S.SERIAL#
     , S.PROGRAM
     , L.TYPE "LOCK TYPE"
     , L.ID1
     , L.CTIME
     , DECODE(L.LMODE, 0, 'NONE', 1, 'NULL', 2, 'RS', 3, 'RX', 4,  'S', 5, 'SRX', 6, 'X', '?') AS HELD
     , DECODE(L.REQUEST, 0, 'NONE', 1, 'NULL', 2, 'RS', 3, 'RX', 4, 'S', 5, 'SRX', 6, 'X', '?') AS REQUESTED
  FROM V$LOCK L, V$SESSION S
WHERE L.SID = S.SID
  AND S.USERNAME LIKE '%'
  AND L.TYPE IN ('TM', 'TX')
ORDER BY S.SID, L.TYPE
;
USERNAME SID SERIAL# PROGRAM LOCK TYPE ID1 CTIME HELD REQUESTED
TEST 136 39458 sqlplus@261d716abc02 (TNS V1-V3) TM 73348 2831 RX NONE
TEST 136 39548 sqlplus@261d716abc02 (TNS V1-V3) TX 196627 2831 X NONE
TEST 254 45859 sqlplus@261d716abc02 (TNS V1-V3) TM 73348 2806 RX NONE
TEST 254 45859 sqlplus@261d716abc02 (TNS V1-V3) TX 393222 2806 X NONE
TEST 254 45859 sqlplus@261d716abc02 (TNS V1-V3) TX 196627 2776 NONE X
LOCK TYPE 종류
LOCK TYPE 특징 LMODE
TX row에 거는 lock. 같은 row에 대하여 다른 MODE의 Lock을 허용하지 않음 X(Exclusive)
TM 테이블에 거는 lock. 테이블의 정의를 변경하는 작업(DROP, ALTER) 불가. 여러 트랜잭션 수행 가능 RX, RS

sid, serial 번호로 세션 해제

ALTER SYSTEM KILL SESSION '136,39548';

사용자1 세션 해제 후 Lock 상세 정보 재조회

USERNAME SID SERIAL# PROGRAM LOCK TYPE ID1 CTIME HELD REQUESTED
TEST 254 45859 sqlplus@261d716abc02 (TNS V1-V3) TM 73348 5361 RX NONE
TEST 254 45859 sqlplus@261d716abc02 (TNS V1-V3) TX 393222 5361 X NONE

사용자1 세션 상태

SQL> select * from t;
select * from t
             *
ERROR at line 1:
ORA-00028: your session has been killed

사용자2 세션 상태

SQL> update T set n1 = 5 where id = 1;

1 row updated.

SQL> select * from T;

	ID	     N1
---------- ----------
	 1	     5
	 2	     3

alert, trace 파일

Deadlock 발생 시 한쪽의 처리가 오라클에 의해 자동으로 rollback 되며 alert, trace 파일에 해당 내역이 기록됩니다.

alert, trace 파일 위치 확인
SQL> select value from v$diag_info where name='Diag Trace' ;

VALUE
--------------------------------------------------------------------------------
/opt/oracle/diag/rdbms/orclcdb/ORCLCDB/trace


bash-4.2$ pwd
/opt/oracle/diag/rdbms/orclcdb/ORCLCDB/trace
bash-4.2$ ls -al|grep -e 4562 -e alert
-rw-r-----  1 oracle dba 2165753 Jun  6 05:37 ORCLCDB_ora_4562.trc
-rw-r-----  1 oracle dba  535416 Jun  6 05:37 ORCLCDB_ora_4562.trm
-rw-r-----  1 oracle dba  351012 Jun  7 22:58 alert_ORCLCDB.log
alert_ORCLCDB.log
2023-06-06T05:37:54.555428+00:00
Errors in file /opt/oracle/diag/rdbms/orclcdb/ORCLCDB/trace/ORCLCDB_ora_4562.trc:
2023-06-06T05:37:54.830624+00:00
ORA-00060: Deadlock detected. See Note 60.1 at My Oracle Support for Troubleshooting ORA-60 Errors. More info in file /opt/oracle/diag/rdbms/orclcdb/ORCLCDB/trace/ORCLCDB_ora_4562.trc.
2023-06-06T05:55:13.031479+00:00
ORCLCDB_ora_4562.trc (sed -n '12072,12118p' ORCLCDB_ora_4562.trc)
*** 2023-06-06T05:37:54.554944+00:00 (CDB$ROOT(1))
DEADLOCK DETECTED ( ORA-00060 )
See Note 60.1 at My Oracle Support for Troubleshooting ORA-60 Errors

[Transaction Deadlock]
 
The following deadlock is not an ORACLE error. It is a
deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:
 
Deadlock graph:
                                          ------------Blocker(s)-----------  ------------Waiter(s)------------
Resource Name                             process session holds waits serial  process session holds waits serial
TX-00030013-000003CD-00000001-00000000         73     136     X        39548      74     254           X  45859
TX-00060006-000003BB-00000001-00000000         74     254     X        45859      73     136           X  39548
 
----- Information for waiting sessions -----
Session 136:
  sid: 136 ser: 39548 audsid: 440036 user: 107/TEST
  pdb: 1/CDB$ROOT
    flags: (0x41) USR/- flags2: (0x40009) -/-/INC
    flags_idl: (0x1) status: BSY/-/-/- kill: -/-/-/-
  pid: 73 O/S info: user: oracle, term: UNKNOWN, ospid: 4562
    image: oracle@261d716abc02 (TNS V1-V3)
  client details:
    O/S info: user: oracle, term: pts/1, ospid: 4561
    machine: 261d716abc02 program: sqlplus@261d716abc02 (TNS V1-V3)
    application name: SQL*Plus, hash value=3669949024
  current SQL:
  update T set n1= 4 where id = 2
 
Session 254:
  sid: 254 ser: 45859 audsid: 440071 user: 107/TEST
  pdb: 1/CDB$ROOT
    flags: (0x41) USR/- flags2: (0x40009) -/-/INC
    flags_idl: (0x1) status: BSY/-/-/- kill: -/-/-/-
  pid: 74 O/S info: user: oracle, term: UNKNOWN, ospid: 5176
    image: oracle@261d716abc02 (TNS V1-V3)
  client details:
    O/S info: user: oracle, term: pts/3, ospid: 5175
    machine: 261d716abc02 program: sqlplus@261d716abc02 (TNS V1-V3)
    application name: SQL*Plus, hash value=3669949024
  current SQL:
  update T set n1 = 5 where id = 1
 
----- End of information for waiting sessions -----

Latch

what? 다중 처리를 구현하기 위한 Lock으로 오라클 내부에서 자동으로 얻으며 SQL 1회 실행을 위해 여러 Latch를 얻고 해제하는 것을 반복합니다.

why? Latch는 병렬 처리를 가능하게 하고 높은 처리량을 실현하기 위해 존재하는데 메모리나 데이터를 조작할 때 상호 배타적(mutual exclusive)으로 처리함으로써 데이터가 손상되는 것을 방지합니다. SGA 내부의 공유 데이터에 대한 배타적인 잠금을 보장하여 메모리 구조의 무결성을 유지합니다. 하나의 프로세스만이 Latch를 보유할 수 있으며 SGA에 접근하는 모든 프로세스는 해당 영역을 관장하는 Latch를 획득해야만 접근이 가능합니다. Lock을 용도에 따라 나누고 Lock(latch)의 종류와 수를 늘림으로써 다른 세션들과 경합할 가능성을 줄일 수 있습니다. image

현실에서는 Latch 경합이 발생하는 경우가 많은데 CPU, OS와 관련이 있습니다. OS에서는 여러 처리를 동시에 실행하는 멀티태스킹이 존재하고 처리중인 CPU를 가로채는 동작인 선점(preemptive)이 존재합니다. image

image

위와 같은 OS의 동작으로 인해 Latch를 가진 세션의 CPU를 가로채는 상황이 발생할 경우 Latch를 가진 세션은 CPU를 사용할 수 없어서 처리를 진행하지 못하고 CPU를 사용할 수 있는 세션은 Latch를 얻지 못해 처리를 진행하지 못하는 상황이 발생할 수 있습니다. 또한 이러한 현상은 CPU의 스케줄링 외에도 OS의 페이징 등의 현상으로 Oracle 프로세스의 처리가 중단되는 경우에도 발생합니다.

참고자료