2026년 10월 21일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-00021 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-00021 session attached to some other process 는?
ORA-00021 에러는 Oracle 데이터베이스에서 특정 세션이 이미 다른 프로세스에 연결(attach)되어 있는 상태에서 해당 세션에 접근하려 할 때 발생하는 오류입니다. 주로 멀티스레드 환경이나 Oracle MTS(Multi-Threaded Server, 현재는 Shared Server) 구성에서 세션과 프로세스 간의 연결 관계가 충돌할 때 나타납니다. 잘못된 세션 전환(Session Switch) 또는 비정상적인 연결 해제 없이 세션을 재사용하려는 시도에서도 동일한 에러가 발생할 수 있습니다.
주요 발생 원인
1. Shared Server(MTS) 환경에서의 세션 충돌
Oracle Shared Server 환경에서는 여러 클라이언트가 하나의 서버 프로세스를 공유합니다. 이 구조에서 특정 세션이 dispatcher를 통해 공유 서버 프로세스에 attach된 상태에서, 다른 프로세스가 동일 세션에 접근하려 하면 ORA-00021이 발생합니다. 특히 비정상적인 네트워크 단절이나 클라이언트 강제 종료 후 세션이 완전히 해제되지 않은 채 남아 있을 경우 이 문제가 더욱 빈번하게 발생합니다.
2. DBMS_SESSION.SWITCH_CURRENT_CONSUMER_GROUP 또는 세션 전환 로직의 오류
애플리케이션 레벨에서 세션을 전환하거나 재사용하는 로직(예: 커넥션 풀링 미들웨어)이 세션을 올바르게 detach하지 않은 상태로 다른 스레드에서 접근하려 할 때 이 에러가 발생합니다. 특히 Java, Python 등 멀티스레드 애플리케이션에서 커넥션 풀이 세션을 공유할 때 동기화 문제로 인해 같은 세션 객체를 동시에 두 스레드가 사용하려는 상황에서 나타납니다. 이 경우 애플리케이션 로그와 Oracle alert log를 동시에 분석하는 것이 필요합니다.
3. 비정상 종료된 세션의 잔류(Zombie Session)
클라이언트 프로그램이 비정상적으로 종료되거나 네트워크 장애가 발생했을 때, Oracle 서버 측에 세션이 완전히 정리되지 않고 남아 있는 경우가 있습니다. 이 좀비 세션(Zombie Session)은 여전히 특정 프로세스에 attach된 것으로 기록되어 있어, 이후 동일한 세션 ID를 재사용하거나 해당 세션에 접근하려는 시도가 ORA-00021을 유발할 수 있습니다. Dead Connection Detection(DCD) 설정이 미흡하거나 SQLNET.EXPIRE_TIME 파라미터가 설정되지 않은 환경에서 특히 자주 발생합니다.
해결 방법
1. 현재 문제 세션 확인
먼저 V$SESSION과 V$PROCESS 뷰를 조인하여 문제가 되는 세션과 연결된 프로세스를 식별합니다.
-- 현재 활성 세션 및 연결된 프로세스 확인
SELECT s.sid,
s.serial#,
s.username,
s.status,
s.machine,
s.program,
p.spid AS os_process_id,
s.logon_time,
s.last_call_et AS seconds_since_last_call
FROM v$session s
JOIN v$process p ON s.paddr = p.addr
WHERE s.type = 'USER'
AND s.status IN ('ACTIVE', 'INACTIVE')
ORDER BY s.last_call_et DESC;
2. 좀비 세션 식별 및 강제 종료
오랫동안 비활성 상태이거나 프로세스가 실제로 살아있지 않은 세션을 찾아 강제 종료합니다.
-- 1시간 이상 비활성 상태인 세션 조회
SELECT s.sid,
s.serial#,
s.username,
s.status,
s.machine,
ROUND(s.last_call_et / 3600, 2) AS inactive_hours
FROM v$session s
WHERE s.status = 'INACTIVE'
AND s.last_call_et > 3600
AND s.username IS NOT NULL
ORDER BY s.last_call_et DESC;
-- 문제 세션 강제 종료 (SID, SERIAL# 값을 위 쿼리 결과로 교체)
ALTER SYSTEM KILL SESSION '123,4567' IMMEDIATE;
3. OS 레벨에서 프로세스 확인 및 정리
Oracle 서버 프로세스가 OS 레벨에서도 실제로 살아있는지 확인합니다.
-- Oracle 프로세스의 OS PID 확인
SELECT s.sid,
s.serial#,
s.username,
p.spid AS os_pid,
s.status
FROM v$session s
JOIN v$process p ON s.paddr = p.addr
WHERE s.sid = &target_sid;
위 쿼리로 OS PID를 확인한 뒤, Linux/Unix 환경에서는 아래 명령으로 프로세스 존재 여부를 확인하고 필요 시 kill 합니다.
# OS 프로세스 확인
ps -ef | grep <spid>
# 프로세스 강제 종료 (필요 시)
kill -9 <spid>
4. Shared Server 환경 설정 재검토
-- Shared Server 관련 파라미터 확인
SHOW PARAMETER shared_servers;
SHOW PARAMETER dispatchers;
SHOW PARAMETER max_shared_servers;
-- Dispatcher 상태 확인
SELECT name, status, accepted, refused, current_load
FROM v$dispatcher;
-- Shared Server 상태 확인
SELECT name, status, requests, idle, busy
FROM v$shared_server;
5. Dead Connection Detection 설정
sqlnet.ora 파일에 아래 설정을 추가하여 죽은 연결을 자동으로 감지합니다.
-- sqlnet.ora 설정 확인 (Oracle Net 파라미터)
-- 아래는 DBA가 sqlnet.ora에 추가해야 할 설정 예시
-- SQLNET.EXPIRE_TIME = 10 (단위: 분)
-- 이 설정 적용 후 확인
SELECT name, value
FROM v$parameter
WHERE name LIKE '%expire%'
OR name LIKE '%dead%';
예방 방법
1. 커넥션 풀링 및 세션 관리 정책 강화
애플리케이션에서 커넥션 풀을 사용할 때는 반드시 각 스레드가 독립된 커넥션을 사용하도록 설계해야 하며, 세션을 여러 스레드 간에 공유하는 구조는 반드시 피해야 합니다. Oracle JDBC, ODP.NET 등 공식 드라이버의 커넥션 풀 설정(최소/최대 커넥션 수, 유효성 검사 쿼리 등)을 환경에 맞게 튜닝하고, 주기적으로 커넥션 상태를 모니터링하는 스크립트를 운영 체계에 포함시키는 것이 좋습니다.
2. Dead Connection Detection 및 세션 타임아웃 설정
sqlnet.ora의 SQLNET.EXPIRE_TIME 파라미터를 적절한 값(예: 10분)으로 설정하여 비정상 종료된 클라이언트의 세션이 서버에 오래 남아있지 않도록 합니다. 또한 Oracle Profile을 활용하여 IDLE_TIME 제한을 설정하면, 일정 시간 동안 아무런 활동이 없는 세션을 자동으로 종료시켜 좀비 세션 누적을 방지할 수 있습니다.
-- Profile을 이용한 세션 IDLE TIME 제한 설정
CREATE PROFILE app_user_profile LIMIT
IDLE_TIME 30 -- 30분 비활성 시 세션 종료
CONNECT_TIME 480 -- 최대 8시간 연결 제한
SESSIONS_PER_USER 10; -- 동일 사용자 동시 세션 제한
-- 기존 사용자에 Profile 적용
ALTER USER app_user PROFILE app_user_profile;
-- Profile 설정 확인
SELECT profile, resource_name, limit
FROM dba_profiles
WHERE profile = 'APP_USER_PROFILE'
ORDER BY resource_name;
관련 에러
- ORA-00020:
maximum number of processes exceeded— 최대 프로세스 수 초과로 새로운 세션을 생성할 수 없을 때 발생하며, 세션/프로세스 관리 문제와 함께 나타나는 경우가 많습니다. - ORA-00031:
session marked for kill— KILL SESSION 명령 후 세션이 즉시 종료되지 않고 종료 대기 상태로 표시될 때 발생합니다. - ORA-02396:
exceeded maximum idle time— Profile의 IDLE_TIME 제한에 의해 세션이 자동 종료될 때 발생하는 에러로, 세션 타임아웃 정책과 밀접한 관련이 있습니다. - ORA-03113:
end-of-file on communication channel— 네트워크 단절이나 서버 프로세스 비정상 종료 시 발생하며, 이후 좀비 세션 생성으로 이어져 ORA-00021을 유발하는 선행 에러가 될 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.