2026년 10월 21일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-00020 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-00020 maximum number of processes exceeded 는?
ORA-00020 에러는 Oracle 데이터베이스에 접속하려는 프로세스 수가 초기화 파라미터 PROCESSES에 설정된 최댓값을 초과했을 때 발생합니다. 새로운 세션이나 백그라운드 프로세스가 더 이상 생성될 수 없는 상태로, 사실상 데이터베이스에 신규 접속이 불가능해집니다. 이 에러는 갑작스러운 트래픽 폭증, 세션 누수(Session Leak), 또는 잘못된 커넥션 풀 설정 등으로 인해 운영 환경에서 빈번하게 발생하며, 서비스 장애로 직결될 수 있는 매우 심각한 에러입니다.
주요 발생 원인
PROCESSES파라미터 값이 너무 낮게 설정된 경우
Oracle 인스턴스 기동 시 설정되는 PROCESSES 파라미터는 동시에 실행 가능한 OS 프로세스(백그라운드 프로세스 + 사용자 프로세스)의 최대 개수를 정의합니다. 시스템 도입 초기에는 적절한 값이었더라도, 시간이 지남에 따라 사용자 수나 애플리케이션 서버가 증가하면 기존에 설정된 값이 부족해지는 경우가 많습니다. 특히 많은 기업 환경에서 기본값(150 또는 300)을 그대로 유지하다가 이 에러를 마주치는 경우가 다반사입니다.
- 세션 누수(Session Leak) 및 좀비 세션 과다
애플리케이션에서 DB 커넥션을 사용한 후 명시적으로 close() 또는 disconnect()를 호출하지 않으면 세션이 계속 Oracle에 남아 있게 됩니다. 이런 좀비 세션(Zombie Session)들이 누적되면 실제 사용자 수가 많지 않더라도 PROCESSES 한도에 빠르게 도달하게 됩니다. 장시간 운영되는 배치 프로그램이나 ORM 프레임워크(Hibernate, MyBatis 등)의 잘못된 설정도 이 문제의 주요 원인이 됩니다.
- 커넥션 풀(Connection Pool) 설정 오류
WAS(Web Application Server) 또는 미들웨어의 커넥션 풀 최대 크기(Max Pool Size)가 지나치게 크게 설정되거나, 여러 WAS 인스턴스가 각자 대규모 커넥션 풀을 유지할 경우 순식간에 PROCESSES 한도를 초과할 수 있습니다. 예를 들어 WAS 10대가 각각 Max Connection 50으로 설정되어 있다면 최대 500개의 DB 커넥션이 생성될 수 있으며, 여기에 백그라운드 프로세스 수까지 더하면 기본 PROCESSES 값은 금세 부족해집니다.
해결 방법
1단계: 현재 프로세스 및 세션 현황 확인
먼저 현재 상태를 정확히 파악하는 것이 최우선입니다.
-- 현재 PROCESSES 파라미터 값 확인
SHOW PARAMETER PROCESSES;
-- 현재 활성 프로세스 수 확인
SELECT COUNT(*) AS current_processes FROM v$process;
-- 현재 세션 수 및 상태별 분류 확인
SELECT status, COUNT(*) AS cnt
FROM v$session
GROUP BY status
ORDER BY cnt DESC;
-- 사용자별 세션 수 확인 (세션 누수 의심 계정 탐지)
SELECT username, status, COUNT(*) AS session_count
FROM v$session
WHERE username IS NOT NULL
GROUP BY username, status
ORDER BY session_count DESC;
-- 장시간 비활성 세션 확인 (좀비 세션 탐지)
SELECT sid, serial#, username, status,
last_call_et AS inactive_seconds,
machine, program
FROM v$session
WHERE status = 'INACTIVE'
AND last_call_et > 3600 -- 1시간 이상 비활성
AND username IS NOT NULL
ORDER BY last_call_et DESC;
2단계: PROCESSES 파라미터 값 증설
단기 조치로 PROCESSES 값을 늘려 즉시 접속을 가능하게 합니다. 단, PROCESSES는 정적(Static) 파라미터이므로 반드시 DB 재기동이 필요합니다.
-- SPFILE을 사용하는 경우 (권장)
-- 현재 값 확인
SELECT name, value, description
FROM v$parameter
WHERE name IN ('processes', 'sessions');
-- PROCESSES 값 변경 (재기동 후 적용)
ALTER SYSTEM SET PROCESSES = 500 SCOPE = SPFILE;
-- SESSIONS는 PROCESSES 변경 시 자동 계산되지만 명시적으로도 설정 가능
-- 일반적으로 SESSIONS = PROCESSES * 1.1 + 5 공식 적용
ALTER SYSTEM SET SESSIONS = 555 SCOPE = SPFILE;
-- 변경 사항 확인 후 DB 재기동
-- SHUTDOWN IMMEDIATE;
-- STARTUP;
-- 재기동 후 적용 확인
SHOW PARAMETER PROCESSES;
SHOW PARAMETER SESSIONS;
3단계: 좀비 세션 강제 종료
장기적인 해결책을 적용하기 전, 누적된 좀비 세션을 제거하여 긴급 조치합니다.
-- 종료할 세션 목록 조회 (1시간 이상 비활성 세션)
SELECT 'ALTER SYSTEM KILL SESSION ''' || sid || ',' || serial# || ''' IMMEDIATE;' AS kill_cmd,
username,
status,
last_call_et,
machine,
program
FROM v$session
WHERE status = 'INACTIVE'
AND last_call_et > 3600
AND username IS NOT NULL
ORDER BY last_call_et DESC;
-- 특정 세션 강제 종료
ALTER SYSTEM KILL SESSION '123,456' IMMEDIATE;
-- OS 레벨에서 프로세스 강제 종료가 필요한 경우 spid 확인
SELECT p.spid AS os_pid, s.sid, s.serial#, s.username, s.status
FROM v$process p
JOIN v$session s ON p.addr = s.paddr
WHERE s.status = 'INACTIVE'
AND s.last_call_et > 7200;
4단계: 자동 세션 정리를 위한 Profile 설정
-- 비활성 세션 자동 종료 Profile 생성
CREATE PROFILE limited_session_profile LIMIT
IDLE_TIME 30 -- 30분 비활성 시 자동 종료
CONNECT_TIME 480 -- 최대 8시간 연결 유지
SESSIONS_PER_USER 10; -- 계정당 최대 세션 수 제한
-- 특정 사용자에게 Profile 적용
ALTER USER app_user PROFILE limited_session_profile;
-- 적용 결과 확인
SELECT username, profile
FROM dba_users
WHERE username = 'APP_USER';
예방 방법
- 프로세스 수 모니터링 자동화 및 임계값 알림 설정
ORA-00020 에러는 대부분 사전 감지가 가능합니다. PROCESSES 파라미터 대비 현재 프로세스 사용률을 주기적으로 모니터링하고, 80% 이상 도달 시 알림을 발송하는 체계를 구축해야 합니다. Oracle Enterprise Manager(OEM), Zabbix, Grafana+Prometheus 등 모니터링 툴을 활용하거나 아래와 같은 쿼리를 cron 스케줄러로 주기적으로 실행하여 임계값 초과 시 DBA에게 알림을 보내는 스크립트를 운용하는 것을 강력히 권장합니다.
“`sql
— 프로세스 사용률 모니터링 쿼리 (80% 초과 시 경고)
SELECT p.current_utilization,
p.max_utilization,
p.limit_value AS processes_limit,
ROUND(p.current_utilization / p.limit_value * 100, 2) AS utilization_pct
FROM v$resource_limit p
WHERE resource_name = ‘processes’;
“`
- 애플리케이션 레벨의 커넥션 관리 표준화
모든 애플리케이션은 반드시 try-finally 블록 또는 try-with-resources 패턴을 사용하여 DB 커넥션을 반드시 반환하도록 코딩 표준을 수립하고 코드 리뷰 시 이를 필수 체크 항목으로 지정해야 합니다. 커넥션 풀 라이브러리(HikariCP, DBCP2 등)에서 제공하는 connectionTimeout, idleTimeout, maxLifetime 등의 설정을 반드시 적용하여 유효하지 않은 커넥션이 풀에 남아있지 않도록 관리해야 합니다.
관련 에러
- ORA-00018:
maximum number of sessions exceeded–SESSIONS파라미터 초과 시 발생하며, ORA-00020과 함께 연쇄적으로 발생하는 경우가 많습니다. - ORA-00019:
maximum number of session licenses exceeded– 라이선스 제한으로 인한 세션 초과 에러입니다. - ORA-12516:
TNS: listener could not find available handler with matching protocol stack– 리스너가 더 이상 서버 프로세스를 할당할 수 없을 때 발생하며, ORA-00020과 증상이 유사합니다. - ORA-12518:
TNS: listener could not hand off client connection– 리스너가 클라이언트 커넥션을 처리할 수 없을 때 발생하는 에러로, 역시 프로세스 자원 부족과 관련이 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.