Oracle ORA-00018 오류 원인과 해결 방법 완벽 가이드

ORA-00018
2026년 10월 21일 | DBMS Error 가이드

이 글에서 다루는 내용

ORA-00018 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

ORA-00018 maximum number of sessions exceeded 는?

ORA-00018 에러는 Oracle 데이터베이스에서 허용된 최대 세션 수를 초과했을 때 발생하는 에러입니다. Oracle은 초기화 파라미터 SESSIONS로 동시에 접속할 수 있는 세션의 최대 개수를 제한하며, 이 한도에 도달하면 새로운 접속 시도가 즉시 차단됩니다. 운영 중인 애플리케이션의 커넥션 풀 설정이 잘못되었거나, 커넥션 누수(Connection Leak)가 발생한 경우 트래픽이 급증할 때 자주 목격되는 에러입니다.


주요 발생 원인

  • SESSIONS 파라미터 값이 실제 업무 부하 대비 너무 낮게 설정된 경우

Oracle의 SESSIONS 파라미터는 데이터베이스가 허용하는 동시 세션의 절대 최대값을 정의합니다. 초기 설치 시 기본값(보통 PROCESSES * 1.5 + 22)으로 설정되는 경우가 많은데, 운영 환경에서 사용자 수나 애플리케이션 연결 수가 급격히 증가하면 이 값이 부족해질 수 있습니다. 특히 배치 작업과 OLTP 트래픽이 동시에 몰리는 업무 피크 타임에 이 현상이 두드러집니다.

  • 커넥션 풀(Connection Pool)의 잘못된 설정 또는 커넥션 누수(Connection Leak)

WAS(WebLogic, JBoss, Tomcat 등)나 애플리케이션에서 사용한 커넥션을 제대로 반환하지 않으면, 사용하지 않는 세션들이 데이터베이스에 계속 남아 세션 자원을 고갈시킵니다. 커넥션 풀의 최대 연결 수(Max Pool Size)가 과도하게 높게 설정되어 있거나, 예외 처리 로직에서 커넥션을 닫지 않는 버그가 있을 경우 시간이 지날수록 세션이 누적되어 결국 ORA-00018이 발생합니다.

  • 좀비 세션(Zombie Session) 및 비정상 종료된 세션의 누적

네트워크 장애, 클라이언트 프로세스 강제 종료, 또는 sqlnet.ora의 Dead Connection Detection(DCD) 설정 미흡으로 인해 이미 클라이언트가 끊어졌음에도 서버 쪽에서 세션이 살아있는 것으로 인식되는 좀비 세션이 발생합니다. 이러한 세션들은 실제 작업은 없지만 세션 카운트를 점유하여 정상적인 신규 접속을 방해합니다.


해결 방법

1. 현재 세션 및 파라미터 상태 확인

먼저 현재 세션 수와 파라미터 설정값을 확인합니다.

-- 현재 세션 수 및 허용 최대값 확인
SELECT
    COUNT(*) AS current_sessions,
    (SELECT value FROM v$parameter WHERE name = 'sessions') AS max_sessions,
    (SELECT value FROM v$parameter WHERE name = 'processes') AS max_processes
FROM v$session;

-- 상태별 세션 현황 상세 조회
SELECT
    status,
    type,
    COUNT(*) AS session_count
FROM v$session
GROUP BY status, type
ORDER BY session_count DESC;

2. SESSIONS 파라미터 값 증가 (SPFile 사용 환경)

SESSIONS 파라미터는 정적(static) 파라미터이므로 변경 후 재시작이 필요합니다.

-- 현재 설정값 확인
SHOW PARAMETER sessions;
SHOW PARAMETER processes;

-- PROCESSES와 SESSIONS 값을 함께 상향 조정 (SESSIONS = PROCESSES * 1.5 + 22 권장)
ALTER SYSTEM SET processes = 500 SCOPE = SPFILE;
ALTER SYSTEM SET sessions = 772 SCOPE = SPFILE;

-- 변경 후 데이터베이스 재시작 필요
SHUTDOWN IMMEDIATE;
STARTUP;

-- 재시작 후 변경값 확인
SHOW PARAMETER sessions;
SHOW PARAMETER processes;

3. 불필요한 세션 강제 종료

긴급 상황에서는 좀비 세션이나 장시간 INACTIVE 상태인 세션을 강제 종료하여 즉시 여유를 확보합니다.

-- 30분 이상 INACTIVE 상태인 세션 조회
SELECT
    sid,
    serial#,
    username,
    status,
    last_call_et,
    machine,
    program
FROM v$session
WHERE status = 'INACTIVE'
  AND username IS NOT NULL
  AND last_call_et > 1800
ORDER BY last_call_et DESC;

