2026년 10월 22일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-00022 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-00022 invalid session ID 는?
ORA-00022 에러는 Oracle 데이터베이스에서 유효하지 않거나 이미 종료된 세션 ID를 참조하려 할 때 발생하는 오류입니다. 주로 특정 세션을 강제 종료(ALTER SYSTEM KILL SESSION)하거나, 세션 정보를 조회·조작하는 과정에서 이미 존재하지 않는 세션 ID와 Serial# 조합을 사용할 때 나타납니다. 30년 현장 경험상 이 에러는 DBA가 긴급 세션 정리 작업을 수행할 때 가장 빈번히 마주치는 오류 중 하나입니다.
주요 발생 원인
1. 이미 종료된 세션에 KILL SESSION 명령 실행
가장 흔한 원인으로, DBA가 V$SESSION 뷰를 조회한 뒤 해당 세션을 종료하기 위해 ALTER SYSTEM KILL SESSION 명령을 실행하는 사이에 해당 세션이 스스로 정상 종료된 경우입니다. 조회 시점과 명령 실행 시점 사이의 간격(레이스 컨디션)이 짧더라도 세션이 이미 사라졌다면 ORA-00022가 발생합니다. 특히 짧은 수명의 배치 세션이나 자동 커밋 트랜잭션이 많은 환경에서 자주 목격됩니다.
2. 잘못된 SID, Serial# 조합 사용
ALTER SYSTEM KILL SESSION 'sid, serial#' 명령에서 SID와 Serial# 값 중 하나라도 틀린 경우 이 에러가 발생합니다. 예를 들어 SID는 맞지만 Serial#이 이미 재사용되어 전혀 다른 세션을 가리키거나, 수작업으로 값을 입력하다가 오타가 발생하는 경우입니다. RAC(Real Application Clusters) 환경에서는 인스턴스 번호(Instance ID)까지 정확히 지정해야 하므로 오류 발생 가능성이 더 높아집니다.
3. RAC 환경에서 잘못된 인스턴스 지정
Oracle RAC 환경에서는 세션이 특정 인스턴스에 귀속되기 때문에, ALTER SYSTEM KILL SESSION 'sid, serial#, @inst_id' 형식으로 인스턴스 ID까지 명시해야 합니다. 다른 인스턴스의 SID를 현재 인스턴스에서 종료하려 하거나, 인스턴스 ID를 생략하거나 잘못 입력했을 때 ORA-00022가 발생합니다. 이 경우 GV$SESSION 뷰를 통해 전체 인스턴스의 세션 정보를 확인해야 합니다.
해결 방법
원인 1 해결: 세션 존재 여부 확인 후 KILL SESSION 실행
세션을 종료하기 전 반드시 해당 세션이 현재 활성 상태인지 확인하세요.
-- 1단계: 종료 대상 세션 조회
SELECT sid, serial#, username, status, machine, program
FROM v$session
WHERE username = 'TARGET_USER' -- 종료할 사용자명 입력
AND status != 'KILLED';
-- 2단계: 세션이 존재하는 경우에만 KILL 실행
-- 아래 예시에서 sid=125, serial#=4321 은 실제 조회값으로 교체
ALTER SYSTEM KILL SESSION '125,4321' IMMEDIATE;
-- 3단계: KILL 후 상태 확인 (STATUS가 KILLED로 표시되면 정상)
SELECT sid, serial#, username, status
FROM v$session
WHERE sid = 125;
PL/SQL을 활용하면 세션 존재 여부를 체크하면서 안전하게 종료할 수 있습니다.
DECLARE
v_sid NUMBER := 125;
v_serial NUMBER := 4321;
v_count NUMBER;
BEGIN
-- 세션 존재 여부 확인
SELECT COUNT(*)
INTO v_count
FROM v$session
WHERE sid = v_sid
AND serial# = v_serial
AND status != 'KILLED';
IF v_count > 0 THEN
EXECUTE IMMEDIATE
'ALTER SYSTEM KILL SESSION ''' || v_sid || ',' || v_serial || ''' IMMEDIATE';
DBMS_OUTPUT.PUT_LINE('세션이 성공적으로 종료되었습니다.');
ELSE
DBMS_OUTPUT.PUT_LINE('해당 세션이 존재하지 않거나 이미 종료되었습니다.');
END IF;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -22 THEN
DBMS_OUTPUT.PUT_LINE('ORA-00022: 세션이 이미 종료된 상태입니다.');
ELSE
RAISE;
END IF;
END;
/
원인 2 해결: 올바른 SID와 Serial# 조합 확인
최신 세션 정보를 동적으로 조회하여 종료 스크립트를 생성하세요.
-- 특정 사용자 또는 조건으로 KILL SESSION 스크립트 자동 생성
SELECT 'ALTER SYSTEM KILL SESSION ''' || sid || ',' || serial# || ''' IMMEDIATE;' AS kill_script,
sid,
serial#,
username,
status,
last_call_et AS 비활성_경과초,
machine,
program
FROM v$session
WHERE username IS NOT NULL
AND status = 'INACTIVE'
AND last_call_et > 3600 -- 1시간 이상 비활성 세션
ORDER BY last_call_et DESC;
원인 3 해결: RAC 환경에서 올바른 KILL SESSION
RAC 환경에서는 반드시 GV$SESSION으로 인스턴스 ID를 포함하여 조회하세요.
-- RAC 전체 인스턴스에서 세션 조회
SELECT inst_id,
sid,
serial#,
username,
status,
machine,
'ALTER SYSTEM KILL SESSION ''' || sid || ',' || serial#
|| ',@' || inst_id || ''' IMMEDIATE;' AS kill_script
FROM gv$session
WHERE username = 'TARGET_USER'
AND status != 'KILLED'
ORDER BY inst_id, sid;
-- RAC에서 특정 인스턴스 세션 종료 (inst_id=2 예시)
ALTER SYSTEM KILL SESSION '125,4321,@2' IMMEDIATE;
OS 레벨에서 프로세스 강제 종료 (최후 수단)
Oracle KILL SESSION으로 해결되지 않는 경우 OS 프로세스를 직접 종료할 수 있습니다.
-- Oracle 프로세스 PID 확인
SELECT s.sid,
s.serial#,
s.username,
p.spid AS os_pid,
s.status
FROM v$session s
JOIN v$process p ON p.addr = s.paddr
WHERE s.sid = 125;
# Linux/Unix에서 OS 프로세스 강제 종료
kill -9 <os_pid>
# 예시
kill -9 23841
예방 방법
1. KILL SESSION 전 세션 상태를 자동 검증하는 래퍼 프로시저 운영
운영 환경에서는 DBA가 직접 ALTER SYSTEM KILL SESSION을 실행하는 대신, 세션 존재 여부와 상태를 사전에 검증하는 공통 프로시저를 만들어 사용하세요. 이 프로시저 내에서 ORA-00022 예외를 처리하면 불필요한 에러 발생을 막고 안정적인 운영이 가능합니다. 또한 세션 종료 이력을 별도 테이블에 로깅하면 감사(Audit) 목적으로도 활용할 수 있습니다.
-- 세션 종료 이력 테이블 예시
CREATE TABLE dba_session_kill_log (
log_id NUMBER GENERATED ALWAYS AS IDENTITY,
kill_time TIMESTAMP DEFAULT SYSTIMESTAMP,
sid NUMBER,
serial_num NUMBER,
inst_id NUMBER,
username VARCHAR2(128),
killed_by VARCHAR2(128) DEFAULT SYS_CONTEXT('USERENV','SESSION_USER'),
result VARCHAR2(200)
);
2. 모니터링 도구와 연계하여 자동화된 세션 관리 체계 구축
장시간 실행 쿼리나 Lock을 유발하는 세션을 탐지하고 자동으로 알림을 보내는 스크립트를 스케줄러(DBMS_SCHEDULER)로 주기적으로 실행하세요. 실시간 대시보드(Oracle Enterprise Manager, Grafana + Prometheus 등)와 연계하면 세션 상태를 실시간으로 파악할 수 있어, 이미 종료된 세션에 KILL 명령을 보내는 실수를 크게 줄일 수 있습니다.
관련 에러
- ORA-00031:
KILL SESSION명령 후 세션이 즉시 종료되지 않고 MARKED FOR KILL 상태로 표시될 때 발생합니다.IMMEDIATE옵션 추가로 대부분 해결됩니다. - ORA-00030: 해당 사용자 프로세스가 존재하지 않을 때 발생하는 에러로, ORA-00022와 유사한 맥락에서 나타납니다.
- ORA-01012: “not logged on” 에러로, 세션 연결이 끊어진 상태에서 작업을 시도할 때 발생하며 세션 관리 오류와 연관됩니다.
- ORA-00028: “your session has been killed” 에러로, 종료된 세션에서 추가 작업을 시도할 때 클라이언트 측에서 발생합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.