본문 바로가기

Database/Oracle

RDS Oracle 세션 KILL 하는 방법

AWS RDS 사용 중에 일반적인 상황에서 세션을 KILL 해야 하거나, 잘못된 상황으로 인해 긴급하고 빠르게 쿼리를 KILL 해야 하는 경우에, SID, SERIAL#을 이용해 KILL 쿼리를 편집하는 대신 쿼리 결과를 복사해서 바로 사용할 수 있도록 다양한 쿼리들을 정리했습니다.

 

 

특정 사용자의 모든 세션을 KILL 할 경우

USER01이 사용하는 세션을 확인

SELECT SID, SERIAL#, USERNAME, STATUS FROM V$SESSION WHERE USERNAME='USER01';

 

해당 세션을 KILL 해도 계속해서 들어올 수 있는 상황에서는 계정을 LOCK 하고, 이후 일괄 쿼리를 이용해서 KILL 수행합니다. 아래 두 번째 쿼리의 수행결과를 복사해서 다시 실행합니다.

필요에 따라 계정명을 바꿔서 사용하시기 바랍니다.

-- 계정 LOCK 처리
alter user USER01 account lock;

-- begin end /까지 생성하는 스크립트
select 'begin' as query from dual
union all
SELECT 'rdsadmin.rdsadmin_util.kill(sid => ' || SID || ', serial => ' || SERIAL# || ' , method => ''IMMEDIATE'');' 
as query
FROM v$session a 
WHERE username IN ('USER01')
union all
select 'end;' as query from dual
union all
select '/' as query from dual;

 

실행 중인 쿼리문 전체 확인 쿼리

실행중인 쿼리 전체를 여러 줄에 걸쳐서 보여줍니다. 시스템계정인 SYSTEM, SYS, DBADMIN은 제외했습니다. 경우에 따라 주석으로 처리된 시간을 조건으로 사용할 수 있습니다.

SELECT TO_CHAR (sid) sid,
       serial#,
       SUBSTR (TO_CHAR (last_call_et), 1, 6) executeSeconds,
       userName,
       machine,
       b.sql_text
FROM v$session a, v$sqltext b
WHERE username NOT IN ('SYSTEM', 'SYS', 'DBADMIN')
   AND a.TYPE != 'BACKGROUND'
   AND a.status = 'ACTIVE'
   AND a.sql_address = b.address(+)
   AND a.sql_hash_value = b.hash_value(+)
   -- AND SUBSTR (TO_CHAR (last_call_et), 1, 6) > 3600
ORDER BY a.last_call_et DESC,
   a.sid, a.serial#, b.address, b.hash_value, b.piece;

 

실행 중인 쿼리문의 첫번째 줄만 확인 쿼리

실행중인실행 중인 쿼리가 많아 가독성이 떨어지거나, 실행 중인 쿼리를 처리하기 위해 첫 번째 줄만 표시합니다.

SELECT TO_CHAR (sid) sid,
       serial#,
       SUBSTR (TO_CHAR (last_call_et), 1, 6) executeSeconds,
       userName,
       machine,
       b.sql_text
FROM v$session a, v$sqltext b
WHERE username NOT IN ('SYSTEM', 'SYS', 'DBADMIN')
   AND a.TYPE != 'BACKGROUND'
   AND a.status = 'ACTIVE'
   AND a.sql_address = b.address(+)
   AND a.sql_hash_value = b.hash_value(+)
   -- AND SUBSTR (TO_CHAR (last_call_et), 1, 6) > 3600
  AND b.piece = 0
ORDER BY a.last_call_et DESC,
   a.sid, a.serial#, b.address, b.hash_value, b.piece;

 

실행 중인 쿼리의 첫 번째 줄을 이용한 KILL 쿼리 생성

실행 중인 쿼리에 시간조건을 추가하여 일정시간 이상 수행되는 쿼리를 일괄로 삭제할 수 있도록 작성되었습니다. 시간조건이나, 정렬조건이 필요하면 해당 주석을 풀고 수행하면 됩니다.

select 'begin' as query from dual
union all
SELECT 'rdsadmin.rdsadmin_util.kill(sid => ' || SID || ', serial => ' || SERIAL# || ' , method => ''IMMEDIATE'');' 
as query
FROM v$session a, v$sqltext b
WHERE username NOT IN ('SYSTEM', 'SYS', 'DBADMIN')
   AND a.TYPE != 'BACKGROUND'
   AND a.status = 'ACTIVE'
   AND a.sql_address = b.address(+)
   AND a.sql_hash_value = b.hash_value(+)
   -- AND SUBSTR (TO_CHAR (last_call_et), 1, 6) > 3600
  AND b.piece = 0
-- ORDER BY a.last_call_et DESC,a.sid, a.serial#, b.address, b.hash_value, b.piece
union all
select 'end;' as query from dual
union all
select '/' as query from dual;

 

쿼리의 실행 결과를 다시 수행합니다. RDS Oracle의 쿼리 KILL 수행 예시는 아래와 같습니다.

begin
rdsadmin.rdsadmin_util.kill(sid => 182, serial => 40408, method => 'IMMEDIATE');
end;
/

 

LOCK이 걸린 Object 확인

v$session테이블과 v$lock테이블을 이용해서 LOCK이 걸린 Object를 확인하는 쿼리입니다.

 

LOCK이 걸린 테이블을 알고 있는 경우

LOCK이 걸린 테이블을 알고 있는 경우 아래쿼리를 사용해서 어떤 세션이 사용하고 있는지 확인합니다.

select a.sid, a.serial#
from v$session a, v$lock b, dba_objects c
where a.sid=b.sid and b.id1=c.object_id and b.type='TM'
and c.object_name='테이블명'