2026년 09월 12일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-12535 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-12535 TNS: operation timed out 는?
ORA-12535 에러는 Oracle 클라이언트가 서버와 네트워크 연결을 시도하는 과정에서 지정된 시간 내에 응답을 받지 못했을 때 발생하는 TNS(Transparent Network Substrate) 계층의 타임아웃 에러입니다. 이 에러는 단순한 네트워크 단절부터 방화벽 설정 문제, 데이터베이스 리스너 장애까지 다양한 원인에 의해 발생할 수 있습니다. 특히 운영 환경에서 갑작스럽게 발생할 경우 애플리케이션 전체의 DB 연결이 끊어져 서비스 장애로 이어질 수 있으므로 빠른 원인 파악과 조치가 매우 중요합니다.
주요 발생 원인
1. 네트워크 방화벽 또는 세션 타임아웃 설정 문제
가장 흔한 원인 중 하나로, 클라이언트와 서버 사이에 위치한 방화벽이나 L4 스위치가 유휴 상태(idle)의 TCP 세션을 일정 시간이 지난 후 강제로 종료하는 경우입니다. 오래된 연결이나 커넥션 풀에서 대기 중이던 세션이 방화벽에 의해 끊겼음에도 클라이언트는 이를 인지하지 못하고 이후 쿼리 전송 시 타임아웃이 발생합니다. 이 경우 sqlnet.ora 파일의 SQLNET.EXPIRE_TIME 파라미터를 설정하면 Dead Connection Detection(DCD) 기능을 활성화하여 유효하지 않은 연결을 미리 감지할 수 있습니다.
2. Oracle Listener 장애 또는 응답 불가 상태
Oracle Listener가 정상적으로 실행 중이지 않거나 과부하로 인해 응답이 지연되는 경우 클라이언트는 연결 요청에 대한 응답을 받지 못하고 ORA-12535가 발생합니다. Listener는 데이터베이스로의 모든 네트워크 연결 요청을 중계하는 핵심 컴포넌트이기 때문에, Listener 프로세스가 비정상 종료되거나 포트 충돌이 발생하면 전체 연결이 불가능해집니다. 서버에서 lsnrctl status 명령어로 Listener 상태를 즉시 확인하고, 필요 시 재시작하는 절차가 필요합니다.
3. sqlnet.ora 및 tnsnames.ora 의 잘못된 타임아웃 설정
sqlnet.ora 파일에 설정된 SQLNET.INBOUND_CONNECT_TIMEOUT, SQLNET.SEND_TIMEOUT, SQLNET.RECV_TIMEOUT 값이 너무 짧게 설정되어 있거나, tnsnames.ora의 CONNECT_TIMEOUT 파라미터가 실제 네트워크 지연 시간보다 작게 설정된 경우 정상적인 연결임에도 타임아웃이 발생할 수 있습니다. 특히 WAN(광역 네트워크) 환경이나 지리적으로 멀리 떨어진 서버에 접속할 때 이 문제가 자주 나타납니다. 네트워크 RTT(Round-Trip Time)를 측정하고 그에 맞는 적절한 타임아웃 값을 설정하는 것이 중요합니다.
해결 방법
원인 1 해결: Dead Connection Detection 및 Keep-Alive 설정
$ORACLE_HOME/network/admin/sqlnet.ora 파일에 아래 설정을 추가하여 유휴 연결을 주기적으로 확인하고 방화벽에 의한 강제 종료를 방지합니다.
-- sqlnet.ora 파일 설정 (분 단위, 10분마다 probe packet 전송)
-- SQLNET.EXPIRE_TIME = 10
-- 현재 세션의 연결 상태 확인 (DBA 권한 필요)
SELECT sid, serial#, username, status, last_call_et, machine, program
FROM v$session
WHERE status = 'INACTIVE'
AND last_call_et > 600 -- 600초(10분) 이상 비활성 세션
ORDER BY last_call_et DESC;
-- 특정 유휴 세션 강제 종료 (방화벽에 의해 이미 끊긴 좀비 세션 정리)
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
-- 예시: SID=123, SERIAL#=456 인 세션 종료
ALTER SYSTEM KILL SESSION '123,456' IMMEDIATE;
OS 레벨에서 TCP Keep-Alive를 설정하는 방법도 병행합니다.
-- TCP Keep-Alive 관련 파라미터 확인 (Linux 서버 기준)
-- /proc/sys/net/ipv4/tcp_keepalive_time (기본 7200초 → 300초로 단축 권장)
-- /proc/sys/net/ipv4/tcp_keepalive_intvl (기본 75초)
-- /proc/sys/net/ipv4/tcp_keepalive_probes (기본 9회)
-- Oracle 파라미터 레벨에서 TCP 연결 확인
SELECT name, value
FROM v$parameter
WHERE name IN ('local_listener', 'remote_listener', 'dispatchers');
원인 2 해결: Listener 상태 점검 및 복구
-- Listener 현재 연결 세션 수 확인
SELECT count(*) AS total_connections,
status,
server
FROM v$session
WHERE type = 'USER'
GROUP BY status, server;
-- Listener 로그 경로 확인
SELECT value
FROM v$diag_info
WHERE name = 'Diag Trace';
-- Listener에 등록된 서비스 목록 조회
SELECT name, network_name, creation_date
FROM v$services
ORDER BY name;
-- 동적 서비스 등록 확인
SELECT inst_id, instance_name, status, host_name
FROM gv$instance;
-- Listener 포트 사용 여부 확인용 쿼리 (1521 기본 포트)
SELECT dbms_xdb_config.gethttpsport() AS https_port,
dbms_xdb_config.gethttpport() AS http_port
FROM dual;
서버 OS에서 직접 실행하는 명령어:
-- 아래는 OS 커맨드이나 sqlplus에서 host 명령으로 실행 가능
-- host lsnrctl status
-- host lsnrctl stop
-- host lsnrctl start
-- Listener 재기동 후 정상 등록 여부 확인
SELECT name, open_mode, db_unique_name
FROM v$database;
원인 3 해결: TNS 타임아웃 파라미터 조정
-- tnsnames.ora 설정 예시 (CONNECT_TIMEOUT 값 상향 조정)
/*
ORCL =
(DESCRIPTION =
(CONNECT_TIMEOUT=30) -- 기본 60초, 필요시 증가
(RETRY_COUNT=3) -- 재시도 횟수
(RETRY_DELAY=3) -- 재시도 간격(초)
(ADDRESS =
(PROTOCOL = TCP)
(HOST = db-server-ip)
(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ORCL)))
*/
-- sqlnet.ora 타임아웃 파라미터 설정
/*
SQLNET.INBOUND_CONNECT_TIMEOUT = 60 -- 인바운드 연결 타임아웃(초)
SQLNET.SEND_TIMEOUT = 60 -- 데이터 전송 타임아웃(초)
SQLNET.RECV_TIMEOUT = 60 -- 데이터 수신 타임아웃(초)
SQLNET.EXPIRE_TIME = 10 -- DCD probe 주기(분)
*/
-- 현재 적용된 네트워크 관련 파라미터 확인
SELECT name, value, description
FROM v$parameter
WHERE name LIKE '%timeout%'
OR name LIKE '%listener%'
ORDER BY name;
-- 알림 로그에서 ORA-12535 관련 에러 이력 조회 (Oracle 11g 이상)
SELECT originating_timestamp,
message_text
FROM v$diag_alert_ext
WHERE message_text LIKE '%ORA-12535%'
OR message_text LIKE '%TNS%timeout%'
ORDER BY originating_timestamp DESC
FETCH FIRST 20 ROWS ONLY;
예방 방법
1. SQLNET.EXPIRE_TIME을 이용한 Dead Connection Detection 상시 활성화
운영 환경의 모든 Oracle 서버 sqlnet.ora에 SQLNET.EXPIRE_TIME=10 (10분)을 반드시 설정하여 방화벽이나 네트워크 장비에 의해 끊어진 좀비 세션을 자동으로 감지하고 정리하는 체계를 구축해야 합니다. 아울러 애플리케이션 커넥션 풀(Connection Pool) 설정에서도 testOnBorrow, validationQuery 옵션을 활성화하여 연결 유효성을 주기적으로 검증하는 것을 권장합니다. 이를 통해 타임아웃으로 인한 장애를 사전에 차단하고 안정적인 서비스를 유지할 수 있습니다.
2. 네트워크 모니터링 및 정기적인 Listener 헬스체크 자동화
아래와 같은 스크립트를 cron job으로 등록하여 Listener 상태와 연결 수를 주기적으로 모니터링하고 임계치 초과 시 자동 알림을 발송하는 체계를 구축해야 합니다. 또한 AWR(Automatic Workload Repository) 또는 OEM(Oracle Enterprise Manager)을 활용하여 네트워크 관련 대기 이벤트(SQLNet message from client, SQLNet more data from client)를 지속적으로 추적하면 ORA-12535 발생 전 조기 징후를 포착할 수 있습니다.
-- 네트워크 관련 대기 이벤트 모니터링
SELECT event,
total_waits,
total_timeouts,
time_waited,
average_wait
FROM v$system_event
WHERE event LIKE 'SQL*Net%'
OR event LIKE '%listener%'
ORDER BY total_timeouts DESC;
-- 최근 연결 실패 이력 확인
SELECT sample_time,
event,
session_state,
sql_id
FROM v$active_session_history
WHERE event LIKE '%timeout%'
AND sample_time > SYSDATE - 1/24 -- 최근 1시간
ORDER BY sample_time DESC;
관련 에러
- ORA-12170: TNS: Connect timeout occurred — ORA-12535와 유사하나 주로 INBOUND_CONNECT_TIMEOUT 초과 시 서버 측에서 발생하는 에러입니다.
- ORA-12541: TNS: no listener — Listener 자체가 중지된 경우 발생하며, ORA-12535와 함께 Listener 장애 시나리오에서 자주 등장합니다.
- ORA-12543: TNS: destination host unreachable — 네트워크 경로 자체가 없을 때 발생하며, ORA-12535 이전 단계의 네트워크 문제를 나타냅니다.
- ORA-03113: end-of-file on communication channel — 연결이 강제 종료된 후 쿼리를 실행할 때 발생하는 에러로, 방화벽에 의한 세션 종료 이후 ORA-12535와 함께 나타날 수 있습니다.
- ORA-03114: not connected to ORACLE — 세션이 이미 끊긴 상태에서 SQL을 실행할 때 발생하며, 타임아웃 이후 후속으로 나타나는 에러입니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.