오라클은 사용자와 데이터베이스 접속이 이루어지면 세션을 생성합니다. 세션은 사용자가 데이터베이스에 연결되어 있는 동안 계속 유지되고, 각 세션에는 SID(Sesiion ID)와 시리얼번호(Serial#)가 부여됩니다. SID와 시리얼번호가 두개 존재하는 이유는 세션이 종료되었으나 다른 세션이 동일한 SID를 갖고 시작되었을 때 세션 명령들이 정확한 세션에 적용될 수 있도록 하기위해서 입니다.
세션이 사용자에 의해 작업중이라면 Active상태가되고 작업을 하게 됩니다. Inactive 세션은 연결은 되어 있지만 작업을 하지 않는 상태입니다. 즉, 자원은 할당되어 있지만 사용하지 않는 세션이라면 불 필요한 자원낭비가 될 수도 있습니다.
기본적으로 오라클 DB에 최대 Session으로 적용되어있는 것을 확인할 수 있는 쿼리입니다.
SYS@ysbae> show parameter sessions
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
java_max_sessionspace_size integer 0
java_soft_sessionspace_limit integer 0
license_max_sessions integer 0
license_sessions_warning integer 0
sessions integer 922
shared_server_sessions integer (null)
위의 DB는 922개의 session을 최대 접속할 수 있습니다.
현재 사용중인 session의 수도 v$resource_limit뷰를 통해 확인할 수 있습니다.
1 select CURRENT_UTILIZATION, MAX_UTILIZATION,LIMIT_VALUE from v$resource_limit
2* where resource_name ='sessions'
SYS@ysbae> /
CURRENT_UTILIZATION MAX_UTILIZATION LIMIT_VALUE
------------------- --------------- --------------------
61 73 922
1 row selected.
현재 61개의 세션이 연결되어 있는것을 확인할 수 있습니다.
기본적으로 불필요한 세션을 확인하고 그 세션의 접속을 죽여주는 작업이 필요할 때가 있습니다. 앞서 말했듯이 자원을 비효율적으로 사용하고 있는 상태이기 때문이기도하고, 정작 필요한 세션이 inactive세션때문에 못 붙어서 작업이 진행이 늦어질 수도 있기 때문입니다.
inactive session을 확인하는 쿼리입니다.
v$session 뷰를 통해 SID와 serial#를 확인할 수 있으며 alter system 명령어를 통해 이 세션을 정리할 수 있습니다. 저의 DB에선 inactive인 세션은 보이지 않아 active세션을 확인 하였습니다.
SYS@ysbae> select username,sid,serial#,status from v$session where status ='INACTIVE';
no rows selected
Elapsed: 00:00:00.01
1* select username,sid,serial#,status from v$session
SYS@ysbae> /
USERNAME SID SERIAL# STATUS
-------------------------------------------------------------------------------------------------------------------------------- ---------- ---------- --------
(null) 2 63023 ACTIVE
(null) 3 12431 ACTIVE
(null) 4 59345 ACTIVE
(null) 5 16001 ACTIVE
(null) 6 51930 ACTIVE
(null) 7 914 ACTIVE
(null) 8 40071 ACTIVE
(null)
....
alter system kill session 'SID,SERIAL#' 명령어를 통해 세션을 죽일 수 있습니다.
immediate 명령어를 붙이면 트랜잭션이 끝날때 까지 기다리지 않고 바로 세션을 죽이게 됩니다.
SQL > alter system kill session '2,63023' immediate;
참고로 유저세션만 죽일 수 있습니다. 유저세션이 아닌 경우 ORA-00029: session is not a user session 에러가 발생합니다.
immediate 명령어를 사용하지 않으면 STATUS에 KILLED상태로 변경되고 v$session에 남아있게 됩니다.
SQL내에서 alter system kill session 명령어를 쳤는데도 ORA-00031: session marked for kill 에러가 발생하거나, 제대로 세션이 끊기지 않아 계속해서 Inactive 상태로 남아 있는 경우도 있습니다. 특히 그 세션이 DML작업 중인데 테이블 Lock을 걸고 있어서 다른 세션들의 작업이 못하는 경우도 생길 수 있으며 그런 경우 업무가 계속 지연되게 됩니다. 이때 OS 명령어로 kill -9로 직접 세션을 죽이는 방법도 있습니다.
select a.sid,a.username,a.osuser,a.process fg_pid,b.spid bg_pid
from v$session a,v$process b
where a.paddr=b.addr;
SID USERNAME OSUSER FG_PID BG_PID
---------- ------------------------------------------------------------------------------------------------------------------------
2 (null) oracle 1968 1968
3 (null) oracle 1970 1970
....
v$session과 v$process조인하여 세션의 PID를 찾습니다. BG_PID라는 컬럼으로 확인할 수 있습니다. 해당 번호 확인 후 kill -9 PID로 하면 OS명령어에서 강제로 세션을 kill 할 수 있습니다.
v$locked_object뷰를 활용해서 lock걸린 object도 확인 할 수 있습니다.
+추가)
쿼리로 alter system kill session 'SID,SERIAL#' immediate; 뽑아내는 법
select 'alter system kill session'||' ''' ||sid||','||serial#||''''||' immediate;' from v$session;
'Oracle > 운영' 카테고리의 다른 글
트랜잭션 격리 수준(isolation level) (0) | 2020.08.17 |
---|---|
ORA-00257 FRA 디렉토리가 Full일때 조치사항 (0) | 2020.07.25 |
권한 부여 삭제(Grant)와 with admin option, with grant option (0) | 2020.02.21 |
TABLE_REDEFINITION (0) | 2020.02.19 |
메모리 자동 관리 방법(PGA,SGA) (0) | 2020.02.13 |
댓글