-- 특정 세션 강제 종료 (SID, SERIAL# 값을 위 쿼리 결과로 대체)
ALTER SYSTEM KILL SESSION '123,4567' IMMEDIATE;

-- 다수의 좀비 세션을 한 번에 처리하는 스크립트 생성
SELECT 'ALTER SYSTEM KILL SESSION ''' || sid || ',' || serial# || ''' IMMEDIATE;'
FROM v$session
WHERE status = 'INACTIVE'
  AND username IS NOT NULL
  AND last_call_et > 3600;

4. 커넥션 누수 원인 세션 특정

특정 프로그램이나 머신에서 과도하게 세션을 점유하는지 확인합니다.

-- 프로그램/머신별 세션 수 집계
SELECT
    machine,
    program,
    username,
    status,
    COUNT(*) AS session_count
FROM v$session
WHERE username IS NOT NULL
GROUP BY machine, program, username, status
ORDER BY session_count DESC;

-- 특정 서버 또는 애플리케이션 서버의 모든 세션 조회
SELECT sid, serial#, username, status, last_call_et, sql_id
FROM v$session
WHERE machine = 'APP_SERVER_01'
ORDER BY last_call_et DESC;

5. Resource Manager를 통한 세션 제한 (선제적 조치)

특정 사용자나 프로파일에 동시 세션 수를 제한하여 세션 자원 독점을 방지합니다.

-- 사용자 프로파일로 세션 수 제한
CREATE PROFILE limited_session_profile LIMIT
    SESSIONS_PER_USER 10
    IDLE_TIME 30
    CONNECT_TIME 480;

-- 기존 사용자에게 프로파일 적용
ALTER USER app_user PROFILE limited_session_profile;

-- 프로파일 적용 확인
SELECT username, profile FROM dba_users WHERE username = 'APP_USER';

예방 방법

  • 세션 사용량 모니터링 자동화 및 임계값 알림 설정

ORA-00018이 발생하기 전에 미리 감지하는 것이 핵심입니다. Oracle Enterprise Manager(OEM)의 알림 기능을 활용하거나, 아래와 같은 모니터링 쿼리를 스케줄러(DBMS_SCHEDULER)로 주기적으로 실행하여 세션 사용률이 80%를 초과할 경우 DBA에게 이메일 또는 알림을 발송하도록 구성합니다. 또한 AWR(Automatic Workload Repository) 보고서를 주기적으로 검토하여 세션 사용 추이를 파악하고 파라미터 증설 시점을 미리 계획하는 것이 중요합니다.

“`sql

— 세션 사용률 확인 쿼리 (80% 초과 시 경고)

SELECT

current_utilization,

max_utilization,

limit_value,

ROUND(current_utilization / limit_value * 100, 2) AS usage_pct

FROM v$resource_limit

WHERE resource_name = ‘sessions’;

“`

  • 커넥션 풀 적정 설정 및 Dead Connection Detection(DCD) 활성화

애플리케이션 레벨에서 커넥션 풀의 최소/최대 연결 수를 업무 특성에 맞게 적절히 설정하고, 커넥션 유효성 검사(Validation Query) 옵션을 활성화하여 죽은 연결이 풀에 잔류하지 않도록 해야 합니다. Oracle 서버 측에서는 sqlnet.ora에 SQLNET.EXPIRE_TIME 파라미터를 설정(예: 10분)하여 끊어진 클라이언트 세션을 자동으로 감지하고 정리하는 DCD 기능을 활성화하는 것이 필수적입니다.

“`sql

— sqlnet.ora 설정 예시 (파일 편집, SQL이 아닌 OS 레벨 설정)

— SQLNET.EXPIRE_TIME = 10 (단위: 분)

— 현재 DCD 설정 확인 (Alert Log 또는 아래 쿼리 활용)

SELECT name, value

FROM v$parameter

WHERE name IN (‘sessions’, ‘processes’, ‘license_max_sessions’);

“`


관련 에러

  • ORA-00019: maximum number of session licenses exceeded — LICENSE_MAX_SESSIONS 파라미터로 설정된 라이선스 기반 세션 제한을 초과했을 때 발생하는 에러로, ORA-00018과 유사하지만 라이선스 관점에서의 제한입니다.
  • ORA-00020: maximum number of processes exceeded — PROCESSES 파라미터 한도 초과 시 발생하며, ORA-00018과 함께 연쇄적으로 발생하는 경우가 많습니다. SESSIONS 값은 PROCESSES 값에 종속적이므로 두 파라미터를 함께 조정해야 합니다.
  • ORA-12516: TNS:listener could not find available handler with matching protocol stack — 리스너가 처리 가능한 서버 프로세스를 찾지 못할 때 발생하며, 세션 과부하 상황에서 ORA-00018과 함께 나타나는 경우가 잦습니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기