오라클 session의 관련된 잡다한 지식.
- 현재 연결되어 있는 모든 세션을 볼 수 있음.
SELECT * FROM v$session
-- 관련 파라미터 --> 최대 세션수는 (Process*1.1) + 5
show parameter processes ;
show parameter sessions ;
-- 현재 세션 확인
select count(*) from v$session ;
select * from v$session where status = 'ACTIVE'
- 상태별로 모든 세션 상태 보는 쿼리.
SELECT COUNT (*) total_cnt,
COUNT (DECODE (server, 'DEDICATED', 1, NULL)) dedicated_cnt,
COUNT (DECODE (TYPE, 'BACKGROUND', 1, NULL)) background_cnt,
COUNT (DECODE (status, 'ACTIVE', 1, NULL)) active_cnt
FROM v$session
- 현재 active 상태인 것과 inactive 상태인것을 확인할 때.
SELECT status,COUNT(*) FROM v$session
WHERE username='유저명'
GROUP BY status
- 세션 kill
alter system kill session 'SID, Serial' ;
ex) alter system kill session '1352,28337' ;
위 명령으로 kill 불가시 spid 를 콘솔에서 kill -9 로 제거
출처 : http://hoonsik69.tistory.com/106
-------------------------------------------------------------------------------------------------------
DB를 사용하다 보면 batch작업이나 long query를 사용하는 경우가 있는데, 이럴때 장시간 반응이 없어서 pc의 전원을 강제로 꺼버리거나 작업도중 정전이 발생할 수도 있는데, 이럴 경우 세션은 비정상적으로 종료가 되어 세션이 정리가 되지 않고 남아 있게된다.
만약 이러한 세션이 다수가 되면 정상적인 다른 세션들에게 자원배분(메모리등)이 정상적으로 되지 않거나 프로세스 초과 에러 메세지가 발생할 수 있다. 이렇게 실제 사용하지 않은 세션들을
DEAD SESSION(죽은 세션)이라고 하는데 이들을 정리할 필요가 있다.
KeepAlive 란 Idle TCP/IP Connection 의 Time out 기능을 말한다.
TCP/IP 기반으로 remote 로 연결된 상태에서 클라이언트의 갑작스런 리부팅이나 스위치 Off 의 경우 해당 연결을 서버에서 Closing 하지 못하게 된다.
이것은 TCP/IP의 제한인 것이지 오라클의 문제는 아니다.
이 때 KeepAlive가 정확하게 configure되어 있다면 좀 더 빨리 Dead connection을 발견하고 빨리 Closing할 것이다.
TCP/IP 에 관련된 것이므로 KeepAlive를 각 플랫폼 별로 지정하는 방법이 모두 틀리다.
예를들면 유저가 PC 에서 Unix Oracle Server로 연결 후 실수로 다음 쿼리 문을 실행했다.
SQL> select * from largetable, greatetable, verybigtable;
적게는 수십분, 많게는 몇시간이 걸릴 작업이라면 유저는 쿼리를 인터럽트하기 보다 reset 버튼을 누르게 될 것이다. 이때 클라이언트 프로세스는 없어졌지만 백그라운드 서버 프로세스는 계속
running 중일것이다.
이런 현상은 수시로 일어날 수 있다. 또한 당연한 것이다.
유저가 사용을 잘못하는 것이기 때문이다.
하지만 SQL*NET 2.1 이상에서 Dead-Connection-Detection 이라 불리는 기능을 지원한다.
이것은 곧 KeepAlive 를 지정할 수 있는 기능이다
반드시 서버 사이드의 $ORACLE_HOME/network/admin/sqlnet.ora 파일에 다음의 파라미터를
지정해야 한다. 클라이언트에는 지정해봐야 전혀 소용이 없다.
sqlnet 설정 속성 값 설명 : http://docs.oracle.com/cd/B28359_01/network.111/b28317/sqlnet.htm#BIIEEGJH
설정 파일 : $ORACLE_HOME/network/admin/sqlnet.ora
각 세션의 INACTIVE 상태가 길게 유지될 때 세션 강제 종료 시간 설정은 아래의 설정 값을 설정.
만약 설정 값이 없을 경우 각 OS의 TCPKeepAliveTime을 따른다. (일반적으로 2시간, 종종 30분 단위로)
ex ) sqlnet.expire_time = 10
설정 값 단위는 '분'
default = 0
mimimum Value : 0
recommended Value : 10
Netware를 제외한 모든 Platform, Protocol에서 지원이 된다.
# Windows NT 에서 KeepAlive 를 지정하는 방법(타 플랫폼은 제외)
Regedt32 를 실행한다.
레지스트리에서
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters
까지 이동한다.
여기서 키 추가가 아닌 값 추가를 한다.
파라미터는 KeepAliveTime (REG_DWORD) 로 입력한다.
값은 Decimal -> 180000 (for example = 3 minutes) 으로 지정한다.
-------------------------------------------------------------------------------------------------------
KeepAliveTime (윈도우의 경우)
KeepAliveTime 값은 TCP/IP가 대기 연결이 계속 원래 상태를 유지하는지 확인을 시도하는 빈도를 제어합니다. 이 시간 동안 활동이 없었을 경우 활성화 상태 지속 전송이 전송됩니다. 네트워크가 원래 상태를 유지하며 상대가 활성 상태일 경우 상대가 응답합니다. 손실된 상대에 대해 민감하게 되려는 경우(즉, 상대가 손실되었음을 더 빨리 인식해야할 경우) 이 값을 줄여 보십시오. 오랜 기간 동안 비활성 상태를 유지하는 연결은 공통이고 손실된 상대는 공통이 아닐 경우 이 값을 늘려 오버헤드를 줄여도 됩니다.
7,200,000밀리초(2시간) 동안 대기 연결이 비활성 상태일 경우 Windows에서는 활성화 상태 지속 메시지를 전송하는 것이 기본값입니다. 종종 값에 1,800,000밀리초를 선택하여 반쯤 닫힌 연결을 30분마다 감지합니다.
다음 프로시저를 사용하여 값을 보거나 사용자 정의하십시오.
출처 : http://nearby2.tistory.com/18
-----------------------------------------------------------------------------------------------
Oracle 세션(Session) 관리
오라클은 데이터베이스 접속이 이루어지면 세션을 시작한다.세션은 사용자가 데이터베이스에 연결되어 있는 동안 계속 유지된다.
세션이 시작되면 오라클은 해당 세션에 세션 ID(SID)를 할당한다. 사용자 세션을 출력하려면 v$session 뷰에 쿼리를 수행하면 된다.
v$session에서 각 세션은 고유한 SID(Session identifier)와 SERIAL#(serial number)를 갖는다.
시리얼 번호는 세션이 종료되었으나 다른 세션이 동일한 SID를 갖고 시작되었 때, 세션 명령들이 정확한 세션 객체에 적용될 수 있도
록 보장해준다.
v$session 뷰는 사용자 이름, 장치 이름, 프로그램 이름, 상캐 및 로그인 시각 등 세션에 대한 많은 유욯한 정보들을 갖고 있다.
(ex)
select username, program from v$session;
-> 어떤 사용자들이 DB에 접속하였고 어떤 프로그램들을 수행하고 있는지 확인하는 쿼리
세션을 강제 종료해야할때는 alter system 명령어를 사용하는데, 사용자 세션을 강제 종료하기 위해서는 v$session 뷰의 SID와
SERIAL# 값이 필요하다.
상황 # 사용자 SUNNY에 의해 생성된 세션을 종료할때..
SQL> select username, sid, serial#, status
from v$session
where username = 'SUNNY';
USERNAME SID SERIAL# STATUS
--------------------- -------------- -------------- ----------------
SUNNY 10 3 INACTIVE
SQL> alter system kill session '10, 3';
System altered.
SQL> select username, sid, serial#, status
from v$session
where username = 'SUNNY';
USERNAME SID SERIAL# STATUS
--------------------- -------------- -------------- ----------------
SUNNY 10 3 KILLED
- 오라클이 세션을 강제 종료할 떄, 해당 세션은 더 이상의 SQL문을 실행하는 것을 막는다. 만일 강제 종료하는 시점에 SQL문을 실행
중이었다면, 해당 SQL문은 종료되고 모든 변경사항들은 롤백된다. 또한 해당 세션에 의해 사용되던 잠금(LOCK) 및 기타 자원들도 해
제된다.
- 오라클이 INACTIVE 세션을 강제 종료하는 경우에는 세션을 종료시키고, 상태를 KILLED로 표시한다. 사용자가 계속하여 해당 세션을
사용하려고 시도하면 에러 메세지가 반환되며, 세션 정보는 v$session에서 제거된다.
- ACTIVE 세션을 강제 종료하는 경우에는 오라클이 세션을 종료시키고, 해당 세션이 종료되었다는 에러 메시지를 사용자에게 즉시 발생 시킨다. 만일 오라클이 세션에 의해 사용되고 있던 자원을 60초 이내에 해제할 수 없을 때에는 해당 세션이 강제 종료될 것이라는
메시지를 사용자에게 발생시킨다. v$session 뷰의 상태는 다시 KILLED로 조회될 것이다.
- 만일 사용자가 현대 트랜잭션을 완료하고 사용 중이던 세션을 종료하려고 하면 DISCONNECT SESSION 옵션을 사용하면 된다.
alter system disconnect '10', '3' post_transation;
immediate 옵션과 사용하면 진행중이던 트랜잭션을 롤백하고 모든 세션의 잠금을 해제하며 전체 세션 상태를 복수한 후 사용자에게
즉시 제어 권한을 넘긴다.
alter system disconnect session '10', '3' immediate;
alter system kill session '10', '3' immediate;
+)
Q. SID는 세션식별자로 유니크한 값을 가지는데 SERIAL#값까지 갖는 이유는 무엇일까?
A. SID는 사용자별로 할당되는 값이 아니라 세션마다 할당되기 때문에 재사용됩니다. 만약 10, 12번 세션을 확인 후 KILL SESSION명령을 하기전에 10번 세션이 로그아웃을 하고 바로 다른 세션이 연결되어서 SID가 10번으로 할당되는 경우가 있다고 해봅시다. 이럴경우 SID만 가지고 세션을 KILL시키면 내가 원하는 세션이 아닌 다른 세션을 KILL 시키는 문제가 발생할 수 있습니다. 그래서 SERIAL#값을 하나 더 두어 세션을 구분하는 것입니다.
참고 : http://dblab.changwon.ac.kr/corenet/education/oraclelec/admin/chap4-6.html
참고 : http://database.sarang.net/?inc=read&aid=27232&criteria=oracle
참고 : http://tip.daum.net/question/62996686
참고 : https://community.oracle.com/thread/468729?start=0&tstart=0
참고 : http://database.sarang.net/?inc=read&aid=27232&criteria=oracle